@@ -12,6 +12,7 @@ import {
1212 Quads ,
1313 RankedType ,
1414 Trios ,
15+ UnitType ,
1516 mapCategories ,
1617} from "../core/game/Game" ;
1718import { PseudoRandom } from "../core/PseudoRandom" ;
@@ -103,27 +104,40 @@ type ModifierKey =
103104 | "isCompact"
104105 | "isCrowded"
105106 | "isHardNations"
106- | "startingGold"
107- | "startingGoldHigh"
107+ | "startingGold1M"
108+ | "startingGold5M"
109+ | "startingGold25M"
108110 | "goldMultiplier"
109- | "isAlliancesDisabled" ;
111+ | "isAlliancesDisabled"
112+ | "isPortsDisabled"
113+ | "isNukesDisabled"
114+ | "isSAMsDisabled"
115+ | "isPeaceTime" ;
110116
111117// Each entry represents one "ticket" in the pool. More tickets = higher chance of selection.
112118const SPECIAL_MODIFIER_POOL : ModifierKey [ ] = [
113119 ...Array < ModifierKey > ( 2 ) . fill ( "isRandomSpawn" ) ,
114- ...Array < ModifierKey > ( 8 ) . fill ( "isCompact" ) ,
115- ...Array < ModifierKey > ( 1 ) . fill ( "isCrowded" ) ,
120+ ...Array < ModifierKey > ( 5 ) . fill ( "isCompact" ) ,
121+ ...Array < ModifierKey > ( 2 ) . fill ( "isCrowded" ) ,
116122 ...Array < ModifierKey > ( 1 ) . fill ( "isHardNations" ) ,
117- ...Array < ModifierKey > ( 8 ) . fill ( "startingGold" ) ,
118- ...Array < ModifierKey > ( 1 ) . fill ( "startingGoldHigh" ) ,
123+ ...Array < ModifierKey > ( 3 ) . fill ( "startingGold1M" ) ,
124+ ...Array < ModifierKey > ( 5 ) . fill ( "startingGold5M" ) ,
125+ ...Array < ModifierKey > ( 1 ) . fill ( "startingGold25M" ) ,
119126 ...Array < ModifierKey > ( 4 ) . fill ( "goldMultiplier" ) ,
120127 ...Array < ModifierKey > ( 1 ) . fill ( "isAlliancesDisabled" ) ,
128+ ...Array < ModifierKey > ( 1 ) . fill ( "isPortsDisabled" ) ,
129+ ...Array < ModifierKey > ( 1 ) . fill ( "isNukesDisabled" ) ,
130+ ...Array < ModifierKey > ( 1 ) . fill ( "isSAMsDisabled" ) ,
131+ ...Array < ModifierKey > ( 1 ) . fill ( "isPeaceTime" ) ,
121132] ;
122133
123134// Modifiers that cannot be active at the same time.
124135const MUTUALLY_EXCLUSIVE_MODIFIERS : [ ModifierKey , ModifierKey ] [ ] = [
125- [ "startingGold" , "startingGoldHigh" ] ,
126- [ "isHardNations" , "startingGoldHigh" ] ,
136+ [ "startingGold5M" , "startingGold25M" ] ,
137+ [ "startingGold5M" , "startingGold1M" ] ,
138+ [ "startingGold25M" , "startingGold1M" ] ,
139+ [ "isHardNations" , "startingGold25M" ] ,
140+ [ "isNukesDisabled" , "isSAMsDisabled" ] ,
127141] ;
128142
129143export class MapPlaylist {
@@ -144,13 +158,14 @@ export class MapPlaylist {
144158 const playerTeams =
145159 mode === GameMode . Team ? this . getTeamCount ( map ) : undefined ;
146160
147- let isCompact = this . playlists [ type ] . length % 3 === 0 ;
161+ let isCompact : boolean | undefined =
162+ this . playlists [ type ] . length % 3 === 0 || undefined ;
148163 if (
149164 isCompact &&
150165 mode === GameMode . Team &&
151166 ! ( await this . supportsCompactMapForTeams ( map , playerTeams ! ) )
152167 ) {
153- isCompact = false ;
168+ isCompact = undefined ;
154169 }
155170
156171 return {
@@ -162,10 +177,6 @@ export class MapPlaylist {
162177 gameMapSize : isCompact ? GameMapSize . Compact : GameMapSize . Normal ,
163178 publicGameModifiers : {
164179 isCompact,
165- isRandomSpawn : false ,
166- isCrowded : false ,
167- isHardNations : false ,
168- isAlliancesDisabled : false ,
169180 } ,
170181 difficulty :
171182 playerTeams === HumansVsNations ? Difficulty . Hard : Difficulty . Medium ,
@@ -216,7 +227,8 @@ export class MapPlaylist {
216227 excludedModifiers . push ( "isHardNations" ) ;
217228 }
218229 if ( playerTeams === HumansVsNations ) {
219- excludedModifiers . push ( "startingGoldHigh" ) ; // Nations are disabled if that modifier is active
230+ excludedModifiers . push ( "startingGold25M" ) ; // Nations are disabled if that modifier is active (Because of PVP immunity)
231+ excludedModifiers . push ( "isPeaceTime" ) ; // Nations don't have PVP immunity
220232 }
221233
222234 const poolResult = this . getRandomSpecialGameModifiers ( excludedModifiers ) ;
@@ -228,26 +240,34 @@ export class MapPlaylist {
228240 goldMultiplier,
229241 isAlliancesDisabled,
230242 isHardNations,
243+ isPortsDisabled,
244+ isNukesDisabled,
245+ isSAMsDisabled,
246+ isPeaceTime,
231247 } = poolResult ;
232248
233249 // Crowded modifier: if the map's biggest player count (first number of calculateMapPlayerCounts) is 60 or lower (small maps),
234250 // set player count to MAX_PLAYER_COUNT (or 60 if compact map is also enabled)
235251 let crowdedMaxPlayers : number | undefined ;
236252 if ( isCrowded ) {
237- crowdedMaxPlayers = await this . getCrowdedMaxPlayers ( map , isCompact ) ;
253+ crowdedMaxPlayers = await this . getCrowdedMaxPlayers ( map , ! ! isCompact ) ;
238254 if ( crowdedMaxPlayers !== undefined ) {
239255 crowdedMaxPlayers = this . adjustForTeams ( crowdedMaxPlayers , playerTeams ) ;
240256 } else {
241257 // Map doesn't support crowded. Drop it and pick one replacement only
242258 // if it was the sole modifier, so the lobby always has at least one.
243- isCrowded = false ;
259+ isCrowded = undefined ;
244260 if (
245261 ! isRandomSpawn &&
246262 ! isCompact &&
247263 ! isHardNations &&
248264 startingGold === undefined &&
249265 goldMultiplier === undefined &&
250- ! isAlliancesDisabled
266+ ! isAlliancesDisabled &&
267+ ! isPortsDisabled &&
268+ ! isNukesDisabled &&
269+ ! isSAMsDisabled &&
270+ ! isPeaceTime
251271 ) {
252272 excludedModifiers . push ( "isCrowded" ) ;
253273 const fallback = this . getRandomSpecialGameModifiers (
@@ -260,6 +280,10 @@ export class MapPlaylist {
260280 startingGold,
261281 goldMultiplier,
262282 isAlliancesDisabled,
283+ isPortsDisabled,
284+ isNukesDisabled,
285+ isSAMsDisabled,
286+ isPeaceTime,
263287 } = fallback ) ;
264288 ( { isHardNations } = fallback ) ;
265289 }
@@ -279,6 +303,28 @@ export class MapPlaylist {
279303 ? "disabled"
280304 : "default" ;
281305
306+ // Build disabledUnits from modifiers
307+ const disabledUnits : UnitType [ ] = [ ] ;
308+ if ( isPortsDisabled ) {
309+ disabledUnits . push ( UnitType . Port ) ;
310+ }
311+ if ( isNukesDisabled ) {
312+ disabledUnits . push (
313+ UnitType . MissileSilo ,
314+ UnitType . AtomBomb ,
315+ UnitType . HydrogenBomb ,
316+ UnitType . MIRV ,
317+ UnitType . SAMLauncher ,
318+ ) ;
319+ }
320+ if ( isSAMsDisabled ) {
321+ disabledUnits . push ( UnitType . SAMLauncher ) ;
322+ }
323+
324+ // 3min peace = 180s = 1800 ticks
325+ // 4min peace = 240s = 2400 ticks
326+ const peaceTimeDuration = isPeaceTime ? 240 * 10 : undefined ;
327+
282328 return {
283329 donateGold : mode === GameMode . Team ,
284330 donateTroops : mode === GameMode . Team ,
@@ -294,10 +340,14 @@ export class MapPlaylist {
294340 startingGold,
295341 goldMultiplier,
296342 isAlliancesDisabled,
343+ isPortsDisabled,
344+ isNukesDisabled,
345+ isSAMsDisabled,
346+ isPeaceTime,
297347 } ,
298348 startingGold,
299349 goldMultiplier,
300- disableAlliances : isAlliancesDisabled ,
350+ disableAlliances : isAlliancesDisabled ? true : undefined ,
301351 difficulty :
302352 isHardNations || playerTeams === HumansVsNations
303353 ? Difficulty . Hard
@@ -306,16 +356,15 @@ export class MapPlaylist {
306356 infiniteTroops : false ,
307357 maxTimerValue : undefined ,
308358 instantBuild : false ,
309- randomSpawn : isRandomSpawn ,
359+ randomSpawn : isRandomSpawn ? true : false ,
310360 nations,
311361 gameMode : mode ,
312362 playerTeams,
313363 bots : isCompact ? 100 : 400 ,
314- spawnImmunityDuration : this . getSpawnImmunityDuration (
315- playerTeams ,
316- startingGold ,
317- ) ,
318- disabledUnits : [ ] ,
364+ spawnImmunityDuration :
365+ peaceTimeDuration ??
366+ this . getSpawnImmunityDuration ( playerTeams , startingGold ) ,
367+ disabledUnits,
319368 } satisfies GameConfig ;
320369 }
321370
@@ -476,17 +525,23 @@ export class MapPlaylist {
476525 }
477526
478527 return {
479- isRandomSpawn : selected . has ( "isRandomSpawn" ) ,
480- isCompact : selected . has ( "isCompact" ) ,
481- isCrowded : selected . has ( "isCrowded" ) ,
482- isHardNations : selected . has ( "isHardNations" ) ,
483- startingGold : selected . has ( "startingGoldHigh " )
528+ isRandomSpawn : selected . has ( "isRandomSpawn" ) || undefined ,
529+ isCompact : selected . has ( "isCompact" ) || undefined ,
530+ isCrowded : selected . has ( "isCrowded" ) || undefined ,
531+ isHardNations : selected . has ( "isHardNations" ) || undefined ,
532+ startingGold : selected . has ( "startingGold25M " )
484533 ? 25_000_000
485- : selected . has ( "startingGold " )
534+ : selected . has ( "startingGold5M " )
486535 ? 5_000_000
487- : undefined ,
536+ : selected . has ( "startingGold1M" )
537+ ? 1_000_000
538+ : undefined ,
488539 goldMultiplier : selected . has ( "goldMultiplier" ) ? 2 : undefined ,
489- isAlliancesDisabled : selected . has ( "isAlliancesDisabled" ) ,
540+ isAlliancesDisabled : selected . has ( "isAlliancesDisabled" ) || undefined ,
541+ isPortsDisabled : selected . has ( "isPortsDisabled" ) || undefined ,
542+ isNukesDisabled : selected . has ( "isNukesDisabled" ) || undefined ,
543+ isSAMsDisabled : selected . has ( "isSAMsDisabled" ) || undefined ,
544+ isPeaceTime : selected . has ( "isPeaceTime" ) || undefined ,
490545 } ;
491546 }
492547
0 commit comments