add new world: Clonkomotive (thanks to Pyrit)

Based on a round made by Pyrit, changed to fit into the worlds folder.
shapetextures
Maikel de Vries 2015-12-29 22:40:36 +01:00
parent ede6078c75
commit 568c57900b
42 changed files with 1126 additions and 3 deletions

View File

@ -2,7 +2,7 @@
Icon=34
Title=AcidRift
Version=6,0
Difficulty=60
Difficulty=70
[Definitions]
Definition1=Objects.ocd

View File

@ -2,7 +2,7 @@
Icon=36
Title=Chine
Version=6,0
Difficulty=40
Difficulty=50
[Definitions]
Definition1=Objects.ocd

View File

@ -0,0 +1 @@
Sky.jpg adapted from http://commons.wikimedia.org/wiki/File:Berge_mountains.JPG (Steinsplitter CC BY-SA 3.0)

View File

@ -0,0 +1,5 @@
Clonkomotive
A once flourishing train route through Clonkomotive Canyon has been disrupted by heavy rockfall. The rockfall destroyed the necessary bridges to connect the cliffs in between the canyons, thereby disconnecting two villages on the route. You are left with the locomotive in one of the villages and now you need to rebuild the route to the other village. Luckily Nature has settled and the rockfall has become less severe.
Goal: Transport the locomotive to the village on the far right.

View File

@ -0,0 +1,5 @@
Clonkomotive
A once flourishing train route through Clonkomotive Canyon has been disrupted by heavy rockfall. The rockfall destroyed the necessary bridges to connect the cliffs in between the canyons, thereby disconnecting two villages on the route. You are left with the locomotive in one of the villages and now you need to rebuild the route to the other village. Luckily Nature has settled and the rockfall has become less severe.
Goal: Transport the locomotive to the village on the far right.

View File

@ -0,0 +1,21 @@
[DefCore]
id=Locomotive
Version=7,0
Category=C4D_Vehicle
ContactCalls=1
Width=24
Height=22
Offset=-12,-11
Vertices=4
VertexX=-12,11,-12,11
VertexY=-11,-11,10,10
VertexCNAT=5,6,9,10
VertexFriction=80,80,50,50
Value=20
Mass=500
Components=Metal=4;Wood=1;
Rotate=15
UprightAttach=8
BorderBound=1
Entrance=-8,-10,16,20
RotatedEntrance=1

View File

@ -0,0 +1,208 @@
/**
Locomotive
Transportation device for long distances and heavy cargo.
@author Pyrit
*/
#include Library_ElevatorControl
local move_dir;
local fuel_amount;
local drive_anim;
local rot_wheels;
protected func Initialize()
{
move_dir = 0;
fuel_amount = 0;
rot_wheels = 0;
AddTimer("Move", 1);
SetAction("Drive");
// Entrance is always open.
SetEntrance(true);
// Start driving animation.
drive_anim = PlayAnimation("Main TrainAction", 1, Anim_Const(0), Anim_Const(1000));
return;
}
public func OnContentMenuOpened()
{
//return Sound("Locomotive::Chuff");
}
public func OnContentMenuClosed()
{
//return Sound("Locomotive::Chuff");
}
public func Collection2(object obj)
{
if (obj->GetOCF() & OCF_CrewMember)
{
obj->SetAction("Walk");
obj->PlayAnimation("Drive", CLONK_ANIM_SLOT_Movement, Anim_Const(10), Anim_Const(1000));
}
return;
}
public func Ejection(object obj)
{
if (obj->GetOCF() & OCF_CrewMember)
{
}
return;
}
/*-- Movement --*/
public func Move()
{
UpdateFuel();
var barrel = GetBarrel();
if (move_dir == 0)
return;
if (fuel_amount <= 0 && !barrel)
return Message("$MsgNoCoalAndWater$");
if (!barrel)
return Message("$MsgNoWater$");
if (fuel_amount <= 0)
return Message("$MsgNoCoal$");
if (Stuck())
return Message("$MsgStuck$");
fuel_amount--;
barrel->GetLiquid("Water", 1, this);
if (move_dir == -1)
SetDir(DIR_Left);
if (move_dir == 1)
SetDir(DIR_Right);
SetXDir(15 * move_dir);
DoExhaust();
TurnWheels();
return;
}
private func DoExhaust()
{
//Sound("Locomotive::Chuff");
Smoke(11 * (2 * GetDir() - 1), -18, 6);
var spark = {
Size = PV_Linear(1, 0),
ForceY = RandomX(-50, -60),
ForceX = PV_Random(-1, 1, 10),
DampingY = PV_Linear(600, 0),
Stretch = PV_Speed(1000, 500),
Rotation = PV_Direction(),
CollisionVertex = 500,
OnCollision = PC_Stop(),
R = 255,
G = PV_Linear(128, 32),
B = PV_Random(0, 128, 2),
Alpha = PV_Random(255, 0, 3),
BlitMode = GFX_BLIT_Additive,
};
CreateParticle("Magic", 12 * (2 * GetDir() - 1), -18, PV_Random(-3, 3), PV_Random(-3, -4), 36, spark, 1);
return;
}
private func TurnWheels()
{
var anim_pos = GetAnimationPosition(drive_anim);
anim_pos += Abs(GetXDir()) * 8;
while (anim_pos < 0)
anim_pos += 2000;
while (anim_pos > 2000)
anim_pos -= 2000;
SetAnimationPosition(drive_anim, Anim_Const(anim_pos));
return;
}
private func UpdateFuel()
{
if (fuel_amount > 0)
return;
var fuel = FindObject(Find_Or(Find_ID(Wood), Find_ID(Coal)), Find_Container(this));
if (fuel)
{
fuel_amount += fuel->GetFuelAmount();
fuel->RemoveObject();
}
return;
}
private func GetBarrel()
{
for (var barrel in FindObjects(Find_ID(Barrel), Find_Container(this)))
if (barrel->GetFillLevel())
return barrel;
return;
}
public func ContainedDown(object clonk)
{
move_dir = 0;
}
public func ContainedLeft(object clonk)
{
move_dir = -1;
}
public func ContainedRight(object clonk)
{
move_dir = 1;
}
public func ContainedStop(object clonk)
{
move_dir = 0;
}
public func Hit2()
{
Sound("Hits::Materials::Metal::DullMetalHit?");
}
public func IsVehicle() { return true; }
public func IsContainer() { return true; }
/*-- Contents --*/
protected func RejectCollect(id object_id)
{
if (object_id == Coal || object_id == Barrel)
return false;
return true;
}
/*-- Properties --*/
local ActMap = {
Drive = {
Prototype = Action,
Name = "Drive",
Procedure = DFA_NONE,
Directions = 2,
FlipDir = 1,
X = 0,
Y = 0,
Wdt = 24,
Hgt = 22,
NextAction = "Drive",
},
};
// this.MeshTransformation = Trans_Mul(Trans_Rotate(90, 0, 0, 1), Trans_Scale(580, -580, 580), Trans_Translate(24000, -27000, 0))
local MeshTransformation = [0, 580, 0, -15660, 580, 0, 0, 13920, 0, 0, 580, 0];
// this.PictureTransformation = Trans_Mul(Trans_Translate(-18000, 27000, 0), Trans_Rotate(90, 0, 0, 1), Trans_Rotate(-20, 1, 0, 0))
local PictureTransformation = [0, -940, -342, -18000, 1000, 0, 0, 27000, 0, -342, 940, 0];
local Name = "$Name$";
local Description = "$Description$";

View File

@ -0,0 +1,7 @@
Name=Lokomotive
Description=Transportmittel für lange Strecken und schwere Ladung.
MsgNoCoal=Keine Kohle im Ofen!
MsgNoWater=Kein Wasser im Kessel!
MsgNoCoalAndWater=Keine Kohle und kein Wasser verfügbar!
MsgStuck=Lokomotive steckt fest

View File

@ -0,0 +1,7 @@
Name=Locomotive
Description=Transportation device for long distances and heavy cargo.
MsgNoCoal=No coal available!
MsgNoWater=No water available!
MsgNoCoalAndWater=No coal and water available!
MsgStuck=Locomotive is stuck

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -0,0 +1,48 @@
// Train genrated by blender2ogre 0.5.9
// This material can be derived from in order to use a normal map with a
// single base texture.
material Train
{
receive_shadows on
technique
{
pass
{
ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0
diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0
specular 0.5 0.5 0.5 1.0 12.5
emissive 0.0 0.0 0.0 1.0
alpha_to_coverage off
//colour_write on
cull_hardware clockwise
depth_check on
//depth_func less_equal
depth_write on
//illumination_stage
//light_clip_planes off
//light_scissor off
//lighting on
//normalise_normals off
//polygon_mode solid
scene_blend one zero
//scene_blend_op add
//shading gouraud
//transparent_sorting on
texture_unit base
{
texture train.jpg
tex_address_mode wrap
scale 1.0 1.0
colour_op modulate
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

View File

@ -0,0 +1,5 @@
[DefCore]
id=Goal_LocomotiveTransport
Version=7,0
Category=C4D_StaticBack|C4D_Goal
Picture=0,0,128,128

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,67 @@
/**
Locomotive Transport Goal
Player must drive the train to a certain position.
@author Sven2, Pyrit
*/
#include Library_Goal
local goal_rect;
public func SetGoalRect(int x, int y, int wdt, int hgt)
{
goal_rect = Rectangle(x, y, wdt, hgt);
return true;
}
/*-- Goal interface --*/
// The goal is fulfilled if the train is somewhere in a rectangle.
public func IsFulfilled()
{
return FindObject(Find_ID(Locomotive), Find_InRect(AbsX(goal_rect.x), AbsY(goal_rect.y), goal_rect.w, goal_rect.h));
}
public func GetDescription(int plr)
{
var message;
if (IsFulfilled())
message = "$MsgGoalFulfilled$";
else
message = "$MsgGoalUnfulfilled$";
return message;
}
// Shows or hides a message window with information.
public func Activate(int plr)
{
// If goal message open -> hide it.
if (GetEffect("GoalMessage", this))
{
CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter);
RemoveEffect("GoalMessage", this);
return;
}
// Otherwise open a new message.
AddEffect("GoalMessage", this, 100, 0, this);
var message;
if (IsFulfilled())
{
message = "@$MsgGoalFulfilled$";
}
else
{
message = "@$MsgGoalUnfulfilled$";
}
CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter);
return;
}
protected func FxGoalMessageStart() {}
/*-- Proplist --*/
local Name = "$Name$";

View File

@ -0,0 +1,5 @@
Name=Eisenbahn Transport
# Goal window
MsgGoalFulfilled=Geschafft! Du hast die Eisenbahn sicher durch die Landschaft gebracht!
MsgGoalUnfulfilled=Bringe die Lokomotive sicher zu dem Bahnhof auf der anderen Seite der Karte! Baue hölzerne Brücken, um tiefe Schluchten zu überqueren. Die Lokomotive braucht viel Kohle und Wasser als Treibstoff.

View File

@ -0,0 +1,5 @@
Name=Locomotive Transport
# Goal window
MsgGoalFulfilled=Done! You brought the locomotive safely across the landscape!
MsgGoalUnfulfilled=Bring the locomotive safely to the train station on the other side of the map! Build wooden bridges to cross deep canyons. The train needs lots of coal and water as fuel.

View File

@ -0,0 +1,145 @@
/**
Clonkomotive
A map with a large number of cliffs.
@author Pyrit, Maikel
*/
#include Library_Map
// Bat cave [x, y] coordinates.
static bat_cave;
// Called be the engine: draw the complete map here.
protected func InitializeMap(proplist map)
{
// Retrieve the settings according to the MapSize setting.
var map_size;
if (SCENPAR_MapSize == 1)
map_size = [400, 120];
if (SCENPAR_MapSize == 2)
map_size = [480, 120];
if (SCENPAR_MapSize == 3)
map_size = [560, 120];
// Set the map size.
map->Resize(map_size[0], map_size[1]);
// First tunnel background on the bottom and set the water level.
var tunnel = {Algo = MAPALGO_Rect, X = 0, Y = map.Hgt - 30, Wdt = map.Wdt, Hgt = 30};
tunnel = {Algo = MAPALGO_Turbulence, Iterations = 2, Amplitude = [10, 16], Scale = 20, Op = tunnel};
Draw("Tunnel", tunnel);
Draw("Water", {Algo = MAPALGO_Rect, X = 0, Y = map.Hgt - 22, Wdt = map.Wdt, Hgt = 22});
// Construct a series of cliffs based on a large surfaced interfaced with lines.
var basic_shape = {Algo = MAPALGO_Polygon, X = [0, 0, map.Wdt, map.Wdt, map.Wdt - 40, map.Wdt / 2], Y = [3 * map.Hgt / 7, map.Hgt, map.Hgt, map.Hgt / 3, map.Hgt / 3, 3 * map.Hgt / 7]};
// Substract lines in the middle of the map, 50 pixels at both borders are left out.
var lines = {Algo = MAPALGO_Lines, X = 40, OffX = 40 + 20, Distance = 80};
var cliff_rect = {Algo = MAPALGO_Rect, X = 40, Y = 0, Wdt = map.Wdt - 80, Hgt = map.Hgt};
lines = {Algo = MAPALGO_And, Op = [lines, cliff_rect]};
lines = {Algo = MAPALGO_Not, Op = lines};
// Construct the basic cliff shape.
var cliffs = {Algo = MAPALGO_And, Op = [basic_shape, lines]};
cliffs = {Algo = MAPALGO_Or, Op = [{Algo = MAPALGO_And, Op = [cliffs, {Algo = MAPALGO_Not, Op = cliff_rect}]}, {Algo = MAPALGO_Turbulence, Iterations = 3, Amplitude = [10, 4], Scale = [8, 4], Seed = Random(65536), Op = cliffs}]};
// Fill the shape with earth (different types).
Draw("Earth", cliffs);
DrawMaterial("Earth-earth_root", cliffs, [6, 2], 20);
DrawMaterial("Earth-earth_spongy", cliffs, [6, 2], 20);
// Construct the cliffs substracting a border.
var cliffs_border = {Algo = MAPALGO_Border, Wdt = 3, Op = cliffs};
var cliffs_noborder = {Algo = MAPALGO_And, Op = [cliffs, {Algo = MAPALGO_Not, Op = cliffs_border}]};
// Fill the bottom of all the cliffs with materials.
var cliffs_bottom = {Algo = MAPALGO_And, Op = [cliffs_noborder, {Algo = MAPALGO_Rect, X = 0, Y = map.Hgt - 28, Wdt = map.Wdt, Hgt = 28}]};
DrawMaterial("Granite", cliffs_bottom, [6, 3], 6);
DrawMaterial("Gold", cliffs_bottom, [6, 3], 6);
DrawMaterial("Tunnel", cliffs_bottom, [6, 6], 6);
DrawMaterial("Firestone", cliffs_bottom, [6, 3], 12);
DrawMaterial("Rock-rock", cliffs_bottom, [6, 3], 20);
DrawMaterial("Rock-rock_smooth", cliffs_bottom, [6, 3], 20);
// Fill the middle of all the cliffs with materials.
var cliffs_middle = {Algo = MAPALGO_And, Op = [cliffs_noborder, {Algo = MAPALGO_Rect, X = 0, Y = map.Hgt - 54, Wdt = map.Wdt, Hgt = 26}]};
DrawMaterial("Coal", cliffs_middle, [6, 3], 12);
DrawMaterial("Ore", cliffs_middle, [6, 3], 12);
DrawMaterial("Tunnel", cliffs_middle, [6, 6], 6);
DrawMaterial("Firestone", cliffs_middle, [6, 3], 8);
DrawMaterial("Rock-rock", cliffs_middle, [6, 3], 6);
DrawMaterial("Rock-rock_smooth", cliffs_middle, [6, 3], 6);
// Fill the top of all the cliffs with materials.
var cliffs_top = {Algo = MAPALGO_And, Op = [cliffs_noborder, {Algo = MAPALGO_Rect, X = 0, Y = 0, Wdt = map.Wdt, Hgt = map.Hgt - 54}]};
DrawMaterial("Tunnel", cliffs_top, [6, 6], 6);
DrawMaterial("Tunnel", cliffs_top, [3, 3], 6);
DrawMaterial("Rock-rock", cliffs_top, [6, 3], 6);
DrawMaterial("Rock-rock_smooth", cliffs_middle, [6, 3], 6);
// The base of the cliff is made out of granite.
var cliff_base = {Algo = MAPALGO_Rect, X = 0, Y = map.Hgt - 8, Wdt = map.Wdt, Hgt = 8};
cliff_base = {Algo = MAPALGO_Or, Op = [cliff_base, {Algo = MAPALGO_Turbulence, Iterations = 3, Amplitude = [6, 16], Scale = [6, 12], Seed = Random(65536), Op = cliff_base}]};
Draw("Granite", cliff_base);
DrawMaterial("Rock-rock", cliff_base, [6, 2], 20);
DrawMaterial("Rock-rock_smooth", cliff_base, [6, 2], 20);
// Construct brick platforms on either side for a small village.
var x = 10;
var height = 0;
while(!GetPixel(x, height) && height < map.Hgt)
height++;
var brick = {Algo = MAPALGO_Rect, X = 0, Y = height, Wdt = 32, Hgt = 2};
brick = {Algo = MAPALGO_Or, Op = [brick, {Algo = MAPALGO_Turbulence, Iterations = 2, Amplitude = [0, 8], Scale = [0, 8], Seed = Random(65536), Op = brick}]};
Draw("Brick", brick);
Draw("Sky", {Algo = MAPALGO_Rect, X = 0, Y = height - 8, Wdt = 36, Hgt = 8});
var x = map.Wdt - 10;
var height = 0;
while(!GetPixel(x, height) && height < map.Hgt)
height++;
var brick = {Algo = MAPALGO_Rect, X = map.Wdt - 32, Y = height, Wdt = 32, Hgt = 2};
brick = {Algo = MAPALGO_Or, Op = [brick, {Algo = MAPALGO_Turbulence, Iterations = 2, Amplitude = [0, 8], Scale = [0, 8], Seed = Random(65536), Op = brick}]};
Draw("Brick", brick);
Draw("Sky", {Algo = MAPALGO_Rect, X = map.Wdt - 36, Y = height - 8, Wdt = 36, Hgt = 8});
// Construct some very small sky islands.
var island_layer = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Not, Op = cliffs}, {Algo = MAPALGO_Rect, X = 0, Y = 3 * map.Hgt / 7 + 9, Wdt = map.Wdt, Hgt = 26}]};
var island_layer_border = {Algo = MAPALGO_Border, Left = 4, Right = 4, Op = island_layer};
island_layer = {Algo = MAPALGO_And, Op = [island_layer, {Algo = MAPALGO_Not, Op = island_layer_border}]};
var islands = {Algo = MAPALGO_And, Op = [island_layer, {Algo = MAPALGO_RndChecker, Seed = Random(65536), Wdt = 3, Hgt = 3, Ratio = 5}]};
islands = {Algo = MAPALGO_Turbulence, Iterations = 4, Amplitude = 18, Scale = 18, Seed = Random(65536), Op = islands};
Draw("Earth", islands);
DrawMaterial("Earth-earth_root", islands, [6, 2], 20);
DrawMaterial("Earth-earth_spongy", islands, [6, 2], 20);
// Make a bat cave in one of the middle cliffs.
for (var tries = 0; tries < 500; tries++)
{
var pos = {};
if (!map->FindPosition(pos, "Solid", [140, map.Hgt - 46, map.Wdt - 240, 22]))
continue;
var correct_pos = true;
var try_positions = [[0, 8], [0, -8], [10, 0], [-10, 0]];
for (try_pos in try_positions)
{
var pix = GetPixel(pos.X + try_pos[0], pos.Y + try_pos[1]);
if (pix == 0 || pix == GetMaterialTextureIndex("Tunnel"))
{
correct_pos = false;
continue;
}
}
if (!correct_pos)
continue;
bat_cave = [pos.X, pos.Y];
break;
}
var cave = {Algo = MAPALGO_Ellipsis, X = bat_cave[0], Y = bat_cave[1], Wdt = 4, Hgt = 5};
cave = {Algo = MAPALGO_Or, Op = [cave, {Algo = MAPALGO_Turbulence, Iterations = 2, Amplitude = [0, 8], Scale = [0, 8], Seed = Random(65536), Op = {Algo = MAPALGO_Rect, X = bat_cave[0] - 8, Y = bat_cave[1] - 4, Wdt = 16, Hgt = 8}}]};
var cave_border = {Algo = MAPALGO_Border, Bottom = -2, Op = cave};
Draw("Tunnel", cave);
Draw("Rock-rock", cave_border);
// Return true to tell the engine a map has been successfully created.
return true;
}

View File

@ -0,0 +1,47 @@
[ParameterDef]
Name=$Difficulty$
Description=$DescDifficulty$
ID=Difficulty
Default=1
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=1
LeagueValue=1
[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,18 @@
[DefCore]
id=RockFragment
Version=7,0
Category=C4D_Object
Width=17
Height=13
Offset=-8,-6
Vertices=3
VertexX=0,7,-7
VertexY=5,-5,-5
VertexFriction=20
Value=1
Mass=80
Components=RockFragment=1
StretchGrowth=1
Projectile=1
Rotate=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,3 @@
[Particle]
Name=RockFragment
Face=0,0,32,24,-16,-12

View File

@ -0,0 +1,63 @@
/**
Rock Fragment
Falls down and destroys objects on its path.
@author Pyrit
*/
protected func Construction()
{
SetGraphics(Format("%d", RandomX(1, 3)));
SetRDir(RandomX(-20, 20));
}
protected func Hit(x, y)
{
if (GetCon() <= 30)
{
RemoveObject();
return;
}
// Do damage to bridges, according to the size of the rock.
var bridge = FindObject(Find_AtPoint(0, 10), Find_Func("IsBridge"));
if (bridge)
bridge->DoDamage(10 * GetCon() / 16);
// Dust and effects.
StonyObjectHit(x, y);
//Ignore SolidMask materials...
if (GetMaterial(0, GetBottomEdge() - GetY() + 2) != Material("Vehicle"))
{
var clr = GetAverageTextureColor(GetTexture(0, GetBottomEdge() - GetY() + 2));
var particles =
{
Prototype = Particles_Dust(),
R = (clr >> 16) & 0xff,
G = (clr >> 8) & 0xff,
B = clr & 0xff,
Size = PV_KeyFrames(0, 0, 0, 150, 20, 500, 15),
};
CreateParticle("Dust", 0, 8, PV_Random(-3, 3), PV_Random(-3, 3), PV_Random(18, 1 * 36), particles, 3);
}
// Leave little craters in materials.
BlastFree(GetX(), GetY(), GetCon() / 12);
// Break into smaller pieces.
for (var i = 0; i < 2; i++)
{
var small = CreateObject(RockFragment);
small->SetVelocity(RandomX(-50, 50), 40);
small->SetCon(10 * GetCon() / 15);
}
RemoveObject();
return;
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";

View File

@ -0,0 +1,2 @@
Name=HeavyCrumb
Description=Hurts Clonks and buildings!

View File

@ -0,0 +1,2 @@
Name=HeavyCrumb
Description=Hurts Clonks and buildings!

View File

@ -0,0 +1,30 @@
[Head]
Icon=24
Title=Clonkomotive
Version=6,0
Difficulty=40
[Definitions]
Definition1=Objects.ocd
[Player1]
Crew=Clonk=2
[Player2]
Crew=Clonk=2
[Player3]
Crew=Clonk=2
[Player4]
Crew=Clonk=2
[Landscape]
MapWidth=400
MapHeight=120
TopOpen=1
[Weather]
Climate=0
YearSpeed=0
Wind=0,100,-100,100

View File

@ -0,0 +1,305 @@
/**
Clonkomotive
Drive the train from left to right in tough terrain.
@author Pyrit, Maikel
*/
// Whether the intro has been initialized.
static intro_init;
// Bat cave [x, y] coordinates.
static bat_cave;
public func Initialize()
{
// Show wealth in HUD.
GUI_Controller->ShowWealth();
// Rules: team account and buying at flagpole.
CreateObject(Rule_TeamAccount);
CreateObject(Rule_BuyAtFlagpole);
// Create goal: transport train to other village.
var goal = CreateObject(Goal_LocomotiveTransport);
goal->SetGoalRect(LandscapeWidth() - 240, FindHeight(LandscapeWidth() - 240) - 200, 240, 200);
// Rescale map coordinates.
var map_zoom = GetScenarioVal("MapZoom", "Landscape");
bat_cave[0] = bat_cave[0] * map_zoom + map_zoom / 2;
bat_cave[1] = bat_cave[1] * map_zoom + map_zoom / 2;
// Initialize different parts of the scenario.
InitEnvironment(SCENPAR_MapSize, SCENPAR_Difficulty);
InitVegetation(SCENPAR_MapSize, SCENPAR_Difficulty);
InitAnimals(SCENPAR_MapSize, SCENPAR_Difficulty);
InitMaterial(4 - SCENPAR_Difficulty);
InitCity();
return;
}
protected func OnGoalsFulfilled()
{
// Give the remaining players their achievement.
GainScenarioAchievement("Done", BoundBy(SCENPAR_Difficulty, 1, 3));
return false;
}
/*-- Player Initialization --*/
public func InitializePlayer(plr)
{
// Move clonks to location and give them a shovel.
var index = 0, crew;
while (crew = GetCrew(plr, index))
{
//var x = 60;
//var y = FindHeight(x);
//crew->SetPosition(x, y - 12);
// First clonk can construct, others can chop.
crew->CreateContents(Shovel);
if (index == 0)
crew->CreateContents(Hammer);
else
crew->CreateContents(Axe);
index++;
}
// Give the player its knowledge.
GivePlayerBasicKnowledge(plr);
GivePlayerPumpingKnowledge(plr);
GivePlayerWeaponryKnowledge(plr);
GivePlayerAdvancedKnowledge(plr);
GivePlayerFarmingKnowledge(plr);
GivePlayerAirKnowledge(plr);
GivePlayerSpecificKnowledge(plr, [WoodenBridge]);
RemovePlayerSpecificKnowledge(plr, [WallKit]);
// Take over small village at the start of the map.
for (var structure in FindObjects(Find_Func("IsFlagpole")))
structure->SetOwner(plr);
// Set zoom range.
SetPlayerZoomByViewRange(plr, 600, nil, PLRZOOM_Direct | PLRZOOM_LimitMax);
SetPlayerViewLock(plr, true);
// 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)
{
// Sky scrolling.
SetSkyParallax(0, 75, 75, nil, nil, nil, -240);
// Set time of day to evening and create some clouds and celestials.
Cloud->Place(16);
Cloud->SetPrecipitation("Water", 30 * difficulty);
if (difficulty == 3)
{
Cloud->SetLightning(20);
Meteor->SetChance(4);
}
Time->Init();
Time->SetTime(60 * 12);
Time->SetCycleSpeed(20);
// Add an effect which controls the rock fall in this round.
AddEffect("ScenarioRockFall", nil, 100, 36, nil, nil, difficulty);
return;
}
// Callback from time controller: this scenario has no celestials.
public func HasNoCelestials() { return true; }
private func InitVegetation(int map_size, int difficulty)
{
var wdt = LandscapeWidth();
var hgt = LandscapeHeight();
// Trees.
Tree_Deciduous->Place(30 + 10 * map_size, Rectangle(wdt / 6, 0, 4 * wdt / 6, 4 * hgt / 9));
Tree_Coniferous2->Place(4 + 2 * map_size, Rectangle(wdt / 6, 0, 4 * wdt / 6, 4 * hgt / 9));
Tree_Coniferous3->Place(4 + 2 * map_size, Rectangle(wdt / 6, 0, 4 * wdt / 6, 4 * hgt / 9));
// Smaller vegetation.
Grass->Place(100);
Wheat->Place(10);
SproutBerryBush->Place(3);
Flower->Place(20 + 4 * map_size);
Mushroom->Place(20 + 4 * map_size);
Trunk->Place(6 + 2 * map_size);
Fern->Place(20 + 4 * map_size);
Branch->Place(20 + 4 * map_size);
Cotton->Place(8, Rectangle(wdt - 600, 0, 600, hgt));
// Under water vegetation.
Seaweed->Place(15 + 5 * map_size);
Coral->Place(10 + 2 * map_size);
// Some objects in the earth.
PlaceObjects(Rock, 30 + 20 * map_size + Random(10),"Earth");
PlaceObjects(Firestone, 30 + 10 * map_size + Random(5), "Earth");
PlaceObjects(Loam, 4 + 2 * map_size, "Earth");
return;
}
private func InitAnimals(int map_size, int difficulty)
{
// Place some fish and piranhas.
Fish->Place(20 + 4 * map_size);
Piranha->Place((10 + 4 * map_size) * (difficulty - 1));
// Some insects: zaps, mosquitos, butterflies, fireflies.
Zaphive->Place(2 + 4 * difficulty);
Mosquito->Place(4 + 2 * map_size);
Butterfly->Place(16 + 4 * map_size);
for (var cnt = 0; cnt < 4 + map_size; cnt++)
{
var tree = FindObject(Find_ID(Tree_Deciduous), Sort_Random());
Firefly->SpawnSwarm(tree, RandomX(6, 12));
}
// Bats in the bat cave.
Bat->Place(4 + 2 * difficulty, Rectangle(bat_cave[0] - 20, bat_cave[1] - 20, 40, 40));
return;
}
private func InitMaterial(int amount)
{
// Train on the start cliff.
var train = CreateObjectAbove(Locomotive, 60, FindHeight(60) - 2);
train->SetDir(DIR_Right);
// Lorry with materials on normal and hard.
if (amount >= 2)
{
var lorry = CreateObject(Lorry, 120, FindHeight(120) - 2);
lorry->SetPosition(train->GetX()-25, train->GetY());
lorry->CreateContents(Metal, 4);
lorry->CreateContents(Wood, 4);
}
// Small settlement on normal.
if (amount >= 3)
{
CreateObjectAbove(WindGenerator, 180, FindHeight(180));
CreateObjectAbove(Sawmill, 210, FindHeight(210));
CreateObjectAbove(ToolsWorkshop, 140, FindHeight(140));
}
// Always a catapult on the second cliff.
CreateObjectAbove(Catapult, 880, FindHeight(880));
// A lorry with rewards in the bat cave.
var lorry = CreateObjectAbove(Lorry, bat_cave[0], bat_cave[1]);
lorry->CreateContents(Pickaxe, amount);
lorry->CreateContents(WallKit, 2 * amount);
lorry->CreateContents(Wood, 2 * amount);
return;
}
private func InitCity()
{
var wdt = LandscapeWidth();
CreateObjectAbove(WoodenCabin, wdt - 60, FindHeight(wdt - 60));
CreateObjectAbove(WoodenCabin, wdt - 190, FindHeight(wdt - 190));
CreateObjectAbove(Windmill, wdt - 120, FindHeight(wdt - 120));
return;
}
/*-- Rockfall --*/
global func FxScenarioRockFallStart(object target, proplist effect, int temp, int diff)
{
if (temp)
return FX_OK;
effect.difficulty = diff;
// Find the range for the rockfall to fall in (the last valley).
var range_end;
for (var x = LandscapeWidth(); x > 0; x -= 5)
{
var y = FindHeight(x) + 5;
if (GetMaterial(x, y) == Material("Water"))
{
range_end = x;
break;
}
}
var end_y = FindHeight(range_end) + 5;
var range_start = range_end;
while (GetMaterial(range_start, end_y) == Material("Water") && range_start > 0)
range_start--;
while (GetMaterial(range_end, end_y) == Material("Water") && range_end < LandscapeWidth())
range_end++;
effect.range = [range_start + 60, range_end - 60];
return FX_OK;
}
global func FxScenarioRockFallTimer(object target, proplist effect, int time)
{
if (Random(600 / effect.difficulty**2) || GetEffect("LaunchRockFall"))
return FX_OK;
// Launch rock fall.
var rockfall_effect = AddEffect("LaunchRockFall", nil, 100, 1, nil);
rockfall_effect.range = effect.range;
rockfall_effect.duration = 36 * (10 + 5 * effect.difficulty);
return FX_OK;
}
global func FxLaunchRockFallStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
Sound("Environment::Disasters::Earthquake", true, 100, nil, 1);
return FX_OK;
}
global func FxLaunchRockFallTimer(object target, proplist effect, int time)
{
// Kill the effect once its duration is reached.
if (time > effect.duration)
return FX_Execute_Kill;
var crumbs =
{
Size = PV_Random(1, 3),
Phase = PV_Random(0, 2),
Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0),
CollisionVertex = 500,
OnCollision = PC_Bounce(20),
ForceY = PV_Gravity(50),
ForceX = PV_Random(-5, 5, 15),
Rotation = PV_Direction(PV_Random(750, 1250)),
Attach = ATTACH_Front
};
if (!Random(3))
CreateParticle("RockFragment", RandomX(effect.range[0], effect.range[1]), 5, PV_Random(-5, 5), 0, 36 * 5, crumbs, 1);
if (time > 36 * 3 && !Random(10))
CastObjects(RockFragment, 1, 10, RandomX(effect.range[0], effect.range[1]), 5, 180, 90);
return FX_OK;
}
global func FxLaunchRockFallStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
// Stop sound.
Sound("Environment::Disasters::Earthquake", true, 100, nil, -1);
Sound("Environment::Disasters::EarthquakeEnd",true);
return FX_OK;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

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,76 @@
// Intro sequence for Clonkomotive: crew drives train which runs out of fuel.
#appendto Sequence
public func Intro_Start()
{
var train = FindObject(Find_ID(Locomotive));
train->CreateContents(Coal, 2)->SetCon(20);
train->CreateContents(Barrel)->SetFilled("Water", 300);
train->ContainedRight();
return ScheduleNext(4);
}
public func Intro_JoinPlayer(int plr)
{
SetPlayerZoomByViewRange(plr, 300, nil, PLRZOOM_Set | PLRZOOM_LimitMax);
var train = FindObject(Find_ID(Locomotive));
var index = 0, crew;
while (crew = GetCrew(plr, index))
{
crew->Enter(train);
index++;
}
return;
}
public func Intro_1()
{
for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
MessageBox("$MsgDriveTrain$", GetCrew(plr, 0), GetCrew(plr, 0), plr, true);
}
return ScheduleNext(6 * 36);
}
public func Intro_2()
{
// Stop the train and remove fuel
var train = FindObject(Find_ID(Locomotive));
train->ContainedStop();
RemoveAll(Find_ID(Barrel), Find_Container(train));
// Exit crew from the train.
for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
var index = 0, crew;
while (crew = GetCrew(plr, index++))
crew->SetCommand("Exit");
}
for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
MessageBox("$MsgOutOfFuel$", GetCrew(plr, 0), GetCrew(plr, 1), plr, true);
}
return ScheduleNext(3 * 36);
}
public func Intro_3()
{
for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
MessageBox("$MsgBridgesGone$", GetCrew(plr, 0), GetCrew(plr, 0), plr, true);
}
return Stop();
}
public func Intro_Stop()
{
// Reset player zoom.
SetPlayerZoomByViewRange(NO_OWNER, 600, nil, PLRZOOM_Set | PLRZOOM_LimitMax);
return true;
}

View File

@ -0,0 +1,4 @@
# Intro sequence messages
MsgDriveTrain=We only have to drive this train to the village on the other side of these canyons.
MsgOutOfFuel=Are we out of fuel again?!
MsgBridgesGone=Yes, and it seems all the bridges over the canyons have been destroyed as well.

View File

@ -0,0 +1,4 @@
# Intro sequence messages
MsgDriveTrain=We only have to drive this train to the village on the other side of these canyons.
MsgOutOfFuel=Are we out of fuel again?!
MsgBridgesGone=Yes, and it seems all the bridges over the canyons have been destroyed as well.

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -0,0 +1,2 @@
DE:Clonkomotive
US:Clonkomotive

View File

@ -2,7 +2,7 @@
Icon=23
Title=Krakatoa
Version=6,0
Difficulty=50
Difficulty=60
[Definitions]
Definition1=Objects.ocd