81 function CheckForWin: boolean; |
81 function CheckForWin: boolean; |
82 var team, AliveTeam: PTeam; |
82 var team, AliveTeam: PTeam; |
83 AliveCount: Longword; |
83 AliveCount: Longword; |
84 s: shortstring; |
84 s: shortstring; |
85 begin |
85 begin |
86 Result:= false; |
|
87 AliveCount:= 0; |
86 AliveCount:= 0; |
88 AliveTeam:= nil; |
87 AliveTeam:= nil; |
89 team:= TeamsList; |
88 team:= TeamsList; |
90 while team <> nil do |
89 while team <> nil do |
91 begin |
90 begin |
92 if team.TeamHealth > 0 then |
91 if team^.TeamHealth > 0 then |
93 begin |
92 begin |
94 inc(AliveCount); |
93 inc(AliveCount); |
95 AliveTeam:= team |
94 AliveTeam:= team |
96 end; |
95 end; |
97 team:= team.Next |
96 team:= team^.Next |
98 end; |
97 end; |
99 |
98 |
100 if AliveCount >= 2 then exit; |
99 if AliveCount >= 2 then exit(false); |
101 Result:= true; |
100 CheckForWin:= true; |
102 |
101 |
103 TurnTimeLeft:= 0; |
102 TurnTimeLeft:= 0; |
104 if AliveCount = 0 then |
103 if AliveCount = 0 then |
105 begin // draw |
104 begin // draw |
106 AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState); |
105 AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState); |
107 SendStat(siGameResult, trmsg[sidDraw]); |
106 SendStat(siGameResult, trmsg[sidDraw]); |
108 AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000) |
107 AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000) |
109 end else // win |
108 end else // win |
110 begin |
109 begin |
111 s:= Format(trmsg[sidWinner], AliveTeam.TeamName); |
110 s:= Format(trmsg[sidWinner], AliveTeam^.TeamName); |
112 AddCaption(s, $FFFFFF, capgrpGameState); |
111 AddCaption(s, $FFFFFF, capgrpGameState); |
113 SendStat(siGameResult, s); |
112 SendStat(siGameResult, s); |
114 AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000) |
113 AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000) |
115 end; |
114 end; |
116 SendStats |
115 SendStats |
117 end; |
116 end; |
118 |
117 |
119 procedure SwitchHedgehog; |
118 procedure SwitchHedgehog; |
120 var tteam: PTeam; |
119 var tteam: PTeam; |
121 th: integer; |
120 th: integer; |
|
121 g: PGear; |
122 begin |
122 begin |
123 FreeActionsList; |
123 FreeActionsList; |
124 TargetPoint.X:= NoPointX; |
124 TargetPoint.X:= NoPointX; |
125 TryDo(CurrentTeam <> nil, 'nil Team', true); |
125 TryDo(CurrentTeam <> nil, 'nil Team', true); |
126 tteam:= CurrentTeam; |
126 tteam:= CurrentTeam; |
127 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do |
127 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do |
128 if Gear <> nil then |
128 if Gear <> nil then |
129 begin |
129 begin |
130 Gear.Message:= 0; |
130 Gear^.Message:= 0; |
131 Gear.Z:= cHHZ |
131 Gear^.Z:= cHHZ |
132 end; |
132 end; |
133 |
133 |
134 repeat |
134 repeat |
135 CurrentTeam:= CurrentTeam.Next; |
135 CurrentTeam:= CurrentTeam^.Next; |
136 if CurrentTeam = nil then CurrentTeam:= TeamsList; |
136 if CurrentTeam = nil then CurrentTeam:= TeamsList; |
137 th:= CurrentTeam.CurrHedgehog; |
137 th:= CurrentTeam^.CurrHedgehog; |
138 repeat |
138 repeat |
139 CurrentTeam.CurrHedgehog:= Succ(CurrentTeam.CurrHedgehog) mod (cMaxHHIndex + 1); |
139 CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (cMaxHHIndex + 1); |
140 until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam.CurrHedgehog = th) |
140 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam^.CurrHedgehog = th) |
141 until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam); |
141 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam); |
142 |
142 |
143 TryDo(CurrentTeam <> tteam, 'Switch hedgehog: only one team?!', true); |
143 TryDo(CurrentTeam <> tteam, 'Switch hedgehog: only one team?!', true); |
144 |
144 |
145 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do |
145 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do |
146 begin |
146 begin |
147 AttacksNum:= 0; |
147 AttacksNum:= 0; |
148 with Gear^ do |
148 with Gear^ do |
149 begin |
149 begin |
150 Z:= cCurrHHZ; |
150 Z:= cCurrHHZ; |
154 RemoveGearFromList(Gear); |
154 RemoveGearFromList(Gear); |
155 InsertGearToList(Gear); |
155 InsertGearToList(Gear); |
156 FollowGear:= Gear |
156 FollowGear:= Gear |
157 end; |
157 end; |
158 ResetKbd; |
158 ResetKbd; |
159 cWindSpeed:= (GetRandom * 2 - 1) * cMaxWindSpeed; |
159 |
160 AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1).Tag:= round(72 * cWindSpeed / cMaxWindSpeed); |
160 cWindSpeed:= rndSign(GetRandom * cMaxWindSpeed); |
|
161 addfilelog('SwitchHedgehog 06'); |
|
162 g:= AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1); |
|
163 g^.Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed); |
|
164 addfilelog('SwitchHedgehog 07'); |
161 {$IFDEF DEBUGFILE}AddFileLog('Wind = '+FloatToStr(cWindSpeed));{$ENDIF} |
165 {$IFDEF DEBUGFILE}AddFileLog('Wind = '+FloatToStr(cWindSpeed));{$ENDIF} |
162 ApplyAmmoChanges(CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog]); |
166 ApplyAmmoChanges(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]); |
163 if CurrentTeam.ExtDriven then SetDefaultBinds |
167 if CurrentTeam^.ExtDriven then SetDefaultBinds |
164 else SetBinds(CurrentTeam.Binds); |
168 else SetBinds(CurrentTeam^.Binds); |
165 bShowFinger:= true; |
169 bShowFinger:= true; |
166 TurnTimeLeft:= cHedgehogTurnTime |
170 TurnTimeLeft:= cHedgehogTurnTime |
167 end; |
171 end; |
168 |
172 |
169 function AddTeam: PTeam; |
173 function AddTeam: PTeam; |
|
174 var Result: PTeam; |
170 begin |
175 begin |
171 New(Result); |
176 New(Result); |
172 TryDo(Result <> nil, 'AddTeam: Result = nil', true); |
177 TryDo(Result <> nil, 'AddTeam: Result = nil', true); |
173 FillChar(Result^, sizeof(TTeam), 0); |
178 FillChar(Result^, sizeof(TTeam), 0); |
174 Result.AttackBar:= 2; |
179 Result^.AttackBar:= 2; |
175 Result.CurrHedgehog:= cMaxHHIndex; |
180 Result^.CurrHedgehog:= cMaxHHIndex; |
176 if TeamsList = nil then TeamsList:= Result |
181 if TeamsList = nil then TeamsList:= Result |
177 else begin |
182 else begin |
178 Result.Next:= TeamsList; |
183 Result^.Next:= TeamsList; |
179 TeamsList:= Result |
184 TeamsList:= Result |
180 end; |
185 end; |
181 CurrentTeam:= Result |
186 CurrentTeam:= Result; |
|
187 AddTeam:= Result |
182 end; |
188 end; |
183 |
189 |
184 procedure FreeTeamsList; |
190 procedure FreeTeamsList; |
185 var t, tt: PTeam; |
191 var t, tt: PTeam; |
186 begin |
192 begin |
187 tt:= TeamsList; |
193 tt:= TeamsList; |
188 TeamsList:= nil; |
194 TeamsList:= nil; |
189 while tt<>nil do |
195 while tt <> nil do |
190 begin |
196 begin |
191 t:= tt; |
197 t:= tt; |
192 tt:= tt.Next; |
198 tt:= tt^.Next; |
193 Dispose(t) |
199 Dispose(t) |
194 end; |
200 end; |
195 end; |
201 end; |
196 |
202 |
197 procedure RecountAllTeamsHealth; |
203 procedure RecountAllTeamsHealth; |
228 begin |
234 begin |
229 TargetPoint.X:= NoPointX; |
235 TargetPoint.X:= NoPointX; |
230 |
236 |
231 with Hedgehog do |
237 with Hedgehog do |
232 begin |
238 begin |
233 if Ammo[CurSlot, CurAmmo].Count = 0 then |
239 if Ammo^[CurSlot, CurAmmo].Count = 0 then |
234 begin |
240 begin |
235 CurAmmo:= 0; |
241 CurAmmo:= 0; |
236 CurSlot:= 0; |
242 CurSlot:= 0; |
237 while (CurSlot <= cMaxSlotIndex) and (Ammo[CurSlot, CurAmmo].Count = 0) do inc(CurSlot) |
243 while (CurSlot <= cMaxSlotIndex) and (Ammo^[CurSlot, CurAmmo].Count = 0) do inc(CurSlot) |
238 end; |
244 end; |
239 |
245 |
240 with Ammo[CurSlot, CurAmmo] do |
246 with Ammo^[CurSlot, CurAmmo] do |
241 begin |
247 begin |
242 CurMinAngle:= Ammoz[AmmoType].minAngle; |
248 CurMinAngle:= Ammoz[AmmoType].minAngle; |
243 if Ammoz[AmmoType].maxAngle <> 0 then CurMaxAngle:= Ammoz[AmmoType].maxAngle |
249 if Ammoz[AmmoType].maxAngle <> 0 then CurMaxAngle:= Ammoz[AmmoType].maxAngle |
244 else CurMaxAngle:= cMaxAngle; |
250 else CurMaxAngle:= cMaxAngle; |
245 with Hedgehog.Gear^ do |
251 with Hedgehog.Gear^ do |
246 begin |
252 begin |
247 if Angle < CurMinAngle then Angle:= CurMinAngle; |
253 if Angle < CurMinAngle then Angle:= CurMinAngle; |
248 if Angle > CurMaxAngle then Angle:= CurMaxAngle; |
254 if Angle > CurMaxAngle then Angle:= CurMaxAngle; |
249 end; |
255 end; |
250 |
256 |
251 s:= trammo[Ammoz[AmmoType].NameId]; |
257 s:= trammo[Ammoz[AmmoType].NameId]; |
252 if Count <> AMMO_INFINITE then |
258 if Count <> AMMO_INFINITE then |
253 s:= s + ' (' + IntToStr(Count) + ')'; |
259 s:= s + ' (' + IntToStr(Count) + ')'; |
254 if (Propz and ammoprop_Timerable) <> 0 then |
260 if (Propz and ammoprop_Timerable) <> 0 then |
255 s:= s + ', ' + inttostr(Timer div 1000) + ' ' + trammo[sidSeconds]; |
261 s:= s + ', ' + inttostr(Timer div 1000) + ' ' + trammo[sidSeconds]; |
256 AddCaption(s, Team.Color, capgrpAmmoinfo); |
262 AddCaption(s, Team^.Color, capgrpAmmoinfo); |
257 if (Propz and ammoprop_NeedTarget) <> 0 |
263 if (Propz and ammoprop_NeedTarget) <> 0 |
258 then begin |
264 then begin |
259 Gear.State:= Gear.State or gstHHChooseTarget; |
265 Gear^.State:= Gear^.State or gstHHChooseTarget; |
260 isCursorVisible:= true |
266 isCursorVisible:= true |
261 end else begin |
267 end else begin |
262 Gear.State:= Gear.State and not gstHHChooseTarget; |
268 Gear^.State:= Gear^.State and not gstHHChooseTarget; |
263 isCursorVisible:= false |
269 isCursorVisible:= false |
264 end; |
270 end; |
265 ShowCrosshair:= (Propz and ammoprop_NoCrosshair) = 0 |
271 ShowCrosshair:= (Propz and ammoprop_NoCrosshair) = 0 |
266 end |
272 end |
267 end |
273 end |
268 end; |
274 end; |
269 |
275 |
270 function TeamSize(p: PTeam): Longword; |
276 function TeamSize(p: PTeam): Longword; |
271 var i: Longword; |
277 var i, Result: Longword; |
272 begin |
278 begin |
273 Result:= 0; |
279 Result:= 0; |
274 for i:= 0 to cMaxHHIndex do |
280 for i:= 0 to cMaxHHIndex do |
275 if p.Hedgehogs[i].Gear <> nil then inc(Result) |
281 if p^.Hedgehogs[i].Gear <> nil then inc(Result); |
|
282 TeamSize:= Result |
276 end; |
283 end; |
277 |
284 |
278 procedure RecountTeamHealth(team: PTeam); |
285 procedure RecountTeamHealth(team: PTeam); |
279 var i: integer; |
286 var i: integer; |
280 begin |
287 begin |
281 with team^ do |
288 with team^ do |
282 begin |
289 begin |
283 TeamHealthBarWidth:= 0; |
290 TeamHealthBarWidth:= 0; |
284 for i:= 0 to cMaxHHIndex do |
291 for i:= 0 to cMaxHHIndex do |
285 if Hedgehogs[i].Gear <> nil then |
292 if Hedgehogs[i].Gear <> nil then |
286 inc(TeamHealthBarWidth, Hedgehogs[i].Gear.Health); |
293 inc(TeamHealthBarWidth, Hedgehogs[i].Gear^.Health); |
287 TeamHealth:= TeamHealthBarWidth; |
294 TeamHealth:= TeamHealthBarWidth; |
288 if TeamHealthBarWidth > MaxTeamHealth then |
295 if TeamHealthBarWidth > MaxTeamHealth then |
289 begin |
296 begin |
290 MaxTeamHealth:= TeamHealthBarWidth; |
297 MaxTeamHealth:= TeamHealthBarWidth; |
291 RecountAllTeamsHealth; |
298 RecountAllTeamsHealth; |
292 end else TeamHealthBarWidth:= (TeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth |
299 end else TeamHealthBarWidth:= (TeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth |
293 end; |
300 end; |
294 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously |
301 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously |
295 AddGear(0, 0, gtTeamHealthSorter, 0) |
302 AddGear(0, 0, gtTeamHealthSorter, 0, 0, 0, 0) |
296 end; |
303 end; |
297 |
304 |
298 procedure RestoreTeamsFromSave; |
305 procedure RestoreTeamsFromSave; |
299 var p: PTeam; |
306 var p: PTeam; |
300 begin |
307 begin |
301 p:= TeamsList; |
308 p:= TeamsList; |
302 while p <> nil do |
309 while p <> nil do |
303 begin |
310 begin |
304 p.ExtDriven:= false; |
311 p^.ExtDriven:= false; |
305 p:= p.Next |
312 p:= p^.Next |
306 end; |
313 end; |
307 end; |
314 end; |
308 |
315 |
309 procedure SetWeapon(weap: TAmmoType); |
316 procedure SetWeapon(weap: TAmmoType); |
310 var t: integer; |
317 var t: integer; |
311 begin |
318 begin |
312 t:= cMaxSlotAmmoIndex; |
319 t:= cMaxSlotAmmoIndex; |
313 with CurrentTeam^ do |
320 with CurrentTeam^ do |
314 with Hedgehogs[CurrHedgehog] do |
321 with Hedgehogs[CurrHedgehog] do |
315 while (Ammo[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do |
322 while (Ammo^[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do |
316 begin |
323 begin |
317 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot)); |
324 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot), true); |
318 dec(t) |
325 dec(t) |
319 end |
326 end |
320 end; |
327 end; |
321 |
328 |
322 procedure SendStats; |
329 procedure SendStats; |