6581
+ − 1
(*
+ − 2
* Hedgewars, a free turn based strategy game
6700
+ − 3
* Copyright (c) 2004-2012 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 uGearsHedgehog;
+ − 22
interface
+ − 23
uses uTypes;
+ − 24
+ − 25
procedure doStepHedgehog(Gear: PGear);
+ − 26
procedure AfterAttack;
+ − 27
procedure HedgehogStep(Gear: PGear);
+ − 28
procedure doStepHedgehogMoving(Gear: PGear);
+ − 29
procedure HedgehogChAngle(HHGear: PGear);
+ − 30
procedure PickUp(HH, Gear: PGear);
+ − 31
+ − 32
implementation
+ − 33
uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, uMisc,
+ − 34
uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
+ − 35
uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
+ − 36
uGearsUtils;
+ − 37
+ − 38
// Shouldn't more of this ammo switching stuff be moved to uAmmos ?
+ − 39
function ChangeAmmo(HHGear: PGear): boolean;
+ − 40
var slot, i: Longword;
+ − 41
ammoidx: LongInt;
+ − 42
begin
+ − 43
ChangeAmmo:= false;
+ − 44
slot:= HHGear^.MsgParam;
+ − 45
+ − 46
with HHGear^.Hedgehog^ do
+ − 47
begin
+ − 48
HHGear^.Message:= HHGear^.Message and (not gmSlot);
+ − 49
ammoidx:= 0;
+ − 50
if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
+ − 51
or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
+ − 52
or ((HHGear^.State and gstHHDriven) = 0) then
+ − 53
exit;
+ − 54
ChangeAmmo:= true;
+ − 55
+ − 56
while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
+ − 57
inc(ammoidx);
+ − 58
+ − 59
if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
+ − 60
OnUsedAmmo(HHGear^.Hedgehog^);
+ − 61
+ − 62
MultiShootAttacks:= 0;
+ − 63
HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
+ − 64
+ − 65
if Ammoz[CurAmmoType].Slot = slot then
+ − 66
begin
+ − 67
i:= 0;
+ − 68
repeat
+ − 69
inc(ammoidx);
+ − 70
if (ammoidx > cMaxSlotAmmoIndex) then
+ − 71
begin
+ − 72
inc(i);
+ − 73
CurAmmoType:= amNothing;
+ − 74
ammoidx:= -1;
+ − 75
//TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
+ − 76
end;
+ − 77
until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
+ − 78
and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
+ − 79
+ − 80
end
+ − 81
else
+ − 82
begin
+ − 83
i:= 0;
+ − 84
// check whether there is ammo in slot
+ − 85
while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
+ − 86
or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns))
+ − 87
do inc(i);
+ − 88
+ − 89
if i <= cMaxSlotAmmoIndex then
+ − 90
ammoidx:= i
+ − 91
else ammoidx:= -1
+ − 92
end;
+ − 93
if ammoidx >= 0 then
+ − 94
CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
+ − 95
end
+ − 96
end;
+ − 97
+ − 98
procedure HHSetWeapon(HHGear: PGear);
+ − 99
var t: LongInt;
+ − 100
weap: TAmmoType;
+ − 101
Hedgehog: PHedgehog;
+ − 102
s: boolean;
+ − 103
begin
+ − 104
s:= false;
+ − 105
+ − 106
weap:= TAmmoType(HHGear^.MsgParam);
+ − 107
Hedgehog:= HHGear^.Hedgehog;
+ − 108
+ − 109
if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then
+ − 110
exit; // weapon is not activated yet
+ − 111
+ − 112
HHGear^.MsgParam:= Ammoz[weap].Slot;
+ − 113
+ − 114
t:= cMaxSlotAmmoIndex;
+ − 115
+ − 116
HHGear^.Message:= HHGear^.Message and (not gmWeapon);
+ − 117
+ − 118
with Hedgehog^ do
+ − 119
while (CurAmmoType <> weap) and (t >= 0) do
+ − 120
begin
+ − 121
s:= ChangeAmmo(HHGear);
+ − 122
dec(t)
+ − 123
end;
+ − 124
+ − 125
if s then
+ − 126
ApplyAmmoChanges(HHGear^.Hedgehog^)
+ − 127
end;
+ − 128
+ − 129
procedure HHSetTimer(Gear: PGear);
+ − 130
var CurWeapon: PAmmo;
+ − 131
color: LongWord;
+ − 132
begin
+ − 133
Gear^.Message:= Gear^.Message and (not gmTimer);
6924
+ − 134
CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^);
6581
+ − 135
with Gear^.Hedgehog^ do
+ − 136
if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then
+ − 137
begin
+ − 138
color:= Gear^.Hedgehog^.Team^.Clan^.Color;
+ − 139
case Gear^.MsgParam of
+ − 140
1: begin
+ − 141
AddCaption(format(trmsg[sidBounce], trmsg[sidBounce1]), color, capgrpAmmostate);
+ − 142
CurWeapon^.Bounciness:= 350;
+ − 143
end;
+ − 144
2: begin
+ − 145
AddCaption(format(trmsg[sidBounce], trmsg[sidBounce2]), color, capgrpAmmostate);
+ − 146
CurWeapon^.Bounciness:= 700;
+ − 147
end;
+ − 148
3: begin
+ − 149
AddCaption(format(trmsg[sidBounce], trmsg[sidBounce3]), color, capgrpAmmostate);
+ − 150
CurWeapon^.Bounciness:= 1000;
+ − 151
end;
+ − 152
4: begin
+ − 153
AddCaption(format(trmsg[sidBounce], trmsg[sidBounce4]), color, capgrpAmmostate);
+ − 154
CurWeapon^.Bounciness:= 2000;
+ − 155
end;
+ − 156
5: begin
+ − 157
AddCaption(format(trmsg[sidBounce], trmsg[sidBounce5]), color, capgrpAmmostate);
+ − 158
CurWeapon^.Bounciness:= 4000;
+ − 159
end
+ − 160
end
+ − 161
end
+ − 162
else if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then
+ − 163
begin
+ − 164
CurWeapon^.Timer:= 1000 * Gear^.MsgParam;
+ − 165
with CurrentTeam^ do
+ − 166
ApplyAmmoChanges(Hedgehogs[CurrHedgehog]);
+ − 167
end;
+ − 168
end;
+ − 169
+ − 170
+ − 171
procedure Attack(Gear: PGear);
+ − 172
var xx, yy, newDx, newDy, lx, ly: hwFloat;
+ − 173
speech: PVisualGear;
+ − 174
newGear: PGear;
+ − 175
CurWeapon: PAmmo;
+ − 176
altUse: boolean;
+ − 177
elastic: hwFloat;
+ − 178
begin
+ − 179
newGear:= nil;
+ − 180
bShowFinger:= false;
6924
+ − 181
CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^);
6581
+ − 182
with Gear^,
+ − 183
Gear^.Hedgehog^ do
+ − 184
begin
+ − 185
if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
+ − 186
or (Power > 0)
+ − 187
or (CurAmmoType = amTeleport)
+ − 188
or
+ − 189
// Allow attacks while moving on ammo with AltAttack
+ − 190
((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
+ − 191
or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
+ − 192
and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
+ − 193
begin
+ − 194
State:= State or gstAttacking;
+ − 195
if Power = cMaxPower then
+ − 196
Message:= Message and (not gmAttack)
+ − 197
else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then
+ − 198
Message:= Message and (not gmAttack)
+ − 199
else
+ − 200
begin
+ − 201
if Power = 0 then
+ − 202
begin
+ − 203
AttackBar:= CurrentTeam^.AttackBar;
+ − 204
PlaySound(sndThrowPowerUp)
+ − 205
end;
+ − 206
inc(Power)
+ − 207
end;
+ − 208
if ((Message and gmAttack) <> 0) then
+ − 209
exit;
+ − 210
+ − 211
if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
+ − 212
begin
+ − 213
StopSound(sndThrowPowerUp);
+ − 214
PlaySound(sndThrowRelease);
+ − 215
end;
+ − 216
+ − 217
xx:= SignAs(AngleSin(Angle), dX);
+ − 218
yy:= -AngleCos(Angle);
+ − 219
+ − 220
lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
+ − 221
ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
+ − 222
+ − 223
if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
+ − 224
xx:= - xx;
+ − 225
if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
+ − 226
AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
+ − 227
+ − 228
// Initiating alt attack
+ − 229
if (CurAmmoGear <> nil)
+ − 230
and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
+ − 231
and ((Gear^.Message and gmLJump) <> 0)
+ − 232
and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
+ − 233
begin
+ − 234
newDx:= dX / _2;
+ − 235
newDy:= dY / _2;
+ − 236
altUse:= true;
+ − 237
end
+ − 238
else
+ − 239
begin
+ − 240
newDx:= xx*Power/cPowerDivisor;
+ − 241
newDy:= yy*Power/cPowerDivisor;
+ − 242
altUse:= false
+ − 243
end;
+ − 244
+ − 245
case CurAmmoType of
+ − 246
amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade, 0, newDx, newDy, CurWeapon^.Timer);
+ − 247
amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, newDx, newDy, 0);
+ − 248
amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, newDx, newDy, CurWeapon^.Timer);
+ − 249
amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, newDx, newDy, CurWeapon^.Timer);
+ − 250
amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell, 0, newDx, newDy, 0);
+ − 251
amSnowball: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSnowball, 0, newDx, newDy, 0);
+ − 252
amBee: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBee, 0, newDx, newDy, 0);
+ − 253
amShotgun: begin
+ − 254
PlaySound(sndShotgunReload);
+ − 255
newGear:= AddGear(hwRound(lx), hwRound(ly), gtShotgunShot, 0, xx * _0_5, yy * _0_5, 0);
+ − 256
end;
+ − 257
amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
+ − 258
amSkip: ParseCommand('/skip', true);
+ − 259
amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
+ − 260
amMine: if altUse then
+ − 261
newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000)
+ − 262
else
+ − 263
newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
+ − 264
amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
+ − 265
amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
+ − 266
amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
+ − 267
amPortalGun: begin
+ − 268
newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6,
+ − 269
// set selected color
+ − 270
CurWeapon^.Pos);
+ − 271
end;
+ − 272
amSniperRifle: begin
+ − 273
PlaySound(sndSniperReload);
+ − 274
newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0);
+ − 275
end;
+ − 276
amDynamite: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000);
+ − 277
amFirePunch: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtFirePunch, 0, xx, _0, 0);
+ − 278
amWhip: begin
+ − 279
newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtWhip, 0, SignAs(_1, dX), - _0_8, 0);
+ − 280
PlaySound(sndWhipCrack)
+ − 281
end;
+ − 282
amHammer: begin
+ − 283
newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtHammer, 0, SignAs(_1, dX), - _0_8, 0);
+ − 284
PlaySound(sndWhack)
+ − 285
end;
+ − 286
amBaseballBat: begin
+ − 287
newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0);
+ − 288
PlaySound(sndBaseballBat) // TODO: Only play if something is hit?
+ − 289
end;
+ − 290
amParachute: begin
+ − 291
newGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0);
+ − 292
PlaySound(sndParachute)
+ − 293
end;
+ − 294
// we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear.
+ − 295
amAirAttack: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0);
+ − 296
amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0);
+ − 297
amDrillStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer);
+ − 298
amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0);
+ − 299
amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0);
+ − 300
amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
+ − 301
amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0);
+ − 302
amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0);
+ − 303
amMortar: begin
+ − 304
playSound(sndMortar);
+ − 305
newGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar, 0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0);
+ − 306
end;
+ − 307
amRCPlane: begin
+ − 308
newGear:= AddGear(hwRound(lx), hwRound(ly), gtRCPlane, 0, xx * cMaxPower / cPowerDivisor / 4, yy * cMaxPower / cPowerDivisor / 4, 0);
+ − 309
newGear^.SoundChannel:= LoopSound(sndRCPlane, nil)
+ − 310
end;
+ − 311
amKamikaze: newGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0);
+ − 312
amCake: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0);
+ − 313
amSeduction: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSeduction, 0, _0, _0, 0);
+ − 314
amWatermelon: newGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon, 0, newDx, newDy, CurWeapon^.Timer);
+ − 315
amHellishBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb, 0, newDx, newDy, 0);
+ − 316
amDrill: newGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, newDx, newDy, 0);
+ − 317
amBallgun: newGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun, 0, xx * _0_5, yy * _0_5, 0);
+ − 318
amJetpack: newGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0);
+ − 319
amBirdy: begin
+ − 320
PlaySound(sndWhistle);
+ − 321
newGear:= AddGear(hwRound(lx), hwRound(ly) - 32, gtBirdy, 0, _0, _0, 0);
+ − 322
end;
+ − 323
amLowGravity: begin
+ − 324
PlaySound(sndLowGravity);
+ − 325
cGravity:= cMaxWindSpeed;
+ − 326
cGravityf:= 0.00025
+ − 327
end;
+ − 328
amExtraDamage: begin
+ − 329
PlaySound(sndHellishImpact4);
+ − 330
cDamageModifier:= _1_5
+ − 331
end;
+ − 332
amInvulnerable: Invulnerable:= true;
+ − 333
amExtraTime: begin
+ − 334
PlaySound(sndSwitchHog);
+ − 335
TurnTimeLeft:= TurnTimeLeft + 30000
+ − 336
end;
+ − 337
amLaserSight: cLaserSighting:= true;
+ − 338
amVampiric: begin
+ − 339
PlaySound(sndOw1, Team^.voicepack);
+ − 340
cVampiric:= true;
+ − 341
end;
+ − 342
amPiano: begin
+ − 343
// Tuck the hedgehog away until the piano attack is completed
+ − 344
Unplaced:= true;
+ − 345
X:= _0;
+ − 346
Y:= _0;
+ − 347
newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
+ − 348
PauseMusic
+ − 349
end;
+ − 350
amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower, 0, xx * _0_5, yy * _0_5, 0);
+ − 351
amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun, 0, xx * _0_5, yy * _0_5, 0);
+ − 352
amResurrector: begin
+ − 353
newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
+ − 354
newGear^.SoundChannel := LoopSound(sndResurrector);
+ − 355
end;
+ − 356
//amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0);
+ − 357
amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
+ − 358
amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
+ − 359
end;
+ − 360
+ − 361
case CurAmmoType of
+ − 362
amGrenade, amMolotov,
+ − 363
amClusterBomb, amGasBomb,
+ − 364
amBazooka, amSnowball,
+ − 365
amBee, amSMine,
+ − 366
amMortar, amWatermelon,
+ − 367
amHellishBomb, amDrill: FollowGear:= newGear;
+ − 368
+ − 369
amShotgun, amPickHammer,
+ − 370
amRope, amDEagle,
+ − 371
amSineGun, amSniperRifle,
+ − 372
amFirePunch, amWhip,
+ − 373
amHammer, amBaseballBat,
+ − 374
amParachute, amBlowTorch,
+ − 375
amGirder, amTeleport,
+ − 376
amSwitch, amRCPlane,
+ − 377
amKamikaze, amCake,
+ − 378
amSeduction, amBallgun,
+ − 379
amJetpack, amBirdy,
+ − 380
amFlamethrower, amLandGun,
+ − 381
amResurrector, amStructure,
+ − 382
amTardis, amPiano: CurAmmoGear:= newGear;
+ − 383
end;
+ − 384
+ − 385
if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
+ − 386
newGear^.FlightTime:= GameTicks + 1000
+ − 387
else if CurAmmoType = amDrill then
+ − 388
newGear^.FlightTime:= GameTicks + 250;
+ − 389
if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
+ − 390
begin
+ − 391
newGear^.Target.X:= TargetPoint.X;
+ − 392
newGear^.Target.Y:= TargetPoint.Y
+ − 393
end;
+ − 394
+ − 395
// Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
+ − 396
if altUse then
+ − 397
FollowGear:= nil;
+ − 398
+ − 399
if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
+ − 400
begin
+ − 401
elastic:= int2hwfloat(CurWeapon^.Bounciness) / _1000;
+ − 402
+ − 403
if elastic < _1 then
+ − 404
newGear^.Elasticity:= newGear^.Elasticity * elastic
+ − 405
else if elastic > _1 then
+ − 406
newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
+ − 407
(* Experimented with friction modifier. Didn't seem helpful
+ − 408
fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
+ − 409
if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
+ − 410
else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
+ − 411
end;
+ − 412
+ − 413
+ − 414
uStats.AmmoUsed(CurAmmoType);
+ − 415
+ − 416
if not (SpeechText = '') then
+ − 417
begin
+ − 418
speech:= AddVisualGear(0, 0, vgtSpeechBubble);
+ − 419
if speech <> nil then
+ − 420
begin
+ − 421
speech^.Text:= SpeechText;
+ − 422
speech^.Hedgehog:= Gear^.Hedgehog;
+ − 423
speech^.FrameTicks:= SpeechType;
+ − 424
end;
+ − 425
SpeechText:= ''
+ − 426
end;
+ − 427
+ − 428
Power:= 0;
+ − 429
if (CurAmmoGear <> nil)
+ − 430
and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
+ − 431
begin
+ − 432
Message:= Message or gmAttack;
+ − 433
CurAmmoGear^.Message:= Message
+ − 434
end
+ − 435
else
+ − 436
begin
+ − 437
if not CurrentTeam^.ExtDriven
+ − 438
and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
+ − 439
SendIPC('a');
+ − 440
AfterAttack;
+ − 441
end
+ − 442
end
+ − 443
else
+ − 444
Message:= Message and (not gmAttack);
+ − 445
end;
+ − 446
TargetPoint.X := NoPointX;
+ − 447
ScriptCall('onHogAttack');
+ − 448
end;
+ − 449
+ − 450
procedure AfterAttack;
+ − 451
var s: shortstring;
+ − 452
a: TAmmoType;
+ − 453
begin
+ − 454
with CurrentHedgehog^.Gear^, CurrentHedgehog^ do
+ − 455
begin
+ − 456
a:= CurAmmoType;
+ − 457
State:= State and (not gstAttacking);
+ − 458
if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
+ − 459
begin
+ − 460
Inc(MultiShootAttacks);
+ − 461
+ − 462
if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
+ − 463
begin
+ − 464
s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
+ − 465
AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
+ − 466
end;
+ − 467
+ − 468
if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
+ − 469
or ((GameFlags and gfMultiWeapon) <> 0) then
+ − 470
begin
+ − 471
isInMultiShoot:= true
+ − 472
end
+ − 473
else
+ − 474
begin
+ − 475
OnUsedAmmo(CurrentHedgehog^);
+ − 476
if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then
+ − 477
begin
+ − 478
if TagTurnTimeLeft = 0 then
+ − 479
TagTurnTimeLeft:= TurnTimeLeft;
+ − 480
TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
+ − 481
end;
+ − 482
if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then
+ − 483
State:= State or gstAttacked;
+ − 484
if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
+ − 485
ApplyAmmoChanges(CurrentHedgehog^)
+ − 486
end;
+ − 487
end
+ − 488
else
+ − 489
begin
+ − 490
OnUsedAmmo(CurrentHedgehog^);
+ − 491
ApplyAmmoChanges(CurrentHedgehog^);
+ − 492
end;
+ − 493
AttackBar:= 0
+ − 494
end
+ − 495
end;
+ − 496
+ − 497
////////////////////////////////////////////////////////////////////////////////
+ − 498
procedure doStepHedgehogDead(Gear: PGear);
+ − 499
const frametime = 200;
+ − 500
timertime = frametime * 6;
+ − 501
begin
+ − 502
if Gear^.Hedgehog^.Unplaced then
+ − 503
exit;
+ − 504
if Gear^.Timer > 1 then
+ − 505
begin
+ − 506
AllInactive:= false;
+ − 507
dec(Gear^.Timer);
+ − 508
if (Gear^.Timer mod frametime) = 0 then
+ − 509
inc(Gear^.Pos)
+ − 510
end
+ − 511
else if Gear^.Timer = 1 then
+ − 512
begin
+ − 513
Gear^.State:= Gear^.State or gstNoDamage;
+ − 514
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
+ − 515
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
+ − 516
DeleteGear(Gear);
+ − 517
SetAllToActive
+ − 518
end
+ − 519
else // Gear^.Timer = 0
+ − 520
begin
+ − 521
AllInactive:= false;
+ − 522
Gear^.Z:= cCurrHHZ;
+ − 523
RemoveGearFromList(Gear);
+ − 524
InsertGearToList(Gear);
+ − 525
PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
+ − 526
Gear^.Pos:= 0;
+ − 527
Gear^.Timer:= timertime
+ − 528
end
+ − 529
end;
+ − 530
+ − 531
////////////////////////////////////////////////////////////////////////////////
+ − 532
procedure doStepHedgehogGone(Gear: PGear);
+ − 533
const frametime = 65;
+ − 534
timertime = frametime * 11;
+ − 535
begin
+ − 536
if Gear^.Hedgehog^.Unplaced then
+ − 537
exit;
+ − 538
if Gear^.Timer > 1 then
+ − 539
begin
+ − 540
AllInactive:= false;
+ − 541
dec(Gear^.Timer);
+ − 542
if (Gear^.Timer mod frametime) = 0 then
+ − 543
inc(Gear^.Pos)
+ − 544
end
+ − 545
else
+ − 546
if Gear^.Timer = 1 then
+ − 547
begin
+ − 548
DeleteGear(Gear);
+ − 549
SetAllToActive
+ − 550
end
+ − 551
else // Gear^.Timer = 0
+ − 552
begin
+ − 553
AllInactive:= false;
+ − 554
Gear^.Z:= cCurrHHZ;
+ − 555
RemoveGearFromList(Gear);
+ − 556
InsertGearToList(Gear);
+ − 557
PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
+ − 558
PlaySound(sndWarp);
+ − 559
Gear^.Pos:= 0;
+ − 560
Gear^.Timer:= timertime
+ − 561
end
+ − 562
end;
+ − 563
+ − 564
////////////////////////////////////////////////////////////////////////////////
+ − 565
procedure PickUp(HH, Gear: PGear);
+ − 566
var s: shortstring;
+ − 567
a: TAmmoType;
+ − 568
i: LongInt;
+ − 569
vga: PVisualGear;
+ − 570
begin
+ − 571
Gear^.Message:= gmDestroy;
+ − 572
PlaySound(sndShotgunReload);
+ − 573
if (Gear^.Pos and posCaseExplode) <> 0 then
+ − 574
if (Gear^.Pos and posCasePoison) <> 0 then
+ − 575
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned)
+ − 576
else
+ − 577
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound)
+ − 578
else if (Gear^.Pos and posCasePoison) <> 0 then
+ − 579
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned + EXPLNoDamage)
+ − 580
else
+ − 581
case Gear^.Pos of
+ − 582
posCaseUtility,
+ − 583
posCaseAmmo: begin
+ − 584
if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType
+ − 585
else
+ − 586
begin
+ − 587
for i:= 0 to GameTicks and $7F do
+ − 588
GetRandom(2); // Burn some random numbers
+ − 589
if Gear^.Pos = posCaseUtility then
+ − 590
a:= GetUtility(HH^.Hedgehog)
+ − 591
else
+ − 592
a:= GetAmmo(HH^.Hedgehog)
+ − 593
end;
+ − 594
AddAmmo(HH^.Hedgehog^, a);
+ − 595
// Possibly needs to check shared clan ammo game flag once added.
+ − 596
// On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
+ − 597
if (not (HH^.Hedgehog^.Team^.ExtDriven
+ − 598
or (HH^.Hedgehog^.BotLevel > 0)))
+ − 599
or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
+ − 600
or (GameType = gmtDemo) then
+ − 601
begin
+ − 602
s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
+ − 603
AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
+ − 604
+ − 605
// show ammo icon
+ − 606
vga:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtAmmo);
+ − 607
if vga <> nil then
+ − 608
vga^.Frame:= Longword(a);
+ − 609
end;
+ − 610
+ − 611
end;
+ − 612
posCaseHealth: begin
+ − 613
inc(HH^.Health, Gear^.Health);
+ − 614
HH^.Hedgehog^.Effects[hePoisoned] := false;
+ − 615
str(Gear^.Health, s);
+ − 616
s:= '+' + s;
+ − 617
AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
+ − 618
RenderHealth(HH^.Hedgehog^);
+ − 619
RecountTeamHealth(HH^.Hedgehog^.Team);
+ − 620
+ − 621
i:= 0;
+ − 622
while i < Gear^.Health do
+ − 623
begin
+ − 624
vga:= AddVisualGear(hwRound(HH^.X), hwRound(HH^.Y), vgtStraightShot);
+ − 625
if vga <> nil then
+ − 626
with vga^ do
+ − 627
begin
+ − 628
Tint:= $00FF00FF;
+ − 629
State:= ord(sprHealth)
+ − 630
end;
+ − 631
inc(i, 5);
+ − 632
end;
+ − 633
end;
+ − 634
end
+ − 635
end;
+ − 636
+ − 637
const StepTicks: LongWord = 0;
+ − 638
+ − 639
procedure HedgehogStep(Gear: PGear);
+ − 640
var PrevdX: LongInt;
+ − 641
CurWeapon: PAmmo;
+ − 642
begin
6924
+ − 643
CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^);
6581
+ − 644
if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
+ − 645
begin
+ − 646
if isCursorVisible then
+ − 647
with Gear^.Hedgehog^ do
+ − 648
with CurWeapon^ do
+ − 649
begin
+ − 650
if (Gear^.Message and gmLeft ) <> 0 then
+ − 651
Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount
+ − 652
else
+ − 653
if (Gear^.Message and gmRight ) <> 0 then
+ − 654
Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount
+ − 655
else
+ − 656
exit;
+ − 657
StepTicks:= 200;
+ − 658
exit
+ − 659
end;
+ − 660
+ − 661
if ((Gear^.Message and gmAnimate) <> 0) then
+ − 662
begin
+ − 663
Gear^.Message:= 0;
+ − 664
Gear^.State:= Gear^.State or gstAnimation;
+ − 665
Gear^.Tag:= Gear^.MsgParam;
+ − 666
Gear^.Timer:= 0;
+ − 667
Gear^.Pos:= 0
+ − 668
end;
+ − 669
+ − 670
if ((Gear^.Message and gmLJump ) <> 0) then
+ − 671
begin
+ − 672
Gear^.Message:= Gear^.Message and (not gmLJump);
+ − 673
DeleteCI(Gear);
+ − 674
if TestCollisionYwithGear(Gear, -1) = 0 then
+ − 675
if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then
+ − 676
Gear^.Y:= Gear^.Y - _2
+ − 677
else
+ − 678
if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then
+ − 679
Gear^.Y:= Gear^.Y - _1;
+ − 680
if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
+ − 681
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 682
begin
+ − 683
Gear^.dY:= -_0_15;
+ − 684
if not cArtillery then
+ − 685
Gear^.dX:= SignAs(_0_15, Gear^.dX);
+ − 686
Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
+ − 687
PlaySound(sndJump1, Gear^.Hedgehog^.Team^.voicepack);
+ − 688
exit
+ − 689
end;
+ − 690
end;
+ − 691
+ − 692
if ((Gear^.Message and gmHJump ) <> 0) then
+ − 693
begin
+ − 694
DeleteCI(Gear);
+ − 695
Gear^.Message:= Gear^.Message and (not gmHJump);
+ − 696
+ − 697
Gear^.dY:= -_0_2;
+ − 698
SetLittle(Gear^.dX);
+ − 699
Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
+ − 700
PlaySound(sndJump3, Gear^.Hedgehog^.Team^.voicepack);
+ − 701
exit
+ − 702
end;
+ − 703
+ − 704
PrevdX:= hwSign(Gear^.dX);
+ − 705
if (Gear^.Message and gmLeft )<>0 then
+ − 706
Gear^.dX:= -cLittle else
+ − 707
if (Gear^.Message and gmRight )<>0 then
+ − 708
Gear^.dX:= cLittle else exit;
+ − 709
+ − 710
if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
+ − 711
begin
+ − 712
StepSoundTimer:= cHHStepTicks;
+ − 713
end;
+ − 714
+ − 715
StepTicks:= cHHStepTicks;
+ − 716
if PrevdX <> hwSign(Gear^.dX) then
+ − 717
begin
+ − 718
FollowGear:= Gear;
+ − 719
exit
+ − 720
end;
+ − 721
DeleteCI(Gear); // must be after exit!! (see previous line)
+ − 722
+ − 723
Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
+ − 724
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+ − 725
begin
+ − 726
if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX))
+ − 727
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 728
Gear^.Y:= Gear^.Y - _1;
+ − 729
if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX))
+ − 730
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 731
Gear^.Y:= Gear^.Y - _1;
+ − 732
if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX))
+ − 733
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 734
Gear^.Y:= Gear^.Y - _1;
+ − 735
if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
+ − 736
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 737
Gear^.Y:= Gear^.Y - _1;
+ − 738
if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
+ − 739
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 740
Gear^.Y:= Gear^.Y - _1;
+ − 741
if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
+ − 742
or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ − 743
Gear^.Y:= Gear^.Y - _1;
+ − 744
end;
+ − 745
+ − 746
if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then
+ − 747
Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX);
+ − 748
+ − 749
SetAllHHToActive;
+ − 750
+ − 751
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 752
begin
+ − 753
Gear^.Y:= Gear^.Y + _1;
+ − 754
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 755
begin
+ − 756
Gear^.Y:= Gear^.Y + _1;
+ − 757
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 758
begin
+ − 759
Gear^.Y:= Gear^.Y + _1;
+ − 760
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 761
begin
+ − 762
Gear^.Y:= Gear^.Y + _1;
+ − 763
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 764
begin
+ − 765
Gear^.Y:= Gear^.Y + _1;
+ − 766
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 767
begin
+ − 768
Gear^.Y:= Gear^.Y + _1;
+ − 769
if TestCollisionYwithGear(Gear, 1) = 0 then
+ − 770
begin
+ − 771
Gear^.Y:= Gear^.Y - _6;
+ − 772
Gear^.dY:= _0;
+ − 773
Gear^.State:= Gear^.State or gstMoving;
+ − 774
exit
+ − 775
end;
+ − 776
end
+ − 777
end
+ − 778
end
+ − 779
end
+ − 780
end
+ − 781
end;
+ − 782
AddGearCI(Gear)
+ − 783
end
+ − 784
end;
+ − 785
+ − 786
procedure HedgehogChAngle(HHGear: PGear);
+ − 787
var da: LongWord;
+ − 788
begin
+ − 789
with HHGear^.Hedgehog^ do
+ − 790
if ((CurAmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
+ − 791
or ((CurAmmoType = amPortalGun) and ((HHGear^.State and gstMoving) <> 0)) then
+ − 792
da:= 2
+ − 793
else da:= 1;
+ − 794
+ − 795
if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
+ − 796
if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then
+ − 797
dec(HHGear^.Angle, da)
+ − 798
else
+ − 799
if ((HHGear^.Message and gmDown) <> 0) and (HHGear^.Angle + da <= CurMaxAngle) then
+ − 800
inc(HHGear^.Angle, da)
+ − 801
end;
+ − 802
+ − 803
+ − 804
////////////////////////////////////////////////////////////////////////////////
+ − 805
procedure doStepHedgehogMoving(Gear: PGear);
+ − 806
var isFalling, isUnderwater: boolean;
+ − 807
land: Word;
+ − 808
begin
+ − 809
land:= 0;
+ − 810
isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
+ − 811
if Gear^.dX.QWordValue > 8160437862 then
+ − 812
Gear^.dX.QWordValue:= 8160437862;
+ − 813
if Gear^.dY.QWordValue > 8160437862 then
+ − 814
Gear^.dY.QWordValue:= 8160437862;
+ − 815
+ − 816
if Gear^.Hedgehog^.Unplaced then
+ − 817
begin
+ − 818
Gear^.dY:= _0;
+ − 819
Gear^.dX:= _0;
+ − 820
Gear^.State:= Gear^.State and (not gstMoving);
+ − 821
exit
+ − 822
end;
+ − 823
isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1);
+ − 824
if isFalling then
+ − 825
begin
+ − 826
if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
+ − 827
Gear^.dY:= _0;
+ − 828
Gear^.State:= Gear^.State or gstMoving;
+ − 829
if (CurrentHedgehog^.Gear = Gear)
+ − 830
and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
+ − 831
begin
+ − 832
FollowGear:= Gear;
+ − 833
end;
+ − 834
if isUnderwater then
+ − 835
Gear^.dY:= Gear^.dY + cGravity / _2
+ − 836
else
+ − 837
begin
+ − 838
Gear^.dY:= Gear^.dY + cGravity;
+ − 839
// this set of circumstances could be less complex if jumping was more clearly identified
+ − 840
if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
+ − 841
or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
+ − 842
or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
+ − 843
Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
+ − 844
end
+ − 845
end
+ − 846
else
+ − 847
begin
+ − 848
land:= TestCollisionYwithGear(Gear, 1);
+ − 849
if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
+ − 850
and ((Gear^.State and gstHHJumping) <> 0) then
+ − 851
SetLittle(Gear^.dX);
+ − 852
+ − 853
if not Gear^.dY.isNegative then
+ − 854
begin
+ − 855
CheckHHDamage(Gear);
+ − 856
+ − 857
if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery)
+ − 858
and (Gear^.dX.QWordValue < _0_02.QWordValue) then
+ − 859
Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
+ − 860
Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
+ − 861
Gear^.dY:= _0;
+ − 862
end
+ − 863
else
+ − 864
Gear^.dY:= Gear^.dY + cGravity;
+ − 865
+ − 866
if ((Gear^.State and gstMoving) <> 0) then
+ − 867
begin
+ − 868
if land and lfIce <> 0 then
+ − 869
begin
+ − 870
Gear^.dX:= Gear^.dX * (_1 - (_1 - Gear^.Friction) / _2)
+ − 871
end
+ − 872
else
+ − 873
Gear^.dX:= Gear^.dX * Gear^.Friction;
+ − 874
end
+ − 875
end;
+ − 876
+ − 877
if (Gear^.State <> 0) then
+ − 878
DeleteCI(Gear);
+ − 879
+ − 880
if isUnderwater then
+ − 881
begin
+ − 882
Gear^.dY:= Gear^.dY * _0_999;
+ − 883
Gear^.dX:= Gear^.dX * _0_999;
+ − 884
end;
+ − 885
+ − 886
if (Gear^.State and gstMoving) <> 0 then
+ − 887
if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
+ − 888
if not isFalling then
+ − 889
if hwAbs(Gear^.dX) > _0_01 then
+ − 890
if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then
+ − 891
begin
+ − 892
Gear^.X:= Gear^.X + Gear^.dX;
+ − 893
Gear^.dX:= Gear^.dX * _0_96;
+ − 894
Gear^.Y:= Gear^.Y - _1
+ − 895
end
+ − 896
else
+ − 897
if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
+ − 898
begin
+ − 899
Gear^.X:= Gear^.X + Gear^.dX;
+ − 900
Gear^.dX:= Gear^.dX * _0_93;
+ − 901
Gear^.Y:= Gear^.Y - _2
+ − 902
end
+ − 903
else
+ − 904
if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
+ − 905
begin
+ − 906
Gear^.X:= Gear^.X + Gear^.dX;
+ − 907
Gear^.dX:= Gear^.dX * _0_9 ;
+ − 908
Gear^.Y:= Gear^.Y - _3
+ − 909
end
+ − 910
else
+ − 911
if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then
+ − 912
begin
+ − 913
Gear^.X:= Gear^.X + Gear^.dX;
+ − 914
Gear^.dX:= Gear^.dX * _0_87;
+ − 915
Gear^.Y:= Gear^.Y - _4
+ − 916
end
+ − 917
else
+ − 918
if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then
+ − 919
begin
+ − 920
Gear^.X:= Gear^.X + Gear^.dX;
+ − 921
Gear^.dX:= Gear^.dX * _0_84;
+ − 922
Gear^.Y:= Gear^.Y - _5
+ − 923
end
+ − 924
else
+ − 925
if hwAbs(Gear^.dX) > _0_02 then
+ − 926
Gear^.dX:= -Gear^.Elasticity * Gear^.dX
+ − 927
else
+ − 928
begin
+ − 929
Gear^.State:= Gear^.State and (not gstMoving);
+ − 930
while TestCollisionYWithGear(Gear,1) = 0 do
+ − 931
Gear^.Y:= Gear^.Y+_1;
+ − 932
SetLittle(Gear^.dX)
+ − 933
end
+ − 934
else
+ − 935
begin
+ − 936
Gear^.State:= Gear^.State and (not gstMoving);
+ − 937
while TestCollisionYWithGear(Gear,1) = 0 do
+ − 938
Gear^.Y:= Gear^.Y+_1;
+ − 939
SetLittle(Gear^.dX)
+ − 940
end
+ − 941
else if (hwAbs(Gear^.dX) > cLittle)
+ − 942
and ((Gear^.State and gstHHJumping) = 0) then
+ − 943
Gear^.dX:= -Gear^.Elasticity * Gear^.dX
+ − 944
else
+ − 945
SetLittle(Gear^.dX);
+ − 946
+ − 947
if (not isFalling)
+ − 948
and (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
+ − 949
begin
+ − 950
Gear^.State:= Gear^.State and (not gstWinner);
+ − 951
Gear^.State:= Gear^.State and (not gstMoving);
+ − 952
while TestCollisionYWithGear(Gear,1) = 0 do
+ − 953
Gear^.Y:= Gear^.Y+_1;
+ − 954
SetLittle(Gear^.dX);
+ − 955
Gear^.dY:= _0
+ − 956
end
+ − 957
else
+ − 958
Gear^.State:= Gear^.State or gstMoving;
+ − 959
+ − 960
if (Gear^.State and gstMoving) <> 0 then
+ − 961
begin
+ − 962
Gear^.State:= Gear^.State and (not gstAnimation);
+ − 963
// ARTILLERY but not being moved by explosions
+ − 964
Gear^.X:= Gear^.X + Gear^.dX;
+ − 965
Gear^.Y:= Gear^.Y + Gear^.dY;
+ − 966
if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
+ − 967
and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
+ − 968
begin
+ − 969
CheckHHDamage(Gear);
+ − 970
Gear^.dY:= _0;
+ − 971
Gear^.Y:= Gear^.Y + _1
+ − 972
end;
+ − 973
CheckGearDrowning(Gear);
+ − 974
// hide target cursor if current hog is drowning
+ − 975
if (Gear^.State and gstDrowning) <> 0 then
+ − 976
if (CurrentHedgehog^.Gear = Gear) then
+ − 977
isCursorVisible:= false
+ − 978
end;
+ − 979
+ − 980
if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
+ − 981
begin
+ − 982
inc(Gear^.FlightTime);
+ − 983
if Gear^.FlightTime = 3000 then
+ − 984
begin
+ − 985
AddCaption(GetEventString(eidHomerun), cWhiteColor, capgrpMessage);
+ − 986
PlaySound(sndHomerun)
+ − 987
end;
+ − 988
end
+ − 989
else
+ − 990
begin
+ − 991
uStats.hedgehogFlight(Gear, Gear^.FlightTime);
+ − 992
Gear^.FlightTime:= 0;
+ − 993
end;
+ − 994
+ − 995
end;
+ − 996
+ − 997
procedure doStepHedgehogDriven(HHGear: PGear);
+ − 998
var t: PGear;
+ − 999
wasJumping: boolean;
+ − 1000
Hedgehog: PHedgehog;
+ − 1001
begin
+ − 1002
Hedgehog:= HHGear^.Hedgehog;
+ − 1003
if isInMultiShoot then
+ − 1004
HHGear^.Message:= 0;
+ − 1005
+ − 1006
if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then
+ − 1007
AllInactive:= true
+ − 1008
else if not isInMultiShoot then
+ − 1009
AllInactive:= false;
+ − 1010
+ − 1011
if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
+ − 1012
begin
+ − 1013
if TagTurnTimeLeft = 0 then
+ − 1014
TagTurnTimeLeft:= TurnTimeLeft;
+ − 1015
TurnTimeLeft:= 0;
+ − 1016
isCursorVisible:= false;
+ − 1017
HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
+ − 1018
AttackBar:= 0;
+ − 1019
if HHGear^.Damage > 0 then
+ − 1020
HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
+ − 1021
exit
+ − 1022
end;
+ − 1023
+ − 1024
if (HHGear^.State and gstAnimation) <> 0 then
+ − 1025
begin
+ − 1026
HHGear^.Message:= 0;
+ − 1027
if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then
+ − 1028
PlaySound(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
+ − 1029
inc(HHGear^.Timer);
+ − 1030
if HHGear^.Timer = Wavez[TWave(HHGear^.Tag)].Interval then
+ − 1031
begin
+ − 1032
HHGear^.Timer:= 0;
+ − 1033
inc(HHGear^.Pos);
+ − 1034
if HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].FramesCount then
+ − 1035
HHGear^.State:= HHGear^.State and (not gstAnimation)
+ − 1036
end;
+ − 1037
exit
+ − 1038
end;
+ − 1039
+ − 1040
if ((HHGear^.State and gstMoving) <> 0)
+ − 1041
or (StepTicks = cHHStepTicks)
+ − 1042
or (CurAmmoGear <> nil) then // we are moving
+ − 1043
begin
+ − 1044
with Hedgehog^ do
+ − 1045
if (CurAmmoGear = nil)
+ − 1046
and (HHGear^.dY > _0_39)
+ − 1047
and (CurAmmoType = amParachute) then
+ − 1048
HHGear^.Message:= HHGear^.Message or gmAttack;
+ − 1049
// check for case with ammo
+ − 1050
t:= CheckGearNear(HHGear, gtCase, 36, 36);
+ − 1051
if t <> nil then
+ − 1052
PickUp(HHGear, t)
+ − 1053
end;
+ − 1054
+ − 1055
if (CurAmmoGear = nil) then
+ − 1056
if (((HHGear^.Message and gmAttack) <> 0)
+ − 1057
or ((HHGear^.State and gstAttacking) <> 0)) then
+ − 1058
Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
+ − 1059
else
+ − 1060
else
+ − 1061
with Hedgehog^ do
+ − 1062
if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
+ − 1063
and ((HHGear^.Message and gmLJump) <> 0)
+ − 1064
and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
+ − 1065
begin
+ − 1066
Attack(HHGear);
+ − 1067
HHGear^.Message:= HHGear^.Message and (not gmLJump)
+ − 1068
end;
+ − 1069
+ − 1070
if (CurAmmoGear = nil)
+ − 1071
or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
+ − 1072
or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
+ − 1073
begin
+ − 1074
if ((HHGear^.Message and gmSlot) <> 0) then
+ − 1075
if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
+ − 1076
+ − 1077
if ((HHGear^.Message and gmWeapon) <> 0) then
+ − 1078
HHSetWeapon(HHGear);
+ − 1079
+ − 1080
if ((HHGear^.Message and gmTimer) <> 0) then
+ − 1081
HHSetTimer(HHGear);
+ − 1082
end;
+ − 1083
+ − 1084
if CurAmmoGear <> nil then
+ − 1085
begin
+ − 1086
CurAmmoGear^.Message:= HHGear^.Message;
+ − 1087
exit
+ − 1088
end;
+ − 1089
+ − 1090
if not isInMultiShoot then
+ − 1091
HedgehogChAngle(HHGear);
+ − 1092
+ − 1093
if (HHGear^.State and gstMoving) <> 0 then
+ − 1094
begin
+ − 1095
wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
+ − 1096
+ − 1097
if ((HHGear^.Message and gmHJump) <> 0) and wasJumping and ((HHGear^.State and gstHHHJump) = 0) then
+ − 1098
if (not (hwAbs(HHGear^.dX) > cLittle)) and (HHGear^.dY < -_0_02) then
+ − 1099
begin
+ − 1100
HHGear^.State:= HHGear^.State or gstHHHJump;
+ − 1101
HHGear^.dY:= -_0_25;
+ − 1102
if not cArtillery then
+ − 1103
HHGear^.dX:= -SignAs(_0_02, HHGear^.dX);
+ − 1104
PlaySound(sndJump2, Hedgehog^.Team^.voicepack)
+ − 1105
end;
+ − 1106
+ − 1107
HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
+ − 1108
+ − 1109
if (not cArtillery) and wasJumping and TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
+ − 1110
SetLittle(HHGear^.dX);
+ − 1111
+ − 1112
if Hedgehog^.Gear <> nil then
+ − 1113
doStepHedgehogMoving(HHGear);
+ − 1114
+ − 1115
if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
+ − 1116
begin
+ − 1117
AddGearCI(HHGear);
+ − 1118
if wasJumping then
+ − 1119
StepTicks:= 410
+ − 1120
else
+ − 1121
StepTicks:= 95
+ − 1122
end;
+ − 1123
exit
+ − 1124
end;
+ − 1125
+ − 1126
if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
+ − 1127
begin
+ − 1128
if StepTicks > 0 then
+ − 1129
dec(StepTicks);
+ − 1130
if (StepTicks = 0) then
+ − 1131
HedgehogStep(HHGear)
+ − 1132
end
+ − 1133
end;
+ − 1134
+ − 1135
////////////////////////////////////////////////////////////////////////////////
+ − 1136
procedure doStepHedgehogFree(Gear: PGear);
+ − 1137
var prevState: Longword;
+ − 1138
begin
+ − 1139
prevState:= Gear^.State;
+ − 1140
+ − 1141
doStepHedgehogMoving(Gear);
+ − 1142
+ − 1143
if (Gear^.State and (gstMoving or gstDrowning)) <> 0 then
+ − 1144
begin
+ − 1145
if Gear^.Damage > 0 then
+ − 1146
CalcRotationDirAngle(Gear);
+ − 1147
AllInactive:= false;
+ − 1148
exit
+ − 1149
end;
+ − 1150
+ − 1151
if (Gear^.Health = 0) then
+ − 1152
begin
+ − 1153
if PrvInactive or ((GameFlags and gfInfAttack) <> 0) then
+ − 1154
begin
+ − 1155
Gear^.Timer:= 0;
+ − 1156
FollowGear:= Gear;
+ − 1157
PrvInactive:= false;
+ − 1158
AllInactive:= false;
+ − 1159
+ − 1160
if (Gear^.State and gstHHGone) = 0 then
+ − 1161
begin
+ − 1162
Gear^.Hedgehog^.Effects[hePoisoned] := false;
+ − 1163
if Gear^.Hedgehog^.Effects[heResurrectable] then
+ − 1164
begin
+ − 1165
ResurrectHedgehog(Gear);
+ − 1166
end
+ − 1167
else
+ − 1168
begin
+ − 1169
Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
+ − 1170
Gear^.doStep:= @doStepHedgehogDead;
+ − 1171
// Death message
+ − 1172
AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
+ − 1173
end;
+ − 1174
end
+ − 1175
else
+ − 1176
begin
+ − 1177
Gear^.State:= Gear^.State and (not gstAnimation);
+ − 1178
Gear^.doStep:= @doStepHedgehogGone;
+ − 1179
+ − 1180
// Gone message
+ − 1181
AddCaption(Format(GetEventString(eidGone), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
+ − 1182
end
+ − 1183
end;
+ − 1184
exit
+ − 1185
end;
+ − 1186
+ − 1187
if ((Gear^.State and gstWait) = 0) and
+ − 1188
(prevState <> Gear^.State) then
+ − 1189
begin
+ − 1190
Gear^.State:= Gear^.State or gstWait;
+ − 1191
Gear^.Timer:= 150
+ − 1192
end
+ − 1193
else
+ − 1194
begin
+ − 1195
if Gear^.Timer = 0 then
+ − 1196
begin
+ − 1197
Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
+ − 1198
Gear^.Active:= false;
+ − 1199
AddGearCI(Gear);
+ − 1200
exit
+ − 1201
end
+ − 1202
else dec(Gear^.Timer)
+ − 1203
end;
+ − 1204
+ − 1205
AllInactive:= false
+ − 1206
end;
+ − 1207
+ − 1208
////////////////////////////////////////////////////////////////////////////////
+ − 1209
procedure doStepHedgehog(Gear: PGear);
+ − 1210
(*
+ − 1211
var x,y,tx,ty: LongInt;
+ − 1212
tdX, tdY, slope: hwFloat;
+ − 1213
land: Word; *)
+ − 1214
var slope: hwFloat;
+ − 1215
begin
+ − 1216
if (Gear^.Message and gmDestroy) <> 0 then
+ − 1217
begin
+ − 1218
DeleteGear(Gear);
+ − 1219
exit
+ − 1220
end;
+ − 1221
+ − 1222
if (Gear^.State and gstHHDriven) = 0 then
+ − 1223
doStepHedgehogFree(Gear)
+ − 1224
else
+ − 1225
begin
+ − 1226
with Gear^.Hedgehog^ do
+ − 1227
if Team^.hasGone then
+ − 1228
TeamGoneEffect(Team^)
+ − 1229
else
+ − 1230
doStepHedgehogDriven(Gear)
+ − 1231
end;
+ − 1232
if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
+ − 1233
and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
+ − 1234
and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
+ − 1235
and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
+ − 1236
begin
+ − 1237
slope:= CalcSlopeBelowGear(Gear);
+ − 1238
Gear^.dX:=Gear^.dX+slope*_0_07;
+ − 1239
if slope.QWordValue <> 0 then
+ − 1240
Gear^.State:= Gear^.State or gstMoving;
+ − 1241
(*
+ − 1242
x:= hwRound(Gear^.X);
+ − 1243
y:= hwRound(Gear^.Y);
+ − 1244
AddVisualGear(x, y, vgtSmokeTrace);
+ − 1245
AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
+ − 1246
AddVisualGear(x + hwRound(_5*slope), y - hwRound(_5*slope), vgtSmokeTrace);
+ − 1247
AddVisualGear(x - hwRound(_20 * slope), y + hwRound(_20 * slope), vgtSmokeTrace);
+ − 1248
AddVisualGear(x + hwRound(_20 * slope), y - hwRound(_20 * slope), vgtSmokeTrace);
+ − 1249
AddVisualGear(x - hwRound(_30 * slope), y + hwRound(_30 * slope), vgtSmokeTrace);
+ − 1250
AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
+ − 1251
AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
+ − 1252
AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
+ − 1253
AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
+ − 1254
AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
+ − 1255
end
+ − 1256
end;
+ − 1257
+ − 1258
end.