1 /*--
2 Escape the volcano EXTREME
3 Author: Sven2
4
5 Difficult upwards parkour. Now with extra volcano coming from bottom!
6 --*/
7
8 static g_volcano;
9
Initialize()10 protected func Initialize()
11 {
12 var w = LandscapeWidth(), h = LandscapeHeight();
13 // Create the parkour goal.
14 var goal = FindObject(Find_ID(Goal_Parkour));
15 if (!goal) goal = CreateObject(Goal_Parkour, 0, 0, NO_OWNER);
16 goal->DisableRespawnHandling();
17 // Set start and finish point.
18 goal->SetStartpoint(w*2/5, h*93/100);
19 goal->SetFinishpoint(w/2, h*5/100);
20 // Create earth materials
21 // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting
22 PlaceBatches([Firestone], 5, 100, 15);
23 PlaceBatches([Dynamite, Dynamite, Dynamite, DynamiteBox], 3, 50, 6);
24 PlaceBatches([Rock, Loam, Loam], 10, 200, 10);
25 // Some dead trees.
26 Tree_Coniferous_Burned->Place(4);
27 Tree_Coniferous2_Burned->Place(2);
28 Tree_Coniferous3_Burned->Place(2);
29 Tree_Coniferous4_Burned->Place(2);
30 // At night with stars.
31 Time->Init();
32 Time->SetTime(24 * 60);
33 Time->SetCycleSpeed(0);
34 // Starting chest
35 var start_chest = CreateObjectAbove(Chest, w*2/5, h*94/100);
36 if (start_chest)
37 {
38 start_chest->CreateContents(Loam,4);
39 start_chest->CreateContents(Bread,3);
40 start_chest->CreateContents(Firestone,3);
41 start_chest->CreateContents(DynamiteBox,2);
42 }
43 // Create big volcano
44 g_volcano=CreateObjectAbove(BigVolcano,0,0,NO_OWNER);
45 var h0 = h-10;
46 g_volcano->Activate(h0, h*10/100);
47 // Schedule script to update volcano speed multiplier
48
49 var fx_volcano = new Effect {
50 Name = "FxVolcano",
51 Timer = Scenario.VolcanoTimer
52 };
53
54 CreateEffect(fx_volcano, 1, 40);
55 // Bottom is open, so put some stable lava here to prevent remaining lava from just flowing out of the map
56 DrawMaterialQuad("StableLava",0,h0,w,h0,w,h,0,h);
57 return;
58 }
59
60 // Timer callback: Update volcano speed (rubberband effect)
VolcanoTimer()61 func VolcanoTimer()
62 {
63 // Safety
64 if (!g_volcano) return;
65 // Get volcano height
66 var y_volcano = g_volcano->GetLavaPeak();
67 // Get player progress
68 var y_plr, crew, n_crew;
69 for (var i=0; i<GetPlayerCount(C4PT_User); ++i)
70 if (crew = GetCursor(GetPlayerByIndex(i, C4PT_User)))
71 {
72 y_plr += crew->GetY();
73 ++n_crew;
74 }
75 if (n_crew) y_plr = y_plr / n_crew;
76 // Calc rubber band
77 var rubber_length = 85 * y_plr / LandscapeHeight() + 65;
78 var new_multiplier;
79 if (n_crew)
80 new_multiplier = Max(1, (y_volcano - y_plr) / rubber_length);
81 else
82 new_multiplier = 1;
83 g_volcano->SetSpeedMultiplier(new_multiplier);
84 //Log("speed %v", new_multiplier);
85 return true;
86 }
87
InitializePlayer(int plr)88 func InitializePlayer(int plr)
89 {
90 // Players only
91 if (GetPlayerType(plr)!=C4PT_User) return;
92 // Harsh zoom range
93 for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct])
94 SetPlayerZoomByViewRange(plr,400,250,flag);
95 SetPlayerViewLock(plr, false); // no view lock so you can see the volcano!
96 return true;
97 }
98
PlaceBatches(array item_ids,int n_per_batch,int batch_radius,int n_batches)99 private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches)
100 {
101 // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects.
102 // fewer batches and/or objects may be placed if no space is found
103 var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj;
104 for (var i=0; i<n_batches; ++i)
105 if (loc = FindLocation(Loc_Material("Earth")))
106 for (var j=0; j<n_per_batch; ++j)
107 if (loc2 = FindLocation(Loc_InRect(loc.x-batch_radius,loc.y-batch_radius,batch_radius*2,batch_radius*2), Loc_Material("Earth")))
108 if (obj=CreateObjectAbove(item_ids[Random(n_item_ids)],loc2.x,loc2.y))
109 {
110 obj->SetPosition(loc2.x,loc2.y);
111 ++n_created;
112 }
113 return n_created;
114 }
115
116 // Gamecall from parkour goal, on respawning.
OnPlayerRespawn(int plr,object cp)117 protected func OnPlayerRespawn(int plr, object cp)
118 {
119 var clonk = GetCrew(plr);
120 RecoverItem(clonk, Shovel);
121 RecoverItem(clonk, Pickaxe);
122 RecoverItem(clonk, Loam);
123 return;
124 }
125
RecoverItem(object clonk,id item_id)126 private func RecoverItem(object clonk, id item_id)
127 {
128 // Try to recover the player's item. if it can't be found, recreate one
129 // Don't fetch item from allied Clonks though
130 var item = FindObject(Find_ID(item_id), Find_Owner(clonk->GetOwner()));
131 if (!item || item->Contained() && item->Contained()->GetAlive())
132 item = clonk->CreateContents(item_id);
133 else
134 item->Enter(clonk);
135 return item;
136 }
137