diff -r cbee69165c6a -r 833c0f32e326 hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Mon Sep 06 20:40:58 2010 +0100 +++ b/hedgewars/HHHandlers.inc Mon Sep 06 16:23:47 2010 -0400 @@ -40,36 +40,41 @@ end end; +// Shouldn't more of this ammo switching stuff be moved to uAmmos ? procedure ChangeAmmo(Gear: PGear); -var slot, i: Longword; +var slot, ammoidx, i: Longword; + CurWeapon: PAmmo; begin slot:= Gear^.MsgParam; with PHedgehog(Gear^.Hedgehog)^ do begin Gear^.Message:= Gear^.Message and not gm_Slot; + ammoidx:= 0; + while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx); + CurWeapon:= @Ammo^[slot, ammoidx]; if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0) or - ((MultiShootAttacks > 0) and ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NoRoundEndHint) = 0)) or + ((MultiShootAttacks > 0) and ((CurWeapon^.Propz and ammoprop_NoRoundEndHint) = 0)) or ((Gear^.State and gstHHDriven) = 0) then exit; - if ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NoRoundEndHint) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(PHedgehog(Gear^.Hedgehog)^); + if ((CurWeapon^.Propz and ammoprop_NoRoundEndHint) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(PHedgehog(Gear^.Hedgehog)^); MultiShootAttacks:= 0; Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); - - if CurSlot = slot then + + if Ammoz[CurAmmoType].Slot = slot then begin i:= 0; repeat - inc(CurAmmo); - if (CurAmmo > cMaxSlotAmmoIndex) then + inc(ammoidx); + if (ammoidx > cMaxSlotAmmoIndex) then begin - CurAmmo:= 0; + ammoidx:= 0; inc(i); TryDo(i < 2, 'Engine bug: no ammo in current slot', true) end; - until (Ammo^[slot, CurAmmo].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, CurAmmo].AmmoType].SkipTurns) + until (Ammo^[slot, ammoidx].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns) end else begin i:= 0; @@ -78,22 +83,21 @@ and ((Ammo^[slot, i].Count = 0) or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i); - if i <= cMaxSlotAmmoIndex then - begin - CurSlot:= slot; - CurAmmo:= i - end - end + if i <= cMaxSlotAmmoIndex then ammoidx:= i + end; + CurAmmoType:= Ammo^[slot, ammoidx].AmmoType; end end; procedure HHSetWeapon(Gear: PGear); var t: LongInt; weap: TAmmoType; + Hedgehog: PHedgehog; begin weap:= TAmmoType(Gear^.MsgParam); +Hedgehog:= PHedgehog(Gear^.Hedgehog); -if PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet +if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet Gear^.MsgParam:= Ammoz[weap].Slot; @@ -101,8 +105,8 @@ Gear^.Message:= Gear^.Message and not gm_Weapon; -with PHedgehog(Gear^.Hedgehog)^ do - while (Ammo^[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do +with Hedgehog^ do + while (CurAmmoType <> weap) and (t >= 0) do begin ChangeAmmo(Gear); dec(t) @@ -112,12 +116,14 @@ end; procedure HHSetTimer(Gear: PGear); +var CurWeapon: PAmmo; begin Gear^.Message:= Gear^.Message and not gm_Timer; +CurWeapon:= GetAmmoEntry(PHedgehog(Gear^.Hedgehog)^); with PHedgehog(Gear^.Hedgehog)^ do - if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Timerable) <> 0 then + if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then begin - Ammo^[CurSlot, CurAmmo].Timer:= 1000 * Gear^.MsgParam; + CurWeapon^.Timer:= 1000 * Gear^.MsgParam; with CurrentTeam^ do ApplyAmmoChanges(Hedgehogs[CurrHedgehog]); end; @@ -127,9 +133,10 @@ procedure Attack(Gear: PGear); var xx, yy, lx, ly: hwFloat; tmpGear: PVisualGear; - tmpGear2: PGear; + CurWeapon: PAmmo; begin bShowFinger:= false; +CurWeapon:= GetAmmoEntry(PHedgehog(Gear^.Hedgehog)^); with Gear^, PHedgehog(Gear^.Hedgehog)^ do begin @@ -138,12 +145,12 @@ (((State and gstMoving) = 0) or // Allow attacks while moving on ammo with AltAttack ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or - ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_AttackInMove) <> 0)) and - ((TargetPoint.X <> NoPointX) or ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NeedTarget) = 0)) then + ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0)) and + ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then begin State:= State or gstAttacking; if Power = cMaxPower then Message:= Message and not gm_Attack - else if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then Message:= Message and not gm_Attack + else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then Message:= Message and not gm_Attack else begin if Power = 0 then begin @@ -154,7 +161,7 @@ end; if ((Message and gm_Attack) <> 0) then exit; - if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Power) <> 0 then + if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then begin StopSound(sndThrowPowerUp); PlaySound(sndThrowRelease); @@ -163,17 +170,17 @@ xx:= SignAs(AngleSin(Angle), dX); yy:= -AngleCos(Angle); - lx:= X + int2hwfloat(round(GetLaunchX(Ammo^[CurSlot, CurAmmo].AmmoType, hwSign(dX), Angle))); - ly:= Y + int2hwfloat(round(GetLaunchY(Ammo^[CurSlot, CurAmmo].AmmoType, Angle))); + lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle))); + ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle))); if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx; - if Ammo^[CurSlot, CurAmmo].AttackVoice <> sndNone then - PlaySound(Ammo^[CurSlot, CurAmmo].AttackVoice, CurrentTeam^.voicepack); - case Ammo^[CurSlot, CurAmmo].AmmoType of - amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Bomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); + if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then + PlaySound(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack); + case CurAmmoType of + amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Bomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); amMolotov: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); - amClusterBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); - amGasBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); + amClusterBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); + amGasBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); amBazooka: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Grenade, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); amBee: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtBee, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); amShotgun: begin @@ -207,12 +214,12 @@ PlaySound(sndBaseballBat) // TODO: Only play if something is hit? end; amParachute: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0); - // we save Ammo^[CurSlot, CurAmmo].Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. - amAirAttack: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 0, _0, _0, 0); - amMineStrike: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 1, _0, _0, 0); + // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. + amAirAttack: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0); + amMineStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0); amBlowTorch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0); - amGirder: CurAmmoGear:= AddGear(0, 0, gtGirder, Ammo^[CurSlot, CurAmmo].Pos, _0, _0, 0); - amTeleport: CurAmmoGear:= AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtTeleport, 0, _0, _0, 0); + amGirder: CurAmmoGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0); + amTeleport: CurAmmoGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0); amSwitch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0); amMortar: begin playSound(sndMortar); @@ -225,9 +232,9 @@ amKamikaze: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0); amCake: CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0); amSeduction: CurAmmoGear:= AddGear(hwRound(lx + xx * cHHRadius * 2), hwRound(ly + yy * cHHRadius * 2), gtSeduction, 0, xx * _0_4, yy * _0_4, 0); - amWatermelon: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); + amWatermelon: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); amHellishBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); - amNapalm: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 2, _0, _0, 0); + amNapalm: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0); amDrill: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); amBallgun: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun, 0, xx * _0_5, yy * _0_5, 0); amJetpack: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0); @@ -258,7 +265,7 @@ amFlamethrower: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower, 0, xx * _0_5, yy * _0_5, 0); end; - uStats.AmmoUsed(Ammo^[CurSlot, CurAmmo].AmmoType); + uStats.AmmoUsed(CurAmmoType); if not (SpeechText = '') then begin @@ -274,15 +281,14 @@ Power:= 0; if (CurAmmoGear <> nil) - and (((Ammo^[CurSlot, CurAmmo].Propz) and ammoprop_AltUse) = 0){check for dropping ammo from rope} then + and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then begin - CurAmmoGear^.Ammo:= @(Ammo^[CurSlot, CurAmmo]); - CurAmmoGear^.AmmoType:= CurAmmoGear^.Ammo^.AmmoType; + CurAmmoGear^.AmmoType:= CurAmmoType; Message:= Message or gm_Attack; CurAmmoGear^.Message:= Message end else begin if not CurrentTeam^.ExtDriven and - ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Power) <> 0) then SendIPC('a'); + ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then SendIPC('a'); AfterAttack; end end else Message:= Message and not gm_Attack; @@ -296,27 +302,27 @@ CurrentHedgehog^ do begin State:= State and not gstAttacking; - if ((Ammo^[CurSlot, CurAmmo].Propz) and ammoprop_Effect) = 0 then + if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Effect) = 0 then begin Inc(MultiShootAttacks); - if (Ammo^[CurSlot, CurAmmo].NumPerTurn >= MultiShootAttacks) then + if (Ammoz[CurAmmoType].Ammo.NumPerTurn >= MultiShootAttacks) then begin - s:= inttostr(Ammo^[CurSlot, CurAmmo].NumPerTurn - MultiShootAttacks + 1); + s:= inttostr(Ammoz[CurAmmoType].Ammo.NumPerTurn - MultiShootAttacks + 1); AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate); end; - if (Ammo^[CurSlot, CurAmmo].NumPerTurn >= MultiShootAttacks) or + if (Ammoz[CurAmmoType].Ammo.NumPerTurn >= MultiShootAttacks) or ((GameFlags and gfMultiWeapon) <> 0) then begin isInMultiShoot:= true end else begin - if ((Ammo^[CurSlot, CurAmmo].Propz) and ammoprop_NoRoundEndHint) = 0 then + if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEndHint) = 0 then begin OnUsedAmmo(CurrentHedgehog^); - TurnTimeLeft:= Ammoz[Ammo^[CurSlot, CurAmmo].AmmoType].TimeAfterTurn; + TurnTimeLeft:= Ammoz[CurAmmoType].TimeAfterTurn; State:= State or gstAttacked end else @@ -331,7 +337,7 @@ OnUsedAmmo(CurrentHedgehog^); ApplyAmmoChanges(CurrentHedgehog^); end; - AttackBar:= 0; + AttackBar:= 0 end end; @@ -449,12 +455,14 @@ procedure HedgehogStep(Gear: PGear); var PrevdX: LongInt; + CurWeapon: PAmmo; begin +CurWeapon:= GetAmmoEntry(PHedgehog(Gear^.Hedgehog)^); if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then begin if isCursorVisible then with PHedgehog(Gear^.Hedgehog)^ do - with Ammo^[CurSlot, CurAmmo] do + with CurWeapon^ do begin if (Gear^.Message and gm_Left ) <> 0 then Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount @@ -583,7 +591,7 @@ var da: LongWord; begin with PHedgehog(Gear^.Hedgehog)^ do - if (Ammo^[CurSlot, CurAmmo].AmmoType = amRope) + if (CurAmmoType = amRope) and ((Gear^.State and (gstMoving or gstHHJumping)) = gstMoving) then da:= 2 else da:= 1; if (((Gear^.Message and gm_Precise) = 0) or ((GameTicks mod 5) = 1)) then @@ -702,7 +710,9 @@ procedure doStepHedgehogDriven(Gear: PGear); var t: PGear; wasJumping: boolean; + Hedgehog: PHedgehog; begin +Hedgehog:= PHedgehog(Gear^.Hedgehog); if not isInMultiShoot then AllInactive:= false else @@ -722,7 +732,7 @@ if (Gear^.State and gstAnimation) <> 0 then begin Gear^.Message:= 0; - if (Gear^.Pos = Wavez[TWave(Gear^.Tag)].VoiceDelay) and (Gear^.Timer = 0) then PlaySound(Wavez[TWave(Gear^.Tag)].Voice, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); + if (Gear^.Pos = Wavez[TWave(Gear^.Tag)].VoiceDelay) and (Gear^.Timer = 0) then PlaySound(Wavez[TWave(Gear^.Tag)].Voice, Hedgehog^.Team^.voicepack); inc(Gear^.Timer); if Gear^.Timer = Wavez[TWave(Gear^.Tag)].Interval then begin @@ -738,10 +748,10 @@ or (StepTicks = cHHStepTicks) or (CurAmmoGear <> nil) then // we are moving begin - with PHedgehog(Gear^.Hedgehog)^ do + with Hedgehog^ do if (CurAmmoGear = nil) and (Gear^.dY > _0_39) - and (Ammo^[CurSlot, CurAmmo].AmmoType = amParachute) then Gear^.Message:= Gear^.Message or gm_Attack; + and (CurAmmoType = amParachute) then Gear^.Message:= Gear^.Message or gm_Attack; // check for case with ammo t:= CheckGearNear(Gear, gtCase, 36, 36); if t <> nil then @@ -753,22 +763,23 @@ or ((Gear^.State and gstAttacking) <> 0)) then Attack(Gear) // should be before others to avoid desync with '/put' msg and changing weapon msgs else -else with PHedgehog(Gear^.Hedgehog)^ do - if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) - and ((Gear^.Message and gm_LJump) <> 0) - and (((Ammo^[CurSlot, CurAmmo].Propz) and ammoprop_AltUse) <> 0) then - begin - Gear^.Message:= Gear^.Message and not gm_LJump; - Attack(Gear) - end; +else + with Hedgehog^ do + if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) + and ((Gear^.Message and gm_LJump) <> 0) + and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then + begin + Gear^.Message:= Gear^.Message and not gm_LJump; + Attack(Gear) + end; if (CurAmmoGear = nil) - or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then + or ((Ammoz[Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then begin if ((Gear^.Message and gm_Slot) <> 0) then begin ChangeAmmo(Gear); - ApplyAmmoChanges(PHedgehog(Gear^.Hedgehog)^) + ApplyAmmoChanges(Hedgehog^) end; if ((Gear^.Message and gm_Weapon) <> 0) then HHSetWeapon(Gear); @@ -797,7 +808,7 @@ Gear^.State:= Gear^.State or gstHHHJump; Gear^.dY:= -_0_25; if not cArtillery then Gear^.dX:= -SignAs(_0_02, Gear^.dX); - PlaySound(sndJump2, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) + PlaySound(sndJump2, Hedgehog^.Team^.voicepack) end; Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump);