New world: Acid Rift.

issue1247
Sven Eberhardt 2014-10-18 01:18:44 +02:00
parent ea65a24ec6
commit 1f3c53cec1
11 changed files with 530 additions and 0 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,212 @@
//static const SCENPAR_MapSize = 2;
//static const SCENPAR_Difficulty = 2;
local top_off = 20; // top open area of basin
local bottom_off = 20; // bottom granite area of basin
local border_width = 10; // left and right border width
local bottom_indent = 5; // diagonal indent at bottom left and bottom right corners
local top_off_earth = 50;// top offset from which earth and materials can start
local bottom_off_earth = 50;// bottom offset from which earth and materials can start
static g_start_map_x, g_start_map_y;
// Called be the engine: draw the complete map here.
func InitializeMap(proplist map)
{
var s = SCENPAR_MapSize - 1;
var d = SCENPAR_Difficulty - 1;
// Map size
var map_size = [[100, 200],[120, 250],[130, 400]][s];
Resize(map_size[0], map_size[1]);
// Parameters by map size and difficulty
var acid_level = [10, 30, 50][d]; // filling (in %) of basin with acid
var num_earth = [15, 20, 30][s];
var num_coal = [12, 15, 20][s];
var num_ore = [4, 5, 8][s];
var num_firestone = [15, 20, 30][s];
var num_water = [4, 5, 8][s];
var num_granite = [80, 100, 120][s];
var num_granite_top = [15, 20, 25][s];
var num_rock = [35,40,60][s];
var num_gold = [15, 18, 25][s];
var num_gems = 100;
var num_acidsurround = [20, 25, 40][s];
var size_earth = [[16,12,8][d], 8];
var size_coal = [6, 3];
var size_ore = [4, 4];
var size_water = [4, 4];
var size_firestone = [3, 3];
var size_granite = [2, 1];
var size_granite_top = [[8,4,1][d], 2];
var size_rock = [3,3];
var size_gold = [5,4,3][d];
var size_gems = [5,3,2][d];
var size_gem_cave = 10;
var size_acidsurround = [[5,4], [6,5], [7,5]][s];
// Draw starting acid filling
var acid_area = [0, top_off + (100-acid_level) * (this.Hgt-top_off-bottom_off) / 100, this.Wdt, this.Hgt];
Draw("^Acid", nil, acid_area);
// Basin surrounded by granite
var surround_poly = [
[-50, top_off],
[border_width, top_off],
[border_width+bottom_indent, this.Hgt*3/4],
[this.Wdt/2, this.Hgt-bottom_off],
[this.Wdt-border_width-bottom_indent, this.Hgt*3/4],
[this.Wdt-border_width, top_off],
[this.Wdt+50, top_off],
[this.Wdt+50, this.Hgt+50],
[-50, this.Hgt+50]
];
surround_poly = TransposeArray(surround_poly);
var algo = {Algo=MAPALGO_Polygon,
X = surround_poly[0],
Y = surround_poly[1]};
algo = { Algo=MAPALGO_Turbulence, Op=algo, Amplitude=10, Scale=30 };
algo = { Algo=MAPALGO_Turbulence, Op=algo, Amplitude=20, Scale=5 };
var basin = CreateLayer();
basin->Draw("Granite", algo);
basin->DrawMaterial("Rock", basin, [10,4], 30);
// Bottom acid cave containing gems
algo = { Algo=MAPALGO_Ellipsis, X=this.Wdt/2, Y=this.Hgt-bottom_off, Wdt=size_gem_cave, Hgt=size_gem_cave };
algo = { Algo=MAPALGO_Turbulence, Op=algo, Amplitude=20, Scale=20 };
basin->Draw("Transparent", algo);
// Materials areas are in surrounding basin
var basin_materials = CreateLayer();
basin_materials->Draw("Snow", {Algo=MAPALGO_Border, Wdt=-5, Op=basin});
// Acid caves in lower area
acid_area[1] += 20;
basin->DrawPatches(num_acidsurround, "Acid", "Granite", size_acidsurround, false, 20, acid_area);
// Gold in upper area
var gold_area = [0, top_off_earth, this.Wdt, this.Hgt-bottom_off-top_off_earth-size_gem_cave];
basin->DrawPatches(num_gold, "Gold", basin_materials, size_gold, false, 10, gold_area);
// Gems in lower area
var gem_area = [0, this.Hgt-bottom_off-size_gem_cave, this.Wdt, this.Hgt];
var i=0;
while (basin->GetPixelCount("Ruby")+basin->GetPixelCount("Amethyst") < num_gems)
{
basin->DrawPatch(["Ruby", "Amethyst"][++i%2], basin_materials, size_gems, false, 6, gem_area);
}
// Initial basin blit to ensure earth is not drawn there
Blit(basin);
// Small patches of rock and granite
DrawPatches(num_granite, "Granite", "^*", size_granite, false, 3);
DrawPatches(num_rock, "Rock", "^*", size_rock, false, 3);
// Alternate rock textures
var rock_area = Duplicate("Rock");
DrawMaterial("Rock-rock_cracked", rock_area, [3, 3], 50);
// Patches of earth
DrawPatches(num_earth, "Earth", "^*", size_earth, true, 20, [0, top_off_earth, this.Wdt, this.Hgt - top_off_earth - bottom_off_earth]);
// Large patches of granite in top map area
DrawPatches(num_granite_top, "Granite", "^*", size_granite_top, false, 3, [0, top_off/2, this.Wdt, this.Hgt/4]);
// Empty starting area
var start_x = this.Wdt/4 + Random(this.Wdt/2);
var start_y = this.Hgt/3;
var start_algo = {Algo = MAPALGO_Ellipsis, X=start_x, Y=start_y, Wdt=10, Hgt=10};
Draw("Sky", start_algo);
g_start_map_x = start_x; g_start_map_y = start_y;
// Materials
DrawPatches(num_water, "Water", "Earth", size_water, false, 10);
Draw("Earth-earth_topSoil", {Algo=MAPALGO_Border, Op=Duplicate("Water")});
DrawPatches(num_firestone, "Firestone", "Earth", size_firestone, false, 10);
DrawPatches(num_coal, "Coal", "Earth", size_coal, false, 7);
DrawPatches(num_ore, "Ore", "Earth", size_ore, true, 6);
// Re-draw basin to ensure it wasn't overdrawn by earth turbulence
Blit(basin);
// Draw starting area
var algo = {Algo = MAPALGO_Ellipsis, X=start_x, Y=start_y+5, Wdt=6, Hgt=5};
algo = {Algo = MAPALGO_Turbulence, Iterations = 1, Amplitude=5, Scale=5, Op = algo};
Draw("Earth", algo);
Draw("Sky", nil, [start_x-4, start_y-6, 8, 8]);
algo = {Algo=MAPALGO_Polygon, X=[start_x-4, start_x+4], Y=[start_y+2, start_y+2]};
// Alternations in earth texture
var earth_area = Duplicate("Earth");
DrawMaterial("Earth-earth_dry", earth_area, [10, 4], 30);
DrawMaterial("Earth-earth_midSoil", earth_area, [10, 4], 30);
// Start area is always dark
Draw("Earth-earth_topSoil", algo);
// Return true to tell the engine a map has been successfully created.
return true;
}
// Takes array of format [[x1,y1], [x2,y2], ...] and returns array [[x1,x2,...],[y1,y2,...]]
private func TransposeArray(array v)
{
var result = [], i=0;
for (var vc in v)
{
var j=0;
for (var c in vc)
{
if (!result[j]) result[j] = CreateArray(GetLength(v));
result[j][i] = c;
++j;
}
++i;
}
return result;
}
/*-- Helper Functions --*/
// Draws some material inside an existing mask.
private func DrawMaterial(string mat, proplist onto_mask, speck_size, int ratio)
{
if (!speck_size)
speck_size = [4,4];
if (!ratio)
ratio = 15;
if (GetType(speck_size) != C4V_Array) speck_size = [speck_size, speck_size];
// Use random checker algorithm to draw patches of the material.
var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = ratio, Wdt = speck_size[0], Hgt = speck_size[1]};
rnd_checker = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = rnd_checker};
var algo = {Algo = MAPALGO_And, Op = [onto_mask, rnd_checker]};
return Draw(mat, algo);
}
// Find places matching mask and draw spots of material on it
private func DrawPatches(int num, ...)
{
for (var i=0; i<num; ++i) DrawPatch(...);
}
private func DrawPatch(string mat, mask, size, bool allow_rotation, int turbulence, array area)
{
var pos = {};
if (!area) area = [0, top_off, this.Wdt, this.Hgt];
if (GetType(size) != C4V_Array) size = [size, size];
var mask_layer = this;
if (GetType(mask) != C4V_String)
{
mask_layer = mask;
mask = "Snow";
}
if (!mask_layer->FindPosition(pos, mask, area)) return false;
var algo = {Algo = MAPALGO_Ellipsis, X=pos.X, Y=pos.Y, Wdt=size[0], Hgt=size[1]};
algo = {Algo = MAPALGO_Turbulence, Iterations = 3, Amplitude=turbulence, Scale=5, Op = algo};
if (allow_rotation) algo = {Algo= MAPALGO_Rotate, R=Random(360), OffX=pos.X, OffY=pos.Y, Op=algo};
return Draw(mat, algo);
}

View File

@ -0,0 +1,47 @@
[ParameterDef]
Name=$Difficulty$
Description=$DescDifficulty$
ID=Difficulty
Default=2
LeagueValue=3
[Options]
[Option]
Name=$DiffNormal$
Description=$DescDiffNormal$
Value=1
[Option]
Name=$DiffHard$
Description=$DescDiffHard$
Value=2
[Option]
Name=$DiffInsane$
Description=$DescDiffInsane$
Value=3
[ParameterDef]
Name=$MapSize$
Description=$DescMapSize$
ID=MapSize
Default=2
LeagueValue=2
[Options]
[Option]
Name=$MapSmall$
Description=$DescMapSmall$
Value=1
[Option]
Name=$MapAverage$
Description=$DescMapAverage$
Value=2
[Option]
Name=$MapLarge$
Description=$DescMapLarge$
Value=3

View File

@ -0,0 +1,35 @@
[Head]
Icon=36
Title=AcidRift
Version=5,4,0,0
Difficulty=60
[Definitions]
Definition1=Objects.ocd
[Game]
[Player1]
Crew=Clonk=2
[Player2]
Crew=Clonk=2
[Player3]
Crew=Clonk=2
[Player4]
Crew=Clonk=2
[Landscape]
Sky=Clouds2
MapZoom=6
MapWidth=40
MapHeight=240
TopOpen=1
BottomOpen=0
[Weather]
Climate=0
YearSpeed=0
Wind=0,100,-100,100

View File

@ -0,0 +1,196 @@
/**
Acid Rift
Mine the rubies before it's too late
@author Sven2
*/
// Whether the intro has been initialized.
static intro_init;
// Set in Map.c
static g_start_map_x, g_start_map_y;
static g_start_x, g_start_y;
protected func Initialize()
{
// Goal: Ruby mine
var goal = CreateObject(Goal_SellGems);
goal->SetTargetAmount(BoundBy(SCENPAR_Difficulty*10, 10, 20));
// Rules: team account and buying at flagpole.
CreateObject(Rule_TeamAccount);
CreateObject(Rule_BuyAtFlagpole);
// Start position from map generation
var map_zoom = 6;
g_start_x = g_start_map_x * map_zoom;
g_start_y = g_start_map_y * map_zoom;
// Initialize different parts of the scenario.
InitEnvironment(SCENPAR_MapSize, SCENPAR_Difficulty);
InitVegetation(SCENPAR_MapSize, SCENPAR_Difficulty);
InitAnimals(SCENPAR_Difficulty);
InitMaterial(4 - SCENPAR_Difficulty);
return;
}
protected func OnGoalsFulfilled()
{
// Give the remaining players their achievement.
GainScenarioAchievement("Done", BoundBy(SCENPAR_Difficulty, 1, 3));
return false;
}
/*-- Player Initialization --*/
protected func InitializePlayer(int plr)
{
// Harsh zoom range.
SetPlayerZoomByViewRange(plr, 500, nil, PLRZOOM_Direct | PLRZOOM_LimitMax);
SetPlayerViewLock(plr, true);
// Move clonks to location and give them a shovel.
var index = 0, crew;
while (crew = GetCrew(plr, index))
{
crew->SetPosition(g_start_x + RandomX(-12, 12), g_start_y);
// First clonk can construct, others can chop.
if (index == 0)
{
crew->CreateContents(Shovel);
crew->CreateContents(Pickaxe);
}
else
{
crew->CreateContents(Axe);
crew->CreateContents(Hammer);
}
index++;
}
// Give the player basic knowledge.
GivePlayerBasicKnowledge(plr);
GivePlayerSpecificKnowledge(plr, [InventorsLab, Ropeladder, MetalBarrel, PowderKeg, GrappleBow, WallKit, Pipe, Pump]);
// Give the player the elementary base materials and some tools.
GivePlayerElementaryBaseMaterial(plr);
GivePlayerToolsBaseMaterial(plr);
SetBaseMaterial(plr, Wood, 100);
SetBaseProduction(plr, Wood, 10);
// Set player wealth.
SetWealth(plr, 75 - 25 * SCENPAR_Difficulty);
// Initialize the intro sequence if not yet started.
if (!intro_init)
{
//StartSequence("Intro", 0);
intro_init = true;
}
return;
}
/*-- Scenario Initialization --*/
private func InitEnvironment(int map_size, int difficulty)
{
// Adjust the sky a bit.
SetSkyParallax(0, 20, 20);
SetSkyAdjust(RGBa(225, 255, 205, 191), RGB(63, 200, 0));
// Disasters
Meteor->SetChance(difficulty * 11);
if (difficulty >= 2) Rockfall->SetChance(difficulty * 60 - 100);
Rockfall->SetArea(Rectangle(200, 0, LandscapeWidth()-400, 1));
if (difficulty >= 2) Rockfall->SetExplosiveness(difficulty * 25);
// Acid rain!
Cloud->Place(20 * difficulty - 10);
Cloud->SetPrecipitation("Acid", 100);
return;
}
private func InitVegetation(int map_size, int difficulty)
{
// Define parts of the map for even distribution.
var top = Rectangle(0, 0, LandscapeWidth(), LandscapeHeight() / 3);
var middle = Rectangle(0, LandscapeHeight() / 3, LandscapeWidth(), LandscapeHeight() / 3);
var bottom = Rectangle(0, 2 * LandscapeHeight() / 3, LandscapeWidth(), LandscapeHeight() / 3);
// Place some cave mushrooms for wood.
LargeCaveMushroom->Place(8, middle, { terraform = false });
LargeCaveMushroom->Place(8, bottom, { terraform = false });
// Place some bushes, ferns and mushrooms.
SproutBerryBush->Place(2, top);
SproutBerryBush->Place(2, middle);
SproutBerryBush->Place(2, bottom);
Fern->Place(20, top);
Fern->Place(20, middle);
Fern->Place(20, bottom);
Mushroom->Place(14, top);
Mushroom->Place(14, middle);
Mushroom->Place(14, bottom);
// Some ranks and trunks.
for (var i = 0; i < 4 + Random(3); i++)
{
PlaceVegetation(Rank, top.x, top.y, top.w, top.h, 1000 * (61 + Random(40)));
PlaceVegetation(Rank, middle.x, middle.y, middle.w, middle.h, 1000 * (61 + Random(40)));
PlaceVegetation(Rank, bottom.x, bottom.y, bottom.w, bottom.h, 1000 * (61 + Random(40)));
PlaceVegetation(Trunk, top.x, top.y, top.w, top.h, 1000 * (61 + Random(40)));
PlaceVegetation(Trunk, middle.x, middle.y, middle.w, middle.h, 1000 * (61 + Random(40)));
PlaceVegetation(Trunk, bottom.x, bottom.y, bottom.w, bottom.h, 1000 * (61 + Random(40)));
}
// Some objects in the earth.
PlaceObjects(Rock, 25 + 10 * map_size + Random(10),"Earth");
PlaceObjects(Firestone, 20 + 10 * map_size + Random(5), "Earth");
PlaceObjects(Loam, (5 + 2 * map_size) * (4 - difficulty) + Random(5), "Earth");
return;
}
private func InitAnimals(int difficulty)
{
// Place some fish or piranhas on the basin.
var fish = Fish;
if (difficulty >= 3)
fish = Piranha;
fish->Place(4);
return;
}
private func InitMaterial(int amount)
{
// No extra materials for little materials.
if (amount <= 1)
return;
// For medium amount of materials provide a lorry with resources.
if (amount >= 2)
{
var lorry = CreateObject(Lorry, g_start_x + RandomX(-12, 12), g_start_y);
lorry->CreateContents(Wood, 6);
lorry->CreateContents(Metal, 4);
lorry->CreateContents(Rock, 4);
lorry->CreateContents(Dynamite, 4);
lorry->CreateContents(Loam, 4);
// For large amount of materials provide some buildings as well.
if (amount >= 3)
{
lorry->CreateContents(Wood, 6);
lorry->CreateContents(Metal, 4);
lorry->CreateContents(Rock, 4);
lorry->CreateContents(DynamiteBox, 4);
lorry->CreateContents(Ropeladder, 4);
}
}
return;
}

View File

@ -0,0 +1,19 @@
# Scenario parameters: difficulty
Difficulty=Schwierigkeit
DescDifficulty=Setzt die Schwierigkeit dieser Runde.
DiffNormal=Normal
DescDiffNormal=Die Schwierigkeit dieser Runde ist normal.
DiffHard=Schwer
DescDiffHard=Die Schwierigkeit dieser Runde ist schwer.
DiffInsane=Irrsinnig
DescDiffInsane=Die Schwierigkeit dieser Runde ist irrsinnig.
# Scenario parameters: map size
MapSize=Kartengröße
DescMapSize=Setzt die Kartengröße dieser Runde.
MapSmall=Klein
DescMapSmall=Die Karte dieser Runde wird klein sein
MapAverage=Durchschnittlich
DescMapAverage=Die Karte dieser Runde wird durchschnittlich sein.
MapLarge=Groß
DescMapLarge=Die Karte dieser Runde wird groß sein.

View File

@ -0,0 +1,19 @@
# Scenario parameters: difficulty
Difficulty=Difficulty
DescDifficulty=Sets this round's difficulty.
DiffNormal=Normal
DescDiffNormal=This round's difficulty will be set to normal.
DiffHard=Hard
DescDiffHard=This round's difficulty will be set to hard.
DiffInsane=Insane
DescDiffInsane=This round's difficulty will be set to insane.
# Scenario parameters: map size
MapSize=Map size
DescMapSize=Sets this round's map size.
MapSmall=Small
DescMapSmall=This round's map will be small.
MapAverage=Average
DescMapAverage=This round's map will be average.
MapLarge=Large
DescMapLarge=This round's map will be large.

View File

@ -0,0 +1,2 @@
DE:Säurekluft
US:Acid Rift