hedgewars/uTeams.pas
changeset 2948 3f21a9dc93d0
parent 2905 f3c79f7193a9
child 3023 a5d0549aebee
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    20 
    20 
    21 unit uTeams;
    21 unit uTeams;
    22 interface
    22 interface
    23 uses SDLh, uConsts, uKeys, uGears, uRandom, uFloat, uStats, uVisualGears, uCollisions, uLand,
    23 uses SDLh, uConsts, uKeys, uGears, uRandom, uFloat, uStats, uVisualGears, uCollisions, uLand,
    24 {$IFDEF GLES11}
    24 {$IFDEF GLES11}
    25 	gles11,
    25     gles11,
    26 {$ELSE}
    26 {$ELSE}
    27 	GL,
    27     GL,
    28 {$ENDIF}
    28 {$ENDIF}
    29 	uSound;
    29     uSound;
    30 
    30 
    31 type PHHAmmo = ^THHAmmo;
    31 type PHHAmmo = ^THHAmmo;
    32 	THHAmmo = array[0..cMaxSlotIndex, 0..cMaxSlotAmmoIndex] of TAmmo;
    32     THHAmmo = array[0..cMaxSlotIndex, 0..cMaxSlotAmmoIndex] of TAmmo;
    33 
    33 
    34 	PHedgehog = ^THedgehog;
    34     PHedgehog = ^THedgehog;
    35 	PTeam     = ^TTeam;
    35     PTeam     = ^TTeam;
    36 	PClan     = ^TClan;
    36     PClan     = ^TClan;
    37 
    37 
    38 	THedgehog = record
    38     THedgehog = record
    39 			Name: string[MAXNAMELEN];
    39             Name: string[MAXNAMELEN];
    40 			Gear: PGear;
    40             Gear: PGear;
    41 			SpeechGear: PVisualGear;
    41             SpeechGear: PVisualGear;
    42 			NameTagTex,
    42             NameTagTex,
    43 			HealthTagTex,
    43             HealthTagTex,
    44 			HatTex: PTexture;
    44             HatTex: PTexture;
    45 			Ammo: PHHAmmo;
    45             Ammo: PHHAmmo;
    46 			AmmoStore: Longword;
    46             AmmoStore: Longword;
    47 			CurSlot, CurAmmo: LongWord;
    47             CurSlot, CurAmmo: LongWord;
    48 			Team: PTeam;
    48             Team: PTeam;
    49 			MultiShootAttacks: Longword;
    49             MultiShootAttacks: Longword;
    50 			visStepPos: LongWord;
    50             visStepPos: LongWord;
    51 			BotLevel  : LongWord; // 0 - Human player
    51             BotLevel  : LongWord; // 0 - Human player
    52 			HatVisibility: GLfloat;
    52             HatVisibility: GLfloat;
    53 			stats: TStatistics;
    53             stats: TStatistics;
    54 			Hat: shortstring;
    54             Hat: shortstring;
    55             King: boolean;  // Flag for a bunch of hedgehog attributes
    55             King: boolean;  // Flag for a bunch of hedgehog attributes
    56             Unplaced: boolean;  // Flag for hog placing mode
    56             Unplaced: boolean;  // Flag for hog placing mode
    57 			end;
    57             end;
    58 
    58 
    59 	TTeam = record
    59     TTeam = record
    60 			Clan: PClan;
    60             Clan: PClan;
    61 			TeamName: string[MAXNAMELEN];
    61             TeamName: string[MAXNAMELEN];
    62 			ExtDriven: boolean;
    62             ExtDriven: boolean;
    63 			Binds: TBinds;
    63             Binds: TBinds;
    64 			Hedgehogs: array[0..cMaxHHIndex] of THedgehog;
    64             Hedgehogs: array[0..cMaxHHIndex] of THedgehog;
    65 			CurrHedgehog: LongWord;
    65             CurrHedgehog: LongWord;
    66 			NameTagTex: PTexture;
    66             NameTagTex: PTexture;
    67 			CrosshairTex,
    67             CrosshairTex,
    68 			GraveTex,
    68             GraveTex,
    69 			HealthTex,
    69             HealthTex,
    70 			FlagTex: PTexture;
    70             FlagTex: PTexture;
    71 			Flag: shortstring;
    71             Flag: shortstring;
    72 			GraveName: shortstring;
    72             GraveName: shortstring;
    73 			FortName: shortstring;
    73             FortName: shortstring;
    74 			TeamHealth: LongInt;
    74             TeamHealth: LongInt;
    75 			TeamHealthBarWidth,
    75             TeamHealthBarWidth,
    76 			NewTeamHealthBarWidth: LongInt;
    76             NewTeamHealthBarWidth: LongInt;
    77 			DrawHealthY: LongInt;
    77             DrawHealthY: LongInt;
    78 			AttackBar: LongWord;
    78             AttackBar: LongWord;
    79 			HedgehogsNumber: Longword;
    79             HedgehogsNumber: Longword;
    80 			hasGone: boolean;
    80             hasGone: boolean;
    81 			voicepack: PVoicepack;
    81             voicepack: PVoicepack;
    82             PlayerHash: shortstring;   // md5 hash of player name. For temporary enabling of hats as thank you. Hashed for privacy of players
    82             PlayerHash: shortstring;   // md5 hash of player name. For temporary enabling of hats as thank you. Hashed for privacy of players
    83 			end;
    83             end;
    84 
    84 
    85 	TClan = record
    85     TClan = record
    86 			Color: Longword;
    86             Color: Longword;
    87 			Teams: array[0..Pred(cMaxTeams)] of PTeam;
    87             Teams: array[0..Pred(cMaxTeams)] of PTeam;
    88 			TeamsNumber: Longword;
    88             TeamsNumber: Longword;
    89 			CurrTeam: LongWord;
    89             CurrTeam: LongWord;
    90 			ClanHealth: LongInt;
    90             ClanHealth: LongInt;
    91 			ClanIndex: LongInt;
    91             ClanIndex: LongInt;
    92 			TurnNumber: LongWord;
    92             TurnNumber: LongWord;
    93 			end;
    93             end;
    94 
    94 
    95 var CurrentTeam: PTeam;
    95 var CurrentTeam: PTeam;
    96     PreviousTeam: PTeam;
    96     PreviousTeam: PTeam;
    97     CurrentHedgehog: PHedgehog;
    97     CurrentHedgehog: PHedgehog;
    98     TeamsArray: array[0..Pred(cMaxTeams)] of PTeam;
    98     TeamsArray: array[0..Pred(cMaxTeams)] of PTeam;
   125     s: shortstring;
   125     s: shortstring;
   126     t, AliveCount, i, j: LongInt;
   126     t, AliveCount, i, j: LongInt;
   127 begin
   127 begin
   128 AliveCount:= 0;
   128 AliveCount:= 0;
   129 for t:= 0 to Pred(ClansCount) do
   129 for t:= 0 to Pred(ClansCount) do
   130 	if ClansArray[t]^.ClanHealth > 0 then
   130     if ClansArray[t]^.ClanHealth > 0 then
   131 		begin
   131         begin
   132 		inc(AliveCount);
   132         inc(AliveCount);
   133 		AliveClan:= ClansArray[t]
   133         AliveClan:= ClansArray[t]
   134 		end;
   134         end;
   135 
   135 
   136 if (AliveCount > 1)
   136 if (AliveCount > 1)
   137 or ((AliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then exit(false);
   137 or ((AliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then exit(false);
   138 CheckForWin:= true;
   138 CheckForWin:= true;
   139 
   139 
   140 TurnTimeLeft:= 0;
   140 TurnTimeLeft:= 0;
   141 if AliveCount = 0 then
   141 if AliveCount = 0 then
   142 	begin // draw
   142     begin // draw
   143 	AddCaption(trmsg[sidDraw], cWhiteColor, capgrpGameState);
   143     AddCaption(trmsg[sidDraw], cWhiteColor, capgrpGameState);
   144 	SendStat(siGameResult, trmsg[sidDraw]);
   144     SendStat(siGameResult, trmsg[sidDraw]);
   145 	AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
   145     AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
   146 	end else // win
   146     end else // win
   147 	with AliveClan^ do
   147     with AliveClan^ do
   148 		begin
   148         begin
   149 		if TeamsNumber = 1 then
   149         if TeamsNumber = 1 then
   150 			s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName)  // team wins
   150             s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName)  // team wins
   151 		else
   151         else
   152 			s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName); // clan wins
   152             s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName); // clan wins
   153 
   153 
   154 		for j:= 0 to Pred(TeamsNumber) do
   154         for j:= 0 to Pred(TeamsNumber) do
   155 			with Teams[j]^ do
   155             with Teams[j]^ do
   156 				for i:= 0 to cMaxHHIndex do
   156                 for i:= 0 to cMaxHHIndex do
   157 					with Hedgehogs[i] do
   157                     with Hedgehogs[i] do
   158 						if (Gear <> nil) then
   158                         if (Gear <> nil) then
   159 							Gear^.State:= gstWinner;
   159                             Gear^.State:= gstWinner;
   160 
   160 
   161 		AddCaption(s, cWhiteColor, capgrpGameState);
   161         AddCaption(s, cWhiteColor, capgrpGameState);
   162 		SendStat(siGameResult, s);
   162         SendStat(siGameResult, s);
   163 		AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
   163         AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
   164 		end;
   164         end;
   165 SendStats
   165 SendStats
   166 end;
   166 end;
   167 
   167 
   168 procedure SwitchHedgehog;
   168 procedure SwitchHedgehog;
   169 var c: LongWord;
   169 var c: LongWord;
   173 TryDo(CurrentTeam <> nil, 'nil Team', true);
   173 TryDo(CurrentTeam <> nil, 'nil Team', true);
   174 with CurrentHedgehog^ do
   174 with CurrentHedgehog^ do
   175     if (PreviousTeam <> nil) and PlacingHogs and Unplaced then
   175     if (PreviousTeam <> nil) and PlacingHogs and Unplaced then
   176         begin
   176         begin
   177         Unplaced:= false;
   177         Unplaced:= false;
   178 	    if Gear <> nil then 
   178         if Gear <> nil then 
   179            begin
   179            begin
   180            DeleteCI(Gear);
   180            DeleteCI(Gear);
   181            FindPlace(Gear, false, 0, LAND_WIDTH);
   181            FindPlace(Gear, false, 0, LAND_WIDTH);
   182            if Gear <> nil then AddGearCI(Gear)
   182            if Gear <> nil then AddGearCI(Gear)
   183            end
   183            end
   184 		end;
   184         end;
   185 
   185 
   186 PreviousTeam:= CurrentTeam;
   186 PreviousTeam:= CurrentTeam;
   187 
   187 
   188 with CurrentHedgehog^ do
   188 with CurrentHedgehog^ do
   189     begin
   189     begin
   190 	if Gear <> nil then
   190     if Gear <> nil then
   191 		begin
   191         begin
   192 		MultiShootAttacks:= 0;
   192         MultiShootAttacks:= 0;
   193 		Gear^.Message:= 0;
   193         Gear^.Message:= 0;
   194 		Gear^.Z:= cHHZ;
   194         Gear^.Z:= cHHZ;
   195 		RemoveGearFromList(Gear);
   195         RemoveGearFromList(Gear);
   196 		InsertGearToList(Gear)
   196         InsertGearToList(Gear)
   197 		end
   197         end
   198     end;
   198     end;
   199 
   199 
   200 c:= CurrentTeam^.Clan^.ClanIndex;
   200 c:= CurrentTeam^.Clan^.ClanIndex;
   201 repeat
   201 repeat
   202 	inc(c);
   202     inc(c);
   203 	if c = ClansCount then
   203     if c = ClansCount then
   204 		begin
   204         begin
   205         if not PlacingHogs then inc(TotalRounds);
   205         if not PlacingHogs then inc(TotalRounds);
   206 		c:= 0
   206         c:= 0
   207 		end;
   207         end;
   208 
   208 
   209 	with ClansArray[c]^ do
   209     with ClansArray[c]^ do
   210 		begin
   210         begin
   211 		PrevTeam:= CurrTeam;
   211         PrevTeam:= CurrTeam;
   212 		repeat
   212         repeat
   213 			CurrTeam:= Succ(CurrTeam) mod TeamsNumber;
   213             CurrTeam:= Succ(CurrTeam) mod TeamsNumber;
   214 			CurrentTeam:= Teams[CurrTeam];
   214             CurrentTeam:= Teams[CurrTeam];
   215 			with CurrentTeam^ do
   215             with CurrentTeam^ do
   216 				begin
   216                 begin
   217 				PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
   217                 PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
   218 				repeat
   218                 repeat
   219 					CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
   219                     CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
   220 				until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
   220                 until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
   221 				end
   221                 end
   222 		until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam);
   222         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam);
   223 		end
   223         end
   224 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
   224 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
   225 
   225 
   226 CurrentHedgehog:= @(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog])
   226 CurrentHedgehog:= @(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog])
   227 end;
   227 end;
   228 
   228 
   249 inc(CurrentTeam^.Clan^.TurnNumber);
   249 inc(CurrentTeam^.Clan^.TurnNumber);
   250 
   250 
   251 SwitchNotHeldAmmo(CurrentHedgehog^);
   251 SwitchNotHeldAmmo(CurrentHedgehog^);
   252 
   252 
   253 with CurrentHedgehog^ do
   253 with CurrentHedgehog^ do
   254 	begin
   254     begin
   255 	with Gear^ do
   255     with Gear^ do
   256 		begin
   256         begin
   257 		Z:= cCurrHHZ;
   257         Z:= cCurrHHZ;
   258 		State:= gstHHDriven;
   258         State:= gstHHDriven;
   259 		Active:= true
   259         Active:= true
   260 		end;
   260         end;
   261 	RemoveGearFromList(Gear);
   261     RemoveGearFromList(Gear);
   262 	InsertGearToList(Gear);
   262     InsertGearToList(Gear);
   263 	FollowGear:= Gear
   263     FollowGear:= Gear
   264 	end;
   264     end;
   265 
   265 
   266 ResetKbd;
   266 ResetKbd;
   267 
   267 
   268 cWindSpeed:= rndSign(GetRandom * cMaxWindSpeed);
   268 cWindSpeed:= rndSign(GetRandom * cMaxWindSpeed);
   269 g:= AddGear(0, 0, gtATSmoothWindCh, 0, _0, _0, 1);
   269 g:= AddGear(0, 0, gtATSmoothWindCh, 0, _0, _0, 1);
   276 {$ENDIF}
   276 {$ENDIF}
   277 
   277 
   278 bShowFinger:= true;
   278 bShowFinger:= true;
   279 
   279 
   280 if (CurrentTeam^.ExtDriven or (CurrentHedgehog^.BotLevel > 0)) then
   280 if (CurrentTeam^.ExtDriven or (CurrentHedgehog^.BotLevel > 0)) then
   281 	PlaySound(sndIllGetYou, CurrentTeam^.voicepack)
   281     PlaySound(sndIllGetYou, CurrentTeam^.voicepack)
   282 else
   282 else
   283 	PlaySound(sndYesSir, CurrentTeam^.voicepack);
   283     PlaySound(sndYesSir, CurrentTeam^.voicepack);
   284 
   284 
   285 if PlacingHogs then
   285 if PlacingHogs then
   286    begin
   286    begin
   287    if CurrentHedgehog^.Unplaced then TurnTimeLeft:= 1000 * (MaxHedgehogs div 4) + 1000
   287    if CurrentHedgehog^.Unplaced then TurnTimeLeft:= 1000 * (MaxHedgehogs div 4) + 1000
   288    else TurnTimeLeft:= 0
   288    else TurnTimeLeft:= 0
   400 
   400 
   401 procedure RecountTeamHealth(team: PTeam);
   401 procedure RecountTeamHealth(team: PTeam);
   402 var i: LongInt;
   402 var i: LongInt;
   403 begin
   403 begin
   404 with team^ do
   404 with team^ do
   405 	begin
   405     begin
   406 	NewTeamHealthBarWidth:= 0;
   406     NewTeamHealthBarWidth:= 0;
   407 
   407 
   408 	if not hasGone then
   408     if not hasGone then
   409 		for i:= 0 to cMaxHHIndex do
   409         for i:= 0 to cMaxHHIndex do
   410 			if Hedgehogs[i].Gear <> nil then
   410             if Hedgehogs[i].Gear <> nil then
   411 				inc(NewTeamHealthBarWidth, Hedgehogs[i].Gear^.Health);
   411                 inc(NewTeamHealthBarWidth, Hedgehogs[i].Gear^.Health);
   412 
   412 
   413 	TeamHealth:= NewTeamHealthBarWidth;
   413     TeamHealth:= NewTeamHealthBarWidth;
   414 	if NewTeamHealthBarWidth > MaxTeamHealth then
   414     if NewTeamHealthBarWidth > MaxTeamHealth then
   415 		begin
   415         begin
   416 		MaxTeamHealth:= NewTeamHealthBarWidth;
   416         MaxTeamHealth:= NewTeamHealthBarWidth;
   417 		RecountAllTeamsHealth;
   417         RecountAllTeamsHealth;
   418 		end else NewTeamHealthBarWidth:= (NewTeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth
   418         end else NewTeamHealthBarWidth:= (NewTeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth
   419 	end;
   419     end;
   420 
   420 
   421 RecountClanHealth(team^.Clan);
   421 RecountClanHealth(team^.Clan);
   422 
   422 
   423 AddVisualGear(0, 0, vgtTeamHealthSorter)
   423 AddVisualGear(0, 0, vgtTeamHealthSorter)
   424 end;
   424 end;
   433 procedure TeamGone(s: shortstring);
   433 procedure TeamGone(s: shortstring);
   434 var t: LongInt;
   434 var t: LongInt;
   435 begin
   435 begin
   436 t:= 0;
   436 t:= 0;
   437 while (t < cMaxTeams)
   437 while (t < cMaxTeams)
   438 	and (TeamsArray[t] <> nil)
   438     and (TeamsArray[t] <> nil)
   439 	and (TeamsArray[t]^.TeamName <> s) do inc(t);
   439     and (TeamsArray[t]^.TeamName <> s) do inc(t);
   440 if (t = cMaxTeams) or (TeamsArray[t] = nil) then exit;
   440 if (t = cMaxTeams) or (TeamsArray[t] = nil) then exit;
   441 
   441 
   442 with TeamsArray[t]^ do
   442 with TeamsArray[t]^ do
   443 	begin
   443     begin
   444 	AddChatString('** '+ TeamName + ' is gone');
   444     AddChatString('** '+ TeamName + ' is gone');
   445 	hasGone:= true
   445     hasGone:= true
   446 	end;
   446     end;
   447 
   447 
   448 RecountTeamHealth(TeamsArray[t])
   448 RecountTeamHealth(TeamsArray[t])
   449 end;
   449 end;
   450 
   450 
   451 procedure TeamGoneEffect(var Team: TTeam);
   451 procedure TeamGoneEffect(var Team: TTeam);
   452 var i: LongInt;
   452 var i: LongInt;
   453 begin
   453 begin
   454 with Team do
   454 with Team do
   455 	for i:= 0 to cMaxHHIndex do
   455     for i:= 0 to cMaxHHIndex do
   456 		with Hedgehogs[i] do
   456         with Hedgehogs[i] do
   457 			if Gear <> nil then
   457             if Gear <> nil then
   458                 begin
   458                 begin
   459                 Gear^.Invulnerable:= false;
   459                 Gear^.Invulnerable:= false;
   460 				Gear^.Damage:= Gear^.Health
   460                 Gear^.Damage:= Gear^.Health
   461                 end
   461                 end
   462 end;
   462 end;
   463 
   463 
   464 procedure init_uTeams;
   464 procedure init_uTeams;
   465 begin
   465 begin
   466 	CurrentTeam:= nil;
   466     CurrentTeam:= nil;
   467 	PreviousTeam:= nil;
   467     PreviousTeam:= nil;
   468 	CurrentHedgehog:= nil;
   468     CurrentHedgehog:= nil;
   469 	TeamsCount:= 0;
   469     TeamsCount:= 0;
   470 	ClansCount:= 0;
   470     ClansCount:= 0;
   471 	LocalClan:= -1;
   471     LocalClan:= -1;
   472 	LocalAmmo:= -1;
   472     LocalAmmo:= -1;
   473 end;
   473 end;
   474 
   474 
   475 procedure free_uTeams;
   475 procedure free_uTeams;
   476 var i: LongWord;
   476 var i: LongWord;
   477 begin
   477 begin