author | nemo |
Thu, 27 Jun 2013 14:01:43 -0400 | |
changeset 9291 | 15f7bb217b66 |
parent 9285 | 8e8b908970c2 |
child 9473 | a51a69094c24 |
permissions | -rw-r--r-- |
6581 | 1 |
(* |
2 |
* Hedgewars, a free turn based strategy game |
|
9080 | 3 |
* Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com> |
6581 | 4 |
* |
5 |
* This program is free software; you can redistribute it and/or modify |
|
6 |
* it under the terms of the GNU General Public License as published by |
|
7 |
* the Free Software Foundation; version 2 of the License |
|
8 |
* |
|
9 |
* This program is distributed in the hope that it will be useful, |
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
13 |
* |
|
14 |
* You should have received a copy of the GNU General Public License |
|
15 |
* along with this program; if not, write to the Free Software |
|
16 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
*) |
|
18 |
||
19 |
{$INCLUDE "options.inc"} |
|
20 |
||
21 |
unit uGearsUtils; |
|
22 |
interface |
|
9285 | 23 |
uses uTypes, uFloat; |
6581 | 24 |
|
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
25 |
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
26 |
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
27 |
|
6581 | 28 |
function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
29 |
procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
|
30 |
procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword); |
|
31 |
procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource); |
|
32 |
procedure CheckHHDamage(Gear: PGear); |
|
33 |
procedure CalcRotationDirAngle(Gear: PGear); |
|
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
34 |
procedure ResurrectHedgehog(var gear: PGear); |
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
35 |
|
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
36 |
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
37 |
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
38 |
|
6581 | 39 |
function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; |
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
40 |
function CheckGearDrowning(var Gear: PGear): boolean; |
7592 | 41 |
procedure CheckCollision(Gear: PGear); inline; |
42 |
procedure CheckCollisionWithLand(Gear: PGear); inline; |
|
6581 | 43 |
|
9285 | 44 |
procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); |
45 |
function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS; |
|
46 |
procedure SpawnBoxOfSmth; |
|
47 |
procedure ShotgunShot(Gear: PGear); |
|
48 |
||
49 |
procedure SetAllToActive; |
|
50 |
procedure SetAllHHToActive; inline; |
|
51 |
procedure SetAllHHToActive(Ice: boolean); |
|
52 |
||
53 |
function GetAmmo(Hedgehog: PHedgehog): TAmmoType; |
|
54 |
function GetUtility(Hedgehog: PHedgehog): TAmmoType; |
|
55 |
||
56 |
||
57 |
||
7719
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
58 |
function MakeHedgehogsStep(Gear: PGear) : boolean; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
59 |
|
6581 | 60 |
var doStepHandlers: array[TGearType] of TGearStepProcedure; |
61 |
||
62 |
||
63 |
implementation |
|
9285 | 64 |
uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc, |
6581 | 65 |
uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore, |
9285 | 66 |
uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug, |
67 |
uGearsList, Math, uVisualGearsList, uGearsHandlersMess, |
|
68 |
uGearsHedgehog; |
|
6581 | 69 |
|
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
70 |
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
71 |
begin |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
72 |
doMakeExplosion(X, Y, Radius, AttackingHog, Mask, $FFFFFFFF); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
73 |
end; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
74 |
|
6581 | 75 |
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
76 |
var Gear: PGear; |
|
6769
44ad49a3a126
Add drowning to grenade too, try some little optimisations
nemo
parents:
6765
diff
changeset
|
77 |
dmg, dmgBase: LongInt; |
6765 | 78 |
fX, fY, tdX, tdY: hwFloat; |
6581 | 79 |
vg: PVisualGear; |
80 |
i, cnt: LongInt; |
|
81 |
begin |
|
82 |
if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')'); |
|
83 |
if Radius > 25 then KickFlakes(Radius, X, Y); |
|
84 |
||
85 |
if ((Mask and EXPLNoGfx) = 0) then |
|
86 |
begin |
|
87 |
vg:= nil; |
|
88 |
if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion) |
|
89 |
else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion); |
|
90 |
if vg <> nil then |
|
91 |
vg^.Tint:= Tint; |
|
92 |
end; |
|
93 |
if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion); |
|
94 |
||
6765 | 95 |
(*if (Mask and EXPLAllDamageInRadius) = 0 then |
6581 | 96 |
dmgRadius:= Radius shl 1 |
97 |
else |
|
98 |
dmgRadius:= Radius; |
|
6765 | 99 |
dmgBase:= dmgRadius + cHHRadius div 2;*) |
100 |
dmgBase:= Radius shl 1 + cHHRadius div 2; |
|
6581 | 101 |
fX:= int2hwFloat(X); |
102 |
fY:= int2hwFloat(Y); |
|
103 |
Gear:= GearsList; |
|
104 |
while Gear <> nil do |
|
105 |
begin |
|
106 |
dmg:= 0; |
|
107 |
//dmg:= dmgRadius + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
|
108 |
//if (dmg > 1) and |
|
109 |
if (Gear^.State and gstNoDamage) = 0 then |
|
110 |
begin |
|
111 |
case Gear^.Kind of |
|
112 |
gtHedgehog, |
|
113 |
gtMine, |
|
114 |
gtBall, |
|
115 |
gtMelonPiece, |
|
116 |
gtGrenade, |
|
117 |
gtClusterBomb, |
|
118 |
// gtCluster, too game breaking I think |
|
119 |
gtSMine, |
|
120 |
gtCase, |
|
121 |
gtTarget, |
|
122 |
gtFlame, |
|
7754 | 123 |
gtKnife, |
8161 | 124 |
gtExplosives: begin //, |
125 |
//gtStructure: begin |
|
6581 | 126 |
// Run the calcs only once we know we have a type that will need damage |
6765 | 127 |
tdX:= Gear^.X-fX; |
128 |
tdY:= Gear^.Y-fY; |
|
7721 | 129 |
if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then |
7272
71df899c4163
Second part of the change. Make collision check use the new mask bit.
nemo
parents:
7190
diff
changeset
|
130 |
dmg:= dmgBase - hwRound(Distance(tdX, tdY)); |
6581 | 131 |
if dmg > 1 then |
132 |
begin |
|
133 |
dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
134 |
//AddFileLog('Damage: ' + inttostr(dmg)); |
|
135 |
if (Mask and EXPLNoDamage) = 0 then |
|
136 |
begin |
|
137 |
if not Gear^.Invulnerable then |
|
138 |
ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
|
139 |
else |
|
140 |
Gear^.State:= Gear^.State or gstWinner; |
|
141 |
end; |
|
142 |
if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
|
143 |
begin |
|
144 |
DeleteCI(Gear); |
|
6765 | 145 |
Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, tdX)/(Gear^.Density/_3); |
146 |
Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, tdY)/(Gear^.Density/_3); |
|
6581 | 147 |
|
148 |
Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
|
7767 | 149 |
if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
6581 | 150 |
if not Gear^.Invulnerable then |
151 |
Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
|
152 |
Gear^.Active:= true; |
|
153 |
if Gear^.Kind <> gtFlame then FollowGear:= Gear |
|
154 |
end; |
|
8763 | 155 |
if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) and ((Gear^.State and gstHHDeath) = 0) then |
7010
10a0a31804f3
Switch effects to longint for convenience of tracking ice states. I could add a new Hedgehog value, but since we have this effects list being all useless as booleans anyway...
nemo
parents:
6990
diff
changeset
|
156 |
Gear^.Hedgehog^.Effects[hePoisoned] := 1; |
6581 | 157 |
end; |
158 |
||
159 |
end; |
|
160 |
gtGrave: begin |
|
161 |
// Run the calcs only once we know we have a type that will need damage |
|
6765 | 162 |
tdX:= Gear^.X-fX; |
163 |
tdY:= Gear^.Y-fY; |
|
7721 | 164 |
if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then |
6765 | 165 |
dmg:= dmgBase - hwRound(Distance(tdX, tdY)); |
6581 | 166 |
if dmg > 1 then |
167 |
begin |
|
168 |
dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
169 |
Gear^.dY:= - _0_004 * dmg; |
|
170 |
Gear^.Active:= true |
|
171 |
end |
|
172 |
end; |
|
173 |
end; |
|
174 |
end; |
|
175 |
Gear:= Gear^.NextGear |
|
176 |
end; |
|
177 |
||
178 |
if (Mask and EXPLDontDraw) = 0 then |
|
179 |
if (GameFlags and gfSolidLand) = 0 then |
|
180 |
begin |
|
181 |
cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk |
|
182 |
if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then |
|
183 |
for i:= 0 to cnt do |
|
184 |
AddVisualGear(X, Y, vgtChunk) |
|
185 |
end; |
|
186 |
||
187 |
uAIMisc.AwareOfExplosion(0, 0, 0) |
|
188 |
end; |
|
189 |
||
190 |
function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
|
191 |
var i: hwFloat; |
|
192 |
begin |
|
193 |
(* Invulnerability cannot be placed in here due to still needing kicks |
|
194 |
Not without a new damage machine. |
|
195 |
King check should be in here instead of ApplyDamage since Tiy wants them kicked less |
|
196 |
*) |
|
197 |
i:= _1; |
|
198 |
if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then |
|
199 |
i:= _1_5; |
|
8632
b5ed76d2a1f9
Make hogs thaw only on enemy turns, make timebox counter decrement only on your turn, adjust knock for frozen hogs, increase damage on frozen hogs, make freezer fuel only reduce when not adjusting angle.
nemo
parents:
8560
diff
changeset
|
200 |
if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then |
9148
78c699d8fdfd
move 0.01 to the end to avoid increase damage fail on small values like fire. thanks to hedgewars wiki for noting this for fire damage.
nemo
parents:
9080
diff
changeset
|
201 |
ModifyDamage:= hwRound(cDamageModifier * dmg * i * cDamagePercent * _0_5 * _0_01) |
9149 | 202 |
else |
9148
78c699d8fdfd
move 0.01 to the end to avoid increase damage fail on small values like fire. thanks to hedgewars wiki for noting this for fire damage.
nemo
parents:
9080
diff
changeset
|
203 |
ModifyDamage:= hwRound(cDamageModifier * dmg * i * cDamagePercent * _0_01) |
6581 | 204 |
end; |
205 |
||
206 |
procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
|
207 |
var s: shortstring; |
|
208 |
vampDmg, tmpDmg, i: Longword; |
|
209 |
vg: PVisualGear; |
|
210 |
begin |
|
211 |
if Damage = 0 then |
|
212 |
exit; // nothing to apply |
|
213 |
||
214 |
if (Gear^.Kind = gtHedgehog) then |
|
215 |
begin |
|
216 |
Gear^.LastDamage := AttackerHog; |
|
217 |
||
218 |
Gear^.Hedgehog^.Team^.Clan^.Flawless:= false; |
|
219 |
HHHurt(Gear^.Hedgehog, Source); |
|
220 |
AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color); |
|
221 |
tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage)); |
|
222 |
if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then |
|
223 |
begin |
|
224 |
if cVampiric then |
|
225 |
begin |
|
226 |
vampDmg:= hwRound(int2hwFloat(tmpDmg)*_0_8); |
|
227 |
if vampDmg >= 1 then |
|
228 |
begin |
|
229 |
// was considering pulsing on attack, Tiy thinks it should be permanent while in play |
|
230 |
//CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric; |
|
231 |
inc(CurrentHedgehog^.Gear^.Health,vampDmg); |
|
232 |
str(vampDmg, s); |
|
233 |
s:= '+' + s; |
|
234 |
AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo); |
|
235 |
RenderHealth(CurrentHedgehog^); |
|
236 |
RecountTeamHealth(CurrentHedgehog^.Team); |
|
237 |
i:= 0; |
|
238 |
while i < vampDmg do |
|
239 |
begin |
|
240 |
vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot); |
|
241 |
if vg <> nil then |
|
242 |
with vg^ do |
|
243 |
begin |
|
244 |
Tint:= $FF0000FF; |
|
245 |
State:= ord(sprHealth) |
|
246 |
end; |
|
247 |
inc(i, 5); |
|
248 |
end; |
|
249 |
end |
|
250 |
end; |
|
251 |
if ((GameFlags and gfKarma) <> 0) and |
|
252 |
((GameFlags and gfInvulnerable) = 0) |
|
253 |
and (not CurrentHedgehog^.Gear^.Invulnerable) then |
|
254 |
begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid |
|
255 |
inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); |
|
256 |
CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog; |
|
257 |
spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg); |
|
258 |
end; |
|
259 |
uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false); |
|
260 |
end; |
|
8199
886ed135665b
Fix crashes and wtf behaviour introduced in r0b8beacff8a5
unc0rr
parents:
8161
diff
changeset
|
261 |
end else |
8161 | 262 |
//else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure |
6581 | 263 |
Gear^.Hedgehog:= AttackerHog; |
264 |
inc(Gear^.Damage, Damage); |
|
265 |
||
266 |
ScriptCall('onGearDamage', Gear^.UID, Damage); |
|
267 |
end; |
|
268 |
||
269 |
procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword); |
|
270 |
var tag: PVisualGear; |
|
271 |
begin |
|
272 |
tag:= AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtHealthTag, dmg); |
|
273 |
if (tag <> nil) then |
|
274 |
tag^.Hedgehog:= HHGear^.Hedgehog; // the tag needs the tag to determine the text color |
|
275 |
AllInactive:= false; |
|
276 |
HHGear^.Active:= true; |
|
277 |
end; |
|
278 |
||
279 |
procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource); |
|
280 |
begin |
|
9071 | 281 |
if Hedgehog^.Effects[heFrozen] <> 0 then exit; |
6581 | 282 |
if (Source = dsFall) or (Source = dsExplosion) then |
283 |
case random(3) of |
|
7053 | 284 |
0: PlaySoundV(sndOoff1, Hedgehog^.Team^.voicepack); |
285 |
1: PlaySoundV(sndOoff2, Hedgehog^.Team^.voicepack); |
|
286 |
2: PlaySoundV(sndOoff3, Hedgehog^.Team^.voicepack); |
|
6581 | 287 |
end |
288 |
else if (Source = dsPoison) then |
|
289 |
case random(2) of |
|
7053 | 290 |
0: PlaySoundV(sndPoisonCough, Hedgehog^.Team^.voicepack); |
291 |
1: PlaySoundV(sndPoisonMoan, Hedgehog^.Team^.voicepack); |
|
6581 | 292 |
end |
293 |
else |
|
294 |
case random(4) of |
|
7053 | 295 |
0: PlaySoundV(sndOw1, Hedgehog^.Team^.voicepack); |
296 |
1: PlaySoundV(sndOw2, Hedgehog^.Team^.voicepack); |
|
297 |
2: PlaySoundV(sndOw3, Hedgehog^.Team^.voicepack); |
|
298 |
3: PlaySoundV(sndOw4, Hedgehog^.Team^.voicepack); |
|
6581 | 299 |
end |
300 |
end; |
|
301 |
||
302 |
procedure CheckHHDamage(Gear: PGear); |
|
303 |
var |
|
304 |
dmg: Longword; |
|
8003 | 305 |
i: LongWord; |
6581 | 306 |
particle: PVisualGear; |
307 |
begin |
|
9071 | 308 |
if _0_4 < Gear^.dY then |
309 |
begin |
|
310 |
dmg := ModifyDamage(1 + hwRound((Gear^.dY - _0_4) * 70), Gear); |
|
311 |
if Gear^.Hedgehog^.Effects[heFrozen] = 0 then |
|
312 |
PlaySound(sndBump) |
|
313 |
else PlaySound(sndFrozenHogImpact); |
|
314 |
if dmg < 1 then |
|
315 |
exit; |
|
6581 | 316 |
|
9071 | 317 |
for i:= min(12, (3 + dmg div 10)) downto 0 do |
318 |
begin |
|
319 |
particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
|
320 |
if particle <> nil then |
|
321 |
particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); |
|
322 |
end; |
|
6581 | 323 |
|
9071 | 324 |
if (Gear^.Invulnerable) then |
325 |
exit; |
|
6581 | 326 |
|
9071 | 327 |
//if _0_6 < Gear^.dY then |
328 |
// PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack) |
|
329 |
//else |
|
330 |
// PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack); |
|
6581 | 331 |
|
9071 | 332 |
if Gear^.LastDamage <> nil then |
333 |
ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall) |
|
334 |
else |
|
335 |
ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall); |
|
6581 | 336 |
end |
337 |
end; |
|
338 |
||
339 |
||
340 |
procedure CalcRotationDirAngle(Gear: PGear); |
|
341 |
var |
|
342 |
dAngle: real; |
|
343 |
begin |
|
7825 | 344 |
// Frac/Round to be kind to JS as of 2012-08-27 where there is yet no int64/uint64 |
345 |
//dAngle := (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000; |
|
346 |
dAngle := (Gear^.dX.Round + Gear^.dY.Round) / 2 + (Gear^.dX.Frac/$100000000+Gear^.dY.Frac/$100000000); |
|
6581 | 347 |
if not Gear^.dX.isNegative then |
348 |
Gear^.DirAngle := Gear^.DirAngle + dAngle |
|
349 |
else |
|
350 |
Gear^.DirAngle := Gear^.DirAngle - dAngle; |
|
351 |
||
352 |
if Gear^.DirAngle < 0 then |
|
353 |
Gear^.DirAngle := Gear^.DirAngle + 360 |
|
354 |
else if 360 < Gear^.DirAngle then |
|
355 |
Gear^.DirAngle := Gear^.DirAngle - 360 |
|
356 |
end; |
|
357 |
||
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
358 |
function CheckGearDrowning(var Gear: PGear): boolean; |
6581 | 359 |
var |
360 |
skipSpeed, skipAngle, skipDecay: hwFloat; |
|
361 |
i, maxDrops, X, Y: LongInt; |
|
362 |
vdX, vdY: real; |
|
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
363 |
particle, splash: PVisualGear; |
6581 | 364 |
isSubmersible: boolean; |
365 |
begin |
|
366 |
// probably needs tweaking. might need to be in a case statement based upon gear type |
|
367 |
Y:= hwRound(Gear^.Y); |
|
368 |
if cWaterLine < Y + Gear^.Radius then |
|
369 |
begin |
|
7389
15c3fb4882df
Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder.
nemo
parents:
7372
diff
changeset
|
370 |
if Gear^.State and gstInvisible <> 0 then |
15c3fb4882df
Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder.
nemo
parents:
7372
diff
changeset
|
371 |
begin |
7406
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
372 |
if Gear^.Kind = gtGenericFaller then |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
373 |
begin |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
374 |
Gear^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
375 |
Gear^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
376 |
Gear^.dX:= _90-(GetRandomf*_360); |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
377 |
Gear^.dY:= _90-(GetRandomf*_360) |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
378 |
end |
1fe2c821f9bf
Try avoiding spamming the log by retaining the gears. untested.
nemo
parents:
7389
diff
changeset
|
379 |
else DeleteGear(Gear); |
7389
15c3fb4882df
Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder.
nemo
parents:
7372
diff
changeset
|
380 |
exit |
15c3fb4882df
Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder.
nemo
parents:
7372
diff
changeset
|
381 |
end; |
8992
5b0be812dcdb
Rename submersible state, increase getaway time for attack underwater, slow down gear dx/dy underwater to simulate water resistance
nemo
parents:
8991
diff
changeset
|
382 |
isSubmersible:= ((Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0)) or (Gear^.State and gstSubmersible <> 0); |
6581 | 383 |
skipSpeed := _0_25; |
384 |
skipAngle := _1_9; |
|
385 |
skipDecay := _0_87; |
|
386 |
X:= hwRound(Gear^.X); |
|
387 |
vdX:= hwFloat2Float(Gear^.dX); |
|
388 |
vdY:= hwFloat2Float(Gear^.dY); |
|
389 |
// this could perhaps be a tiny bit higher. |
|
8990 | 390 |
if (cWaterLine + 64 + Gear^.Radius > Y) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) |
6581 | 391 |
and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then |
392 |
begin |
|
393 |
Gear^.dY.isNegative := true; |
|
394 |
Gear^.dY := Gear^.dY * skipDecay; |
|
395 |
Gear^.dX := Gear^.dX * skipDecay; |
|
396 |
CheckGearDrowning := false; |
|
397 |
PlaySound(sndSkip) |
|
398 |
end |
|
399 |
else |
|
400 |
begin |
|
401 |
if not isSubmersible then |
|
402 |
begin |
|
403 |
CheckGearDrowning := true; |
|
404 |
Gear^.State := gstDrowning; |
|
405 |
Gear^.RenderTimer := false; |
|
406 |
if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) |
|
407 |
and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then |
|
408 |
if Gear^.Kind = gtHedgehog then |
|
409 |
begin |
|
7010
10a0a31804f3
Switch effects to longint for convenience of tracking ice states. I could add a new Hedgehog value, but since we have this effects list being all useless as booleans anyway...
nemo
parents:
6990
diff
changeset
|
410 |
if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then |
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
411 |
begin |
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
412 |
// Gear could become nil after this, just exit to skip splashes |
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
413 |
ResurrectHedgehog(Gear); |
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
414 |
exit |
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
415 |
end |
6581 | 416 |
else |
417 |
begin |
|
418 |
Gear^.doStep := @doStepDrowningGear; |
|
419 |
Gear^.State := Gear^.State and (not gstHHDriven); |
|
420 |
AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage); |
|
421 |
end |
|
422 |
end |
|
423 |
else |
|
424 |
Gear^.doStep := @doStepDrowningGear; |
|
425 |
if Gear^.Kind = gtFlake then |
|
426 |
exit // skip splashes |
|
8990 | 427 |
end |
8991
82e3a6e5d51b
Actually, let's use *4 since could be fired from lower down
nemo
parents:
8990
diff
changeset
|
428 |
else if (Y > cWaterLine + cVisibleWater*4) and |
8992
5b0be812dcdb
Rename submersible state, increase getaway time for attack underwater, slow down gear dx/dy underwater to simulate water resistance
nemo
parents:
8991
diff
changeset
|
429 |
((Gear <> CurrentHedgehog^.Gear) or (CurAmmoGear = nil) or (CurAmmoGear^.State and gstSubmersible = 0)) then |
8990 | 430 |
Gear^.doStep:= @doStepDrowningGear; |
6581 | 431 |
if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) |
8989 | 432 |
or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0) |
6581 | 433 |
and (CurAmmoGear^.dY < _0_01))) then |
6804 | 434 |
if Gear^.Density * Gear^.dY > _1 then |
435 |
PlaySound(sndSplash) |
|
436 |
else if Gear^.Density * Gear^.dY > _0_5 then |
|
437 |
PlaySound(sndSkip) |
|
438 |
else |
|
439 |
PlaySound(sndDroplet2); |
|
6581 | 440 |
end; |
441 |
||
442 |
if ((cReducedQuality and rqPlainSplash) = 0) |
|
443 |
and (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) |
|
8989 | 444 |
or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0) |
6581 | 445 |
and (CurAmmoGear^.dY < _0_01)))) then |
446 |
begin |
|
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
447 |
splash:= AddVisualGear(X, cWaterLine, vgtSplash); |
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
448 |
if splash <> nil then |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
449 |
with splash^ do |
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
450 |
begin |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
451 |
Scale:= hwFloat2Float(Gear^.Density / _3 * Gear^.dY); |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
452 |
if Scale > 1 then Scale:= power(Scale,0.3333) |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
453 |
else Scale:= Scale + ((1-Scale) / 2); |
7420 | 454 |
if Scale > 1 then Timer:= round(min(Scale*0.0005/cGravityf,4)) |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
455 |
else Timer:= 1; |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
456 |
// Low Gravity |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
457 |
FrameTicks:= FrameTicks*Timer; |
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
458 |
end; |
6581 | 459 |
|
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
460 |
maxDrops := (hwRound(Gear^.Density) * 3) div 2 + round(vdX * hwRound(Gear^.Density) * 6) + round(vdY * hwRound(Gear^.Density) * 6); |
6581 | 461 |
for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do |
462 |
begin |
|
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
463 |
particle := AddVisualGear(X - 3 + Random(7), cWaterLine, vgtDroplet); |
6581 | 464 |
if particle <> nil then |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
465 |
with particle^ do |
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
466 |
begin |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
467 |
dX := dX - vdX / 10; |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
468 |
dY := dY - vdY / 5; |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
469 |
if splash <> nil then |
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
470 |
begin |
7372
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
471 |
if splash^.Scale > 1 then |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
472 |
begin |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
473 |
dX:= dX * power(splash^.Scale,0.3333); // tone down the droplet height further |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
474 |
dY:= dY * power(splash^.Scale, 0.3333) |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
475 |
end |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
476 |
else |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
477 |
begin |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
478 |
dX:= dX * splash^.Scale; |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
479 |
dY:= dY * splash^.Scale |
fcc002658832
Spread the droplets around more so it looks less square (looked especially bad with piano). Slow down large splashes a bit for dramatic purposes, also taking low-g into account. Small splashes you can't really tell anyway.
nemo
parents:
7357
diff
changeset
|
480 |
end |
6803
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
481 |
end |
0e70f3ea3bf8
bit of an experiment in variable splash sizes based on object/speed. not sure if it looks good yet. need to drown more stuff.
nemo
parents:
6769
diff
changeset
|
482 |
end |
6581 | 483 |
end |
484 |
end; |
|
8989 | 485 |
if isSubmersible and (Gear = CurAmmoGear) and (CurAmmoGear^.Pos = 0) then |
6581 | 486 |
CurAmmoGear^.Pos := 1000 |
487 |
end |
|
488 |
else |
|
489 |
CheckGearDrowning := false; |
|
490 |
end; |
|
491 |
||
492 |
||
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
493 |
procedure ResurrectHedgehog(var gear: PGear); |
6581 | 494 |
var tempTeam : PTeam; |
7092
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
495 |
sparkles: PVisualGear; |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
496 |
gX, gY: LongInt; |
6581 | 497 |
begin |
7357
06454899d0d2
Score AI resurrection as a kill. These values will not be the same as the in-game scoring, since in-game scoring doesn't count friendlies.
nemo
parents:
7272
diff
changeset
|
498 |
if (Gear^.LastDamage <> nil) then |
06454899d0d2
Score AI resurrection as a kill. These values will not be the same as the in-game scoring, since in-game scoring doesn't count friendlies.
nemo
parents:
7272
diff
changeset
|
499 |
uStats.HedgehogDamaged(Gear, Gear^.LastDamage, 0, true) |
06454899d0d2
Score AI resurrection as a kill. These values will not be the same as the in-game scoring, since in-game scoring doesn't count friendlies.
nemo
parents:
7272
diff
changeset
|
500 |
else |
06454899d0d2
Score AI resurrection as a kill. These values will not be the same as the in-game scoring, since in-game scoring doesn't count friendlies.
nemo
parents:
7272
diff
changeset
|
501 |
uStats.HedgehogDamaged(Gear, CurrentHedgehog, 0, true); |
6581 | 502 |
AttackBar:= 0; |
503 |
gear^.dX := _0; |
|
504 |
gear^.dY := _0; |
|
505 |
gear^.Damage := 0; |
|
506 |
gear^.Health := gear^.Hedgehog^.InitialHealth; |
|
7010
10a0a31804f3
Switch effects to longint for convenience of tracking ice states. I could add a new Hedgehog value, but since we have this effects list being all useless as booleans anyway...
nemo
parents:
6990
diff
changeset
|
507 |
gear^.Hedgehog^.Effects[hePoisoned] := 0; |
7176
fb4b0c6dfdbd
Make watching AI v AI on ai survival a bit more entertaining
nemo
parents:
7168
diff
changeset
|
508 |
if (CurrentHedgehog^.Effects[heResurrectable] = 0) or ((CurrentHedgehog^.Effects[heResurrectable] <> 0) |
fb4b0c6dfdbd
Make watching AI v AI on ai survival a bit more entertaining
nemo
parents:
7168
diff
changeset
|
509 |
and (Gear^.Hedgehog^.Team^.Clan <> CurrentHedgehog^.Team^.Clan)) then |
6581 | 510 |
with CurrentHedgehog^ do |
511 |
begin |
|
512 |
inc(Team^.stats.AIKills); |
|
513 |
FreeTexture(Team^.AIKillsTex); |
|
514 |
Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16); |
|
515 |
end; |
|
516 |
tempTeam := gear^.Hedgehog^.Team; |
|
517 |
DeleteCI(gear); |
|
7092
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
518 |
gX := hwRound(gear^.X); |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
519 |
gY := hwRound(gear^.Y); |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
520 |
// might need more sparkles for a column |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
521 |
sparkles:= AddVisualGear(gX, gY, vgtDust, 1); |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
522 |
if sparkles <> nil then |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
523 |
begin |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
524 |
sparkles^.Tint:= tempTeam^.Clan^.Color shl 8 or $FF; |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
525 |
//sparkles^.Angle:= random(360); |
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
526 |
end; |
6581 | 527 |
FindPlace(gear, false, 0, LAND_WIDTH, true); |
528 |
if gear <> nil then |
|
529 |
begin |
|
7092
c9ca770fd7fc
Add an emergency return to the timebox in the case of death of rest of team. Also add a small visual effect to AI survival
nemo
parents:
7066
diff
changeset
|
530 |
AddVisualGear(hwRound(gear^.X), hwRound(gear^.Y), vgtExplosion); |
7168
8defaabce92e
warp sound when AI survival hog respawns. attempt at a bit of a crate spawn animation (moar sparkles and a quick fadein)
nemo
parents:
7092
diff
changeset
|
531 |
PlaySound(sndWarp); |
6581 | 532 |
RenderHealth(gear^.Hedgehog^); |
533 |
ScriptCall('onGearResurrect', gear^.uid); |
|
534 |
gear^.State := gstWait; |
|
8947
e906ebd59612
CheckGearDrowning could delete hedgehogs gear! (CheckGearDrowning -> ResurrectHedgehog -> FindPlace). Fixes bug 620.
unc0rr
parents:
8763
diff
changeset
|
535 |
end; |
6581 | 536 |
RecountTeamHealth(tempTeam); |
537 |
end; |
|
538 |
||
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
539 |
function CountNonZeroz(x, y, r, c: LongInt; mask: LongWord): LongInt; |
6581 | 540 |
var i: LongInt; |
541 |
count: LongInt = 0; |
|
542 |
begin |
|
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
543 |
if (y and LAND_HEIGHT_MASK) = 0 then |
7509 | 544 |
for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do |
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
545 |
if Land[y, i] and mask <> 0 then |
6581 | 546 |
begin |
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
547 |
inc(count); |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
548 |
if count = c then |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
549 |
begin |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
550 |
CountNonZeroz:= count; |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
551 |
exit |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
552 |
end; |
6581 | 553 |
end; |
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
554 |
CountNonZeroz:= count; |
6581 | 555 |
end; |
556 |
||
6888 | 557 |
|
558 |
function NoGearsToAvoid(mX, mY: LongInt; rX, rY: LongInt): boolean; |
|
559 |
var t: PGear; |
|
560 |
begin |
|
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
561 |
NoGearsToAvoid:= false; |
6888 | 562 |
t:= GearsList; |
563 |
rX:= sqr(rX); |
|
564 |
rY:= sqr(rY); |
|
565 |
while t <> nil do |
|
566 |
begin |
|
567 |
if t^.Kind <= gtExplosives then |
|
568 |
if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then |
|
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
569 |
exit; |
6888 | 570 |
t:= t^.NextGear |
571 |
end; |
|
572 |
NoGearsToAvoid:= true |
|
573 |
end; |
|
574 |
||
6986
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
575 |
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline; |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
576 |
begin |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
577 |
FindPlace(Gear, withFall, Left, Right, false); |
409dd3851309
add support for default pascal mode by removing default arguments value (maybe this also helps the parser)
koda
parents:
6888
diff
changeset
|
578 |
end; |
6888 | 579 |
|
6581 | 580 |
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); |
581 |
var x: LongInt; |
|
582 |
y, sy: LongInt; |
|
8007 | 583 |
ar: array[0..1023] of TPoint; |
584 |
ar2: array[0..2047] of TPoint; |
|
6581 | 585 |
cnt, cnt2: Longword; |
586 |
delta: LongInt; |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
587 |
ignoreNearObjects, ignoreOverlap, tryAgain: boolean; |
6581 | 588 |
begin |
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
589 |
ignoreNearObjects:= false; // try not skipping proximity at first |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
590 |
ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates). Saving it for a 3rd pass. With this active, winning AI Survival goes back to virtual impossibility |
6581 | 591 |
tryAgain:= true; |
592 |
while tryAgain do |
|
593 |
begin |
|
8007 | 594 |
delta:= LAND_WIDTH div 16; |
6581 | 595 |
cnt2:= 0; |
596 |
repeat |
|
8007 | 597 |
x:= Left + max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta))); |
6581 | 598 |
repeat |
599 |
inc(x, Delta); |
|
600 |
cnt:= 0; |
|
7603
e9c3c67b5dfd
reducing this value is sufficient to ensure crates drop just below top border or a girder
nemo
parents:
7599
diff
changeset
|
601 |
y:= min(1024, topY) - 2 * Gear^.Radius; |
6581 | 602 |
while y < cWaterLine do |
603 |
begin |
|
604 |
repeat |
|
605 |
inc(y, 2); |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
606 |
until (y >= cWaterLine) or |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
607 |
(not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or |
8751
4609823efc94
More flagging of Land values. Also use less than for tests of non-terrain, instead of "and $FF00 = 0". Saves a couple of ops, which actually matters a small amount in a few places.
nemo
parents:
8632
diff
changeset
|
608 |
(ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) = 0)); |
6581 | 609 |
|
610 |
sy:= y; |
|
611 |
||
612 |
repeat |
|
613 |
inc(y); |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
614 |
until (y >= cWaterLine) or |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
615 |
(not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or |
8751
4609823efc94
More flagging of Land values. Also use less than for tests of non-terrain, instead of "and $FF00 = 0". Saves a couple of ops, which actually matters a small amount in a few places.
nemo
parents:
8632
diff
changeset
|
616 |
(ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) <> 0)); |
6581 | 617 |
|
618 |
if (y - sy > Gear^.Radius * 2) |
|
619 |
and (((Gear^.Kind = gtExplosives) |
|
620 |
and (y < cWaterLine) |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
621 |
and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60)) |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
622 |
and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1, $FFFF) > Gear^.Radius)) |
6581 | 623 |
or |
624 |
((Gear^.Kind <> gtExplosives) |
|
625 |
and (y < cWaterLine) |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
626 |
and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110)) |
6888 | 627 |
)) then |
628 |
begin |
|
6581 | 629 |
ar[cnt].X:= x; |
630 |
if withFall then |
|
631 |
ar[cnt].Y:= sy + Gear^.Radius |
|
632 |
else |
|
633 |
ar[cnt].Y:= y - Gear^.Radius; |
|
634 |
inc(cnt) |
|
635 |
end; |
|
636 |
||
7603
e9c3c67b5dfd
reducing this value is sufficient to ensure crates drop just below top border or a girder
nemo
parents:
7599
diff
changeset
|
637 |
inc(y, 10) |
6581 | 638 |
end; |
639 |
||
640 |
if cnt > 0 then |
|
641 |
with ar[GetRandom(cnt)] do |
|
642 |
begin |
|
643 |
ar2[cnt2].x:= x; |
|
644 |
ar2[cnt2].y:= y; |
|
645 |
inc(cnt2) |
|
646 |
end |
|
647 |
until (x + Delta > Right); |
|
648 |
||
649 |
dec(Delta, 60) |
|
650 |
until (cnt2 > 0) or (Delta < 70); |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
651 |
// if either of these has not been tried, do another pass |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
652 |
if (cnt2 = 0) and skipProximity and (not ignoreOverlap) then |
6581 | 653 |
tryAgain:= true |
654 |
else tryAgain:= false; |
|
7190
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
655 |
if ignoreNearObjects then ignoreOverlap:= true; |
aa8d68817c32
Make it AI survival almost definitely impossible by adding a 3rd pass to FindGear. 1st pass normal, 2nd pass allow close to objects, 3rd pass, allow overlapping objects.
nemo
parents:
7176
diff
changeset
|
656 |
ignoreNearObjects:= true; |
6581 | 657 |
end; |
658 |
||
659 |
if cnt2 > 0 then |
|
660 |
with ar2[GetRandom(cnt2)] do |
|
661 |
begin |
|
662 |
Gear^.X:= int2hwFloat(x); |
|
663 |
Gear^.Y:= int2hwFloat(y); |
|
664 |
AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')'); |
|
665 |
end |
|
666 |
else |
|
667 |
begin |
|
668 |
OutError('Can''t find place for Gear', false); |
|
669 |
if Gear^.Kind = gtHedgehog then |
|
7010
10a0a31804f3
Switch effects to longint for convenience of tracking ice states. I could add a new Hedgehog value, but since we have this effects list being all useless as booleans anyway...
nemo
parents:
6990
diff
changeset
|
670 |
Gear^.Hedgehog^.Effects[heResurrectable] := 0; |
6581 | 671 |
DeleteGear(Gear); |
672 |
Gear:= nil |
|
673 |
end |
|
674 |
end; |
|
675 |
||
676 |
function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; |
|
677 |
var t: PGear; |
|
678 |
begin |
|
679 |
t:= GearsList; |
|
680 |
rX:= sqr(rX); |
|
681 |
rY:= sqr(rY); |
|
682 |
||
683 |
while t <> nil do |
|
684 |
begin |
|
685 |
if (t <> Gear) and (t^.Kind = Kind) then |
|
686 |
if not((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1) then |
|
6990
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
687 |
begin |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
688 |
CheckGearNear:= t; |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
689 |
exit; |
40e5af28d026
change every return value into a more pascal-ish form, using the name of the fucntion (helps the parser and macpas compaitilibity)
koda
parents:
6986
diff
changeset
|
690 |
end; |
6581 | 691 |
t:= t^.NextGear |
692 |
end; |
|
693 |
||
694 |
CheckGearNear:= nil |
|
695 |
end; |
|
696 |
||
7592 | 697 |
procedure CheckCollision(Gear: PGear); inline; |
698 |
begin |
|
699 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
|
700 |
or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then |
|
701 |
Gear^.State := Gear^.State or gstCollision |
|
702 |
else |
|
703 |
Gear^.State := Gear^.State and (not gstCollision) |
|
704 |
end; |
|
705 |
||
706 |
procedure CheckCollisionWithLand(Gear: PGear); inline; |
|
707 |
begin |
|
708 |
if TestCollisionX(Gear, hwSign(Gear^.dX)) |
|
709 |
or TestCollisionY(Gear, hwSign(Gear^.dY)) then |
|
710 |
Gear^.State := Gear^.State or gstCollision |
|
711 |
else |
|
712 |
Gear^.State := Gear^.State and (not gstCollision) |
|
713 |
end; |
|
714 |
||
7719
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
715 |
function MakeHedgehogsStep(Gear: PGear) : boolean; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
716 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
717 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
718 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
719 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
720 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
721 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
722 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
723 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
724 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
725 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
726 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
727 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
728 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
729 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
730 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
731 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
732 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
733 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
734 |
Gear^.Y:= Gear^.Y - _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
735 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
736 |
Gear^.Y:= Gear^.Y + _6 |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
737 |
end else Gear^.Y:= Gear^.Y + _5 else |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
738 |
end else Gear^.Y:= Gear^.Y + _4 else |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
739 |
end else Gear^.Y:= Gear^.Y + _3 else |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
740 |
end else Gear^.Y:= Gear^.Y + _2 else |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
741 |
end else Gear^.Y:= Gear^.Y + _1 |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
742 |
end; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
743 |
|
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
744 |
if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
745 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
746 |
Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX); |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
747 |
MakeHedgehogsStep:= true |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
748 |
end else |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
749 |
MakeHedgehogsStep:= false; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
750 |
|
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
751 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
752 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
753 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
754 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
755 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
756 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
757 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
758 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
759 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
760 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
761 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
762 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
763 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
764 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
765 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
766 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
767 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
768 |
Gear^.Y:= Gear^.Y + _1; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
769 |
if TestCollisionYwithGear(Gear, 1) = 0 then |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
770 |
begin |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
771 |
Gear^.Y:= Gear^.Y - _6; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
772 |
Gear^.dY:= _0; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
773 |
Gear^.State:= Gear^.State or gstMoving; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
774 |
exit |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
775 |
end; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
776 |
end |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
777 |
end |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
778 |
end |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
779 |
end |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
780 |
end |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
781 |
end; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
782 |
end; |
eeae1cb6b6bf
Move hedgehog's step routine into separate function, use it in both hedgehog and ai code
unc0rr
parents:
7627
diff
changeset
|
783 |
|
9285 | 784 |
|
785 |
procedure ShotgunShot(Gear: PGear); |
|
786 |
var t: PGear; |
|
787 |
dmg, r, dist: LongInt; |
|
788 |
dx, dy: hwFloat; |
|
789 |
begin |
|
790 |
Gear^.Radius:= cShotgunRadius; |
|
791 |
t:= GearsList; |
|
792 |
while t <> nil do |
|
793 |
begin |
|
794 |
case t^.Kind of |
|
795 |
gtHedgehog, |
|
796 |
gtMine, |
|
797 |
gtSMine, |
|
798 |
gtKnife, |
|
799 |
gtCase, |
|
800 |
gtTarget, |
|
801 |
gtExplosives: begin//, |
|
802 |
// gtStructure: begin |
|
803 |
//addFileLog('ShotgunShot radius: ' + inttostr(Gear^.Radius) + ', t^.Radius = ' + inttostr(t^.Radius) + ', distance = ' + inttostr(dist) + ', dmg = ' + inttostr(dmg)); |
|
804 |
dmg:= 0; |
|
805 |
r:= Gear^.Radius + t^.Radius; |
|
806 |
dx:= Gear^.X-t^.X; |
|
807 |
dx.isNegative:= false; |
|
808 |
dy:= Gear^.Y-t^.Y; |
|
809 |
dy.isNegative:= false; |
|
810 |
if r-hwRound(dx+dy) > 0 then |
|
811 |
begin |
|
812 |
dist:= hwRound(Distance(dx, dy)); |
|
813 |
dmg:= ModifyDamage(min(r - dist, 25), t); |
|
814 |
end; |
|
815 |
if dmg > 0 then |
|
816 |
begin |
|
817 |
if (not t^.Invulnerable) then |
|
818 |
ApplyDamage(t, Gear^.Hedgehog, dmg, dsBullet) |
|
819 |
else |
|
820 |
Gear^.State:= Gear^.State or gstWinner; |
|
821 |
||
822 |
DeleteCI(t); |
|
823 |
t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX); |
|
824 |
t^.dY:= t^.dY + Gear^.dY * dmg * _0_01; |
|
825 |
t^.State:= t^.State or gstMoving; |
|
826 |
if t^.Kind = gtKnife then t^.State:= t^.State and (not gstCollision); |
|
827 |
t^.Active:= true; |
|
828 |
FollowGear:= t |
|
829 |
end |
|
830 |
end; |
|
831 |
gtGrave: begin |
|
832 |
dmg:= 0; |
|
833 |
r:= Gear^.Radius + t^.Radius; |
|
834 |
dx:= Gear^.X-t^.X; |
|
835 |
dx.isNegative:= false; |
|
836 |
dy:= Gear^.Y-t^.Y; |
|
837 |
dy.isNegative:= false; |
|
838 |
if r-hwRound(dx+dy) > 0 then |
|
839 |
begin |
|
840 |
dist:= hwRound(Distance(dx, dy)); |
|
841 |
dmg:= ModifyDamage(min(r - dist, 25), t); |
|
842 |
end; |
|
843 |
if dmg > 0 then |
|
844 |
begin |
|
845 |
t^.dY:= - _0_1; |
|
846 |
t^.Active:= true |
|
847 |
end |
|
848 |
end; |
|
849 |
end; |
|
850 |
t:= t^.NextGear |
|
851 |
end; |
|
852 |
if (GameFlags and gfSolidLand) = 0 then |
|
853 |
DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius) |
|
854 |
end; |
|
855 |
||
856 |
procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); |
|
857 |
var t: PGearArray; |
|
858 |
Gear: PGear; |
|
859 |
i, j, tmpDmg: LongInt; |
|
860 |
VGear: PVisualGear; |
|
861 |
begin |
|
862 |
t:= CheckGearsCollision(Ammo); |
|
863 |
// Just to avoid hogs on rope dodging fire. |
|
864 |
if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy)) |
|
865 |
and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1) |
|
866 |
and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then |
|
867 |
begin |
|
868 |
t^.ar[t^.Count]:= CurrentHedgehog^.Gear; |
|
869 |
inc(t^.Count) |
|
870 |
end; |
|
871 |
||
872 |
i:= t^.Count; |
|
873 |
||
874 |
if (Ammo^.Kind = gtFlame) and (i > 0) then |
|
875 |
Ammo^.Health:= 0; |
|
876 |
while i > 0 do |
|
877 |
begin |
|
878 |
dec(i); |
|
879 |
Gear:= t^.ar[i]; |
|
880 |
if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and |
|
881 |
(Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then |
|
882 |
Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000); |
|
883 |
tmpDmg:= ModifyDamage(Damage, Gear); |
|
884 |
if (Gear^.State and gstNoDamage) = 0 then |
|
885 |
begin |
|
886 |
||
887 |
if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then |
|
888 |
begin |
|
889 |
VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); |
|
890 |
if VGear <> nil then |
|
891 |
VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); |
|
892 |
end; |
|
893 |
||
894 |
if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then |
|
895 |
Gear^.FlightTime:= 1; |
|
896 |
||
897 |
||
898 |
case Gear^.Kind of |
|
899 |
gtHedgehog, |
|
900 |
gtMine, |
|
901 |
gtSMine, |
|
902 |
gtKnife, |
|
903 |
gtTarget, |
|
904 |
gtCase, |
|
905 |
gtExplosives: //, |
|
906 |
//gtStructure: |
|
907 |
begin |
|
908 |
if (Ammo^.Kind = gtDrill) then |
|
909 |
begin |
|
910 |
Ammo^.Timer:= 0; |
|
911 |
exit; |
|
912 |
end; |
|
913 |
if (not Gear^.Invulnerable) then |
|
914 |
begin |
|
915 |
if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then |
|
916 |
for j:= 1 to max(1,min(3,tmpDmg div 5)) do |
|
917 |
begin |
|
918 |
VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot); |
|
919 |
if VGear <> nil then |
|
920 |
with VGear^ do |
|
921 |
begin |
|
922 |
Tint:= $FFCC00FF; |
|
923 |
Angle:= random(360); |
|
924 |
dx:= 0.0005 * (random(100)); |
|
925 |
dy:= 0.0005 * (random(100)); |
|
926 |
if random(2) = 0 then |
|
927 |
dx := -dx; |
|
928 |
if random(2) = 0 then |
|
929 |
dy := -dy; |
|
930 |
FrameTicks:= 600+random(200); |
|
931 |
State:= ord(sprStar) |
|
932 |
end |
|
933 |
end; |
|
934 |
ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove) |
|
935 |
end |
|
936 |
else |
|
937 |
Gear^.State:= Gear^.State or gstWinner; |
|
938 |
if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then |
|
939 |
begin |
|
940 |
if (Ammo^.Hedgehog^.Gear <> nil) then |
|
941 |
Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable); |
|
942 |
ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch |
|
943 |
end; |
|
944 |
||
945 |
if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then |
|
946 |
begin |
|
947 |
Gear^.dX:= Ammo^.dX * Power * _0_005; |
|
948 |
Gear^.dY:= Ammo^.dY * Power * _0_005 |
|
949 |
end |
|
950 |
else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then |
|
951 |
begin |
|
952 |
Gear^.dX:= Ammo^.dX * Power * _0_01; |
|
953 |
Gear^.dY:= Ammo^.dY * Power * _0_01 |
|
954 |
end; |
|
955 |
||
956 |
if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then |
|
957 |
begin |
|
958 |
Gear^.Active:= true; |
|
959 |
DeleteCI(Gear); |
|
960 |
Gear^.State:= Gear^.State or gstMoving; |
|
961 |
if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
|
962 |
// move the gear upwards a bit to throw it over tiny obstacles at start |
|
963 |
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
|
964 |
begin |
|
965 |
if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) |
|
966 |
or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
|
967 |
Gear^.Y:= Gear^.Y - _1; |
|
968 |
if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) |
|
969 |
or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
|
970 |
Gear^.Y:= Gear^.Y - _1; |
|
971 |
if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) |
|
972 |
or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
|
973 |
Gear^.Y:= Gear^.Y - _1; |
|
974 |
end |
|
975 |
end; |
|
976 |
||
977 |
||
978 |
if (Ammo^.Kind <> gtFlame) or ((Ammo^.State and gsttmpFlag) = 0) then |
|
979 |
FollowGear:= Gear |
|
980 |
end; |
|
981 |
end |
|
982 |
end; |
|
983 |
end; |
|
984 |
if i <> 0 then |
|
985 |
SetAllToActive |
|
986 |
end; |
|
987 |
||
988 |
||
989 |
function CountGears(Kind: TGearType): Longword; |
|
990 |
var t: PGear; |
|
991 |
count: Longword = 0; |
|
992 |
begin |
|
993 |
||
994 |
t:= GearsList; |
|
995 |
while t <> nil do |
|
996 |
begin |
|
997 |
if t^.Kind = Kind then |
|
998 |
inc(count); |
|
999 |
t:= t^.NextGear |
|
1000 |
end; |
|
1001 |
CountGears:= count; |
|
1002 |
end; |
|
1003 |
||
1004 |
procedure SetAllToActive; |
|
1005 |
var t: PGear; |
|
1006 |
begin |
|
1007 |
AllInactive:= false; |
|
1008 |
t:= GearsList; |
|
1009 |
while t <> nil do |
|
1010 |
begin |
|
1011 |
t^.Active:= true; |
|
1012 |
t:= t^.NextGear |
|
1013 |
end |
|
1014 |
end; |
|
1015 |
||
1016 |
procedure SetAllHHToActive; inline; |
|
1017 |
begin |
|
1018 |
SetAllHHToActive(true) |
|
1019 |
end; |
|
1020 |
||
1021 |
||
1022 |
procedure SetAllHHToActive(Ice: boolean); |
|
1023 |
var t: PGear; |
|
1024 |
begin |
|
1025 |
AllInactive:= false; |
|
1026 |
t:= GearsList; |
|
1027 |
while t <> nil do |
|
1028 |
begin |
|
1029 |
if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then |
|
1030 |
begin |
|
1031 |
if (t^.Kind = gtHedgehog) and Ice then CheckIce(t); |
|
1032 |
t^.Active:= true |
|
1033 |
end; |
|
1034 |
t:= t^.NextGear |
|
1035 |
end |
|
1036 |
end; |
|
1037 |
||
1038 |
||
1039 |
var GearsNearArray : TPGearArray; |
|
1040 |
function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS; |
|
1041 |
var |
|
1042 |
t: PGear; |
|
1043 |
s: Longword; |
|
1044 |
begin |
|
1045 |
r:= r*r; |
|
1046 |
s:= 0; |
|
1047 |
SetLength(GearsNearArray, s); |
|
1048 |
t := GearsList; |
|
1049 |
while t <> nil do |
|
1050 |
begin |
|
1051 |
if (t^.Kind = Kind) |
|
1052 |
and ((X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < int2hwFloat(r)) then |
|
1053 |
begin |
|
1054 |
inc(s); |
|
1055 |
SetLength(GearsNearArray, s); |
|
1056 |
GearsNearArray[s - 1] := t; |
|
1057 |
end; |
|
1058 |
t := t^.NextGear; |
|
1059 |
end; |
|
1060 |
||
1061 |
GearsNear.size:= s; |
|
1062 |
GearsNear.ar:= @GearsNearArray |
|
1063 |
end; |
|
1064 |
||
1065 |
||
1066 |
procedure SpawnBoxOfSmth; |
|
1067 |
var t, aTot, uTot, a, h: LongInt; |
|
1068 |
i: TAmmoType; |
|
1069 |
begin |
|
1070 |
if (PlacingHogs) or |
|
1071 |
(cCaseFactor = 0) |
|
1072 |
or (CountGears(gtCase) >= 5) |
|
1073 |
or (GetRandom(cCaseFactor) <> 0) then |
|
1074 |
exit; |
|
1075 |
||
1076 |
FollowGear:= nil; |
|
1077 |
aTot:= 0; |
|
1078 |
uTot:= 0; |
|
1079 |
for i:= Low(TAmmoType) to High(TAmmoType) do |
|
1080 |
if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then |
|
1081 |
inc(aTot, Ammoz[i].Probability) |
|
1082 |
else |
|
1083 |
inc(uTot, Ammoz[i].Probability); |
|
1084 |
||
1085 |
t:=0; |
|
1086 |
a:=aTot; |
|
1087 |
h:= 1; |
|
1088 |
||
1089 |
if (aTot+uTot) <> 0 then |
|
1090 |
if ((GameFlags and gfInvulnerable) = 0) then |
|
1091 |
begin |
|
1092 |
h:= cHealthCaseProb * 100; |
|
1093 |
t:= GetRandom(10000); |
|
1094 |
a:= (10000-h)*aTot div (aTot+uTot) |
|
1095 |
end |
|
1096 |
else |
|
1097 |
begin |
|
1098 |
t:= GetRandom(aTot+uTot); |
|
1099 |
h:= 0 |
|
1100 |
end; |
|
1101 |
||
1102 |
||
1103 |
if t<h then |
|
1104 |
begin |
|
1105 |
FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); |
|
1106 |
FollowGear^.Health:= cHealthCaseAmount; |
|
1107 |
FollowGear^.Pos:= posCaseHealth; |
|
1108 |
AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
|
1109 |
end |
|
1110 |
else if (t<a+h) then |
|
1111 |
begin |
|
1112 |
t:= aTot; |
|
1113 |
if (t > 0) then |
|
1114 |
begin |
|
1115 |
FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); |
|
1116 |
t:= GetRandom(t); |
|
1117 |
i:= Low(TAmmoType); |
|
1118 |
FollowGear^.Pos:= posCaseAmmo; |
|
1119 |
FollowGear^.AmmoType:= i; |
|
1120 |
AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo); |
|
1121 |
end |
|
1122 |
end |
|
1123 |
else |
|
1124 |
begin |
|
1125 |
t:= uTot; |
|
1126 |
if (t > 0) then |
|
1127 |
begin |
|
1128 |
FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); |
|
1129 |
t:= GetRandom(t); |
|
1130 |
i:= Low(TAmmoType); |
|
1131 |
FollowGear^.Pos:= posCaseUtility; |
|
1132 |
FollowGear^.AmmoType:= i; |
|
1133 |
AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo); |
|
1134 |
end |
|
1135 |
end; |
|
1136 |
||
1137 |
// handles case of no ammo or utility crates - considered also placing booleans in uAmmos and altering probabilities |
|
1138 |
if (FollowGear <> nil) then |
|
1139 |
begin |
|
1140 |
FindPlace(FollowGear, true, 0, LAND_WIDTH); |
|
1141 |
||
1142 |
if (FollowGear <> nil) then |
|
1143 |
AddVoice(sndReinforce, CurrentTeam^.voicepack) |
|
1144 |
end |
|
1145 |
end; |
|
1146 |
||
1147 |
||
1148 |
function GetAmmo(Hedgehog: PHedgehog): TAmmoType; |
|
1149 |
var t, aTot: LongInt; |
|
1150 |
i: TAmmoType; |
|
1151 |
begin |
|
1152 |
Hedgehog:= Hedgehog; // avoid hint |
|
1153 |
||
1154 |
aTot:= 0; |
|
1155 |
for i:= Low(TAmmoType) to High(TAmmoType) do |
|
1156 |
if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then |
|
1157 |
inc(aTot, Ammoz[i].Probability); |
|
1158 |
||
1159 |
t:= aTot; |
|
1160 |
i:= Low(TAmmoType); |
|
1161 |
if (t > 0) then |
|
1162 |
begin |
|
1163 |
t:= GetRandom(t); |
|
1164 |
while t >= 0 do |
|
1165 |
begin |
|
1166 |
inc(i); |
|
1167 |
if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then |
|
1168 |
dec(t, Ammoz[i].Probability) |
|
1169 |
end |
|
1170 |
end; |
|
1171 |
GetAmmo:= i |
|
1172 |
end; |
|
1173 |
||
1174 |
function GetUtility(Hedgehog: PHedgehog): TAmmoType; |
|
1175 |
var t, uTot: LongInt; |
|
1176 |
i: TAmmoType; |
|
1177 |
begin |
|
1178 |
||
1179 |
uTot:= 0; |
|
1180 |
for i:= Low(TAmmoType) to High(TAmmoType) do |
|
1181 |
if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0) |
|
1182 |
and ((Hedgehog^.Team^.HedgehogsNumber > 1) or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then |
|
1183 |
inc(uTot, Ammoz[i].Probability); |
|
1184 |
||
1185 |
t:= uTot; |
|
1186 |
i:= Low(TAmmoType); |
|
1187 |
if (t > 0) then |
|
1188 |
begin |
|
1189 |
t:= GetRandom(t); |
|
1190 |
while t >= 0 do |
|
1191 |
begin |
|
1192 |
inc(i); |
|
1193 |
if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0) and ((Hedgehog^.Team^.HedgehogsNumber > 1) |
|
1194 |
or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then |
|
1195 |
dec(t, Ammoz[i].Probability) |
|
1196 |
end |
|
1197 |
end; |
|
1198 |
GetUtility:= i |
|
1199 |
end; |
|
1200 |
||
1201 |
||
6581 | 1202 |
end. |