diff -r 31570b766315 -r ed5a6478e710 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Tue Nov 10 18:16:35 2015 +0100 +++ b/hedgewars/uTeams.pas Tue Nov 10 20:43:13 2015 +0100 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2013 Andrey Korotaev + * Copyright (c) 2004-2015 Andrey Korotaev * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,14 +13,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *) {$INCLUDE "options.inc"} unit uTeams; interface -uses uConsts, uInputHandler, uRandom, uFloat, uStats, +uses uConsts, uInputHandler, uRandom, uFloat, uStats, uCollisions, uSound, uStore, uTypes, uScript {$IFDEF USE_TOUCH_INTERFACE}, uWorld{$ENDIF}; @@ -34,6 +34,7 @@ procedure InitTeams; function TeamSize(p: PTeam): Longword; procedure RecountTeamHealth(team: PTeam); +procedure RecountAllTeamsHealth(); procedure RestoreHog(HH: PHedgehog); procedure RestoreTeamsFromSave; @@ -53,7 +54,7 @@ function CheckForWin: boolean; var AliveClan: PClan; - s: shortstring; + s, ts: ansistring; t, AliveCount, i, j: LongInt; begin CheckForWin:= false; @@ -81,16 +82,17 @@ if AliveCount = 0 then begin // draw AddCaption(trmsg[sidDraw], cWhiteColor, capgrpGameState); - SendStat(siGameResult, trmsg[sidDraw]); + SendStat(siGameResult, shortstring(trmsg[sidDraw])); AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000) end else // win with AliveClan^ do begin + ts:= ansistring(Teams[0]^.TeamName); if TeamsNumber = 1 then - s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName) // team wins + s:= FormatA(trmsg[sidWinner], ts) // team wins else - s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName); // clan wins + s:= FormatA(trmsg[sidWinner], ts); // clan wins for j:= 0 to Pred(TeamsNumber) do with Teams[j]^ do @@ -104,7 +106,7 @@ AddVoice(sndVictory, Teams[0]^.voicepack); AddCaption(s, cWhiteColor, capgrpGameState); - SendStat(siGameResult, s); + SendStat(siGameResult, shortstring(s)); AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000) end; SendStats; @@ -155,7 +157,7 @@ if c > cMaxHHIndex then c:= 0 end - until (c = CurrHedgehog) or (Hedgehogs[c].Gear <> nil); + until (c = CurrHedgehog) or (Hedgehogs[c].Gear <> nil) and (Hedgehogs[c].Effects[heFrozen] < 50255); LocalAmmo:= Hedgehogs[c].AmmoStore end; @@ -237,7 +239,7 @@ CurWeapon: PAmmo; w: real; vg: PVisualGear; - + s: ansistring; begin if PlacingHogs then begin @@ -334,7 +336,8 @@ end; if cHedgehogTurnTime < 1000000 then ReadyTimeLeft:= cReadyDelay; - AddCaption(Format(shortstring(trmsg[sidReady]), CurrentTeam^.TeamName), cWhiteColor, capgrpGameState) + s:= ansistring(CurrentTeam^.TeamName); + AddCaption(FormatA(trmsg[sidReady], s), cWhiteColor, capgrpGameState) end else begin @@ -514,20 +517,31 @@ procedure TeamGoneEffect(var Team: TTeam); var i: LongInt; begin -with Team do - for i:= 0 to cMaxHHIndex do - with Hedgehogs[i] do + with Team do + if skippedTurns < 3 then begin - if Hedgehogs[i].GearHidden <> nil then - RestoreHog(@Hedgehogs[i]); + inc(skippedTurns); + for i:= 0 to cMaxHHIndex do + with Hedgehogs[i] do + if Gear <> nil then + Gear^.State:= Gear^.State and (not gstHHDriven); - if Gear <> nil then - begin - Gear^.Hedgehog^.Effects[heInvulnerable]:= 0; - Gear^.Damage:= Gear^.Health; - Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven) - end + ParseCommand('/skip', true); end + else + for i:= 0 to cMaxHHIndex do + with Hedgehogs[i] do + begin + if Hedgehogs[i].GearHidden <> nil then + RestoreHog(@Hedgehogs[i]); + + if Gear <> nil then + begin + Gear^.Hedgehog^.Effects[heInvulnerable]:= 0; + Gear^.Damage:= Gear^.Health; + Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven) + end + end end; procedure chAddHH(var id: shortstring); @@ -535,10 +549,12 @@ Gear: PGear; begin s:= ''; -if (not isDeveloperMode) or (CurrentTeam = nil) then +if (not isDeveloperMode) then exit; +TryDo((CurrentTeam <> nil), 'Can''t add hedgehogs yet, add a team first!', true); with CurrentTeam^ do begin + TryDo(HedgehogsNumber<=cMaxHHIndex, 'Can''t add hedgehog to "' + TeamName + '"! (already ' + intToStr(HedgehogsNumber) + ' hogs)', true); SplitBySpace(id, s); SwitchCurrentHedgehog(@Hedgehogs[HedgehogsNumber]); CurrentHedgehog^.BotLevel:= StrToInt(id); @@ -567,7 +583,10 @@ var i: LongInt; begin for i:= 1 to length(s) do - if s[i] in ['\', '/', ':'] then s[i]:= '_'; + if ((s[i] = '\') or + (s[i] = '/') or + (s[i] = ':')) then + s[i]:= '_'; s:= cPathz[ptTeams] + '/' + s + '.hwt'; @@ -585,7 +604,6 @@ SplitBySpace(s, cs); SplitBySpace(cs, ts); Color:= StrToInt(cs); - TryDo(Color <> 0, 'Error: black team color', true); // color is always little endian so the mask must be constant also in big endian archs Color:= Color or $FF000000; @@ -593,7 +611,7 @@ CurrentTeam^.TeamName:= ts; CurrentTeam^.PlayerHash:= s; loadTeamBinds(ts); - + if GameType in [gmtDemo, gmtSave, gmtRecord] then CurrentTeam^.ExtDriven:= true; @@ -624,21 +642,85 @@ end; procedure chTeamGone(var s:shortstring); -var t: LongInt; +var t, i: LongInt; + isSynced: boolean; begin -t:= 0; -while (t < cMaxTeams) and (TeamsArray[t] <> nil) and (TeamsArray[t]^.TeamName <> s) do - inc(t); -if (t = cMaxTeams) or (TeamsArray[t] = nil) then - exit; + isSynced:= s[1] = 's'; + + Delete(s, 1, 1); + + t:= 0; + while (t < TeamsCount) and (TeamsArray[t]^.TeamName <> s) do + inc(t); + if t = TeamsCount then + exit; + + TeamsArray[t]^.isGoneFlagPendingToBeSet:= true; + + if isSynced then + begin + for i:= 0 to Pred(TeamsCount) do + with TeamsArray[i]^ do + begin + if (not hasGone) and isGoneFlagPendingToBeSet then + begin + AddChatString(#7 + '* '+ TeamName + ' is gone'); // TODO: localize + if not CurrentTeam^.ExtDriven then SendIPC(_S'f' + s); + hasGone:= true; + skippedTurns:= 0; + isGoneFlagPendingToBeSet:= false; + RecountTeamHealth(TeamsArray[i]) + end; + if hasGone and isGoneFlagPendingToBeUnset then + ParseCommand('/teamback s' + s, true) + end + end + else + begin + //TeamsArray[t]^.isGoneFlagPendingToBeSet:= true; -with TeamsArray[t]^ do - if not hasGone then + if (not CurrentTeam^.ExtDriven) or (CurrentTeam^.TeamName = s) or (CurrentTeam^.hasGone) then + ParseCommand('/teamgone s' + s, true) + end; +end; + +procedure chTeamBack(var s:shortstring); +var t: LongInt; + isSynced: boolean; +begin + isSynced:= s[1] = 's'; + + Delete(s, 1, 1); + + t:= 0; + while (t < TeamsCount) and (TeamsArray[t]^.TeamName <> s) do + inc(t); + if t = TeamsCount then + exit; + + if isSynced then begin - AddChatString('** '+ TeamName + ' is gone'); - hasGone:= true; + with TeamsArray[t]^ do + if hasGone then + begin + AddChatString(#8 + '* '+ TeamName + ' is back'); + if not CurrentTeam^.ExtDriven then SendIPC(_S'g' + s); + hasGone:= false; + + RecountTeamHealth(TeamsArray[t]); - RecountTeamHealth(TeamsArray[t]) + if isGoneFlagPendingToBeUnset and (Owner = UserNick) then + ExtDriven:= false; + + isGoneFlagPendingToBeUnset:= false; + end; + end + else + begin + TeamsArray[t]^.isGoneFlagPendingToBeUnset:= true; + + if not CurrentTeam^.ExtDriven then + ParseCommand('/teamback s' + s, true); end; end; @@ -649,14 +731,16 @@ // avoid compiler hint s:= s; +isPaused:= false; + t:= 0; -while (t < cMaxTeams) and (TeamsArray[t] <> nil) do +while t < TeamsCount do begin TeamsArray[t]^.hasGone:= true; - inc(t); + inc(t) end; -AddChatString('** Good-bye!'); +AddChatString(#7 + '* Good-bye!'); RecountAllTeamsHealth(); end; @@ -672,8 +756,6 @@ if newCI then DeleteCI(newHog^.Gear); oldHH:= CurrentHedgehog; CurrentHedgehog:= newHog; - if (CurrentHedgehog <> nil) and (CurrentHedgehog^.CurAmmoType = amKnife) then - LoadHedgehogHat(CurrentHedgehog^, 'Reserved/chef'); if oldCI then AddCI(oldHH^.Gear); if newCI then AddCI(newHog^.Gear) end; @@ -742,6 +824,7 @@ RegisterVariable('hhcoords', @chSetHHCoords, false); RegisterVariable('bind', @chBind, true ); RegisterVariable('teamgone', @chTeamGone, true ); +RegisterVariable('teamback', @chTeamBack, true ); RegisterVariable('finish', @chFinish, true ); // all teams gone RegisterVariable('fort' , @chFort , false); RegisterVariable('grave' , @chGrave , false); @@ -765,6 +848,7 @@ procedure freeModule; var i, h: LongWord; begin +CurrentHedgehog:= nil; if TeamsCount > 0 then begin for i:= 0 to Pred(TeamsCount) do @@ -772,28 +856,32 @@ for h:= 0 to cMaxHHIndex do with TeamsArray[i]^.Hedgehogs[h] do begin +// if Gear <> nil then +// DeleteGearStage(Gear, true); if GearHidden <> nil then Dispose(GearHidden); +// DeleteGearStage(GearHidden, true); - FreeTexture(NameTagTex); - FreeTexture(HealthTagTex); - FreeTexture(HatTex); + FreeAndNilTexture(NameTagTex); + FreeAndNilTexture(HealthTagTex); + FreeAndNilTexture(HatTex) end; with TeamsArray[i]^ do begin - FreeTexture(NameTagTex); - FreeTexture(GraveTex); - FreeTexture(AIKillsTex); - FreeTexture(FlagTex); + FreeAndNilTexture(NameTagTex); + FreeAndNilTexture(OwnerTex); + FreeAndNilTexture(GraveTex); + FreeAndNilTexture(AIKillsTex); + FreeAndNilTexture(FlagTex); end; - Dispose(TeamsArray[i]); - end; + Dispose(TeamsArray[i]) + end; for i:= 0 to Pred(ClansCount) do begin - FreeTexture(ClansArray[i]^.HealthTex); - Dispose(ClansArray[i]); + FreeAndNilTexture(ClansArray[i]^.HealthTex); + Dispose(ClansArray[i]) end end; TeamsCount:= 0;