1 // Intro sequence for Krakatoa: Players crash with an airplane on the slope of the volcano.
2 
3 #appendto Sequence
4 
Intro_Init(int difficulty)5 public func Intro_Init(int difficulty)
6 {
7 	// Set wind to the left, so that less lava is on the starting place.
8 	SetWind(-50 - Random(50));
9 
10 	// Determine crater lava height.
11 	var lava_y = 0;
12 	while (!GBackLiquid(LandscapeWidth() / 2, lava_y) && lava_y < LandscapeHeight())
13 		lava_y++;
14 
15 	// Create an airplane with pilot and fly it towards the peak.
16 	this.airplane = CreateObjectAbove(Airplane, LandscapeWidth() / 2 - 564, lava_y - 176);
17 	this.pilot = CreateObjectAbove(Clonk, LandscapeWidth() / 2 - 564, lava_y - 176);
18 	this.pilot->SetName("$PilotName$");
19 	this.pilot->SetSkin(2);
20 	this.pilot->Enter(this.airplane);
21 	this.pilot->SetAction("Walk");
22 	this.pilot->SetDir(DIR_Right);
23 	this.pilot->SetColor(0xff0000aa);
24 	this.airplane->PlaneMount(this.pilot);
25 	this.airplane->FaceRight();
26 	this.airplane->StartInstantFlight(90, 15);
27 	this.airplane->SetXDir(12);
28 	this.airplane->SetYDir(-1);
29 	this.airplane->MakeInvincible();
30 	this.airplane.intro_seq = this;
31 	// Fill the airplane with some materials.
32 	this.difficulty = difficulty;
33 	if (difficulty <= 2)
34 	{
35 		this.airplane->CreateContents(Loam, 5);
36 		this.airplane->CreateContents(Bread, 5);
37 		this.airplane->CreateContents(Wood, 8);
38 		this.airplane->CreateContents(Rock, 4);
39 		this.airplane->CreateContents(Metal, 4);
40 		if (difficulty <= 1)
41 		{
42 			this.airplane->CreateContents(Pickaxe, 2);
43 			for (var i = 0; i < 5; i++)
44 				this.airplane->CreateContents(Barrel)->PutLiquid("Water", 300);
45 		}
46 	}
47 	return;
48 }
49 
Intro_Start()50 public func Intro_Start()
51 {
52 	return ScheduleNext(4);
53 }
54 
Intro_JoinPlayer(int plr)55 public func Intro_JoinPlayer(int plr)
56 {
57 	// Move player's crew into the plane.
58 	var j = 0, crew;
59 	while (crew = GetCrew(plr, j++))
60 	{
61 		crew->Enter(this.airplane);
62 		crew->SetAction("Walk");
63 	}
64 	// Increase zoom.
65 	SetPlayerZoomByViewRange(plr, 700, nil, PLRZOOM_Set | PLRZOOM_LimitMax);
66 	SetViewTarget(this.pilot);
67 	return;
68 }
69 
Intro_1()70 public func Intro_1()
71 {
72 	// Prepare players for drop.
73 	MessageBoxAll("$MsgNearVolcano$", this.pilot, true);
74 	return ScheduleNext(108);
75 }
76 
Intro_2()77 public func Intro_2()
78 {
79 	// Determine crater lava height.
80 	var lava_y = 0;
81 	while (!GBackLiquid(LandscapeWidth() / 2, lava_y) && lava_y < LandscapeHeight())
82 		lava_y++;
83 	// Launch a big eruption from this location.
84 	AddEffect("BigEruption", nil, 100, 1, nil, nil, LandscapeWidth() / 2, lava_y - 2);
85 	return ScheduleNext(12);
86 }
87 
Intro_3()88 public func Intro_3()
89 {
90 	// Message about volcano eruption.
91 	MessageBoxAll("$MsgEruption$", this.pilot, true);
92 	return ScheduleNext(23);
93 }
94 
Intro_4()95 public func Intro_4()
96 {
97 	// Determine crater lava height.
98 	var lava_y = 0;
99 	while (!GBackLiquid(LandscapeWidth() / 2, lava_y) && lava_y < LandscapeHeight())
100 		lava_y++;
101 	// Launch the killing chunk.
102 	this.chunk = CreateObjectAbove(LavaChunk, LandscapeWidth() / 2, lava_y);
103 	this.chunk->SetSpeed(36, -100);
104 	return ScheduleNext(28);
105 }
106 
Intro_5()107 public func Intro_5()
108 {
109 	// Explide lava chunk at plane location.
110 	this.chunk->Explode(36);
111 	// Destroy and fling the plane.
112 	this.airplane->SetMeshMaterial("CrashedAirplane");
113 	this.airplane->MakeBroken();
114 	this.airplane->CancelFlight();
115 	this.airplane->RemovePlaneControl();
116 	this.airplane->SetRDir(10);
117 	this.airplane->SetSpeed(46, -56);
118 	// Forward plane hit call to sequence.
119 	this.plane_hitcall = this.airplane.Hit;
120 	this.airplane.Hit = this.Intro_PlaneHit;
121 	// Eject message.
122 	MessageBoxAll("$MsgEject$", this.pilot, true);
123 	SetViewTarget(this.airplane);
124 	return ScheduleNext(24);
125 }
126 
Intro_6()127 public func Intro_6()
128 {
129 	// Let pilot get away in boompack.
130 	this.pilot->Exit();
131 	var boompack = this.pilot->CreateObjectAbove(Boompack);
132 	boompack->SetFuel(1000);
133 	boompack->SetDirectionDeviation(8);
134 	boompack->SetControllable(false);
135 	boompack->Launch(40, this.pilot);
136 	ScheduleCall(boompack, "RemoveObject", 100);
137 	ScheduleCall(this.pilot, "RemoveObject", 100);
138 	// Rest of intro will be triggered on plane hit.
139 	return true;
140 }
141 
Intro_PlaneHit()142 public func Intro_PlaneHit()
143 {
144 	// Airplane hit ground! Continue sequence.
145 	Sound("Objects::Plane::PlaneCrash", true);
146 	var particles = Particles_Smoke(true);
147 	particles.Size = PV_Linear(PV_Random(20, 60), PV_Random(50, 100));
148 	CreateParticle("Smoke", PV_Random(-30,30), PV_Random(-30,30), PV_Random(-60, 60), PV_Random(-20,0), PV_Random(200, 500), particles, 20);
149 	particles.Size = PV_Linear(PV_Random(50, 80), PV_Random(100, 200));
150 	CreateParticle("Smoke", PV_Random(-30,30), PV_Random(-30,30), PV_Random(-20, 20), PV_Random(-20,0), PV_Random(100, 200), particles, 20);
151 	for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
152 	{
153 		var plr = GetPlayerByIndex(i, C4PT_User);
154 		var icrew = 0, crew;
155 		while (crew = GetCrew(plr, icrew++))
156 		{
157 			crew->Exit(0,-5, 0, 1 + Random(2), Random(3) - 5);
158 			crew->SetAction("Tumble");
159 			crew->ClearInvincible();
160 			crew->DoEnergy(-this.intro_seq.difficulty * RandomX(5, 8));
161 			crew->MakeInvincible();
162 		}
163 	}
164 	// Stop plane movement and rotate for crash effect.
165 	SetXDir(0);
166 	this.Hit = this.intro_seq.plane_hit;
167 	this.MeshTransformation = Trans_Mul(Trans_Rotate(10,0,2,1), Airplane.MeshTransformation);
168 	this.intro_seq->ScheduleNext(50);
169 	return true;
170 }
171 
Intro_7()172 public func Intro_7()
173 {
174 	// Message from first clonk to other crew members.
175 	for (var i = 0; i < GetPlayerCount(C4PT_User); ++i)
176 	{
177 		var plr = GetPlayerByIndex(i, C4PT_User);
178 		MessageBox("$MsgConstructPlane$", GetCrew(plr, 0), GetCrew(plr, 0), plr, true);
179 	}
180 	return ScheduleNext(12);
181 }
182 
Intro_8()183 public func Intro_8()
184 {
185 	return Stop();
186 }
187 
Intro_Stop()188 public func Intro_Stop()
189 {
190 	// Reset player zoom.
191 	SetPlayerZoomByViewRange(NO_OWNER, 500, nil, PLRZOOM_Set | PLRZOOM_LimitMax);
192 	return true;
193 }
194