improvements to gem grabbers

- bats as a challenge
- less gem mining on normal
- everrock on insane
- basements for shipyard and inventors lab
epoxy
Maikel de Vries 2016-02-04 17:53:59 +01:00
parent 456678afbd
commit 0ac6093b1a
3 changed files with 91 additions and 118 deletions

View File

@ -84,19 +84,19 @@ public func DrawMainIsland(proplist map, int size)
Draw("Sand", sand_border);
Draw("Earth-earth_root", topsoil_border);
// Draw a bottom border out of granite and rock.
// Draw a bottom border out of granite and rock (or everrock on insane).
var granite_border = {Algo = MAPALGO_Border, Op = island, Bottom = [-4, 3]};
Draw("Granite", granite_border);
var rock_border = {Algo = MAPALGO_RndChecker, Ratio = 20, Wdt = 2, Hgt = 2};
Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw(["Rock", "Granite", "Everrock"][SCENPAR_Difficulty - 1], granite_border);
var rock_border = {Algo = MAPALGO_RndChecker, Ratio = 25, Wdt = 2, Hgt = 2};
Draw(["Granite", "Rock", "Rock"][SCENPAR_Difficulty - 1], {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw(["Granite", "Rock", "Granite"][SCENPAR_Difficulty - 1], {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
// Draw some gems attached at the bottom of the island.
var full_island = {Algo = MAPALGO_Or, Op = [island, granite_border]};
var rect = [x - size / 2, y - size / 3, size / 2, 3 * size / 4];
DrawGems("Ruby", rect, 3, map);
DrawGems("Ruby", rect, 3, map, full_island);
rect = [x, y - size / 3, size / 2, 3 * size / 4];
DrawGems("Amethyst", rect, 3, map);
DrawGems("Amethyst", rect, 3, map, full_island);
return;
}
@ -129,22 +129,22 @@ public func DrawIsland(proplist map, int x, int y, int wdt, int hgt, array mats)
Draw("Sand", sand_border);
Draw("Earth-earth", topsoil_border);
// Draw a bottom border out of granite and rock.
// Draw a bottom border out of granite and rock (or everrock on insane).
var granite_border = {Algo = MAPALGO_Border, Op = island, Bottom = [-2,3]};
Draw("Granite", granite_border);
Draw(["Rock", "Granite", "Everrock"][SCENPAR_Difficulty - 1], granite_border);
var rock_border = {Algo = MAPALGO_RndChecker, Ratio = 20, Wdt = 2, Hgt = 2};
Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw(["Granite", "Rock", "Granite"][SCENPAR_Difficulty - 1], {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
Draw(["Granite", "Rock", "Granite"][SCENPAR_Difficulty - 1], {Algo = MAPALGO_And, Op = [granite_border, rock_border]});
// Draw some gems attached at the bottom of the island.
var gem = ["Ruby", "Amethyst"][Random(2)];
DrawGems(gem, rect, 3, map);
var full_island = {Algo = MAPALGO_Or, Op = [island, granite_border]};
DrawGems(gem, rect, 3, map, full_island);
return true;
}
// Looks for a location at the bottom of a sky islands and places some gems.
public func DrawGems(string gem_mat, array rect, int size, proplist map)
public func DrawGems(string gem_mat, array rect, int size, proplist map, proplist island)
{
// Adapt rect to find at least a spot 8 * MapZoom pixel distance from the map borders.
rect[2] -= Max(0, 8 - rect[0]); rect[0] = Max(8, rect[0]); // Left boundary.
@ -160,14 +160,25 @@ public func DrawGems(string gem_mat, array rect, int size, proplist map)
low_spot = spot;
}
}
// Sometimes draw a large patch of tunnel behind the gems.
if (!Random(3))
{
var gem_tunnel = {Algo = MAPALGO_Ellipsis, X = low_spot.X, Y = low_spot.Y + 2, Wdt = size * 3, Hgt = 2 * size};
gem_tunnel = {Algo = MAPALGO_And, Op = [gem_tunnel, {Algo = MAPALGO_Not, Op = {Algo = MAPALGO_Lines, X = 1, Y = 0, OffX = Random(6), Distance = RandomX(4, 6)}}]};
gem_tunnel = {Algo = MAPALGO_Turbulence, Iterations = 4, Amplitude = 14, Scale = 8, Seed = Random(65536), Op = gem_tunnel};
gem_tunnel = {Algo = MAPALGO_And, Op = [gem_tunnel, {Algo = MAPALGO_Not, Op = island}]};
Draw("Tunnel", gem_tunnel);
}
// Draw the gems.
var gems = {Algo = MAPALGO_Ellipsis, X = low_spot.X, Y = low_spot.Y + 1, Wdt = size - 1, Hgt = size};
gems = {Algo = MAPALGO_Turbulence, Amplitude = 5, Scale = 5, Iterations = 2, Op = gems};
Draw(gem_mat, gems);
// Some granite border above the gems to be sure.
// Some rock/granite/everrock border above the gems to make it harder to reach.
var gem_border = {Algo = MAPALGO_Border, Top = -4, Op = gems};
Draw("Granite", gem_border);
Draw(["Rock", "Granite", "Everrock"][SCENPAR_Difficulty - 1], gem_border);
return;
}
@ -184,6 +195,5 @@ public func DrawIslandMat(string mat, proplist onto_mask, int speck_size, int ra
var mask_border = {Algo = MAPALGO_Border, Op = onto_mask, Wdt = 3};
var algo = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Xor, Op = [onto_mask, mask_border]}, rnd_checker]};
Draw(mat, algo);
return;
}

View File

@ -1,47 +0,0 @@
OverloadMaterials
OverloadTextures
10=Tunnel-tunnel
12=Tunnel-brickback
13=BrickSoft-brick
19=DuroLava-lava_red
20=Water-water
22=Acid-acid
23=Lava-lava_red
25=Water-water
28=Earth-earth
29=Earth-earth_root
30=Earth-earth_spongy
31=Earth-earth
32=Earth-earth
33=Ashes-ashes
36=Ore-ore
40=Granite-granite
42=Granite-rock
45=Gold-gold
50=Rock-rock
51=Rock-rock
53=Firestone-firestone
54=Coal-coal
55=Sand-sand
56=Sand-sand
60=Ruby-ruby
61=Amethyst-amethyst
65=Ice-ice
67=Ice-ice2
70=Snow-snow1
73=Brick-brick

View File

@ -25,18 +25,17 @@ protected func Initialize()
// Goal: Sell Gems, amount depends on difficulty and initial availability.
var gems = (4 * GetMaterialCount(Material("Ruby"))) / (5 * GetMaterialVal("Blast2ObjectRatio", "Material", Material("Ruby")));
gems += (4 * GetMaterialCount(Material("Amethyst"))) / (5 * GetMaterialVal("Blast2ObjectRatio", "Material", Material("Amethyst")));
var percentage = 55 + 15 * SCENPAR_Difficulty;
var percentage = 40 + 20 * SCENPAR_Difficulty;
var goal = CreateObject(Goal_SellGems);
goal->SetTargetAmount((gems * percentage) / 100);
// Initialize different parts of the scenario.
InitEnvironment(SCENPAR_Difficulty);
InitVegetation();
InitAnimals();
InitVegetation(SCENPAR_MapSize);
InitAnimals(SCENPAR_MapSize, SCENPAR_Difficulty);
InitResources(SCENPAR_Difficulty);
InitMainIsland(4 - SCENPAR_Difficulty);
InitIslands(4 - SCENPAR_Difficulty);
return;
}
@ -94,10 +93,10 @@ protected func InitializePlayer(int plr)
// Initializes environment and disasters.
private func InitEnvironment(int difficulty)
{
// Set time to almost night and have stars.
var time = CreateObject(Time);
time->SetTime(20 * 60 + 15);
time->SetCycleSpeed(0);
// Set time to almost night and have stars.
Time->Init();
Time->SetTime(20 * 60 + 15);
Time->SetCycleSpeed(0);
// Clouds and rain.
Cloud->Place(15);
@ -117,39 +116,41 @@ private func InitEnvironment(int difficulty)
// Disasters: meteors and lightning.
Meteor->SetChance(2 * difficulty);
Cloud->SetLightning(8 * difficulty);
Cloud->SetLightning(3 * difficulty**2 + difficulty + 2);
return;
}
// Initializes grass, trees and in-earth objects.
private func InitVegetation()
private func InitVegetation(int amount)
{
// Grass on all islands.
PlaceGrass(85);
Grass->Place(85);
// Place some cocont trees all around the island and some extra trees on the main island.
for (var i = 0; i < 40 + Random(8); i++)
PlaceVegetation(Tree_Coconut, 0, 0, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(40)));
for (var i = 0; i < 6 + Random(2); i++)
PlaceVegetation(Tree_Coconut, LandscapeWidth()/2 - 300, LandscapeHeight()/2 - 200, 600, 400, 1000 * (71 + Random(30)));
// Vegetation around all islands.
Flower->Place(10 + 4 * amount);
Mushroom->Place(10 + 4 * amount);
Branch->Place(10 + 4 * amount);
Trunk->Place(4 + 2 * amount);
// Place trees around the islands.
Tree_Deciduous->Place(10 + 4 * amount);
Tree_Coconut->Place(40 + 8 * amount);
Tree_Coconut->Place(6 + Random(3), Rectangle(LandscapeWidth()/2 - 300, LandscapeHeight()/2 - 200, 600, 400));
// Place some cotton plants over the map
for (var i = 0; i < 8 + Random(2); i++)
PlaceVegetation(Cotton, 0, 0, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(40)));
Cotton->Place(8 + 2 * amount);
// Create an effect to make sure there will always grow some new trees.
AddEffect("EnsureTreesOnMainIsland", nil, 100, 20, nil);
// Create an effect to make sure there will always grow some new trees and cotton.
AddEffect("EnsureVegetationOnMainIsland", nil, 100, 20, nil);
// Some objects in the earth.
PlaceObjects(Rock, 35 + Random(10), "Earth");
PlaceObjects(Firestone, 25 + Random(5), "Earth");
return;
}
// Ensures that there will always grow some trees on the main island.
global func FxEnsureTreesOnMainIslandTimer()
// Ensures that there will always grow some trees and cotton on the main island.
global func FxEnsureVegetationOnMainIslandTimer()
{
var wdt = LandscapeWidth();
var hgt = LandscapeHeight();
@ -158,18 +159,29 @@ global func FxEnsureTreesOnMainIslandTimer()
if (Random(9) >= nr_trees)
if (!Random(20))
PlaceVegetation(Tree_Coconut, wdt / 2 - 300, hgt / 2 - 200, 600, 400, 3);
// Place cotton plants (at least two)
// Place cotton plants (at least two).
var nr_cotton = ObjectCount(Find_ID(Cotton), Find_InRect(wdt / 2 - 300, hgt / 2 - 200, 600, 400));
if (Random(3) >= nr_trees)
if (Random(3) >= nr_cotton)
if (!Random(20))
PlaceVegetation(Cotton, wdt / 2 - 300, hgt / 2 - 200, 600, 400, 3);
return FX_OK;
}
// Initializes animals.
private func InitAnimals()
private func InitAnimals(int amount, int difficulty)
{
// Some fireflies attracted to deciduous trees.
var count = 0;
for (var tree in FindObjects(Find_ID(Tree_Deciduous), Sort_Random()))
{
Firefly->SpawnSwarm(tree, RandomX(6, 12));
count++;
if (count > 4 + 2 * amount)
break;
}
// Place some bats on insane difficulty.
if (difficulty == 3)
Bat->Place(6 + 2 * amount, nil, {tunnel_only = true});
return;
}
@ -190,10 +202,10 @@ global func FxGrowGemStalactitesTimer(object target, proplist effect, int time)
gems += ObjectCount(Find_Or(Find_ID(Ruby), Find_ID(Amethyst)));
var goal = FindObject(Find_ID(Goal_SellGems));
if (!goal)
return 1;
return FX_OK;
// The comparison depends on the difficulty settings.
if (gems - goal->GetTargetAmount() > 5 * (4 - effect.difficulty))
return 1;
return FX_OK;
// Find a location to grow a stalactite, possible away from others and clonks.
var pos, good_pos;
@ -225,32 +237,31 @@ global func FxGrowGemStalactitesTimer(object target, proplist effect, int time)
}
if (!good_pos)
return 1;
return FX_OK;
// Add growing stalactite effect.
effect = AddEffect("GrowStalactite", nil, 100, 8, nil);
effect.Material = "Ruby";
if (Random(2))
effect.Material = "Amethyst";
effect.X = pos.x;
effect.Y = pos.y;
effect.Size = 36;
return 1;
effect.x = pos.x;
effect.y = pos.y;
effect.size = 36;
return FX_OK;
}
// Grows a single stalactite.
global func FxGrowStalactiteTimer(object target, proplist effect, int time)
{
if (effect.Size <= 1)
return -1;
if (effect.size <= 1)
return FX_Execute_Kill;
var width = 4 * Min(effect.Size, 24) / 3 + RandomX(3, 5);
var width = 4 * Min(effect.size, 24) / 3 + RandomX(3, 5);
for (var x = effect.X - width / 2; x <= effect.X + width / 2; x++)
for (var x = effect.x - width / 2; x <= effect.x + width / 2; x++)
{
var cnt = 0;
var y = effect.Y;
var y = effect.y;
while (!GBackSemiSolid(x, y) && ++cnt < 10)
{
DrawMaterialQuad(effect.Material, x, y, x + 1, y, x + 1, y + 1, x, y + 1, true);
@ -258,9 +269,10 @@ global func FxGrowStalactiteTimer(object target, proplist effect, int time)
}
}
effect.Y += Random(2) + 1;
effect.X += RandomX(-1, 1);
effect.Size--;
effect.y += Random(2) + 1;
effect.x += RandomX(-1, 1);
effect.size--;
return FX_OK;
}
// Initializes the main island according to the material specification.
@ -312,7 +324,6 @@ private func InitMainIsland(int amount)
lorry->CreateContents(Loam, 4);
lorry->CreateContents(DynamiteBox, 1);
}
return;
}
@ -337,7 +348,6 @@ private func FindMainIslandPosition(int xpos, int sep, bool no_struct)
if (!no_struct || !FindObject(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")), Find_Distance(60, x, y)))
break;
}
return [x, y];
}
@ -357,7 +367,6 @@ private func InitIslands(int amount)
var island_nr = 1;
for (var island in islands)
island_nr += ProvideIsland(island, island_nr, amount);
return;
}
@ -382,7 +391,6 @@ private func FindIslands()
}
}
while (spot = FindLocation(Loc_Solid(), Loc_Not(Loc_InRect(main[0], main[1], main[2], main[3])), island_cond));
return islands;
}
@ -439,6 +447,8 @@ private func ProvideIsland(array island, int number, int amount)
lab->CreateContents(PowderKeg, amount - 1);
lab->CreateContents(Firestone, amount - 1);
lab->MakeInvincible();
var basement = lab->CreateObjectAbove(Basement, 0, lab->GetBottom() + 8);
basement->SetParent(lab);
}
// A shipyard with material for a airship, but without power supply for the second island.
@ -449,6 +459,8 @@ private func ProvideIsland(array island, int number, int amount)
shipyard->CreateContents(Wood, 4);
shipyard->CreateContents(Metal, 2 * amount);
shipyard->MakeInvincible();
var basement = shipyard->CreateObjectAbove(Basement, 0, shipyard->GetBottom() + 8);
basement->SetParent(shipyard);
}
// A cannon with a powder keg for the third island and place some metal & wood.
@ -488,7 +500,6 @@ private func ProvideIsland(array island, int number, int amount)
if (spot)
CreateObjectAbove(Column, spot.x, spot.y);
}
return 1;
}
@ -514,7 +525,6 @@ global func DrawBoundingBox(int x, int y, int wdt, int hgt)
// Draw right and left lines.
DrawMaterialQuad("Brick", x - 1, y, x + 1, y, x + 1, y + hgt, x - 1, y + hgt);
DrawMaterialQuad("Brick", x + wdt - 1, y, x + wdt + 1, y, x + wdt + 1, y + hgt, x + wdt - 1, y + hgt);
DrawMaterialQuad("Brick", x + wdt - 1, y, x + wdt + 1, y, x + wdt + 1, y + hgt, x + wdt - 1, y + hgt);
return;
}