52 var TeamsGameOver: boolean; |
52 var TeamsGameOver: boolean; |
53 NextClan: boolean; |
53 NextClan: boolean; |
54 |
54 |
55 function CheckForWin: boolean; |
55 function CheckForWin: boolean; |
56 var AliveClan: PClan; |
56 var AliveClan: PClan; |
57 s, ts, cap: ansistring; |
57 s, cap: ansistring; |
|
58 ts: array[0..(cMaxTeams - 1)] of ansistring; |
58 t, AliveCount, i, j: LongInt; |
59 t, AliveCount, i, j: LongInt; |
59 begin |
60 begin |
60 CheckForWin:= false; |
61 CheckForWin:= false; |
61 AliveCount:= 0; |
62 AliveCount:= 0; |
62 for t:= 0 to Pred(ClansCount) do |
63 for t:= 0 to Pred(ClansCount) do |
88 end |
89 end |
89 else // win |
90 else // win |
90 begin |
91 begin |
91 with AliveClan^ do |
92 with AliveClan^ do |
92 begin |
93 begin |
93 ts:= ansistring(Teams[0]^.TeamName); |
94 if TeamsNumber = 1 then // single team wins |
94 if TeamsNumber = 1 then // team wins |
|
95 begin |
95 begin |
96 s:= FormatA(trmsg[sidWinner], ts); |
96 s:= ansistring(Teams[0]^.TeamName); |
97 cap:= FormatA(GetEventString(eidRoundWin), ts); |
97 // Victory caption is randomly selected |
|
98 cap:= FormatA(GetEventString(eidRoundWin), s); |
98 AddCaption(cap, cWhiteColor, capgrpGameState); |
99 AddCaption(cap, cWhiteColor, capgrpGameState); |
|
100 s:= FormatA(trmsg[sidWinner], s); |
99 end |
101 end |
100 else // clan wins |
102 else // clan with at least 2 teams wins |
101 begin |
103 begin |
102 s:= ''; |
104 s:= ''; |
103 for j:= 0 to Pred(TeamsNumber) do |
105 for j:= 0 to Pred(TeamsNumber) do |
104 begin |
106 begin |
105 (* |
107 ts[j] := Teams[j]^.TeamName; |
106 Currently, the game result string is just the victory |
|
107 string concatenated multiple times. This assumes that |
|
108 sidWinner is a complete sentence. |
|
109 This might not work well for some languages. |
|
110 |
|
111 FIXME/TODO: Add event strings for 2, 3, 4 and >4 teams winning. |
|
112 This requires FormatA to work with multiple parameters. *) |
|
113 ts:= Teams[j]^.TeamName; |
|
114 s:= s + ' ' + FormatA(trmsg[sidWinner], ts); |
|
115 |
|
116 // FIXME: Show victory captions one-by-one, not all at once |
|
117 cap:= FormatA(GetEventString(eidRoundWin), ts); |
|
118 AddCaption(cap, cWhiteColor, capgrpGameState); |
|
119 end; |
108 end; |
|
109 |
|
110 // Write victory message for caption and stats page |
|
111 if (TeamsNumber = cMaxTeams) or (TeamsCount = TeamsNumber) then |
|
112 // No enemies for some reason … Everyone wins!!1! |
|
113 s:= trmsg[sidWinnerAll] |
|
114 else if (TeamsNumber >= 2) and (TeamsNumber < cMaxTeams) then |
|
115 // List all winning teams in a list |
|
116 s:= FormatA(trmsg[TMsgStrId(Ord(sidWinner2) + (TeamsNumber - 2))], ts); |
|
117 |
|
118 // The winner caption is the same as the stats message and not randomized |
|
119 cap:= s; |
|
120 AddCaption(cap, cWhiteColor, capgrpGameState); |
|
121 // TODO (maybe): Show victory animation/captions per-team instead of all winners at once? |
120 end; |
122 end; |
121 |
123 |
122 for j:= 0 to Pred(TeamsNumber) do |
124 for j:= 0 to Pred(TeamsNumber) do |
123 with Teams[j]^ do |
125 with Teams[j]^ do |
124 for i:= 0 to cMaxHHIndex do |
126 for i:= 0 to cMaxHHIndex do |
189 end; |
191 end; |
190 |
192 |
191 c:= CurrentTeam^.Clan^.ClanIndex; |
193 c:= CurrentTeam^.Clan^.ClanIndex; |
192 repeat |
194 repeat |
193 with ClansArray[c]^ do |
195 with ClansArray[c]^ do |
194 if (CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0) then |
196 if (GameFlags and gfTagTeam) <> 0 then |
195 begin |
197 begin |
196 TagTeamIndex:= Pred(TagTeamIndex) mod TeamsNumber; |
198 if (CurrTeam = TagTeamIndex) then |
197 CurrTeam:= Pred(CurrTeam) mod TeamsNumber; |
199 begin |
198 inc(c); |
200 if (c = 0) and (not PlacingHogs) then |
199 NextClan:= true; |
201 inc(TotalRounds); |
200 end; |
202 TagTeamIndex:= Pred(TagTeamIndex) mod TeamsNumber; |
|
203 CurrTeam:= Pred(CurrTeam) mod TeamsNumber; |
|
204 inc(c); |
|
205 NextClan:= true; |
|
206 end; |
|
207 end |
|
208 else if (c = 0) and (not PlacingHogs) then |
|
209 inc(TotalRounds); |
201 |
210 |
202 if (GameFlags and gfTagTeam) = 0 then |
211 if (GameFlags and gfTagTeam) = 0 then |
203 inc(c); |
212 inc(c); |
204 |
213 |
205 if c = ClansCount then |
214 if c = ClansCount then |
206 begin |
215 c:= 0; |
207 if not PlacingHogs then |
|
208 inc(TotalRounds); |
|
209 c:= 0 |
|
210 end; |
|
211 |
216 |
212 with ClansArray[c]^ do |
217 with ClansArray[c]^ do |
213 begin |
218 begin |
214 PrevTeam:= CurrTeam; |
219 PrevTeam:= CurrTeam; |
215 repeat |
220 repeat |
325 ApplyAmmoChanges(CurrentHedgehog^); |
331 ApplyAmmoChanges(CurrentHedgehog^); |
326 |
332 |
327 if (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then |
333 if (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then |
328 SetBinds(CurrentTeam^.Binds); |
334 SetBinds(CurrentTeam^.Binds); |
329 |
335 |
330 bShowFinger:= true; |
|
331 |
|
332 if PlacingHogs then |
336 if PlacingHogs then |
333 begin |
337 begin |
334 if CurrentHedgehog^.Unplaced then |
338 if CurrentHedgehog^.Unplaced then |
335 TurnTimeLeft:= 15000 |
339 TurnTimeLeft:= 15000 |
336 else TurnTimeLeft:= 0 |
340 else TurnTimeLeft:= 0 |
337 end |
341 end |
338 else if ((GameFlags and gfTagTeam) <> 0) and (not NextClan) then |
|
339 begin |
|
340 if TagTurnTimeLeft <> 0 then |
|
341 TurnTimeLeft:= TagTurnTimeLeft; |
|
342 TagTurnTimeLeft:= 0; |
|
343 end |
|
344 else |
342 else |
345 begin |
343 begin |
346 TurnTimeLeft:= cHedgehogTurnTime; |
344 if ((GameFlags and gfTagTeam) <> 0) and (not NextClan) then |
347 TagTurnTimeLeft:= 0; |
345 begin |
348 NextClan:= false; |
346 if TagTurnTimeLeft <> 0 then |
|
347 TurnTimeLeft:= TagTurnTimeLeft; |
|
348 TagTurnTimeLeft:= 0; |
|
349 end |
|
350 else |
|
351 begin |
|
352 TurnTimeLeft:= cHedgehogTurnTime; |
|
353 TagTurnTimeLeft:= 0; |
|
354 NextClan:= false; |
|
355 end; |
|
356 |
|
357 if (GameFlags and gfSwitchHog) <> 0 then |
|
358 begin |
|
359 g:= AddGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), gtSwitcher, 0, _0, _0, 0); |
|
360 CurAmmoGear:= g; |
|
361 lastGearByUID:= g; |
|
362 end |
|
363 else |
|
364 bShowFinger:= true; |
349 end; |
365 end; |
350 IsGetAwayTime:= false; |
366 IsGetAwayTime:= false; |
351 |
367 |
352 if (TurnTimeLeft > 0) and (CurrentHedgehog^.BotLevel = 0) then |
368 if (TurnTimeLeft > 0) and (CurrentHedgehog^.BotLevel = 0) then |
353 begin |
369 begin |
379 end; |
395 end; |
380 end; |
396 end; |
381 |
397 |
382 function AddTeam(TeamColor: Longword): PTeam; |
398 function AddTeam(TeamColor: Longword): PTeam; |
383 var team: PTeam; |
399 var team: PTeam; |
384 c, t: LongInt; |
400 c: LongInt; |
385 begin |
401 begin |
386 if checkFails(TeamsCount < cMaxTeams, 'Too many teams', true) then exit(nil); |
402 if checkFails(TeamsCount < cMaxTeams, 'Too many teams', true) then exit(nil); |
387 New(team); |
403 New(team); |
388 if checkFails(team <> nil, 'AddTeam: team = nil', true) then exit(nil); |
404 if checkFails(team <> nil, 'AddTeam: team = nil', true) then exit(nil); |
389 FillChar(team^, sizeof(TTeam), 0); |
405 FillChar(team^, sizeof(TTeam), 0); |
391 team^.CurrHedgehog:= 0; |
407 team^.CurrHedgehog:= 0; |
392 team^.Flag:= 'hedgewars'; |
408 team^.Flag:= 'hedgewars'; |
393 |
409 |
394 TeamsArray[TeamsCount]:= team; |
410 TeamsArray[TeamsCount]:= team; |
395 inc(TeamsCount); |
411 inc(TeamsCount); |
396 |
412 inc(VisibleTeamsCount); |
397 for t:= 0 to cKbdMaxIndex do |
413 |
398 team^.Binds[t]:= DefaultBinds[t]; |
414 team^.Binds:= DefaultBinds; |
399 |
415 |
400 c:= Pred(ClansCount); |
416 c:= Pred(ClansCount); |
401 while (c >= 0) and (ClansArray[c]^.Color <> TeamColor) do dec(c); |
417 while (c >= 0) and (ClansArray[c]^.Color <> TeamColor) do dec(c); |
402 if c < 0 then |
418 if c < 0 then |
403 begin |
419 begin |
533 HH^.GearHidden:= nil; |
549 HH^.GearHidden:= nil; |
534 InsertGearToList(HH^.Gear); |
550 InsertGearToList(HH^.Gear); |
535 HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked; |
551 HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked; |
536 AddCI(HH^.Gear); |
552 AddCI(HH^.Gear); |
537 HH^.Gear^.Active:= true; |
553 HH^.Gear^.Active:= true; |
538 ScriptCall('onHogRestore', HH^.Gear^.Uid) |
554 ScriptCall('onHogRestore', HH^.Gear^.Uid); |
|
555 AddVisualGear(0, 0, vgtTeamHealthSorter); |
539 end; |
556 end; |
540 |
557 |
541 procedure RestoreTeamsFromSave; |
558 procedure RestoreTeamsFromSave; |
542 var t: LongInt; |
559 var t: LongInt; |
543 begin |
560 begin |
697 for i:= 0 to Pred(TeamsCount) do |
714 for i:= 0 to Pred(TeamsCount) do |
698 with TeamsArray[i]^ do |
715 with TeamsArray[i]^ do |
699 begin |
716 begin |
700 if (not hasGone) and isGoneFlagPendingToBeSet then |
717 if (not hasGone) and isGoneFlagPendingToBeSet then |
701 begin |
718 begin |
702 AddChatString(#7 + '* '+ TeamName + ' is gone'); // TODO: localize |
719 AddChatString(#7 + '* '+ FormatA(trmsg[sidTeamGone], TeamName)); |
703 if not CurrentTeam^.ExtDriven then SendIPC(_S'f' + s); |
720 if not CurrentTeam^.ExtDriven then SendIPC(_S'f' + s); |
704 hasGone:= true; |
721 hasGone:= true; |
705 skippedTurns:= 0; |
722 skippedTurns:= 0; |
706 isGoneFlagPendingToBeSet:= false; |
723 isGoneFlagPendingToBeSet:= false; |
707 RecountTeamHealth(TeamsArray[i]) |
724 RecountTeamHealth(TeamsArray[i]) |
886 begin |
903 begin |
887 FreeAndNilTexture(NameTagTex); |
904 FreeAndNilTexture(NameTagTex); |
888 FreeAndNilTexture(OwnerTex); |
905 FreeAndNilTexture(OwnerTex); |
889 FreeAndNilTexture(GraveTex); |
906 FreeAndNilTexture(GraveTex); |
890 FreeAndNilTexture(AIKillsTex); |
907 FreeAndNilTexture(AIKillsTex); |
|
908 FreeAndNilTexture(LuaTeamValueTex); |
891 FreeAndNilTexture(FlagTex); |
909 FreeAndNilTexture(FlagTex); |
892 end; |
910 end; |
893 |
911 |
894 Dispose(TeamsArray[i]) |
912 Dispose(TeamsArray[i]) |
895 end; |
913 end; |