18 |
18 |
19 procedure doStepDrowningGear(Gear: PGear); forward; |
19 procedure doStepDrowningGear(Gear: PGear); forward; |
20 |
20 |
21 function CheckGearDrowning(Gear: PGear): boolean; |
21 function CheckGearDrowning(Gear: PGear): boolean; |
22 begin |
22 begin |
23 Result:= Gear.Y + Gear.Radius >= cWaterLine; |
23 if cWaterLine < Gear^.Y + Gear^.Radius then |
24 if Result then |
24 begin |
25 begin |
25 CheckGearDrowning:= true; |
26 Gear.State:= gstDrowning; |
26 Gear^.State:= gstDrowning; |
27 Gear.doStep:= doStepDrowningGear; |
27 Gear^.doStep:= @doStepDrowningGear; |
28 PlaySound(sndSplash) |
28 PlaySound(sndSplash, false) |
29 end |
29 end else |
|
30 CheckGearDrowning:= false |
30 end; |
31 end; |
31 |
32 |
32 procedure CheckCollision(Gear: PGear); |
33 procedure CheckCollision(Gear: PGear); |
33 begin |
34 begin |
34 if TestCollisionXwithGear(Gear, hwSign(Gear.X)) or TestCollisionYwithGear(Gear, hwSign(Gear.Y)) |
35 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y)) |
35 then Gear.State:= Gear.State or gstCollision |
36 then Gear^.State:= Gear^.State or gstCollision |
36 else Gear.State:= Gear.State and not gstCollision |
37 else Gear^.State:= Gear^.State and not gstCollision |
37 end; |
38 end; |
38 |
39 |
39 procedure CheckHHDamage(Gear: PGear); |
40 procedure CheckHHDamage(Gear: PGear); |
40 begin |
41 begin |
41 if Gear.dY > 0.40 then Gear.Damage:= Gear.Damage + 1 + round(70 * (abs(Gear.dY) - 0.40)); |
42 if _0_4 < Gear^.dY then Gear^.Damage:= Gear^.Damage + 1 + hwRound(70 * (hwAbs(Gear^.dY) - _0_4)); |
42 end; |
43 end; |
43 |
44 |
44 //////////////////////////////////////////////////////////////////////////////// |
45 //////////////////////////////////////////////////////////////////////////////// |
45 //////////////////////////////////////////////////////////////////////////////// |
46 //////////////////////////////////////////////////////////////////////////////// |
46 procedure CalcRotationDirAngle(Gear: PGear); |
47 procedure CalcRotationDirAngle(Gear: PGear); |
47 var dAngle: Double; |
48 var dAngle: hwFloat; |
48 begin |
49 begin |
49 dAngle:= (abs(Gear.dX) + abs(Gear.dY))*0.1; |
50 dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)) * _0_1; |
50 if Gear.dX >= 0 then Gear.DirAngle:= Gear.DirAngle + dAngle |
51 if not Gear^.dX.isNegative then Gear^.DirAngle:= Gear^.DirAngle + dAngle |
51 else Gear.DirAngle:= Gear.DirAngle - dAngle; |
52 else Gear^.DirAngle:= Gear^.DirAngle - dAngle; |
52 if Gear.DirAngle < 0 then Gear.DirAngle:= Gear.DirAngle + 16 |
53 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 16 |
53 else if Gear.DirAngle >= 16 then Gear.DirAngle:= Gear.DirAngle - 16 |
54 else if 16 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 16 |
54 end; |
55 end; |
55 |
56 |
56 //////////////////////////////////////////////////////////////////////////////// |
57 //////////////////////////////////////////////////////////////////////////////// |
57 procedure doStepDrowningGear(Gear: PGear); |
58 procedure doStepDrowningGear(Gear: PGear); |
58 begin |
59 begin |
59 AllInactive:= false; |
60 AllInactive:= false; |
60 Gear.Y:= Gear.Y + cDrownSpeed; |
61 Gear^.Y:= Gear^.Y + cDrownSpeed; |
61 if round(Gear.Y) > Gear.Radius + cWaterLine + cVisibleWater then DeleteGear(Gear) |
62 if hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater then DeleteGear(Gear) |
62 end; |
63 end; |
63 |
64 |
64 //////////////////////////////////////////////////////////////////////////////// |
65 //////////////////////////////////////////////////////////////////////////////// |
65 procedure doStepFallingGear(Gear: PGear); |
66 procedure doStepFallingGear(Gear: PGear); |
66 var b: boolean; |
67 var b: boolean; |
67 begin |
68 begin |
68 if TestCollisionYwithGear(Gear, hwSign(Gear.dY)) then |
69 if TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) then |
69 begin |
70 begin |
70 Gear.dX:= Gear.dX * Gear.Friction; |
71 Gear^.dX:= Gear^.dX * Gear^.Friction; |
71 Gear.dY:= - Gear.dY * Gear.Elasticity; |
72 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
72 b:= false |
73 b:= false |
73 end else b:= true; |
74 end else b:= true; |
74 if TestCollisionXwithGear(Gear, hwSign(Gear.dX)) then |
75 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
75 begin |
76 begin |
76 Gear.dX:= - Gear.dX * Gear.Elasticity; |
77 Gear^.dX:= - Gear^.dX * Gear^.Elasticity; |
77 // Gear.dY:= Gear.dY; |
78 // Gear^.dY:= Gear^.dY; |
78 b:= false |
79 b:= false |
79 end; |
80 end; |
80 if b then |
81 if b then |
81 begin |
82 begin |
82 Gear.dY:= Gear.dY + cGravity; |
83 Gear^.dY:= Gear^.dY + cGravity; |
83 Gear.State:= Gear.State and not gstCollision |
84 Gear^.State:= Gear^.State and not gstCollision |
84 end else |
85 end else |
85 begin |
86 begin |
86 if sqr(Gear.dX) + sqr(Gear.dY) < 0.00001 then |
87 if hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _1div100000 then |
87 if (Gear.Timer = 0) then Gear.Active:= false |
88 if (Gear^.Timer = 0) then Gear^.Active:= false |
88 else begin |
89 else begin |
89 Gear.dX:= 0; |
90 Gear^.dX:= 0; |
90 Gear.dY:= 0 |
91 Gear^.dY:= 0 |
91 end; |
92 end; |
92 Gear.State:= Gear.State or gstCollision |
93 Gear^.State:= Gear^.State or gstCollision |
93 end; |
94 end; |
94 Gear.X:= Gear.X + Gear.dX; |
95 Gear^.X:= Gear^.X + Gear^.dX; |
95 Gear.Y:= Gear.Y + Gear.dY; |
96 Gear^.Y:= Gear^.Y + Gear^.dY; |
96 CheckGearDrowning(Gear); |
97 CheckGearDrowning(Gear); |
97 if (sqr(Gear.dX) + sqr(Gear.dY) < 0.003) then Gear.State:= Gear.State and not gstMoving |
98 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_003) then Gear^.State:= Gear^.State and not gstMoving |
98 else Gear.State:= Gear.State or gstMoving |
99 else Gear^.State:= Gear^.State or gstMoving |
99 end; |
100 end; |
100 |
101 |
101 //////////////////////////////////////////////////////////////////////////////// |
102 //////////////////////////////////////////////////////////////////////////////// |
102 procedure doStepCloud(Gear: PGear); |
103 procedure doStepCloud(Gear: PGear); |
103 begin |
104 begin |
104 Gear.X:= Gear.X + cWindSpeed * 200 + Gear.dX; |
105 Gear^.X:= Gear^.X + cWindSpeed * 200 + Gear^.dX; |
105 if Gear.Y > -160 then Gear.dY:= Gear.dY - 0.00002 |
106 if Gear^.Y > -160 then Gear^.dY:= Gear^.dY - _1div50000 |
106 else Gear.dY:= Gear.dY + 0.00002; |
107 else Gear^.dY:= Gear^.dY + _1div50000; |
107 Gear.Y:= Gear.Y + Gear.dY; |
108 Gear^.Y:= Gear^.Y + Gear^.dY; |
108 if Gear.X < -cScreenWidth - 256 then Gear.X:= cScreenWidth + 2048 else |
109 if Gear^.X < -cScreenWidth - 256 then Gear^.X:= cScreenWidth + 2048 else |
109 if Gear.X > cScreenWidth + 2048 then Gear.X:= -cScreenWidth - 256 |
110 if Gear^.X > cScreenWidth + 2048 then Gear^.X:= -cScreenWidth - 256 |
110 end; |
111 end; |
111 |
112 |
112 //////////////////////////////////////////////////////////////////////////////// |
113 //////////////////////////////////////////////////////////////////////////////// |
113 procedure doStepBomb(Gear: PGear); |
114 procedure doStepBomb(Gear: PGear); |
114 var i: integer; |
115 var i: integer; |
115 begin |
116 begin |
116 AllInactive:= false; |
117 AllInactive:= false; |
117 doStepFallingGear(Gear); |
118 doStepFallingGear(Gear); |
118 dec(Gear.Timer); |
119 dec(Gear^.Timer); |
119 if Gear.Timer = 0 then |
120 if Gear^.Timer = 0 then |
120 begin |
121 begin |
121 case Gear.Kind of |
122 case Gear^.Kind of |
122 gtAmmo_Bomb: doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); |
123 gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
123 gtClusterBomb: begin |
124 gtClusterBomb: begin |
124 doMakeExplosion(round(Gear.X), round(Gear.Y), 30, EXPLAutoSound); |
125 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
125 for i:= 0 to 4 do |
126 for i:= 0 to 4 do |
126 AddGear(round(Gear.X), round(Gear.Y), gtCluster, 0, (getrandom - 0.5)*0.2, (getrandom - 3) * 0.08); |
127 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, (getrandom - _0_5) * _0_2, (getrandom - 3) * _0_08, 0); |
127 end |
128 end |
128 end; |
129 end; |
129 DeleteGear(Gear); |
130 DeleteGear(Gear); |
130 exit |
131 exit |
131 end; |
132 end; |
132 CalcRotationDirAngle(Gear); |
133 CalcRotationDirAngle(Gear); |
133 if (Gear.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then PlaySound(sndGrenadeImpact) |
134 if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then PlaySound(sndGrenadeImpact, false) |
134 end; |
135 end; |
135 |
136 |
136 procedure doStepCluster(Gear: PGear); |
137 procedure doStepCluster(Gear: PGear); |
137 begin |
138 begin |
138 AllInactive:= false; |
139 AllInactive:= false; |
139 doStepFallingGear(Gear); |
140 doStepFallingGear(Gear); |
140 if (Gear.State and gstCollision) <> 0 then |
141 if (Gear^.State and gstCollision) <> 0 then |
141 begin |
142 begin |
142 doMakeExplosion(round(Gear.X), round(Gear.Y), 20, EXPLAutoSound); |
143 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); |
143 DeleteGear(Gear); |
144 DeleteGear(Gear); |
144 exit |
145 exit |
145 end; |
146 end; |
146 if (GameTicks and $1F) = 0 then |
147 if (GameTicks and $1F) = 0 then |
147 AddGear(round(Gear.X), round(Gear.Y), gtSmokeTrace, 0) |
148 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) |
148 end; |
149 end; |
149 |
150 |
150 //////////////////////////////////////////////////////////////////////////////// |
151 //////////////////////////////////////////////////////////////////////////////// |
151 procedure doStepGrenade(Gear: PGear); |
152 procedure doStepGrenade(Gear: PGear); |
152 begin |
153 begin |
153 AllInactive:= false; |
154 AllInactive:= false; |
154 Gear.dX:= Gear.dX + cWindSpeed; |
155 Gear^.dX:= Gear^.dX + cWindSpeed; |
155 doStepFallingGear(Gear); |
156 doStepFallingGear(Gear); |
156 if (Gear.State and gstCollision) <> 0 then |
157 if (Gear^.State and gstCollision) <> 0 then |
157 begin |
158 begin |
158 doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); |
159 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
159 DeleteGear(Gear); |
160 DeleteGear(Gear); |
160 exit |
161 exit |
161 end; |
162 end; |
162 if (GameTicks and $3F) = 0 then |
163 if (GameTicks and $3F) = 0 then |
163 AddGear(round(Gear.X), round(Gear.Y), gtSmokeTrace, 0) |
164 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) |
164 end; |
165 end; |
165 |
166 |
166 //////////////////////////////////////////////////////////////////////////////// |
167 //////////////////////////////////////////////////////////////////////////////// |
167 procedure doStepHealthTagWork(Gear: PGear); |
168 procedure doStepHealthTagWork(Gear: PGear); |
168 begin |
169 begin |
169 AllInactive:= false; |
170 AllInactive:= false; |
170 dec(Gear.Timer); |
171 dec(Gear^.Timer); |
171 Gear.Y:= Gear.Y - 0.07; |
172 Gear^.Y:= Gear^.Y - _0_08; |
172 if Gear.Timer = 0 then |
173 if Gear^.Timer = 0 then |
173 begin |
174 begin |
174 PHedgehog(Gear.Hedgehog).Gear.Active:= true; // to let current hh die |
175 PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die |
175 DeleteGear(Gear) |
176 DeleteGear(Gear) |
176 end |
177 end |
177 end; |
178 end; |
178 |
179 |
179 procedure doStepHealthTagWorkUnderWater(Gear: PGear); |
180 procedure doStepHealthTagWorkUnderWater(Gear: PGear); |
180 begin |
181 begin |
181 AllInactive:= false; |
182 AllInactive:= false; |
182 Gear.Y:= Gear.Y - 0.07; |
183 Gear^.Y:= Gear^.Y - _0_08; |
183 if Gear.Y <= cWaterLine + 10 then |
184 if Gear^.Y < cWaterLine + 10 then |
184 DeleteGear(Gear) |
185 DeleteGear(Gear) |
185 end; |
186 end; |
186 |
187 |
187 procedure doStepHealthTag(Gear: PGear); |
188 procedure doStepHealthTag(Gear: PGear); |
188 var s: shortstring; |
189 var s: shortstring; |
189 begin |
190 begin |
190 AllInactive:= false; |
191 AllInactive:= false; |
191 str(Gear.State, s); |
192 str(Gear^.State, s); |
192 Gear.Surf:= RenderString(s, PHedgehog(Gear.Hedgehog).Team.Color, fnt16); |
193 Gear^.Surf:= RenderString(s, PHedgehog(Gear^.Hedgehog)^.Team^.Color, fnt16); |
193 if Gear.Y < cWaterLine then Gear.doStep:= doStepHealthTagWork |
194 if Gear^.Y < cWaterLine then Gear^.doStep:= @doStepHealthTagWork |
194 else Gear.doStep:= doStepHealthTagWorkUnderWater |
195 else Gear^.doStep:= @doStepHealthTagWorkUnderWater |
195 end; |
196 end; |
196 |
197 |
197 //////////////////////////////////////////////////////////////////////////////// |
198 //////////////////////////////////////////////////////////////////////////////// |
198 procedure doStepGrave(Gear: PGear); |
199 procedure doStepGrave(Gear: PGear); |
199 begin |
200 begin |
200 AllInactive:= false; |
201 AllInactive:= false; |
201 if Gear.dY < 0 then |
202 if Gear^.dY < 0 then |
202 if TestCollisionY(Gear, -1) then Gear.dY:= 0; |
203 if TestCollisionY(Gear, -1) then Gear^.dY:= 0; |
203 |
204 |
204 if Gear.dY >=0 then |
205 if not Gear^.dY.isNegative then |
205 if TestCollisionY(Gear, 1) then |
206 if TestCollisionY(Gear, 1) then |
206 begin |
207 begin |
207 Gear.dY:= - Gear.dY * Gear.Elasticity; |
208 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
208 if Gear.dY > - 0.001 then |
209 if Gear^.dY > - _1div1024 then |
209 begin |
210 begin |
210 Gear.Active:= false; |
211 Gear^.Active:= false; |
211 exit |
212 exit |
212 end else if Gear.dY < - 0.03 then PlaySound(sndGraveImpact) |
213 end else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact, false) |
213 end; |
214 end; |
214 Gear.Y:= Gear.Y + Gear.dY; |
215 Gear^.Y:= Gear^.Y + Gear^.dY; |
215 CheckGearDrowning(Gear); |
216 CheckGearDrowning(Gear); |
216 Gear.dY:= Gear.dY + cGravity |
217 Gear^.dY:= Gear^.dY + cGravity |
217 end; |
218 end; |
218 |
219 |
219 //////////////////////////////////////////////////////////////////////////////// |
220 //////////////////////////////////////////////////////////////////////////////// |
220 procedure doStepUFOWork(Gear: PGear); |
221 procedure doStepUFOWork(Gear: PGear); |
221 var t: Double; |
222 var t: hwFloat; |
222 begin |
223 begin |
223 AllInactive:= false; |
224 AllInactive:= false; |
224 t:= sqrt(sqr(Gear.dX) + sqr(Gear.dY)); |
225 t:= Distance(Gear^.dX, Gear^.dY); |
225 Gear.dX:= Gear.Elasticity * (Gear.dX + 0.000004 * (TargetPoint.X - trunc(Gear.X))); |
226 Gear^.dX:= Gear^.Elasticity * (Gear^.dX + _0_000004 * (TargetPoint.X - hwRound(Gear^.X))); |
226 Gear.dY:= Gear.Elasticity * (Gear.dY + 0.000004 * (TargetPoint.Y - trunc(Gear.Y))); |
227 Gear^.dY:= Gear^.Elasticity * (Gear^.dY + _0_000004 * (TargetPoint.Y - hwRound(Gear^.Y))); |
227 t:= t / (sqrt(sqr(Gear.dX) + sqr(Gear.dY))); |
228 t:= t / Distance(Gear^.dX, Gear^.dY); |
228 Gear.dX:= Gear.dX * t; |
229 Gear^.dX:= Gear^.dX * t; |
229 Gear.dY:= Gear.dY * t; |
230 Gear^.dY:= Gear^.dY * t; |
230 Gear.X:= Gear.X + Gear.dX; |
231 Gear^.X:= Gear^.X + Gear^.dX; |
231 Gear.Y:= Gear.Y + Gear.dY; |
232 Gear^.Y:= Gear^.Y + Gear^.dY; |
232 CheckCollision(Gear); |
233 CheckCollision(Gear); |
233 dec(Gear.Timer); |
234 dec(Gear^.Timer); |
234 if ((Gear.State and gstCollision) <> 0) or (Gear.Timer = 0) then |
235 if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then |
235 begin |
236 begin |
236 doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); |
237 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
237 DeleteGear(Gear); |
238 DeleteGear(Gear); |
238 end; |
239 end; |
239 end; |
240 end; |
240 |
241 |
241 procedure doStepUFO(Gear: PGear); |
242 procedure doStepUFO(Gear: PGear); |
242 begin |
243 begin |
243 AllInactive:= false; |
244 AllInactive:= false; |
244 Gear.X:= Gear.X + Gear.dX; |
245 Gear^.X:= Gear^.X + Gear^.dX; |
245 Gear.Y:= Gear.Y + Gear.dY; |
246 Gear^.Y:= Gear^.Y + Gear^.dY; |
246 Gear.dY:= Gear.dY + cGravity; |
247 Gear^.dY:= Gear^.dY + cGravity; |
247 CheckCollision(Gear); |
248 CheckCollision(Gear); |
248 if (Gear.State and gstCollision) <> 0 then |
249 if (Gear^.State and gstCollision) <> 0 then |
249 begin |
250 begin |
250 doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); |
251 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
251 DeleteGear(Gear); |
252 DeleteGear(Gear); |
252 exit |
253 exit |
253 end; |
254 end; |
254 dec(Gear.Timer); |
255 dec(Gear^.Timer); |
255 if Gear.Timer = 0 then |
256 if Gear^.Timer = 0 then |
256 begin |
257 begin |
257 Gear.Timer:= 5000; |
258 Gear^.Timer:= 5000; |
258 Gear.doStep:= doStepUFOWork |
259 Gear^.doStep:= @doStepUFOWork |
259 end; |
260 end; |
260 end; |
261 end; |
261 |
262 |
262 //////////////////////////////////////////////////////////////////////////////// |
263 //////////////////////////////////////////////////////////////////////////////// |
263 procedure doStepShotgunShot(Gear: PGear); |
264 procedure doStepShotgunShot(Gear: PGear); |
264 var i: LongWord; |
265 var i: LongWord; |
265 begin |
266 begin |
266 AllInactive:= false; |
267 AllInactive:= false; |
267 if Gear.Timer > 0 then |
268 if Gear^.Timer > 0 then |
268 begin |
269 begin |
269 dec(Gear.Timer); |
270 dec(Gear^.Timer); |
270 if Gear.Timer = 0 then PlaySound(sndShotgunFire); |
271 if Gear^.Timer = 0 then PlaySound(sndShotgunFire, false); |
271 exit |
272 exit |
272 end; |
273 end; |
273 i:= 200; |
274 i:= 200; |
274 repeat |
275 repeat |
275 Gear.X:= Gear.X + Gear.dX; |
276 Gear^.X:= Gear^.X + Gear^.dX; |
276 Gear.Y:= Gear.Y + Gear.dY; |
277 Gear^.Y:= Gear^.Y + Gear^.dY; |
277 CheckCollision(Gear); |
278 CheckCollision(Gear); |
278 if (Gear.State and gstCollision) <> 0 then |
279 if (Gear^.State and gstCollision) <> 0 then |
279 begin |
280 begin |
280 AmmoShove(Gear, 25, 25); |
281 AmmoShove(Gear, 25, 25); |
281 doMakeExplosion(round(Gear.X), round(Gear.Y), 25, EXPLNoDamage or EXPLDoNotTouchHH); |
282 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLNoDamage or EXPLDoNotTouchHH); |
282 DeleteGear(Gear); |
283 DeleteGear(Gear); |
283 AfterAttack; |
284 AfterAttack; |
284 exit |
285 exit |
285 end; |
286 end; |
286 dec(i) |
287 dec(i) |
287 until i = 0; |
288 until i = 0; |
288 if (Gear.X < 0) or (Gear.Y < 0) or (Gear.X > 2048) or (Gear.Y > 1024) then |
289 if (Gear^.X < 0) or (Gear^.Y < 0) or (Gear^.X > 2048) or (Gear^.Y > 1024) then |
289 begin |
290 begin |
290 DeleteGear(Gear); |
291 DeleteGear(Gear); |
291 AfterAttack |
292 AfterAttack |
292 end |
293 end |
293 end; |
294 end; |
294 |
295 |
295 //////////////////////////////////////////////////////////////////////////////// |
296 //////////////////////////////////////////////////////////////////////////////// |
296 procedure doStepDEagleShot(Gear: PGear); |
297 procedure doStepDEagleShot(Gear: PGear); |
297 var i, x, y: LongWord; |
298 var i, x, y: LongWord; |
298 oX, oY: Double; |
299 oX, oY: hwFloat; |
299 begin |
300 begin |
300 AllInactive:= false; |
301 AllInactive:= false; |
301 i:= 80; |
302 i:= 80; |
302 oX:= Gear.X; |
303 oX:= Gear^.X; |
303 oY:= Gear.Y; |
304 oY:= Gear^.Y; |
304 repeat |
305 repeat |
305 Gear.X:= Gear.X + Gear.dX; |
306 Gear^.X:= Gear^.X + Gear^.dX; |
306 Gear.Y:= Gear.Y + Gear.dY; |
307 Gear^.Y:= Gear^.Y + Gear^.dY; |
307 x:= round(Gear.X); |
308 x:= hwRound(Gear^.X); |
308 y:= round(Gear.Y); |
309 y:= hwRound(Gear^.Y); |
309 if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0) |
310 if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0) |
310 and (Land[y, x] <> 0) then inc(Gear.Damage); |
311 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
311 AmmoShove(Gear, 7, 20); |
312 AmmoShove(Gear, 7, 20); |
312 dec(i) |
313 dec(i) |
313 until (i = 0) or (Gear.Damage > Gear.Health); |
314 until (i = 0) or (Gear^.Damage > Gear^.Health); |
314 if Gear.Damage > 0 then |
315 if Gear^.Damage > 0 then |
315 begin |
316 begin |
316 DrawTunnel(oX, oY, Gear.dX, Gear.dY, 82 - i, 1); |
317 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1); |
317 dec(Gear.Health, Gear.Damage); |
318 dec(Gear^.Health, Gear^.Damage); |
318 Gear.Damage:= 0 |
319 Gear^.Damage:= 0 |
319 end; |
320 end; |
320 if (Gear.Health <= 0) or (Gear.X < 0) or (Gear.Y < 0) or (Gear.X > 2048) or (Gear.Y > 1024) then |
321 if (Gear^.Health <= 0) or (Gear^.X < 0) or (Gear^.Y < 0) or (Gear^.X > 2048) or (Gear^.Y > 1024) then |
321 DeleteGear(Gear) |
322 DeleteGear(Gear) |
322 end; |
323 end; |
323 |
324 |
324 //////////////////////////////////////////////////////////////////////////////// |
325 //////////////////////////////////////////////////////////////////////////////// |
325 procedure doStepActionTimer(Gear: PGear); |
326 procedure doStepActionTimer(Gear: PGear); |
326 begin |
327 begin |
327 dec(Gear.Timer); |
328 dec(Gear^.Timer); |
328 case Gear.Kind of |
329 case Gear^.Kind of |
329 gtATStartGame: begin |
330 gtATStartGame: begin |
330 AllInactive:= false; |
331 AllInactive:= false; |
331 if Gear.Timer = 0 then |
332 if Gear^.Timer = 0 then |
332 AddCaption(trmsg[sidStartFight], $FFFFFF, capgrpGameState); |
333 AddCaption(trmsg[sidStartFight], $FFFFFF, capgrpGameState); |
333 end; |
334 end; |
334 gtATSmoothWindCh: begin |
335 gtATSmoothWindCh: begin |
335 if Gear.Timer = 0 then |
336 if Gear^.Timer = 0 then |
336 begin |
337 begin |
337 if WindBarWidth < Gear.Tag then inc(WindBarWidth) |
338 if WindBarWidth < Gear^.Tag then inc(WindBarWidth) |
338 else if WindBarWidth > Gear.Tag then dec(WindBarWidth); |
339 else if WindBarWidth > Gear^.Tag then dec(WindBarWidth); |
339 if WindBarWidth <> Gear.Tag then Gear.Timer:= 10; |
340 if WindBarWidth <> Gear^.Tag then Gear^.Timer:= 10; |
340 end |
341 end |
341 end; |
342 end; |
342 gtATFinishGame: begin |
343 gtATFinishGame: begin |
343 AllInactive:= false; |
344 AllInactive:= false; |
344 if Gear.Timer = 0 then |
345 if Gear^.Timer = 0 then |
345 begin |
346 begin |
346 SendIPC('N'); |
347 SendIPC('N'); |
347 SendIPC('q'); |
348 SendIPC('q'); |
348 GameState:= gsExit |
349 GameState:= gsExit |
349 end |
350 end |
350 end; |
351 end; |
351 end; |
352 end; |
352 if Gear.Timer = 0 then DeleteGear(Gear) |
353 if Gear^.Timer = 0 then DeleteGear(Gear) |
353 end; |
354 end; |
354 |
355 |
355 //////////////////////////////////////////////////////////////////////////////// |
356 //////////////////////////////////////////////////////////////////////////////// |
356 procedure doStepPickHammerWork(Gear: PGear); |
357 procedure doStepPickHammerWork(Gear: PGear); |
357 var i, ei: integer; |
358 var i, ei: integer; |
358 HHGear: PGear; |
359 HHGear: PGear; |
359 begin |
360 begin |
360 AllInactive:= false; |
361 AllInactive:= false; |
361 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
362 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
362 dec(Gear.Timer); |
363 dec(Gear^.Timer); |
363 if (Gear.Timer = 0)or((Gear.Message and gm_Destroy) <> 0)or((HHGear.State and gstHHDriven) = 0) then |
364 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then |
364 begin |
365 begin |
365 StopSound(sndPickhammer); |
366 StopSound(sndPickhammer); |
366 DeleteGear(Gear); |
367 DeleteGear(Gear); |
367 AfterAttack; |
368 AfterAttack; |
368 exit |
369 exit |
369 end; |
370 end; |
370 if (Gear.Timer and $3F) = 0 then |
371 if (Gear^.Timer and $3F) = 0 then |
371 begin |
372 begin |
372 i:= round(Gear.X) - Gear.Radius - GetRandom(2); |
373 i:= hwRound(Gear^.X) - Gear^.Radius - GetRandom(2); |
373 ei:= round(Gear.X) + Gear.Radius + GetRandom(2); |
374 ei:= hwRound(Gear^.X) + Gear^.Radius + GetRandom(2); |
374 while i <= ei do |
375 while i <= ei do |
375 begin |
376 begin |
376 doMakeExplosion(i, round(Gear.Y) + 3, 3, 0); |
377 doMakeExplosion(i, hwRound(Gear^.Y) + 3, 3, 0); |
377 inc(i, 1) |
378 inc(i, 1) |
378 end; |
379 end; |
379 Gear.X:= Gear.X + Gear.dX; |
380 Gear^.X:= Gear^.X + Gear^.dX; |
380 Gear.Y:= Gear.Y + 1.9; |
381 Gear^.Y:= Gear^.Y + _1_9; |
381 SetAllHHToActive; |
382 SetAllHHToActive; |
382 end; |
383 end; |
383 if TestCollisionYwithGear(Gear, 1) then |
384 if TestCollisionYwithGear(Gear, 1) then |
384 begin |
385 begin |
385 Gear.dY:= 0; |
386 Gear^.dY:= 0; |
386 SetLittle(HHGear.dX); |
387 SetLittle(HHGear^.dX); |
387 HHGear.dY:= 0; |
388 HHGear^.dY:= 0; |
388 end else |
389 end else |
389 begin |
390 begin |
390 Gear.dY:= Gear.dY + cGravity; |
391 Gear^.dY:= Gear^.dY + cGravity; |
391 Gear.Y:= Gear.Y + Gear.dY; |
392 Gear^.Y:= Gear^.Y + Gear^.dY; |
392 if Gear.Y > 1024 then Gear.Timer:= 1 |
393 if Gear^.Y > 1024 then Gear^.Timer:= 1 |
393 end; |
394 end; |
394 |
395 |
395 Gear.X:= Gear.X + HHGear.dX; |
396 Gear^.X:= Gear^.X + HHGear^.dX; |
396 HHGear.X:= Gear.X; |
397 HHGear^.X:= Gear^.X; |
397 HHGear.Y:= Gear.Y - cHHRadius; |
398 HHGear^.Y:= Gear^.Y - cHHRadius; |
398 |
399 |
399 if (Gear.Message and gm_Attack) <> 0 then |
400 if (Gear^.Message and gm_Attack) <> 0 then |
400 if (Gear.State and gsttmpFlag) <> 0 then Gear.Timer:= 1 else else |
401 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer:= 1 else else |
401 if (Gear.State and gsttmpFlag) = 0 then Gear.State:= Gear.State or gsttmpFlag; |
402 if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
402 if ((Gear.Message and gm_Left) <> 0) then Gear.dX:= -0.3 else |
403 if ((Gear^.Message and gm_Left) <> 0) then Gear^.dX:= - _0_3 else |
403 if ((Gear.Message and gm_Right) <> 0) then Gear.dX:= 0.3 |
404 if ((Gear^.Message and gm_Right) <> 0) then Gear^.dX:= _0_3 |
404 else Gear.dX:= 0; |
405 else Gear^.dX:= 0; |
405 end; |
406 end; |
406 |
407 |
407 procedure doStepPickHammer(Gear: PGear); |
408 procedure doStepPickHammer(Gear: PGear); |
408 var i, y: integer; |
409 var i, y: integer; |
409 ar: TRangeArray; |
410 ar: TRangeArray; |
410 begin |
411 begin |
411 i:= 0; |
412 i:= 0; |
412 y:= round(Gear.Y) - cHHRadius*2; |
413 y:= hwRound(Gear^.Y) - cHHRadius*2; |
413 while y < round(Gear.Y) do |
414 while y < hwRound(Gear^.Y) do |
414 begin |
415 begin |
415 ar[i].Left := round(Gear.X) - Gear.Radius - GetRandom(2); |
416 ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - GetRandom(2); |
416 ar[i].Right:= round(Gear.X) + Gear.Radius + GetRandom(2); |
417 ar[i].Right:= hwRound(Gear^.X) + Gear^.Radius + GetRandom(2); |
417 inc(y, 2); |
418 inc(y, 2); |
418 inc(i) |
419 inc(i) |
419 end; |
420 end; |
420 DrawHLinesExplosions(@ar, 3, round(Gear.Y) - cHHRadius*2, 2, Pred(i)); |
421 DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius*2, 2, Pred(i)); |
421 Gear.dY:= PHedgehog(Gear.Hedgehog).Gear.dY; |
422 Gear^.dY:= PHedgehog(Gear^.Hedgehog)^.Gear^.dY; |
422 PlaySound(sndPickhammer, true); |
423 PlaySound(sndPickhammer, true); |
423 doStepPickHammerWork(Gear); |
424 doStepPickHammerWork(Gear); |
424 Gear.doStep:= doStepPickHammerWork |
425 Gear^.doStep:= @doStepPickHammerWork |
425 end; |
426 end; |
426 |
427 |
427 //////////////////////////////////////////////////////////////////////////////// |
428 //////////////////////////////////////////////////////////////////////////////// |
428 var BTPrevAngle, BTSteps: Longword; |
429 var BTPrevAngle, BTSteps: Longword; |
429 |
430 |
430 procedure doStepBlowTorchWork(Gear: PGear); |
431 procedure doStepBlowTorchWork(Gear: PGear); |
431 var HHGear: PGear; |
432 var HHGear: PGear; |
432 b: boolean; |
433 b: boolean; |
433 begin |
434 begin |
434 AllInactive:= false; |
435 AllInactive:= false; |
435 dec(Gear.Timer); |
436 dec(Gear^.Timer); |
436 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
437 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
437 |
438 |
438 HedgehogChAngle(HHGear); |
439 HedgehogChAngle(HHGear); |
439 |
440 |
440 b:= false; |
441 b:= false; |
441 |
442 |
442 if (HHGear.Angle <> BTPrevAngle) then |
443 if (HHGear^.Angle <> BTPrevAngle) then |
443 begin |
444 begin |
444 Gear.dX:= hwSign(HHGear.dX) * Sin(HHGear.Angle * pi / cMaxAngle) * 0.5; |
445 Gear^.dX:= hwSign(HHGear^.dX) * _0_5;//hwSign(HHGear^.dX) * Sin(HHGear^.Angle * pi / cMaxAngle) * _0_5; |
445 Gear.dY:= Cos(HHGear.Angle * pi / cMaxAngle) * (-0.5); |
446 Gear^.dY:= 0;//Cos(HHGear^.Angle * pi / cMaxAngle) * (-0.5); |
446 BTPrevAngle:= HHGear.Angle; |
447 BTPrevAngle:= HHGear^.Angle; |
447 b:= true |
448 b:= true |
448 end; |
449 end; |
449 |
450 |
450 if Gear.Timer mod cHHStepTicks = 0 then |
451 if Gear^.Timer mod cHHStepTicks = 0 then |
451 begin |
452 begin |
452 b:= true; |
453 b:= true; |
453 if Gear.dX < 0 then HHGear.Message:= (HHGear.Message or gm_Left) and not gm_Right |
454 if Gear^.dX < 0 then HHGear^.Message:= (HHGear^.Message or gm_Left) and not gm_Right |
454 else HHGear.Message:= (HHGear.Message or gm_Right) and not gm_Left; |
455 else HHGear^.Message:= (HHGear^.Message or gm_Right) and not gm_Left; |
455 HedgehogStep(HHGear); |
456 HedgehogStep(HHGear); |
456 |
457 |
457 inc(BTSteps); |
458 inc(BTSteps); |
458 if BTSteps = 11 then |
459 if BTSteps = 11 then |
459 begin |
460 begin |
460 BTSteps:= 0; |
461 BTSteps:= 0; |
461 Gear.X:= HHGear.X + Gear.dX * cHHRadius * 2; |
462 Gear^.X:= HHGear^.X + Gear^.dX * cHHRadius * 2; |
462 Gear.Y:= HHGear.Y + Gear.dY * cHHRadius * 2; |
463 Gear^.Y:= HHGear^.Y + Gear^.dY * cHHRadius * 2; |
463 HHGear.State:= HHGear.State or gstNoDamage; |
464 HHGear^.State:= HHGear^.State or gstNoDamage; |
464 AmmoShove(Gear, 3, 14); |
465 AmmoShove(Gear, 3, 14); |
465 HHGear.State:= HHGear.State and not gstNoDamage |
466 HHGear^.State:= HHGear^.State and not gstNoDamage |
466 end; |
467 end; |
467 |
468 |
468 if (HHGear.State and gstFalling) <> 0 then Gear.Timer:= 0 |
469 if (HHGear^.State and gstFalling) <> 0 then Gear^.Timer:= 0 |
469 end; |
470 end; |
470 |
471 |
471 if b then |
472 if b then |
472 DrawTunnel(HHGear.X - Gear.dX * cHHRadius, HHGear.Y - 4 - Gear.dY * cHHRadius + abs(Gear.dY) * 7, |
473 DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - 4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, |
473 Gear.dX, Gear.dY, |
474 Gear^.dX, Gear^.dY, |
474 cHHRadius * 5, cHHRadius * 2 + 6); |
475 cHHRadius * 5, cHHRadius * 2 + 6); |
475 |
476 |
476 if (Gear.Timer = 0) or ((HHGear.Message and gm_Attack) <> 0) then |
477 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then |
477 begin |
478 begin |
478 HHGear.Message:= 0; |
479 HHGear^.Message:= 0; |
479 DeleteGear(Gear); |
480 DeleteGear(Gear); |
480 AfterAttack |
481 AfterAttack |
481 end |
482 end |
482 end; |
483 end; |
483 |
484 |
484 procedure doStepBlowTorch(Gear: PGear); |
485 procedure doStepBlowTorch(Gear: PGear); |
485 var HHGear: PGear; |
486 var HHGear: PGear; |
486 begin |
487 begin |
487 BTPrevAngle:= High(Longword); |
488 BTPrevAngle:= High(Longword); |
488 BTSteps:= 0; |
489 BTSteps:= 0; |
489 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
490 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
490 HHGear.State:= HHGear.State and not gstAttacking; |
491 HHGear^.State:= HHGear^.State and not gstAttacking; |
491 HHGear.Message:= 0; |
492 HHGear^.Message:= 0; |
492 Gear.doStep:= doStepBlowTorchWork |
493 Gear^.doStep:= @doStepBlowTorchWork |
493 end; |
494 end; |
494 |
495 |
495 //////////////////////////////////////////////////////////////////////////////// |
496 //////////////////////////////////////////////////////////////////////////////// |
496 |
497 |
497 procedure doStepRopeWork(Gear: PGear); |
498 procedure doStepRopeWork(Gear: PGear); |
498 const flCheck: boolean = false; |
499 const flCheck: boolean = false; |
499 var HHGear: PGear; |
500 var HHGear: PGear; |
500 len, cs, cc, tx, ty: Double; |
501 len, cs, cc, tx, ty: hwFloat; |
501 lx, ly: LongInt; |
502 lx, ly: LongInt; |
502 |
503 |
503 procedure DeleteMe; |
504 procedure DeleteMe; |
504 begin |
505 begin |
505 with HHGear^ do |
506 with HHGear^ do |
506 begin |
507 begin |
507 Message:= Message and not gm_Attack; |
508 Message:= Message and not gm_Attack; |
508 State:= State or gstFalling; |
509 State:= State or gstFalling; |
509 end; |
510 end; |
510 DeleteGear(Gear); |
511 DeleteGear(Gear); |
511 OnUsedAmmo(PHedgehog(HHGear.Hedgehog)^.Ammo); |
512 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^.Ammo); |
512 ApplyAmmoChanges(PHedgehog(HHGear.Hedgehog)^) |
513 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) |
513 end; |
514 end; |
514 |
515 |
515 begin |
516 begin |
516 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
517 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
517 |
518 |
518 if ((HHGear.State and gstHHDriven) = 0) |
519 if ((HHGear^.State and gstHHDriven) = 0) |
519 or (CheckGearDrowning(HHGear)) then |
520 or (CheckGearDrowning(HHGear)) then |
520 begin |
521 begin |
521 DeleteMe; |
522 DeleteMe; |
522 exit |
523 exit |
523 end; |
524 end; |
524 Gear.dX:= HHGear.X - Gear.X; |
525 Gear^.dX:= HHGear^.X - Gear^.X; |
525 Gear.dY:= HHGear.Y - Gear.Y; |
526 Gear^.dY:= HHGear^.Y - Gear^.Y; |
526 |
527 |
527 if (Gear.Message and gm_Left <> 0) then HHGear.dX:= HHGear.dX - 0.0002 else |
528 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
528 if (Gear.Message and gm_Right <> 0) then HHGear.dX:= HHGear.dX + 0.0002; |
529 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002; |
529 |
530 |
530 if not TestCollisionYwithGear(HHGear, 1) then HHGear.dY:= HHGear.dY + cGravity; |
531 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity; |
531 |
532 |
532 cs:= Gear.dY + HHGear.dY; |
533 cs:= Gear^.dY + HHGear^.dY; |
533 cc:= Gear.dX + HHGear.dX; |
534 cc:= Gear^.dX + HHGear^.dX; |
534 len:= 1 / sqrt(sqr(cc)+sqr(cs)); |
535 len:= 1 / Distance(cc, cs); |
535 cc:= cc * len; |
536 cc:= cc * len; |
536 cs:= cs * len; |
537 cs:= cs * len; |
537 |
538 |
538 flCheck:= not flCheck; |
539 flCheck:= not flCheck; |
539 if flCheck then // check whether rope needs dividing |
540 if flCheck then // check whether rope needs dividing |
540 begin |
541 begin |
541 len:= Gear.Elasticity - 20; |
542 len:= Gear^.Elasticity - 20; |
542 while len > 5 do |
543 while len > 5 do |
543 begin |
544 begin |
544 tx:= cc*len; |
545 tx:= cc*len; |
545 ty:= cs*len; |
546 ty:= cs*len; |
546 lx:= round(Gear.X + tx) + hwSign(HHGear.dX); |
547 lx:= hwRound(Gear^.X + tx) + hwSign(HHGear^.dX); |
547 ly:= round(Gear.Y + ty) + hwSign(HHGear.dY); |
548 ly:= hwRound(Gear^.Y + ty) + hwSign(HHGear^.dY); |
548 if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0)and (Land[ly, lx] <> 0) then |
549 if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0)and (Land[ly, lx] <> 0) then |
549 begin |
550 begin |
550 with RopePoints.ar[RopePoints.Count] do |
551 with RopePoints.ar[RopePoints.Count] do |
551 begin |
552 begin |
552 X:= Gear.X; |
553 X:= Gear^.X; |
553 Y:= Gear.Y; |
554 Y:= Gear^.Y; |
554 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle32(Gear.dY, Gear.dX); |
555 if RopePoints.Count = 0 then RopePoints.HookAngle:= 0;//DxDy2Angle32(Gear^.dY, Gear^.dX); |
555 b:= (cc * HHGear.dY) > (cs * HHGear.dX); |
556 b:= (cc * HHGear^.dY) > (cs * HHGear^.dX); |
556 dLen:= len |
557 dLen:= len |
557 end; |
558 end; |
558 Gear.X:= Gear.X + tx; |
559 Gear^.X:= Gear^.X + tx; |
559 Gear.Y:= Gear.Y + ty; |
560 Gear^.Y:= Gear^.Y + ty; |
560 inc(RopePoints.Count); |
561 inc(RopePoints.Count); |
561 Gear.Elasticity:= Gear.Elasticity - len; |
562 Gear^.Elasticity:= Gear^.Elasticity - len; |
562 Gear.Friction:= Gear.Friction - len; |
563 Gear^.Friction:= Gear^.Friction - len; |
563 break |
564 break |
564 end; |
565 end; |
565 len:= len - 3 |
566 len:= len - 3 |
566 end; |
567 end; |
567 end else |
568 end else |
568 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
569 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
569 begin |
570 begin |
570 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
571 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
571 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
572 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
572 if GameTicks = 189245 then |
573 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then |
573 begin |
|
574 AddFileLog('tx = ' + floattostr(tx) + ' ty = ' + floattostr(ty)); |
|
575 AddFileLog('Gear.X = ' + floattostr(Gear.X) + ' Gear.Y = ' + floattostr(Gear.Y)); |
|
576 AddFileLog('HHGear.X = ' + floattostr(HHGear.X) + ' HHGear.Y = ' + floattostr(HHGear.Y)); |
|
577 end; |
|
578 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear.X) * (ty - HHGear.Y) > (tx - HHGear.X) * (ty - Gear.Y)) then |
|
579 begin |
574 begin |
580 dec(RopePoints.Count); |
575 dec(RopePoints.Count); |
581 Gear.X:=RopePoints.ar[RopePoints.Count].X; |
576 Gear^.X:=RopePoints.ar[RopePoints.Count].X; |
582 Gear.Y:=RopePoints.ar[RopePoints.Count].Y; |
577 Gear^.Y:=RopePoints.ar[RopePoints.Count].Y; |
583 Gear.Elasticity:= Gear.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
578 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
584 Gear.Friction:= Gear.Friction + RopePoints.ar[RopePoints.Count].dLen |
579 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen |
585 end |
580 end |
586 end; |
581 end; |
587 |
582 |
588 Gear.dX:= HHGear.X - Gear.X; |
583 Gear^.dX:= HHGear^.X - Gear^.X; |
589 Gear.dY:= HHGear.Y - Gear.Y; |
584 Gear^.dY:= HHGear^.Y - Gear^.Y; |
590 |
585 |
591 cs:= Gear.dY + HHGear.dY; |
586 cs:= Gear^.dY + HHGear^.dY; |
592 cc:= Gear.dX + HHGear.dX; |
587 cc:= Gear^.dX + HHGear^.dX; |
593 len:= 1 / sqrt(sqr(cc)+sqr(cs)); |
588 len:= 1 / Distance(cc, cs); |
594 cc:= cc * len; |
589 cc:= cc * len; |
595 cs:= cs * len; |
590 cs:= cs * len; |
596 |
591 |
597 HHGear.dX:= HHGear.X; |
592 HHGear^.dX:= HHGear^.X; |
598 HHGear.dY:= HHGear.Y; |
593 HHGear^.dY:= HHGear^.Y; |
599 |
594 |
600 if ((Gear.Message and gm_Down) <> 0) and (Gear.Elasticity < Gear.Friction) then |
595 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
601 if not (TestCollisionXwithGear(HHGear, hwSign(Gear.dX)) |
596 if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
602 or TestCollisionYwithGear(HHGear, hwSign(Gear.dY))) then Gear.Elasticity:= Gear.Elasticity + 0.3; |
597 or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
603 |
598 |
604 if ((Gear.Message and gm_Up) <> 0) and (Gear.Elasticity > 30) then |
599 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > 30) then |
605 if not (TestCollisionXwithGear(HHGear, -hwSign(Gear.dX)) |
600 if not (TestCollisionXwithGear(HHGear, -hwSign(Gear^.dX)) |
606 or TestCollisionYwithGear(HHGear, -hwSign(Gear.dY))) then Gear.Elasticity:= Gear.Elasticity - 0.3; |
601 or TestCollisionYwithGear(HHGear, -hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
607 |
602 |
608 HHGear.X:= Gear.X + cc*Gear.Elasticity; |
603 HHGear^.X:= Gear^.X + cc*Gear^.Elasticity; |
609 HHGear.Y:= Gear.Y + cs*Gear.Elasticity; |
604 HHGear^.Y:= Gear^.Y + cs*Gear^.Elasticity; |
610 |
605 |
611 HHGear.dX:= HHGear.X - HHGear.dX; |
606 HHGear^.dX:= HHGear^.X - HHGear^.dX; |
612 HHGear.dY:= HHGear.Y - HHGear.dY; |
607 HHGear^.dY:= HHGear^.Y - HHGear^.dY; |
613 |
608 |
614 if TestCollisionXwithGear(HHGear, hwSign(HHGear.dX)) then |
609 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
615 HHGear.dX:= -0.6 * HHGear.dX; |
610 HHGear^.dX:= -_0_6 * HHGear^.dX; |
616 if TestCollisionYwithGear(HHGear, hwSign(HHGear.dY)) then |
611 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
617 HHGear.dY:= -0.6 * HHGear.dY; |
612 HHGear^.dY:= -_0_6 * HHGear^.dY; |
618 |
613 |
619 if (Gear.Message and gm_Attack) <> 0 then |
614 if (Gear^.Message and gm_Attack) <> 0 then |
620 if (Gear.State and gsttmpFlag) <> 0 then DeleteMe else |
615 if (Gear^.State and gsttmpFlag) <> 0 then DeleteMe else |
621 else if (Gear.State and gsttmpFlag) = 0 then Gear.State:= Gear.State or gsttmpFlag; |
616 else if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
622 end; |
617 end; |
623 |
618 |
624 |
619 |
625 procedure doStepRopeAttach(Gear: PGear); |
620 procedure doStepRopeAttach(Gear: PGear); |
626 var HHGear: PGear; |
621 var HHGear: PGear; |
627 tx, ty, tt: Double; |
622 tx, ty, tt: hwFloat; |
628 begin |
623 begin |
629 Gear.X:= Gear.X - Gear.dX; |
624 Gear^.X:= Gear^.X - Gear^.dX; |
630 Gear.Y:= Gear.Y - Gear.dY; |
625 Gear^.Y:= Gear^.Y - Gear^.dY; |
631 Gear.Elasticity:= Gear.Elasticity + 1.0; |
626 Gear^.Elasticity:= Gear^.Elasticity + 1; |
632 HHGear:= PHedgehog(Gear.Hedgehog)^.Gear; |
627 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
633 if (HHGear.State and gstFalling) <> 0 then |
628 if (HHGear^.State and gstFalling) <> 0 then |
634 if TestCollisionYwithGear(HHGear, 1) then |
629 if TestCollisionYwithGear(HHGear, 1) then |
635 begin |
630 begin |
636 HHGear.dY:= 0; |
631 HHGear^.dY:= 0; |
637 CheckHHDamage(HHGear); |
632 CheckHHDamage(HHGear); |
638 HHGear.State:= HHGear.State and not (gstFalling or gstHHJumping); |
633 HHGear^.State:= HHGear^.State and not (gstFalling or gstHHJumping); |
639 end else |
634 end else |
640 begin |
635 begin |
641 if TestCollisionXwithGear(HHGear, hwSign(HHGear.dX)) then HHGear.dX:= 0.0000001 * hwSign(HHGear.dX); |
636 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
642 HHGear.X:= HHGear.X + HHGear.dX; |
637 HHGear^.X:= HHGear^.X + HHGear^.dX; |
643 HHGear.Y:= HHGear.Y + HHGear.dY; |
638 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
644 Gear.X:= Gear.X + HHGear.dX; |
639 Gear^.X:= Gear^.X + HHGear^.dX; |
645 Gear.Y:= Gear.Y + HHGear.dY; |
640 Gear^.Y:= Gear^.Y + HHGear^.dY; |
646 HHGear.dY:= HHGear.dY + cGravity; |
641 HHGear^.dY:= HHGear^.dY + cGravity; |
647 tt:= Gear.Elasticity; |
642 tt:= Gear^.Elasticity; |
648 tx:= 0; |
643 tx:= 0; |
649 ty:= 0; |
644 ty:= 0; |
650 while tt > 20 do |
645 while tt > 20 do |
651 begin |
646 begin |
652 if TestCollisionXwithXYShift(Gear, round(tx), round(ty), hwSign(Gear.dX)) |
647 if TestCollisionXwithXYShift(Gear, hwRound(tx), hwRound(ty), hwSign(Gear^.dX)) |
653 or TestCollisionYwithXYShift(Gear, round(tx), round(ty), hwSign(Gear.dY)) then |
648 or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), hwSign(Gear^.dY)) then |
654 begin |
649 begin |
655 Gear.X:= Gear.X + tx; |
650 Gear^.X:= Gear^.X + tx; |
656 Gear.Y:= Gear.Y + ty; |
651 Gear^.Y:= Gear^.Y + ty; |
657 Gear.Elasticity:= tt; |
652 Gear^.Elasticity:= tt; |
658 Gear.doStep:= doStepRopeWork; |
653 Gear^.doStep:= @doStepRopeWork; |
659 with HHGear^ do State:= State and not gstAttacking; |
654 with HHGear^ do State:= State and not gstAttacking; |
660 tt:= 0 |
655 tt:= 0 |
661 end; |
656 end; |
662 tx:= tx + Gear.dX - Gear.dX; |
657 tx:= tx + Gear^.dX - Gear^.dX; |
663 ty:= ty + Gear.dY - Gear.dY; |
658 ty:= ty + Gear^.dY - Gear^.dY; |
664 tt:= tt - 2.0; |
659 tt:= tt - 2; |
665 end; |
660 end; |
666 end; |
661 end; |
667 CheckCollision(Gear); |
662 CheckCollision(Gear); |
668 if (Gear.State and gstCollision) <> 0 then |
663 if (Gear^.State and gstCollision) <> 0 then |
669 begin |
664 begin |
670 Gear.doStep:= doStepRopeWork; |
665 Gear^.doStep:= @doStepRopeWork; |
671 with HHGear^ do State:= State and not gstAttacking; |
666 with HHGear^ do State:= State and not gstAttacking; |
672 if Gear.Elasticity < 10 then |
667 if Gear^.Elasticity < 10 then |
673 Gear.Elasticity:= 10000; |
668 Gear^.Elasticity:= 10000; |
674 end; |
669 end; |
675 |
670 |
676 if (Gear.Elasticity >= Gear.Friction) or ((Gear.Message and gm_Attack) = 0) then |
671 if (Gear^.Elasticity > Gear^.Friction) or ((Gear^.Message and gm_Attack) = 0) then |
677 begin |
672 begin |
678 with PHedgehog(Gear.Hedgehog).Gear^ do |
673 with PHedgehog(Gear^.Hedgehog)^.Gear^ do |
679 begin |
674 begin |
680 State:= State and not gstAttacking; |
675 State:= State and not gstAttacking; |
681 Message:= Message and not gm_Attack |
676 Message:= Message and not gm_Attack |
682 end; |
677 end; |
683 DeleteGear(Gear) |
678 DeleteGear(Gear) |
684 end |
679 end |
685 end; |
680 end; |
686 |
681 |
687 procedure doStepRope(Gear: PGear); |
682 procedure doStepRope(Gear: PGear); |
688 begin |
683 begin |
689 Gear.dX:= - Gear.dX; |
684 Gear^.dX:= - Gear^.dX; |
690 Gear.dY:= - Gear.dY; |
685 Gear^.dY:= - Gear^.dY; |
691 Gear.doStep:= doStepRopeAttach |
686 Gear^.doStep:= @doStepRopeAttach |
692 end; |
687 end; |
693 |
688 |
694 //////////////////////////////////////////////////////////////////////////////// |
689 //////////////////////////////////////////////////////////////////////////////// |
695 procedure doStepSmokeTrace(Gear: PGear); |
690 procedure doStepSmokeTrace(Gear: PGear); |
696 begin |
691 begin |
697 inc(Gear.Timer); |
692 inc(Gear^.Timer); |
698 if Gear.Timer > 64 then |
693 if Gear^.Timer > 64 then |
699 begin |
694 begin |
700 Gear.Timer:= 0; |
695 Gear^.Timer:= 0; |
701 dec(Gear.State) |
696 dec(Gear^.State) |
702 end; |
697 end; |
703 Gear.dX:= Gear.dX + cWindSpeed; |
698 Gear^.dX:= Gear^.dX + cWindSpeed; |
704 Gear.X:= Gear.X + Gear.dX; |
699 Gear^.X:= Gear^.X + Gear^.dX; |
705 if Gear.State = 0 then DeleteGear(Gear) |
700 if Gear^.State = 0 then DeleteGear(Gear) |
706 end; |
701 end; |
707 |
702 |
708 //////////////////////////////////////////////////////////////////////////////// |
703 //////////////////////////////////////////////////////////////////////////////// |
709 procedure doStepExplosion(Gear: PGear); |
704 procedure doStepExplosion(Gear: PGear); |
710 begin |
705 begin |
711 inc(Gear.Timer); |
706 inc(Gear^.Timer); |
712 if Gear.Timer > 75 then |
707 if Gear^.Timer > 75 then |
713 begin |
708 begin |
714 inc(Gear.State); |
709 inc(Gear^.State); |
715 Gear.Timer:= 0; |
710 Gear^.Timer:= 0; |
716 if Gear.State > 5 then DeleteGear(Gear) |
711 if Gear^.State > 5 then DeleteGear(Gear) |
717 end; |
712 end; |
718 end; |
713 end; |
719 |
714 |
720 //////////////////////////////////////////////////////////////////////////////// |
715 //////////////////////////////////////////////////////////////////////////////// |
721 procedure doStepMine(Gear: PGear); |
716 procedure doStepMine(Gear: PGear); |
722 begin |
717 begin |
723 if (Gear.dX <> 0) or (Gear.dY <> 0) then |
718 if (Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0) then |
724 begin |
719 begin |
725 if Gear.CollIndex < High(Longword) then DeleteCI(Gear); |
720 if Gear^.CollIndex < High(Longword) then DeleteCI(Gear); |
726 doStepFallingGear(Gear); |
721 doStepFallingGear(Gear); |
727 if Gear.Active = false then |
722 if Gear^.Active = false then |
728 begin |
723 begin |
729 if Gear.CollIndex = High(Longword) then AddGearCI(Gear); |
724 if Gear^.CollIndex = High(Longword) then AddGearCI(Gear); |
730 Gear.dX:= 0; |
725 Gear^.dX:= 0; |
731 Gear.dY:= 0 |
726 Gear^.dY:= 0 |
732 end; |
727 end; |
733 CalcRotationDirAngle(Gear); |
728 CalcRotationDirAngle(Gear); |
734 AllInactive:= false |
729 AllInactive:= false |
735 end; |
730 end; |
736 |
731 |
737 if ((Gear.State and gsttmpFlag) <> 0) then |
732 if ((Gear^.State and gsttmpFlag) <> 0) then |
738 if ((Gear.State and gstAttacking) = 0) then |
733 if ((Gear^.State and gstAttacking) = 0) then |
739 begin |
734 begin |
740 if ((GameTicks and $F) = 0) then |
735 if ((GameTicks and $F) = 0) then |
741 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear.State:= Gear.State or gstAttacking |
736 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking |
742 end else // gstAttacking <> 0 |
737 end else // gstAttacking <> 0 |
743 begin |
738 begin |
744 AllInactive:= false; |
739 AllInactive:= false; |
745 if (Gear.Timer and $FF) = 0 then PlaySound(sndMineTick); |
740 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick, false); |
746 if Gear.Timer = 0 then |
741 if Gear^.Timer = 0 then |
747 begin |
742 begin |
748 doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); |
743 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
749 DeleteGear(Gear) |
744 DeleteGear(Gear) |
750 end; |
745 end; |
751 dec(Gear.Timer); |
746 dec(Gear^.Timer); |
752 end else // gsttmpFlag = 0 |
747 end else // gsttmpFlag = 0 |
753 if TurnTimeLeft = 0 then Gear.State:= Gear.State or gsttmpFlag; |
748 if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
754 end; |
749 end; |
755 |
750 |
756 //////////////////////////////////////////////////////////////////////////////// |
751 //////////////////////////////////////////////////////////////////////////////// |
757 procedure doStepDynamite(Gear: PGear); |
752 procedure doStepDynamite(Gear: PGear); |
758 begin |
753 begin |
759 doStepFallingGear(Gear); |
754 doStepFallingGear(Gear); |
760 AllInactive:= false; |
755 AllInactive:= false; |
761 if Gear.Timer mod 166 = 0 then inc(Gear.Tag); |
756 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
762 if Gear.Timer = 0 then |
757 if Gear^.Timer = 0 then |
763 begin |
758 begin |
764 doMakeExplosion(round(Gear.X), round(Gear.Y), 75, EXPLAutoSound); |
759 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
765 DeleteGear(Gear); |
760 DeleteGear(Gear); |
766 exit |
761 exit |
767 end; |
762 end; |
768 dec(Gear.Timer); |
763 dec(Gear^.Timer); |
769 end; |
764 end; |
770 |
765 |
771 //////////////////////////////////////////////////////////////////////////////// |
766 /////////////////////////////////////////////////////////////////////////////// |
772 procedure doStepCase(Gear: PGear); |
767 procedure doStepCase(Gear: PGear); |
773 var i, x, y: integer; |
768 var i, x, y: integer; |
774 begin |
769 begin |
775 if (Gear.Message and gm_Destroy) > 0 then |
770 if (Gear^.Message and gm_Destroy) > 0 then |
776 begin |
771 begin |
777 DeleteGear(Gear); |
772 DeleteGear(Gear); |
778 exit |
773 exit |
779 end; |
774 end; |
780 |
775 |
781 if Gear.Damage > 0 then |
776 if Gear^.Damage > 0 then |
782 begin |
777 begin |
783 x:= round(Gear.X); |
778 x:= hwRound(Gear^.X); |
784 y:= round(Gear.Y); |
779 y:= hwRound(Gear^.Y); |
785 DeleteGear(Gear); |
780 DeleteGear(Gear); |
786 doMakeExplosion(x, y, 25, EXPLAutoSound); |
781 doMakeExplosion(x, y, 25, EXPLAutoSound); |
787 for i:= 0 to 63 do |
782 for i:= 0 to 63 do |
788 AddGear(x, y, gtFlame, 0); |
783 AddGear(x, y, gtFlame, 0, 0, 0, 0); |
789 exit |
784 exit |
790 end; |
785 end; |
791 |
786 |
792 if (Gear.dY <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
787 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
793 begin |
788 begin |
794 AllInactive:= false; |
789 AllInactive:= false; |
795 Gear.dY:= Gear.dY + cGravity; |
790 Gear^.dY:= Gear^.dY + cGravity; |
796 Gear.Y:= Gear.Y + Gear.dY; |
791 Gear^.Y:= Gear^.Y + Gear^.dY; |
797 if (Gear.dY < 0) and TestCollisionYwithGear(Gear, -1) then Gear.dY:= 0 else |
792 if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= 0 else |
798 if (Gear.dY >= 0) and TestCollisionYwithGear(Gear, 1) then |
793 if (Gear^.dY.QWordValue <> 0) and TestCollisionYwithGear(Gear, 1) then |
799 begin |
794 begin |
800 Gear.dY:= - Gear.dY * Gear.Elasticity; |
795 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
801 if Gear.dY > - 0.001 then Gear.dY:= 0 |
796 if Gear^.dY > - _0_001 then Gear^.dY:= 0 |
802 else if Gear.dY < - 0.03 then PlaySound(sndGraveImpact); |
797 else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact, false); |
803 end; |
798 end; |
804 CheckGearDrowning(Gear); |
799 CheckGearDrowning(Gear); |
805 end; |
800 end; |
806 |
801 |
807 if (Gear.CollIndex = High(Longword)) and (Gear.dY = 0) then AddGearCI(Gear) |
802 if (Gear^.CollIndex = High(Longword)) and (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
808 else if (Gear.CollIndex < High(Longword)) and (Gear.dY <> 0) then DeleteCI(Gear); |
803 else if (Gear^.CollIndex < High(Longword)) and (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear); |
809 end; |
804 end; |
810 |
805 |
811 //////////////////////////////////////////////////////////////////////////////// |
806 //////////////////////////////////////////////////////////////////////////////// |
812 var thexchar: array[0..5] of record |
807 var thexchar: array[0..5] of record |
813 oy, ny: integer; |
808 oy, ny: integer; |
841 AllInactive:= false; |
836 AllInactive:= false; |
842 team:= TeamsList; |
837 team:= TeamsList; |
843 i:= 0; |
838 i:= 0; |
844 while team <> nil do |
839 while team <> nil do |
845 begin |
840 begin |
846 thexchar[i].oy:= team.DrawHealthY; |
841 thexchar[i].oy:= team^.DrawHealthY; |
847 thexchar[i].team:= team; |
842 thexchar[i].team:= team; |
848 inc(i); |
843 inc(i); |
849 team:= team.Next |
844 team:= team^.Next |
850 end; |
845 end; |
851 thexchcnt:= i; |
846 thexchcnt:= i; |
852 for i:= 1 to thexchcnt do |
847 for i:= 1 to thexchcnt do |
853 for t:= 0 to thexchcnt - 2 do |
848 for t:= 0 to thexchcnt - 2 do |
854 if thexchar[t].team.TeamHealthBarWidth > thexchar[Succ(t)].team.TeamHealthBarWidth then |
849 if thexchar[t].team^.TeamHealthBarWidth > thexchar[Succ(t)].team^.TeamHealthBarWidth then |
855 begin |
850 begin |
856 thexchar[5]:= thexchar[t]; |
851 thexchar[5]:= thexchar[t]; |
857 thexchar[t]:= thexchar[Succ(t)]; |
852 thexchar[t]:= thexchar[Succ(t)]; |
858 thexchar[Succ(t)]:= thexchar[5] |
853 thexchar[Succ(t)]:= thexchar[5] |
859 end; |
854 end; |
860 t:= cScreenHeight - 4; |
855 t:= cScreenHeight - 4; |
861 for i:= 0 to Pred(thexchcnt) do |
856 for i:= 0 to Pred(thexchcnt) do |
862 with thexchar[i] do |
857 with thexchar[i] do |
863 begin |
858 begin |
864 dec(t, team.HealthRect.h + 2); |
859 dec(t, team^.HealthRect.h + 2); |
865 ny:= t |
860 ny:= t |
866 end; |
861 end; |
867 Gear.Timer:= 640; |
862 Gear^.Timer:= 640; |
868 Gear.doStep:= doStepTeamHealthSorterWork; |
863 Gear^.doStep:= @doStepTeamHealthSorterWork; |
869 currsorter:= Gear |
864 currsorter:= Gear |
870 end; |
865 end; |
871 |
866 |
872 //////////////////////////////////////////////////////////////////////////////// |
867 //////////////////////////////////////////////////////////////////////////////// |
873 procedure doStepShover(Gear: PGear); |
868 procedure doStepShover(Gear: PGear); |
874 var HHGear: PGear; |
869 var HHGear: PGear; |
875 begin |
870 begin |
876 HHGear:= PHedgehog(Gear.Hedgehog)^.Gear; |
871 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
877 HHGear.State:= HHGear.State or gstNoDamage; |
872 HHGear^.State:= HHGear^.State or gstNoDamage; |
878 AmmoShove(Gear, 30, 115); |
873 AmmoShove(Gear, 30, 115); |
879 HHGear.State:= HHGear.State and not gstNoDamage; |
874 HHGear^.State:= HHGear^.State and not gstNoDamage; |
880 DeleteGear(Gear) |
875 DeleteGear(Gear) |
881 end; |
876 end; |
882 |
877 |
883 //////////////////////////////////////////////////////////////////////////////// |
878 //////////////////////////////////////////////////////////////////////////////// |
884 procedure doStepFlame(Gear: PGear); |
879 procedure doStepFlame(Gear: PGear); |
885 begin |
880 begin |
886 AllInactive:= false; |
881 AllInactive:= false; |
887 if not TestCollisionYwithGear(Gear, 1) then |
882 if not TestCollisionYwithGear(Gear, 1) then |
888 begin |
883 begin |
889 Gear.dX:= Gear.dX + cWindSpeed; |
884 Gear^.dX:= Gear^.dX + cWindSpeed; |
890 Gear.dY:= Gear.dY + cGravity; |
885 Gear^.dY:= Gear^.dY + cGravity; |
891 if abs(Gear.dX) > 0.12 then Gear.dX:= Gear.dX * 0.5; |
886 if hwAbs(Gear^.dX) > _0_1 then Gear^.dX:= Gear^.dX * _0_5; |
892 if Gear.dY > 0.12 then Gear.dY:= Gear.dY * 0.995; |
887 if Gear^.dY > _0_1 then Gear^.dY:= Gear^.dY * _0_995; |
893 Gear.X:= Gear.X + Gear.dX; |
888 Gear^.X:= Gear^.X + Gear^.dX; |
894 Gear.Y:= Gear.Y + Gear.dY; |
889 Gear^.Y:= Gear^.Y + Gear^.dY; |
895 if Gear.Y > 1023 then |
890 if Gear^.Y > 1023 then |
896 begin |
891 begin |
897 DeleteGear(Gear); |
892 DeleteGear(Gear); |
898 exit |
893 exit |
899 end |
894 end |
900 end else begin |
895 end else begin |
901 if Gear.Timer > 0 then dec(Gear.Timer) |
896 if Gear^.Timer > 0 then dec(Gear^.Timer) |
902 else begin |
897 else begin |
903 doMakeExplosion(round(Gear.X), round(Gear.Y), 2, 0); |
898 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 2, 0); |
904 dec(Gear.Health); |
899 dec(Gear^.Health); |
905 Gear.Timer:= 1250 - Gear.Angle * 12 |
900 Gear^.Timer:= 1250 - Gear^.Angle * 12 |
906 end |
901 end |
907 end; |
902 end; |
908 |
903 |
909 if (((GameTicks div 8) mod 64) = Gear.Angle) then |
904 if (((GameTicks div 8) mod 64) = Gear^.Angle) then |
910 AmmoFlameWork(Gear); |
905 AmmoFlameWork(Gear); |
911 |
906 |
912 if Gear.Health = 0 then |
907 if Gear^.Health = 0 then |
913 DeleteGear(Gear) |
908 DeleteGear(Gear) |
914 end; |
909 end; |
915 |
910 |
916 //////////////////////////////////////////////////////////////////////////////// |
911 //////////////////////////////////////////////////////////////////////////////// |
917 procedure doStepFirePunchWork(Gear: PGear); |
912 procedure doStepFirePunchWork(Gear: PGear); |
918 var HHGear: PGear; |
913 var HHGear: PGear; |
919 begin |
914 begin |
920 AllInactive:= false; |
915 AllInactive:= false; |
921 if ((Gear.Message and gm_Destroy) <> 0) then |
916 if ((Gear^.Message and gm_Destroy) <> 0) then |
922 begin |
917 begin |
923 DeleteGear(Gear); |
918 DeleteGear(Gear); |
924 AfterAttack; |
919 AfterAttack; |
925 exit |
920 exit |
926 end; |
921 end; |
927 |
922 |
928 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
923 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
929 if round(HHGear.Y) <= Gear.Tag - 2 then |
924 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then |
930 begin |
925 begin |
931 Gear.Tag:= round(HHGear.Y); |
926 Gear^.Tag:= hwRound(HHGear^.Y); |
932 DrawTunnel(HHGear.X - cHHRadius, HHGear.Y - 1, 0.5, 0.0, cHHRadius * 4, 2); |
927 DrawTunnel(HHGear^.X - cHHRadius, HHGear^.Y - 1, _0_5, 0, cHHRadius * 4, 2); |
933 HHGear.State:= HHGear.State or gstNoDamage; |
928 HHGear^.State:= HHGear^.State or gstNoDamage; |
934 Gear.Y:= HHGear.Y; |
929 Gear^.Y:= HHGear^.Y; |
935 AmmoShove(Gear, 30, 40); |
930 AmmoShove(Gear, 30, 40); |
936 HHGear.State:= HHGear.State and not gstNoDamage |
931 HHGear^.State:= HHGear^.State and not gstNoDamage |
937 end; |
932 end; |
938 |
933 |
939 HHGear.dY:= HHGear.dY + cGravity; |
934 HHGear^.dY:= HHGear^.dY + cGravity; |
940 if HHGear.dY >= 0 then |
935 if not (HHGear^.dY.isNegative) then |
941 begin |
936 begin |
942 HHGear.State:= HHGear.State or gstFalling; |
937 HHGear^.State:= HHGear^.State or gstFalling; |
943 DeleteGear(Gear); |
938 DeleteGear(Gear); |
944 AfterAttack; |
939 AfterAttack; |
945 exit |
940 exit |
946 end; |
941 end; |
947 HHGear.Y:= HHGear.Y + HHGear.dY |
942 HHGear^.Y:= HHGear^.Y + HHGear^.dY |
948 end; |
943 end; |
949 |
944 |
950 procedure doStepFirePunch(Gear: PGear); |
945 procedure doStepFirePunch(Gear: PGear); |
951 var HHGear: PGear; |
946 var HHGear: PGear; |
952 begin |
947 begin |
953 AllInactive:= false; |
948 AllInactive:= false; |
954 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
949 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
955 HHGear.X:= round(HHGear.X) - 0.5; |
950 HHGear^.X:= hwRound(HHGear^.X) - _0_5; |
956 HHGear.dX:= 0.0000001 * hwSign(HHGear.dX); |
951 SetLittle(HHGear^.dX); |
957 HHGear.dY:= -0.30; |
952 HHGear^.dY:= - _0_3; |
958 |
953 |
959 Gear.X:= HHGear.X; |
954 Gear^.X:= HHGear^.X; |
960 Gear.dX:= hwSign(HHGear.dX)* 0.45; |
955 Gear^.dX:= hwSign(HHGear^.dX) * _0_45; |
961 Gear.dY:= -0.9; |
956 Gear^.dY:= - _0_9; |
962 Gear.doStep:= doStepFirePunchWork; |
957 Gear^.doStep:= @doStepFirePunchWork; |
963 DrawTunnel(HHGear.X - cHHRadius, HHGear.Y + 1, 0.5, 0.0, cHHRadius * 4, 5); |
958 DrawTunnel(HHGear^.X - cHHRadius, HHGear^.Y + 1, _0_5, 0, cHHRadius * 4, 5); |
964 end; |
959 end; |
965 |
960 |
966 //////////////////////////////////////////////////////////////////////////////// |
961 //////////////////////////////////////////////////////////////////////////////// |
967 |
962 |
968 procedure doStepParachute(Gear: PGear); |
963 procedure doStepParachute(Gear: PGear); |
969 var HHGear: PGear; |
964 var HHGear: PGear; |
970 begin |
965 begin |
971 HHGear:= PHedgehog(Gear.Hedgehog).Gear; |
966 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
972 HHGear.State:= HHGear.State and not gstAttacking; |
967 HHGear^.State:= HHGear^.State and not gstAttacking; |
973 |
968 |
974 if TestCollisionYwithGear(HHGear, 1) |
969 if TestCollisionYwithGear(HHGear, 1) |
975 or ((HHGear.State and gstHHDriven) = 0) |
970 or ((HHGear^.State and gstHHDriven) = 0) |
976 or CheckGearDrowning(HHGear) then |
971 or CheckGearDrowning(HHGear) then |
977 begin |
972 begin |
978 with HHGear^ do |
973 with HHGear^ do |
979 begin |
974 begin |
980 Message:= 0; |
975 Message:= 0; |
981 dx:= 0.0000001 * hwSign(dX); |
976 SetLittle(dx); |
982 dY:= 0; |
977 dY:= 0; |
983 State:= State and not (gstAttacking or gstAttacked); |
978 State:= State and not (gstAttacking or gstAttacked); |
984 State:= State or gstFalling; |
979 State:= State or gstFalling; |
985 end; |
980 end; |
986 DeleteGear(Gear); |
981 DeleteGear(Gear); |
987 OnUsedAmmo(PHedgehog(HHGear.Hedgehog)^.Ammo); |
982 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^.Ammo); |
988 ApplyAmmoChanges(PHedgehog(HHGear.Hedgehog)^); |
983 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
989 exit |
984 exit |
990 end; |
985 end; |
991 |
986 |
992 if not TestCollisionXwithGear(HHGear, hwSign(HHGear.dX)) then |
987 if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
993 HHGear.X:= HHGear.X + cWindSpeed * 200; |
988 HHGear^.X:= HHGear^.X + cWindSpeed * 200; |
994 |
989 |
995 if (Gear.Message and gm_Left) <> 0 then HHGear.X:= HHGear.X - cMaxWindSpeed * 40 |
990 if (Gear^.Message and gm_Left) <> 0 then HHGear^.X:= HHGear^.X - cMaxWindSpeed * 40 |
996 else if (Gear.Message and gm_Right) <> 0 then HHGear.X:= HHGear.X + cMaxWindSpeed * 40; |
991 else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X:= HHGear^.X + cMaxWindSpeed * 40; |
997 if (Gear.Message and gm_Up) <> 0 then HHGear.Y:= HHGear.Y - cGravity * 40 |
992 if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y:= HHGear^.Y - cGravity * 40 |
998 else if (Gear.Message and gm_Down) <> 0 then HHGear.Y:= HHGear.Y + cGravity * 40; |
993 else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y:= HHGear^.Y + cGravity * 40; |
999 |
994 |
1000 HHGear.Y:= HHGear.Y + cGravity * 100; |
995 HHGear^.Y:= HHGear^.Y + cGravity * 100; |
1001 end; |
996 end; |
1002 |
997 |
1003 //////////////////////////////////////////////////////////////////////////////// |
998 //////////////////////////////////////////////////////////////////////////////// |
1004 const cAirPlaneSpeed = 1.4; |
999 const cAirPlaneSpeed: hwFloat = (isNegative: false; QWordValue: 6012954214); // 1.4 |
1005 cBombsDistance = 30; |
1000 cBombsDistance: hwFloat = (isNegative: false; QWordValue: 128849018880); // 30 |
1006 cBombsSpeed = 0.1; |
1001 cBombsSpeed : hwFloat = (isNegative: false; QWordValue: 429496729); |
1007 |
1002 |
1008 procedure doStepAirAttackWork(Gear: PGear); |
1003 procedure doStepAirAttackWork(Gear: PGear); |
1009 begin |
1004 begin |
1010 AllInactive:= false; |
1005 AllInactive:= false; |
1011 Gear.X:= Gear.X + cAirPlaneSpeed; |
1006 Gear^.X:= Gear^.X + cAirPlaneSpeed; |
1012 if (Gear.Health > 0)and(Gear.X >= Gear.dX)and(Gear.X < Gear.dX + cAirPlaneSpeed) then |
1007 if (Gear^.Health > 0)and( not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
1013 begin |
1008 begin |
1014 dec(Gear.Health); |
1009 dec(Gear^.Health); |
1015 case Gear.State of |
1010 case Gear^.State of |
1016 0: AddGear(round(Gear.X), round(Gear.Y), gtAirBomb, 0, cBombsSpeed, 0.0); |
1011 0: AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed, 0, 0); |
1017 1: AddGear(round(Gear.X), round(Gear.Y), gtMine, 0, cBombsSpeed, 0.0); |
1012 1: AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed, 0, 0); |
1018 end; |
1013 end; |
1019 Gear.dX:= Gear.dX + cBombsDistance |
1014 Gear^.dX:= Gear^.dX + cBombsDistance |
1020 end; |
1015 end; |
1021 if Gear.X > 3072 then DeleteGear(Gear) |
1016 if Gear^.X > 3072 then DeleteGear(Gear) |
1022 end; |
1017 end; |
1023 |
1018 |
1024 procedure doStepAirAttack(Gear: PGear); |
1019 procedure doStepAirAttack(Gear: PGear); |
1025 begin |
1020 begin |
1026 AllInactive:= false; |
1021 AllInactive:= false; |
1027 Gear.X:= -1024; |
1022 Gear^.X:= -1024; |
1028 Gear.Y:= -128; |
1023 Gear^.Y:= -128; |
1029 Gear.dX:= TargetPoint.X - |
1024 Gear^.dX:= TargetPoint.X - |
1030 cBombsDistance * 5 / 2 - |
1025 cBombsDistance * 5 / 2;{ - |
1031 cBombsSpeed * sqrt(2 * (TargetPoint.Y - Gear.Y) / cGravity); |
1026 cBombsSpeed * sqrt(2 * (TargetPoint.Y - Gear^.Y) / cGravity);} |
1032 Gear.Health:= 6; |
1027 Gear^.Health:= 6; |
1033 Gear.doStep:= doStepAirAttackWork |
1028 Gear^.doStep:= @doStepAirAttackWork |
1034 end; |
1029 end; |
1035 |
1030 |
1036 //////////////////////////////////////////////////////////////////////////////// |
1031 //////////////////////////////////////////////////////////////////////////////// |
1037 |
1032 |
1038 procedure doStepAirBomb(Gear: PGear); |
1033 procedure doStepAirBomb(Gear: PGear); |
1039 begin |
1034 begin |
1040 AllInactive:= false; |
1035 AllInactive:= false; |
1041 doStepFallingGear(Gear); |
1036 doStepFallingGear(Gear); |
1042 if (Gear.State and gstCollision) <> 0 then |
1037 if (Gear^.State and gstCollision) <> 0 then |
1043 begin |
1038 begin |
1044 doMakeExplosion(round(Gear.X), round(Gear.Y), 30, EXPLAutoSound); |
1039 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
1045 DeleteGear(Gear); |
1040 DeleteGear(Gear); |
1046 exit |
1041 exit |
1047 end; |
1042 end; |
1048 if (GameTicks and $3F) = 0 then |
1043 if (GameTicks and $3F) = 0 then |
1049 AddGear(round(Gear.X), round(Gear.Y), gtSmokeTrace, 0) |
1044 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) |
1050 end; |
1045 end; |
1051 |
|
1052 |
|