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); |
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 |