81 end |
84 end |
82 end; |
85 end; |
83 |
86 |
84 |
87 |
85 // ================================================================== |
88 // ================================================================== |
86 procedure doStepFlake(Gear: PVisualGear; Steps: Longword); |
|
87 var sign: hwFloat; |
|
88 begin |
|
89 sign:= _1; |
|
90 with Gear^ do |
|
91 begin |
|
92 inc(FrameTicks, Steps); |
|
93 if FrameTicks > vobFrameTicks then |
|
94 begin |
|
95 dec(FrameTicks, vobFrameTicks); |
|
96 inc(Frame); |
|
97 if Frame = vobFramesCount then Frame:= 0 |
|
98 end; |
|
99 X:= X + (cWindSpeed * 200 + dX + tdX) * Steps; |
|
100 Y:= Y + (dY + tdY + cGravity * vobFallSpeed) * Steps; |
|
101 Angle:= Angle + dAngle * Steps; |
|
102 |
|
103 if (hwRound(X) >= -cScreenWidth - 64) and |
|
104 (hwRound(X) <= cScreenWidth + LAND_WIDTH) and |
|
105 (hwRound(Y) <= (LAND_HEIGHT + 75)) and |
|
106 (Timer > 0) and (Timer-Steps > 0) then |
|
107 begin |
|
108 sign.isNegative:=tdX.isNegative; |
|
109 tdX:= tdX - _0_005*Steps*sign; |
|
110 if (sign.isNegative and (tdX > _0)) or (not sign.isNegative and (tdX < _0)) then tdX:= _0; |
|
111 sign.isNegative:=tdY.isNegative; |
|
112 tdY:= tdY - _0_005*Steps*sign; |
|
113 if (sign.isNegative and (tdY > _0)) or (not sign.isNegative and (tdY < _0)) then tdY:= _0; |
|
114 dec(Timer, Steps) |
|
115 end |
|
116 else |
|
117 begin |
|
118 if hwRound(X) < -cScreenWidth - 64 then X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else |
|
119 if hwRound(X) > cScreenWidth + LAND_WIDTH then X:= int2hwFloat(-cScreenWidth - 64); |
|
120 // if hwRound(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + int2hwFloat(25); // For if flag is set for flakes rising upwards? |
|
121 if hwRound(Y) > (LAND_HEIGHT + 75) then Y:= Y - int2hwFloat(1024 + 150); // TODO - configure in theme (jellies for example could use limited range) |
|
122 Timer:= 0; |
|
123 tdX:= _0; |
|
124 tdY:= _0 |
|
125 end; |
|
126 end; |
|
127 |
|
128 end; |
|
129 |
|
130 procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword); |
|
131 begin |
|
132 if Gear^.FrameTicks > Steps then |
|
133 dec(Gear^.FrameTicks, Steps) |
|
134 else |
|
135 DeleteVisualGear(Gear); |
|
136 end; |
|
137 |
|
138 procedure doStepCloud(Gear: PVisualGear; Steps: Longword); |
|
139 var i: Longword; |
|
140 begin |
|
141 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps; |
|
142 |
|
143 for i:= 0 to Steps - 1 do |
|
144 begin |
|
145 if hwRound(Gear^.Y) > LAND_HEIGHT-1184 then // TODO - configure in theme |
|
146 Gear^.dY:= Gear^.dY - _1div50000 |
|
147 else |
|
148 Gear^.dY:= Gear^.dY + _1div50000; |
|
149 |
|
150 Gear^.Y:= Gear^.Y + Gear^.dY |
|
151 end; |
|
152 |
|
153 if hwRound(Gear^.X) < -cScreenWidth - 256 then Gear^.X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else |
|
154 if hwRound(Gear^.X) > cScreenWidth + LAND_WIDTH then Gear^.X:= int2hwFloat(-cScreenWidth - 256) |
|
155 end; |
|
156 |
|
157 procedure doStepExpl(Gear: PVisualGear; Steps: Longword); |
|
158 begin |
|
159 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
160 |
|
161 Gear^.Y:= Gear^.Y + Gear^.dY * Steps; |
|
162 //Gear^.dY:= Gear^.dY + cGravity; |
|
163 |
|
164 if Gear^.FrameTicks <= Steps then |
|
165 if Gear^.Frame = 0 then DeleteVisualGear(Gear) |
|
166 else |
|
167 begin |
|
168 dec(Gear^.Frame); |
|
169 Gear^.FrameTicks:= cExplFrameTicks |
|
170 end |
|
171 else dec(Gear^.FrameTicks, Steps) |
|
172 end; |
|
173 |
|
174 procedure doStepEgg(Gear: PVisualGear; Steps: Longword); |
|
175 begin |
|
176 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
177 |
|
178 Gear^.Y:= Gear^.Y + Gear^.dY * Steps; |
|
179 Gear^.dY:= Gear^.dY + cGravity * Steps; |
|
180 |
|
181 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; |
|
182 |
|
183 if Gear^.FrameTicks <= Steps then |
|
184 DeleteVisualGear(Gear) |
|
185 else |
|
186 dec(Gear^.FrameTicks, Steps) |
|
187 end; |
|
188 |
|
189 procedure doStepFire(Gear: PVisualGear; Steps: Longword); |
|
190 begin |
|
191 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
192 |
|
193 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;// + cGravity * (Steps * Steps); |
|
194 Gear^.dY:= Gear^.dY + cGravity * Steps; |
|
195 |
|
196 if Gear^.FrameTicks <= Steps then |
|
197 DeleteVisualGear(Gear) |
|
198 else |
|
199 dec(Gear^.FrameTicks, Steps) |
|
200 end; |
|
201 |
|
202 procedure doStepShell(Gear: PVisualGear; Steps: Longword); |
|
203 begin |
|
204 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
205 |
|
206 Gear^.Y:= Gear^.Y + Gear^.dY * Steps; |
|
207 Gear^.dY:= Gear^.dY + cGravity * Steps; |
|
208 |
|
209 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; |
|
210 |
|
211 if Gear^.FrameTicks <= Steps then |
|
212 DeleteVisualGear(Gear) |
|
213 else |
|
214 dec(Gear^.FrameTicks, Steps) |
|
215 end; |
|
216 |
|
217 procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword); |
|
218 begin |
|
219 Gear^.Y:= Gear^.Y - _0_02 * Steps; |
|
220 |
|
221 if Gear^.FrameTicks <= Steps then |
|
222 DeleteVisualGear(Gear) |
|
223 else |
|
224 dec(Gear^.FrameTicks, Steps) |
|
225 end; |
|
226 |
|
227 procedure doStepBubble(Gear: PVisualGear; Steps: Longword); |
|
228 begin |
|
229 Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps; |
|
230 Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; |
|
231 |
|
232 if (Gear^.FrameTicks <= Steps) or (hwRound(Gear^.Y) < cWaterLine) then |
|
233 DeleteVisualGear(Gear) |
|
234 else |
|
235 dec(Gear^.FrameTicks, Steps) |
|
236 end; |
|
237 |
|
238 procedure doStepHealth(Gear: PVisualGear; Steps: Longword); |
|
239 begin |
|
240 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
241 Gear^.Y:= Gear^.Y - Gear^.dY * Steps; |
|
242 |
|
243 if Gear^.FrameTicks <= Steps then |
|
244 DeleteVisualGear(Gear) |
|
245 else |
|
246 dec(Gear^.FrameTicks, Steps); |
|
247 end; |
|
248 |
|
249 procedure doStepSteam(Gear: PVisualGear; Steps: Longword); |
|
250 begin |
|
251 Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps; |
|
252 Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; |
|
253 |
|
254 if Gear^.FrameTicks <= Steps then |
|
255 if Gear^.Frame = 0 then DeleteVisualGear(Gear) |
|
256 else |
|
257 begin |
|
258 if Random(2) = 0 then dec(Gear^.Frame); |
|
259 Gear^.FrameTicks:= cExplFrameTicks |
|
260 end |
|
261 else dec(Gear^.FrameTicks, Steps) |
|
262 end; |
|
263 |
|
264 procedure doStepAmmo(Gear: PVisualGear; Steps: Longword); |
|
265 begin |
|
266 Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; |
|
267 |
|
268 Gear^.scale:= Gear^.scale + 0.0025 * Steps; |
|
269 Gear^.alpha:= Gear^.alpha - 0.0015 * Steps; |
|
270 |
|
271 if Gear^.alpha < 0 then DeleteVisualGear(Gear) |
|
272 end; |
|
273 |
|
274 procedure doStepSmoke(Gear: PVisualGear; Steps: Longword); |
|
275 begin |
|
276 Gear^.X:= Gear^.X + (cWindSpeed + Gear^.dX) * Steps; |
|
277 Gear^.Y:= Gear^.Y - (cDrownSpeed + Gear^.dY) * Steps; |
|
278 |
|
279 Gear^.dX := Gear^.dX + (cWindSpeed * _0_3 * Steps); |
|
280 //Gear^.dY := Gear^.dY - (cDrownSpeed * _0_995); |
|
281 |
|
282 if Gear^.FrameTicks <= Steps then |
|
283 if Gear^.Frame = 0 then DeleteVisualGear(Gear) |
|
284 else |
|
285 begin |
|
286 if Random(2) = 0 then dec(Gear^.Frame); |
|
287 Gear^.FrameTicks:= cExplFrameTicks |
|
288 end |
|
289 else dec(Gear^.FrameTicks, Steps) |
|
290 end; |
|
291 |
|
292 procedure doStepDust(Gear: PVisualGear; Steps: Longword); |
|
293 begin |
|
294 Gear^.X:= Gear^.X + (cWindSpeed + (cWindSpeed * _0_03 * Steps) + Gear^.dX) * Steps; |
|
295 Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps; |
|
296 |
|
297 Gear^.dX := Gear^.dX - (Gear^.dX * _0_005 * Steps); |
|
298 Gear^.dY := Gear^.dY - (cDrownSpeed * _0_001 * Steps); |
|
299 |
|
300 if Gear^.FrameTicks <= Steps then |
|
301 if Gear^.Frame = 0 then DeleteVisualGear(Gear) |
|
302 else |
|
303 begin |
|
304 dec(Gear^.Frame); |
|
305 Gear^.FrameTicks:= cExplFrameTicks |
|
306 end |
|
307 else dec(Gear^.FrameTicks, Steps) |
|
308 end; |
|
309 |
|
310 procedure doStepSplash(Gear: PVisualGear; Steps: Longword); |
|
311 begin |
|
312 if Gear^.FrameTicks <= Steps then |
|
313 DeleteVisualGear(Gear) |
|
314 else |
|
315 dec(Gear^.FrameTicks, Steps); |
|
316 end; |
|
317 |
|
318 procedure doStepDroplet(Gear: PVisualGear; Steps: Longword); |
|
319 begin |
|
320 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
321 |
|
322 Gear^.Y:= Gear^.Y + Gear^.dY * Steps; |
|
323 Gear^.dY:= Gear^.dY + cGravity * Steps; |
|
324 |
|
325 if hwRound(Gear^.Y) > cWaterLine then begin |
|
326 DeleteVisualGear(Gear); |
|
327 PlaySound(TSound(ord(sndDroplet1) + Random(3))); |
|
328 end; |
|
329 end; |
|
330 |
|
331 procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword); |
|
332 begin |
|
333 inc(Gear^.Timer, Steps); |
|
334 if Gear^.Timer >= Gear^.FrameTicks then DeleteVisualGear(Gear) |
|
335 else |
|
336 begin |
|
337 Gear^.scale := 1.25 * (-power(2, -10 * Int(Gear^.Timer)/Gear^.FrameTicks) + 1) + 0.4; |
|
338 Gear^.alpha := 1 - power(Gear^.Timer / 350, 4); |
|
339 if Gear^.alpha < 0 then Gear^.alpha:= 0; |
|
340 end; |
|
341 end; |
|
342 |
|
343 procedure doStepFeather(Gear: PVisualGear; Steps: Longword); |
|
344 begin |
|
345 Gear^.X:= Gear^.X + Gear^.dX * Steps; |
|
346 |
|
347 Gear^.Y:= Gear^.Y + Gear^.dY * Steps; |
|
348 Gear^.dY:= Gear^.dY + cGravity * Steps; |
|
349 |
|
350 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; |
|
351 |
|
352 if Gear^.FrameTicks <= Steps then |
|
353 DeleteVisualGear(Gear) |
|
354 else |
|
355 dec(Gear^.FrameTicks, Steps) |
|
356 end; |
|
357 //////////////////////////////////////////////////////////////////////////////// |
|
358 const cSorterWorkTime = 640; |
|
359 var thexchar: array[0..cMaxTeams] of |
|
360 record |
|
361 dy, ny, dw: LongInt; |
|
362 team: PTeam; |
|
363 SortFactor: QWord; |
|
364 end; |
|
365 currsorter: PVisualGear = nil; |
|
366 |
|
367 procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword); |
|
368 var i, t: LongInt; |
|
369 begin |
|
370 for t:= 1 to Steps do |
|
371 begin |
|
372 dec(Gear^.Timer); |
|
373 if (Gear^.Timer and 15) = 0 then |
|
374 for i:= 0 to Pred(TeamsCount) do |
|
375 with thexchar[i] do |
|
376 begin |
|
377 {$WARNINGS OFF} |
|
378 team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div 640; |
|
379 team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime; |
|
380 {$WARNINGS ON} |
|
381 end; |
|
382 |
|
383 if (Gear^.Timer = 0) or (currsorter <> Gear) then |
|
384 begin |
|
385 if currsorter = Gear then currsorter:= nil; |
|
386 DeleteVisualGear(Gear); |
|
387 exit |
|
388 end |
|
389 end |
|
390 end; |
|
391 |
|
392 procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword); |
|
393 var i: Longword; |
|
394 b: boolean; |
|
395 t: LongInt; |
|
396 begin |
|
397 Steps:= Steps; // avoid compiler hint |
|
398 for t:= 0 to Pred(TeamsCount) do |
|
399 with thexchar[t] do |
|
400 begin |
|
401 dy:= TeamsArray[t]^.DrawHealthY; |
|
402 dw:= TeamsArray[t]^.TeamHealthBarWidth - TeamsArray[t]^.NewTeamHealthBarWidth; |
|
403 team:= TeamsArray[t]; |
|
404 SortFactor:= TeamsArray[t]^.Clan^.ClanHealth; |
|
405 SortFactor:= (SortFactor shl 3) + TeamsArray[t]^.Clan^.ClanIndex; |
|
406 SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth; |
|
407 end; |
|
408 |
|
409 if TeamsCount > 1 then |
|
410 repeat |
|
411 b:= true; |
|
412 for t:= 0 to TeamsCount - 2 do |
|
413 if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then |
|
414 begin |
|
415 thexchar[cMaxTeams]:= thexchar[t]; |
|
416 thexchar[t]:= thexchar[Succ(t)]; |
|
417 thexchar[Succ(t)]:= thexchar[cMaxTeams]; |
|
418 b:= false |
|
419 end |
|
420 until b; |
|
421 |
|
422 t:= - 4; |
|
423 for i:= 0 to Pred(TeamsCount) do |
|
424 with thexchar[i] do |
|
425 begin |
|
426 dec(t, team^.HealthTex^.h + 2); |
|
427 ny:= t; |
|
428 dy:= dy - ny |
|
429 end; |
|
430 |
|
431 Gear^.Timer:= cSorterWorkTime; |
|
432 Gear^.doStep:= @doStepTeamHealthSorterWork; |
|
433 currsorter:= Gear; |
|
434 //doStepTeamHealthSorterWork(Gear, Steps) |
|
435 end; |
|
436 |
|
437 procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword); |
|
438 begin |
|
439 if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0; |
|
440 |
|
441 if (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then |
|
442 begin |
|
443 Gear^.X:= PHedgehog(Gear^.Hedgehog)^.Gear^.X + int2hwFloat(Gear^.Tex^.w div 2 - Gear^.FrameTicks); |
|
444 Gear^.Y:= PHedgehog(Gear^.Hedgehog)^.Gear^.Y - int2hwFloat(16 + Gear^.Tex^.h); |
|
445 end; |
|
446 |
|
447 if Gear^.Timer = 0 then |
|
448 begin |
|
449 if PHedgehog(Gear^.Hedgehog)^.SpeechGear = Gear then |
|
450 PHedgehog(Gear^.Hedgehog)^.SpeechGear:= nil; |
|
451 DeleteVisualGear(Gear) |
|
452 end; |
|
453 end; |
|
454 |
|
455 procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword); |
|
456 begin |
|
457 Steps:= Steps; // avoid compiler hint |
|
458 |
|
459 with PHedgehog(Gear^.Hedgehog)^ do |
|
460 if SpeechGear <> nil then SpeechGear^.Timer:= 0; |
|
461 |
|
462 PHedgehog(Gear^.Hedgehog)^.SpeechGear:= Gear; |
|
463 |
|
464 Gear^.Timer:= max(Length(Gear^.Text) * 150, 3000); |
|
465 |
|
466 Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16); |
|
467 |
|
468 case Gear^.FrameTicks of |
|
469 1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28; |
|
470 2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20; |
|
471 3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10; |
|
472 end; |
|
473 |
|
474 Gear^.doStep:= @doStepSpeechBubbleWork; |
|
475 |
|
476 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h) |
|
477 end; |
|
478 |
89 |
479 // ================================================================== |
90 // ================================================================== |
480 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure = |
91 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure = |
481 ( |
92 ( |
482 @doStepFlake, |
93 @doStepFlake, |