38 2: PlaySound(sndOw3, Hedgehog^.Team^.voicepack); |
38 2: PlaySound(sndOw3, Hedgehog^.Team^.voicepack); |
39 3: PlaySound(sndOw4, Hedgehog^.Team^.voicepack); |
39 3: PlaySound(sndOw4, Hedgehog^.Team^.voicepack); |
40 end |
40 end |
41 end; |
41 end; |
42 |
42 |
|
43 // Shouldn't more of this ammo switching stuff be moved to uAmmos ? |
43 procedure ChangeAmmo(Gear: PGear); |
44 procedure ChangeAmmo(Gear: PGear); |
44 var slot, i: Longword; |
45 var slot, ammoidx, i: Longword; |
|
46 CurWeapon: PAmmo; |
45 begin |
47 begin |
46 slot:= Gear^.MsgParam; |
48 slot:= Gear^.MsgParam; |
47 |
49 |
48 with PHedgehog(Gear^.Hedgehog)^ do |
50 with PHedgehog(Gear^.Hedgehog)^ do |
49 begin |
51 begin |
50 Gear^.Message:= Gear^.Message and not gm_Slot; |
52 Gear^.Message:= Gear^.Message and not gm_Slot; |
|
53 ammoidx:= 0; |
|
54 while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx); |
|
55 CurWeapon:= @Ammo^[slot, ammoidx]; |
51 |
56 |
52 if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0) or |
57 if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0) or |
53 ((MultiShootAttacks > 0) and ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NoRoundEndHint) = 0)) or |
58 ((MultiShootAttacks > 0) and ((CurWeapon^.Propz and ammoprop_NoRoundEndHint) = 0)) or |
54 ((Gear^.State and gstHHDriven) = 0) then exit; |
59 ((Gear^.State and gstHHDriven) = 0) then exit; |
55 |
60 |
56 if ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NoRoundEndHint) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(PHedgehog(Gear^.Hedgehog)^); |
61 if ((CurWeapon^.Propz and ammoprop_NoRoundEndHint) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(PHedgehog(Gear^.Hedgehog)^); |
57 |
62 |
58 MultiShootAttacks:= 0; |
63 MultiShootAttacks:= 0; |
59 Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); |
64 Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); |
60 |
65 |
61 if CurSlot = slot then |
66 if Ammoz[CurAmmoType].Slot = slot then |
62 begin |
67 begin |
63 i:= 0; |
68 i:= 0; |
64 repeat |
69 repeat |
65 inc(CurAmmo); |
70 inc(ammoidx); |
66 if (CurAmmo > cMaxSlotAmmoIndex) then |
71 if (ammoidx > cMaxSlotAmmoIndex) then |
67 begin |
72 begin |
68 CurAmmo:= 0; |
73 ammoidx:= 0; |
69 inc(i); |
74 inc(i); |
70 TryDo(i < 2, 'Engine bug: no ammo in current slot', true) |
75 TryDo(i < 2, 'Engine bug: no ammo in current slot', true) |
71 end; |
76 end; |
72 until (Ammo^[slot, CurAmmo].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, CurAmmo].AmmoType].SkipTurns) |
77 until (Ammo^[slot, ammoidx].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns) |
73 end else |
78 end else |
74 begin |
79 begin |
75 i:= 0; |
80 i:= 0; |
76 // check whether there is ammo in slot |
81 // check whether there is ammo in slot |
77 while (i <= cMaxSlotAmmoIndex) |
82 while (i <= cMaxSlotAmmoIndex) |
78 and ((Ammo^[slot, i].Count = 0) |
83 and ((Ammo^[slot, i].Count = 0) |
79 or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i); |
84 or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i); |
80 |
85 |
81 if i <= cMaxSlotAmmoIndex then |
86 if i <= cMaxSlotAmmoIndex then ammoidx:= i |
82 begin |
87 end; |
83 CurSlot:= slot; |
88 CurAmmoType:= Ammo^[slot, ammoidx].AmmoType; |
84 CurAmmo:= i |
|
85 end |
|
86 end |
|
87 end |
89 end |
88 end; |
90 end; |
89 |
91 |
90 procedure HHSetWeapon(Gear: PGear); |
92 procedure HHSetWeapon(Gear: PGear); |
91 var t: LongInt; |
93 var t: LongInt; |
92 weap: TAmmoType; |
94 weap: TAmmoType; |
|
95 Hedgehog: PHedgehog; |
93 begin |
96 begin |
94 weap:= TAmmoType(Gear^.MsgParam); |
97 weap:= TAmmoType(Gear^.MsgParam); |
95 |
98 Hedgehog:= PHedgehog(Gear^.Hedgehog); |
96 if PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet |
99 |
|
100 if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet |
97 |
101 |
98 Gear^.MsgParam:= Ammoz[weap].Slot; |
102 Gear^.MsgParam:= Ammoz[weap].Slot; |
99 |
103 |
100 t:= cMaxSlotAmmoIndex; |
104 t:= cMaxSlotAmmoIndex; |
101 |
105 |
102 Gear^.Message:= Gear^.Message and not gm_Weapon; |
106 Gear^.Message:= Gear^.Message and not gm_Weapon; |
103 |
107 |
104 with PHedgehog(Gear^.Hedgehog)^ do |
108 with Hedgehog^ do |
105 while (Ammo^[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do |
109 while (CurAmmoType <> weap) and (t >= 0) do |
106 begin |
110 begin |
107 ChangeAmmo(Gear); |
111 ChangeAmmo(Gear); |
108 dec(t) |
112 dec(t) |
109 end; |
113 end; |
110 |
114 |
111 ApplyAmmoChanges(PHedgehog(Gear^.Hedgehog)^) |
115 ApplyAmmoChanges(PHedgehog(Gear^.Hedgehog)^) |
112 end; |
116 end; |
113 |
117 |
114 procedure HHSetTimer(Gear: PGear); |
118 procedure HHSetTimer(Gear: PGear); |
|
119 var CurWeapon: PAmmo; |
115 begin |
120 begin |
116 Gear^.Message:= Gear^.Message and not gm_Timer; |
121 Gear^.Message:= Gear^.Message and not gm_Timer; |
|
122 CurWeapon:= GetAmmoEntry(PHedgehog(Gear^.Hedgehog)^); |
117 with PHedgehog(Gear^.Hedgehog)^ do |
123 with PHedgehog(Gear^.Hedgehog)^ do |
118 if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Timerable) <> 0 then |
124 if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then |
119 begin |
125 begin |
120 Ammo^[CurSlot, CurAmmo].Timer:= 1000 * Gear^.MsgParam; |
126 CurWeapon^.Timer:= 1000 * Gear^.MsgParam; |
121 with CurrentTeam^ do |
127 with CurrentTeam^ do |
122 ApplyAmmoChanges(Hedgehogs[CurrHedgehog]); |
128 ApplyAmmoChanges(Hedgehogs[CurrHedgehog]); |
123 end; |
129 end; |
124 end; |
130 end; |
125 |
131 |
126 |
132 |
127 procedure Attack(Gear: PGear); |
133 procedure Attack(Gear: PGear); |
128 var xx, yy, lx, ly: hwFloat; |
134 var xx, yy, lx, ly: hwFloat; |
129 tmpGear: PVisualGear; |
135 tmpGear: PVisualGear; |
130 tmpGear2: PGear; |
136 CurWeapon: PAmmo; |
131 begin |
137 begin |
132 bShowFinger:= false; |
138 bShowFinger:= false; |
|
139 CurWeapon:= GetAmmoEntry(PHedgehog(Gear^.Hedgehog)^); |
133 with Gear^, |
140 with Gear^, |
134 PHedgehog(Gear^.Hedgehog)^ do |
141 PHedgehog(Gear^.Hedgehog)^ do |
135 begin |
142 begin |
136 if ((State and gstHHDriven) <> 0)and |
143 if ((State and gstHHDriven) <> 0)and |
137 ((State and (gstAttacked or gstHHChooseTarget)) = 0) and |
144 ((State and (gstAttacked or gstHHChooseTarget)) = 0) and |
138 (((State and gstMoving) = 0) or |
145 (((State and gstMoving) = 0) or |
139 // Allow attacks while moving on ammo with AltAttack |
146 // Allow attacks while moving on ammo with AltAttack |
140 ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or |
147 ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or |
141 ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_AttackInMove) <> 0)) and |
148 ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0)) and |
142 ((TargetPoint.X <> NoPointX) or ((Ammo^[CurSlot, CurAmmo].Propz and ammoprop_NeedTarget) = 0)) then |
149 ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then |
143 begin |
150 begin |
144 State:= State or gstAttacking; |
151 State:= State or gstAttacking; |
145 if Power = cMaxPower then Message:= Message and not gm_Attack |
152 if Power = cMaxPower then Message:= Message and not gm_Attack |
146 else if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then Message:= Message and not gm_Attack |
153 else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then Message:= Message and not gm_Attack |
147 else begin |
154 else begin |
148 if Power = 0 then |
155 if Power = 0 then |
149 begin |
156 begin |
150 AttackBar:= CurrentTeam^.AttackBar; |
157 AttackBar:= CurrentTeam^.AttackBar; |
151 PlaySound(sndThrowPowerUp) |
158 PlaySound(sndThrowPowerUp) |
152 end; |
159 end; |
153 inc(Power) |
160 inc(Power) |
154 end; |
161 end; |
155 if ((Message and gm_Attack) <> 0) then exit; |
162 if ((Message and gm_Attack) <> 0) then exit; |
156 |
163 |
157 if (Ammo^[CurSlot, CurAmmo].Propz and ammoprop_Power) <> 0 then |
164 if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then |
158 begin |
165 begin |
159 StopSound(sndThrowPowerUp); |
166 StopSound(sndThrowPowerUp); |
160 PlaySound(sndThrowRelease); |
167 PlaySound(sndThrowRelease); |
161 end; |
168 end; |
162 |
169 |
163 xx:= SignAs(AngleSin(Angle), dX); |
170 xx:= SignAs(AngleSin(Angle), dX); |
164 yy:= -AngleCos(Angle); |
171 yy:= -AngleCos(Angle); |
165 |
172 |
166 lx:= X + int2hwfloat(round(GetLaunchX(Ammo^[CurSlot, CurAmmo].AmmoType, hwSign(dX), Angle))); |
173 lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle))); |
167 ly:= Y + int2hwfloat(round(GetLaunchY(Ammo^[CurSlot, CurAmmo].AmmoType, Angle))); |
174 ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle))); |
168 |
175 |
169 if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx; |
176 if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx; |
170 if Ammo^[CurSlot, CurAmmo].AttackVoice <> sndNone then |
177 if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then |
171 PlaySound(Ammo^[CurSlot, CurAmmo].AttackVoice, CurrentTeam^.voicepack); |
178 PlaySound(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack); |
172 case Ammo^[CurSlot, CurAmmo].AmmoType of |
179 case CurAmmoType of |
173 amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Bomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); |
180 amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Bomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); |
174 amMolotov: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
181 amMolotov: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
175 amClusterBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); |
182 amClusterBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); |
176 amGasBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); |
183 amGasBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); |
177 amBazooka: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Grenade, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
184 amBazooka: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtAmmo_Grenade, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
178 amBee: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtBee, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
185 amBee: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtBee, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
179 amShotgun: begin |
186 amShotgun: begin |
180 PlaySound(sndShotgunReload); |
187 PlaySound(sndShotgunReload); |
181 CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtShotgunShot, 0, xx * _0_5, yy * _0_5, 0); |
188 CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtShotgunShot, 0, xx * _0_5, yy * _0_5, 0); |
205 amBaseballBat: begin |
212 amBaseballBat: begin |
206 CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0); |
213 CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0); |
207 PlaySound(sndBaseballBat) // TODO: Only play if something is hit? |
214 PlaySound(sndBaseballBat) // TODO: Only play if something is hit? |
208 end; |
215 end; |
209 amParachute: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0); |
216 amParachute: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0); |
210 // we save Ammo^[CurSlot, CurAmmo].Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. |
217 // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. |
211 amAirAttack: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 0, _0, _0, 0); |
218 amAirAttack: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0); |
212 amMineStrike: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 1, _0, _0, 0); |
219 amMineStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0); |
213 amBlowTorch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0); |
220 amBlowTorch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0); |
214 amGirder: CurAmmoGear:= AddGear(0, 0, gtGirder, Ammo^[CurSlot, CurAmmo].Pos, _0, _0, 0); |
221 amGirder: CurAmmoGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0); |
215 amTeleport: CurAmmoGear:= AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtTeleport, 0, _0, _0, 0); |
222 amTeleport: CurAmmoGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0); |
216 amSwitch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0); |
223 amSwitch: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0); |
217 amMortar: begin |
224 amMortar: begin |
218 playSound(sndMortar); |
225 playSound(sndMortar); |
219 FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar, 0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0); |
226 FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar, 0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0); |
220 end; |
227 end; |
223 CurAmmoGear^.SoundChannel:= LoopSound(sndRCPlane, nil) |
230 CurAmmoGear^.SoundChannel:= LoopSound(sndRCPlane, nil) |
224 end; |
231 end; |
225 amKamikaze: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0); |
232 amKamikaze: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0); |
226 amCake: CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0); |
233 amCake: CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0); |
227 amSeduction: CurAmmoGear:= AddGear(hwRound(lx + xx * cHHRadius * 2), hwRound(ly + yy * cHHRadius * 2), gtSeduction, 0, xx * _0_4, yy * _0_4, 0); |
234 amSeduction: CurAmmoGear:= AddGear(hwRound(lx + xx * cHHRadius * 2), hwRound(ly + yy * cHHRadius * 2), gtSeduction, 0, xx * _0_4, yy * _0_4, 0); |
228 amWatermelon: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); |
235 amWatermelon: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, CurWeapon^.Timer); |
229 amHellishBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
236 amHellishBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
230 amNapalm: AddGear(Ammo^[CurSlot, CurAmmo].Pos, 0, gtAirAttack, 2, _0, _0, 0); |
237 amNapalm: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0); |
231 amDrill: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
238 amDrill: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
232 amBallgun: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun, 0, xx * _0_5, yy * _0_5, 0); |
239 amBallgun: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun, 0, xx * _0_5, yy * _0_5, 0); |
233 amJetpack: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0); |
240 amJetpack: CurAmmoGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0); |
234 amBirdy: begin |
241 amBirdy: begin |
235 PlaySound(sndWhistle); |
242 PlaySound(sndWhistle); |