Ticket #3102: t3102_survival_7b.diff
File t3102_survival_7b.diff, 10.8 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/maps/random/survivalofthefittest.js
198 198 ); 199 199 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); 200 200 201 // creating female citizens201 // Creating seeker woman (these need to have a lower ID than other starting woman for InitGame to identify them) 202 202 var femaleLocation = getTIPIADBON([ix, iz], [mapSize / 2, mapSize / 2], [-3 , 3.5], 1, 3); 203 203 if (femaleLocation !== undefined) 204 204 { -
binaries/data/mods/public/maps/random/survivalofthefittest_triggers.js
1 var treasures = 2 [ 1 /** 2 * Time in minutes to the first enemy wave. 3 */ 4 var firstAttackWave = randFloat(5, 15); 5 6 /** 7 * Time after which resources are distributed periodically. 8 */ 9 var provideResourcesOffset = randFloat(14, 16); 10 11 /** 12 * Time interval between enemy waves. 13 */ 14 var attackerWaveInterval = [2, 3]; 15 16 /** 17 * Time interval when treasures are distributed periodically. 18 */ 19 var treasureInterval = [3, 4]; 20 21 /** 22 * Time interval after which resources are distributed periodically. 23 */ 24 var provideResourcesInterval = [1.25, 1.75]; 25 26 /** 27 * Amount interval of resources distributed. 28 */ 29 var resourceAmountInterval = [50, 150]; 30 31 /** 32 * Amount of miliseconds in minute. 33 */ 34 const minutes = 60 * 1000; 35 36 var treasures = [ 3 37 "gaia/special_treasure_food_barrel", 4 38 "gaia/special_treasure_food_bin", 5 39 "gaia/special_treasure_food_crate", … … 10 44 "gaia/special_treasure_wood", 11 45 "gaia/special_treasure_wood" 12 46 ]; 13 var attackerEntityTemplates = 14 [ 47 48 /** 49 * Templates of the attacking units, sorted by civ 50 */ 51 var attackerTemplates = [ 15 52 [ 16 53 "units/athen_champion_infantry", 17 54 "units/athen_champion_marine", 18 55 "units/athen_champion_ranged", 19 "units/athen_ siege_lithobolos_packed",20 "units/athen_ siege_oxybeles_packed",56 "units/athen_mechanical_siege_lithobolos_packed", 57 "units/athen_mechanical_siege_oxybeles_packed", 21 58 ], 22 59 [ 23 60 "units/brit_champion_cavalry", … … 88 125 Trigger.prototype.StartAnEnemyWave = function() 89 126 { 90 127 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 91 let attackerEntities = attackerEntityTemplates[Math.floor(Math.random() * attackerEntityTemplates.length)]; 92 // A soldier for each 2-3 minutes of the game. Should be waves of 20 soldiers after an hour 93 let nextTime = Math.round(120000 + Math.random() * 60000); 94 let attackerCount = Math.round(cmpTimer.GetTime() / nextTime / attackerEntities.length); 128 let templates = attackerTemplates[Math.floor(Math.random() * attackerTemplates.length)]; 129 let nextTime = randFloat(...attackerWaveInterval) * minutes; 130 let attackerCount = Math.ceil(cmpTimer.GetTime() / nextTime / templates.length); 95 131 96 // spawn attackers 97 let attackers = []; 98 for (let attackerEntity of attackerEntities) 99 attackers.push(TriggerHelper.SpawnUnitsFromTriggerPoints("A", attackerEntity, attackerCount, 0)); 132 let attackers = templates.map(ent => 133 TriggerHelper.SpawnUnitsFromTriggerPoints("A", ent, attackerCount, 0)); 100 134 101 135 for (let entityType of attackers) 102 {103 136 for (let origin in entityType) 104 137 { 138 // Destroy attackers for non active players 105 139 let cmpPlayer = QueryOwnerInterface(+origin, IID_Player); 106 if (cmpPlayer.GetState() != "active") 140 if (!cmpPlayer || !cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()]) 141 { 142 Engine.DestroyEntity(+entityType[origin]) 107 143 continue; 144 } 108 145 109 let cmpPosition = Engine.QueryInterface(this.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position);110 // this shouldn't happen if the player is still active146 let cmpPosition = Engine.QueryInterface(cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position); 147 // This shouldn't happen if the player is still active 111 148 if (!cmpPosition || !cmpPosition.IsInWorld) 112 149 continue; 113 150 114 // store the x and z coordinates in the command 115 let cmd = cmpPosition.GetPosition(); 116 cmd.type = "attack-walk"; 117 cmd.entities = entityType[origin]; 118 cmd.queued = true; 119 cmd.targetClasses = undefined; 120 // send the attack-walk command 121 ProcessCommand(0, cmd); 151 let pos = cmpPosition.GetPosition(); 152 ProcessCommand(0, { 153 "type": "attack-walk", 154 "entities": entityType[origin], 155 "x": pos.x, 156 "z": pos.z, 157 "targetClasses": undefined, 158 "queued": true 159 }); 122 160 } 123 }124 161 125 162 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 126 163 cmpGUIInterface.PushNotification({ … … 127 164 "message": markForTranslation("An enemy wave is attacking!"), 128 165 "translateMessage": true 129 166 }); 130 cmpTrigger.DoAfterDelay(nextTime, "StartAnEnemyWave", {}); // The next wave will come in 3 minutes167 cmpTrigger.DoAfterDelay(nextTime, "StartAnEnemyWave", {}); 131 168 }; 132 169 170 /** 171 * Find all of the civic centers and females, disable some structures, setup activity watch. 172 */ 133 173 Trigger.prototype.InitGame = function() 134 174 { 135 175 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers(); 136 // Find all of the civic centers, disable some structures137 176 for (let i = 1; i < numberOfPlayers; ++i) 138 177 { 139 178 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 140 179 let playerEntities = cmpRangeManager.GetEntitiesByPlayer(i); // Get all of each player's entities 141 180 181 let foundSeeker = false; 142 182 for (let entity of playerEntities) 183 { 143 184 if (TriggerHelper.EntityHasClass(entity, "CivilCentre")) 144 185 cmpTrigger.playerCivicCenter[i] = entity; 186 187 if (TriggerHelper.EntityHasClass(entity, "Female") && !foundSeeker) 188 { 189 foundSeeker = true; 190 let cmpDamageReceiver = Engine.QueryInterface(entity, IID_DamageReceiver); 191 cmpDamageReceiver.SetInvulnerability(true); 192 193 let cmpHealth = Engine.QueryInterface(entity, IID_Health); 194 cmpHealth.SetUndeletable(true); 195 } 196 } 145 197 } 146 198 147 199 // Fix alliances … … 158 210 // Make gaia black 159 211 QueryPlayerIDInterface(0).SetColor(0, 0, 0); 160 212 161 // Place the treasures162 213 this.PlaceTreasures(); 163 214 164 215 // Disable farms, civic centers and walls for all players … … 166 217 { 167 218 let cmpPlayer = QueryPlayerIDInterface(i); 168 219 let civ = cmpPlayer.GetCiv(); 220 169 221 cmpPlayer.SetDisabledTemplates([ 170 222 "structures/" + civ + "_field", 171 223 "structures/" + civ + "_corral", … … 172 224 "structures/" + civ + "_civil_centre", 173 225 "structures/" + civ + "_military_colony", 174 226 "structures/" + civ + "_wallset_stone", 227 "structures/brit_crannog", 175 228 "other/wallset_palisade" 176 229 ]); 177 230 } … … 183 236 let triggerPoints = cmpTrigger.GetTriggerPoints(point); 184 237 for (let point of triggerPoints) 185 238 { 186 let template = treasures[Math.floor(Math.random() * treasures.length)] 187 TriggerHelper.SpawnUnits(point, template, 1, 0); 239 let template = treasures[Math.floor(Math.random() * treasures.length)]; 240 let cmpPosition = Engine.QueryInterface(point, IID_Position); 241 let ent = Engine.AddEntity(template); 242 243 let cmpEntOwnership = Engine.QueryInterface(ent, IID_Ownership); 244 let cmpEntPosition = Engine.QueryInterface(ent, IID_Position); 245 246 if (cmpEntOwnership) 247 cmpEntOwnership.SetOwner(0); 248 249 let xOffset = randInt(0, 23); 250 let zOffset = randInt(0, 23); 251 252 if (Math.random() >= 0.8) 253 { 254 xOffset += randInt(5, 8); 255 zOffset += randInt(5, 8); 256 } 257 258 if (Math.round(Math.random()) == 1) 259 xOffset = -xOffset; 260 261 if (Math.round(Math.random()) == 1) 262 zOffset = -zOffset; 263 264 cmpEntPosition.JumpTo(cmpPosition.GetPosition().x + xOffset, cmpPosition.GetPosition().z - zOffset); 188 265 } 189 cmpTrigger.DoAfterDelay(4*60*1000, "PlaceTreasures", {}); //Place more treasures after 4 minutes 266 267 cmpTrigger.DoAfterDelay(randFloat(...treasureInterval) * minutes, "PlaceTreasures", {}); 268 269 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 270 cmpGUIInterface.PushNotification({ 271 "message": markForTranslation("New treasures have been placed!"), 272 "translateMessage": true 273 }); 190 274 }; 191 275 192 276 Trigger.prototype.InitializeEnemyWaves = function() 193 277 { 194 let time = (5 + Math.round(Math.random() * 10)) * 60 * 1000;195 278 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 279 280 cmpGUIInterface.PushNotification({ 281 "message": markForTranslation("Welcome to Survival of the Fittest"), 282 "translateMessage": true 283 }); 284 285 cmpGUIInterface.PushNotification({ 286 "message": markForTranslation("Collect treasures with your woman to prepare for the enemies."), 287 "translateMessage": true 288 }); 289 290 let time = firstAttackWave * minutes; 196 291 cmpGUIInterface.AddTimeNotification({ 197 292 "message": markForTranslation("The first wave will start in %(time)s!"), 198 293 "translateMessage": true … … 202 297 203 298 Trigger.prototype.DefeatPlayerOnceCCIsDestroyed = function(data) 204 299 { 205 // Defeat a player that has lost his civic center 206 if (data.entity == cmpTrigger.playerCivicCenter[data.from]) 207 { 300 if (data.entity == cmpTrigger.playerCivicCenter[data.from] && data.to == -1) 208 301 TriggerHelper.DefeatPlayer(data.from); 302 }; 209 303 210 // Check if only one player remains. He will be the winner. 211 let lastPlayerStanding = 0; 212 let numPlayersStanding = 0; 213 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers(); 214 for (let i = 1; i < numberOfPlayers; ++i) 215 { 216 if (QueryPlayerIDInterface(i).GetState() == "active") 217 { 218 lastPlayerStanding = i; 219 ++numPlayersStanding; 220 } 221 } 222 if (numPlayersStanding == 1) 223 TriggerHelper.SetPlayerWon(lastPlayerStanding); 304 Trigger.prototype.ProvideResources = function(data) 305 { 306 if (data.first) 307 { 308 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 309 cmpGUIInterface.PushNotification({ 310 "message": markForTranslation("From now on, all players will receive some resources from time to time."), 311 "translateMessage": true 312 }); 224 313 } 314 315 let resources = {}; 316 for (let type of ["food", "wood", "stone", "metal"]) 317 resources[type] = randInt(resourceAmountInterval[0], resourceAmountInterval[1]); 318 319 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers(); 320 for (let i = 1; i < numberOfPlayers; ++i) 321 QueryPlayerIDInterface(i).AddResources(resources); 322 323 cmpTrigger.DoAfterDelay(randFloat(...provideResourcesInterval) * minutes, "ProvideResources", {}); 225 324 }; 226 325 227 326 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 228 327 cmpTrigger.playerCivicCenter = {}; 328 229 329 cmpTrigger.DoAfterDelay(0, "InitGame", {}); 230 330 cmpTrigger.DoAfterDelay(1000, "InitializeEnemyWaves", {}); 331 cmpTrigger.DoAfterDelay(provideResourcesOffset * minutes, "ProvideResources", { "first": true }); 231 332 232 333 cmpTrigger.RegisterTrigger("OnOwnershipChanged", "DefeatPlayerOnceCCIsDestroyed", { "enabled": true });