158 (* Invulnerability cannot be placed in here due to still needing kicks |
158 (* Invulnerability cannot be placed in here due to still needing kicks |
159 Not without a new damage machine. |
159 Not without a new damage machine. |
160 King check should be in here instead of ApplyDamage since Tiy wants them kicked less |
160 King check should be in here instead of ApplyDamage since Tiy wants them kicked less |
161 *) |
161 *) |
162 i:= _1; |
162 i:= _1; |
163 if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then i:= _1_5; |
163 if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then |
|
164 i:= _1_5; |
164 if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then |
165 if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then |
165 ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5) |
166 ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5) |
166 else |
167 else |
167 ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent) |
168 ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent) |
168 end; |
169 end; |
169 |
170 |
170 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
171 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
171 var s: shortstring; |
172 var s: shortstring; |
172 vampDmg, tmpDmg, i: Longword; |
173 vampDmg, tmpDmg, i: Longword; |
173 vg: PVisualGear; |
174 vg: PVisualGear; |
174 begin |
175 begin |
175 if Damage = 0 then exit; // nothing to apply |
176 if Damage = 0 then |
|
177 exit; // nothing to apply |
176 |
178 |
177 if (Gear^.Kind = gtHedgehog) then |
179 if (Gear^.Kind = gtHedgehog) then |
178 begin |
180 begin |
179 Gear^.LastDamage := AttackerHog; |
181 Gear^.LastDamage := AttackerHog; |
180 |
182 |
181 Gear^.Hedgehog^.Team^.Clan^.Flawless:= false; |
183 Gear^.Hedgehog^.Team^.Clan^.Flawless:= false; |
182 HHHurt(Gear^.Hedgehog, Source); |
184 HHHurt(Gear^.Hedgehog, Source); |
183 AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color); |
185 AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color); |
184 tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage)); |
186 tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage)); |
185 if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then |
187 if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then |
186 begin |
188 begin |
187 if cVampiric then |
189 if cVampiric then |
188 begin |
|
189 vampDmg:= hwRound(int2hwFloat(tmpDmg)*_0_8); |
|
190 if vampDmg >= 1 then |
|
191 begin |
190 begin |
192 // was considering pulsing on attack, Tiy thinks it should be permanent while in play |
191 vampDmg:= hwRound(int2hwFloat(tmpDmg)*_0_8); |
193 //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric; |
192 if vampDmg >= 1 then |
194 inc(CurrentHedgehog^.Gear^.Health,vampDmg); |
|
195 str(vampDmg, s); |
|
196 s:= '+' + s; |
|
197 AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo); |
|
198 RenderHealth(CurrentHedgehog^); |
|
199 RecountTeamHealth(CurrentHedgehog^.Team); |
|
200 i:= 0; |
|
201 while i < vampDmg do |
|
202 begin |
193 begin |
203 vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot); |
194 // was considering pulsing on attack, Tiy thinks it should be permanent while in play |
204 if vg <> nil then |
195 //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric; |
205 with vg^ do |
196 inc(CurrentHedgehog^.Gear^.Health,vampDmg); |
206 begin |
197 str(vampDmg, s); |
207 Tint:= $FF0000FF; |
198 s:= '+' + s; |
208 State:= ord(sprHealth) |
199 AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo); |
209 end; |
200 RenderHealth(CurrentHedgehog^); |
210 inc(i, 5); |
201 RecountTeamHealth(CurrentHedgehog^.Team); |
211 end; |
202 i:= 0; |
212 end |
203 while i < vampDmg do |
213 end; |
204 begin |
214 if ((GameFlags and gfKarma) <> 0) and |
205 vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot); |
215 ((GameFlags and gfInvulnerable) = 0) and |
206 if vg <> nil then |
216 (not CurrentHedgehog^.Gear^.Invulnerable) then |
207 with vg^ do |
217 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid |
208 begin |
218 inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); |
209 Tint:= $FF0000FF; |
219 CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog; |
210 State:= ord(sprHealth) |
220 spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg); |
211 end; |
221 end; |
212 inc(i, 5); |
|
213 end; |
|
214 end |
|
215 end; |
|
216 if ((GameFlags and gfKarma) <> 0) and |
|
217 ((GameFlags and gfInvulnerable) = 0) |
|
218 and (not CurrentHedgehog^.Gear^.Invulnerable) then |
|
219 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid |
|
220 inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); |
|
221 CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog; |
|
222 spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg); |
|
223 end; |
222 uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false); |
224 uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false); |
223 end; |
225 end; |
224 end else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure |
226 end |
|
227 else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure |
225 begin |
228 begin |
226 Gear^.Hedgehog:= AttackerHog; |
229 Gear^.Hedgehog:= AttackerHog; |
227 end; |
230 end; |
228 inc(Gear^.Damage, Damage); |
231 inc(Gear^.Damage, Damage); |
229 |
232 |
270 begin |
273 begin |
271 if _0_4 < Gear^.dY then |
274 if _0_4 < Gear^.dY then |
272 begin |
275 begin |
273 dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
276 dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
274 PlaySound(sndBump); |
277 PlaySound(sndBump); |
275 if dmg < 1 then exit; |
278 if dmg < 1 then |
|
279 exit; |
276 |
280 |
277 for i:= min(12, (3 + dmg div 10)) downto 0 do |
281 for i:= min(12, (3 + dmg div 10)) downto 0 do |
278 begin |
282 begin |
279 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
283 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
280 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); |
284 if particle <> nil then |
281 end; |
285 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); |
282 |
286 end; |
283 if (Gear^.Invulnerable) then exit; |
287 |
|
288 if (Gear^.Invulnerable) then |
|
289 exit; |
284 |
290 |
285 //if _0_6 < Gear^.dY then |
291 //if _0_6 < Gear^.dY then |
286 // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack) |
292 // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack) |
287 //else |
293 //else |
288 // PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack); |
294 // PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack); |
289 |
295 |
290 if Gear^.LastDamage <> nil then |
296 if Gear^.LastDamage <> nil then |
291 ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall) |
297 ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall) |
292 else |
298 else |
293 ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall); |
299 ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall); |
294 end |
300 end |
295 end; |
301 end; |
296 |
302 |
297 |
303 |
327 skipDecay := _0_87; |
335 skipDecay := _0_87; |
328 X:= hwRound(Gear^.X); |
336 X:= hwRound(Gear^.X); |
329 vdX:= hwFloat2Float(Gear^.dX); |
337 vdX:= hwFloat2Float(Gear^.dX); |
330 vdY:= hwFloat2Float(Gear^.dY); |
338 vdY:= hwFloat2Float(Gear^.dY); |
331 // this could perhaps be a tiny bit higher. |
339 // this could perhaps be a tiny bit higher. |
332 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and |
340 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) |
333 (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then |
341 and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then |
334 begin |
342 begin |
335 Gear^.dY.isNegative := true; |
343 Gear^.dY.isNegative := true; |
336 Gear^.dY := Gear^.dY * skipDecay; |
344 Gear^.dY := Gear^.dY * skipDecay; |
337 Gear^.dX := Gear^.dX * skipDecay; |
345 Gear^.dX := Gear^.dX * skipDecay; |
338 CheckGearDrowning := false; |
346 CheckGearDrowning := false; |
356 Gear^.doStep := @doStepDrowningGear; |
364 Gear^.doStep := @doStepDrowningGear; |
357 Gear^.State := Gear^.State and (not gstHHDriven); |
365 Gear^.State := Gear^.State and (not gstHHDriven); |
358 AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage); |
366 AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage); |
359 end |
367 end |
360 end |
368 end |
361 else Gear^.doStep := @doStepDrowningGear; |
369 else |
362 if Gear^.Kind = gtFlake then exit // skip splashes |
370 Gear^.doStep := @doStepDrowningGear; |
|
371 if Gear^.Kind = gtFlake then |
|
372 exit // skip splashes |
363 end; |
373 end; |
364 if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or |
374 if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) |
365 (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01))) then |
375 or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) |
|
376 and (CurAmmoGear^.dY < _0_01))) then |
366 // don't play splash if they are already way past the surface |
377 // don't play splash if they are already way past the surface |
367 PlaySound(sndSplash) |
378 PlaySound(sndSplash) |
368 end; |
379 end; |
369 |
380 |
370 if ((cReducedQuality and rqPlainSplash) = 0) and |
381 if ((cReducedQuality and rqPlainSplash) = 0) |
371 (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or |
382 and (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) |
372 (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01)))) then |
383 or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) |
|
384 and (CurAmmoGear^.dY < _0_01)))) then |
373 begin |
385 begin |
374 AddVisualGear(X, cWaterLine, vgtSplash); |
386 AddVisualGear(X, cWaterLine, vgtSplash); |
375 |
387 |
376 maxDrops := (Gear^.Radius div 2) + round(vdX * Gear^.Radius * 2) + round(vdY * Gear^.Radius * 2); |
388 maxDrops := (Gear^.Radius div 2) + round(vdX * Gear^.Radius * 2) + round(vdY * Gear^.Radius * 2); |
377 for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do |
389 for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do |
408 Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16); |
421 Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16); |
409 end; |
422 end; |
410 tempTeam := gear^.Hedgehog^.Team; |
423 tempTeam := gear^.Hedgehog^.Team; |
411 DeleteCI(gear); |
424 DeleteCI(gear); |
412 FindPlace(gear, false, 0, LAND_WIDTH, true); |
425 FindPlace(gear, false, 0, LAND_WIDTH, true); |
413 if gear <> nil then begin |
426 if gear <> nil then |
|
427 begin |
414 RenderHealth(gear^.Hedgehog^); |
428 RenderHealth(gear^.Hedgehog^); |
415 ScriptCall('onGearResurrect', gear^.uid); |
429 ScriptCall('onGearResurrect', gear^.uid); |
416 gear^.State := gstWait; |
430 gear^.State := gstWait; |
417 end; |
431 end; |
418 RecountTeamHealth(tempTeam); |
432 RecountTeamHealth(tempTeam); |
463 |
478 |
464 repeat |
479 repeat |
465 inc(y); |
480 inc(y); |
466 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0); |
481 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0); |
467 |
482 |
468 if (y - sy > Gear^.Radius * 2) and |
483 if (y - sy > Gear^.Radius * 2) |
469 (((Gear^.Kind = gtExplosives) |
484 and (((Gear^.Kind = gtExplosives) |
470 and (y < cWaterLine) |
485 and (y < cWaterLine) |
471 and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil)) |
486 and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil)) |
472 and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius)) |
487 and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius)) |
473 or |
488 or |
474 ((Gear^.Kind <> gtExplosives) |
489 ((Gear^.Kind <> gtExplosives) |
475 and (y < cWaterLine) |
490 and (y < cWaterLine) |
476 and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then |
491 and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then |
477 begin |
492 |
|
493 begin |
478 ar[cnt].X:= x; |
494 ar[cnt].X:= x; |
479 if withFall then ar[cnt].Y:= sy + Gear^.Radius |
495 if withFall then |
480 else ar[cnt].Y:= y - Gear^.Radius; |
496 ar[cnt].Y:= sy + Gear^.Radius |
|
497 else |
|
498 ar[cnt].Y:= y - Gear^.Radius; |
481 inc(cnt) |
499 inc(cnt) |
482 end; |
500 end; |
483 |
501 |
484 inc(y, 45) |
502 inc(y, 45) |
485 end; |
503 end; |