--- 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 <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
*
* 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;