Ticket #3102: t3102_survival_3.diff
File t3102_survival_3.diff, 11.9 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 number than other starting woman 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 * This is the Script containing all the Triggers for the "Survival of the Fittest" Map. 3 */ 4 5 var treasures = [ 3 6 "gaia/special_treasure_food_barrel", 4 7 "gaia/special_treasure_food_bin", 5 8 "gaia/special_treasure_food_crate", … … 10 13 "gaia/special_treasure_wood", 11 14 "gaia/special_treasure_wood" 12 15 ]; 13 var attackerEntityTemplates = 14 [ 16 17 var treasureTime = 3; // Time in minutes when treasures are distributed periodically without random offset. 18 19 var provideResourcesCount = 0; 20 21 var provideResourcesTime = 1.25; // Time in minutes when resources are distributed periodically without random offset. 22 var provideResourcesOffset = 14 + 2 * Math.random(); // Time in minutes after which resources are distributed periodically. 23 24 // These are the templates of the attacking units, sorted by civ 25 var attackerEntityTemplates = [ 15 26 [ 16 27 "units/athen_champion_infantry", 17 28 "units/athen_champion_marine", 18 29 "units/athen_champion_ranged", 19 "units/athen_ siege_lithobolos_packed",20 "units/athen_ siege_oxybeles_packed",30 "units/athen_mechanical_siege_lithobolos_packed", 31 "units/athen_mechanical_siege_oxybeles_packed" 21 32 ], 22 33 [ 23 34 "units/brit_champion_cavalry", 24 35 "units/brit_champion_infantry", 25 "units/brit_mechanical_siege_ram" ,36 "units/brit_mechanical_siege_ram" 26 37 ], 27 38 [ 28 39 "units/cart_champion_cavalry", 29 40 "units/cart_champion_elephant", 30 41 "units/cart_champion_infantry", 31 "units/cart_champion_pikeman" ,42 "units/cart_champion_pikeman" 32 43 ], 33 44 [ 34 45 "units/gaul_champion_cavalry", 35 46 "units/gaul_champion_fanatic", 36 47 "units/gaul_champion_infantry", 37 "units/gaul_mechanical_siege_ram" ,48 "units/gaul_mechanical_siege_ram" 38 49 ], 39 50 [ 40 51 "units/iber_champion_cavalry", 41 52 "units/iber_champion_infantry", 42 "units/iber_mechanical_siege_ram" ,53 "units/iber_mechanical_siege_ram" 43 54 ], 44 55 [ 45 56 "units/mace_champion_cavalry", … … 46 57 "units/mace_champion_infantry_a", 47 58 "units/mace_champion_infantry_e", 48 59 "units/mace_mechanical_siege_lithobolos_packed", 49 "units/mace_mechanical_siege_oxybeles_packed" ,60 "units/mace_mechanical_siege_oxybeles_packed" 50 61 ], 51 62 [ 52 63 "units/maur_champion_chariot", … … 53 64 "units/maur_champion_elephant", 54 65 "units/maur_champion_infantry", 55 66 "units/maur_champion_maiden", 56 "units/maur_champion_maiden_archer" ,67 "units/maur_champion_maiden_archer" 57 68 ], 58 69 [ 59 70 "units/pers_champion_cavalry", 60 "units/pers_champion_infantry",61 71 "units/pers_champion_elephant", 72 "units/pers_champion_infantry" 62 73 ], 63 74 [ 64 75 "units/ptol_champion_cavalry", 65 "units/ptol_champion_elephant" ,76 "units/ptol_champion_elephant" 66 77 ], 67 78 [ 68 79 "units/rome_champion_cavalry", 69 80 "units/rome_champion_infantry", 70 81 "units/rome_mechanical_siege_ballista_packed", 71 "units/rome_mechanical_siege_scorpio_packed" ,82 "units/rome_mechanical_siege_scorpio_packed" 72 83 ], 73 84 [ 74 85 "units/sele_champion_cavalry", … … 75 86 "units/sele_champion_chariot", 76 87 "units/sele_champion_elephant", 77 88 "units/sele_champion_infantry_pikeman", 78 "units/sele_champion_infantry_swordsman" ,89 "units/sele_champion_infantry_swordsman" 79 90 ], 80 91 [ 81 92 "units/spart_champion_infantry_pike", 82 93 "units/spart_champion_infantry_spear", 83 94 "units/spart_champion_infantry_sword", 84 "units/spart_mechanical_siege_ram" ,95 "units/spart_mechanical_siege_ram" 85 96 ], 86 97 ]; 87 98 … … 93 104 let nextTime = Math.round(120000 + Math.random() * 60000); 94 105 let attackerCount = Math.round(cmpTimer.GetTime() / nextTime / attackerEntities.length); 95 106 96 // spawn attackers97 let attackers = 107 // Spawn attackers 108 let attackers = []; 98 109 for (let attackerEntity of attackerEntities) 99 110 attackers.push(TriggerHelper.SpawnUnitsFromTriggerPoints("A", attackerEntity, attackerCount, 0)); 100 111 … … 103 114 for (let origin in entityType) 104 115 { 105 116 let cmpPlayer = QueryOwnerInterface(+origin, IID_Player); 106 if ( cmpPlayer.GetState() != "active")117 if (!cmpPlayer || !cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()]) 107 118 continue; 108 119 109 let cmpPosition = Engine.QueryInterface(this.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position);110 // this shouldn't happen if the player is still active120 let cmpPosition = Engine.QueryInterface(cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position); 121 // This shouldn't happen if the player is still active 111 122 if (!cmpPosition || !cmpPosition.IsInWorld) 112 123 continue; 113 124 114 // store the x and z coordinates in the command125 // Store the x and z coordinates in the command 115 126 let cmd = cmpPosition.GetPosition(); 116 127 cmd.type = "attack-walk"; 117 128 cmd.entities = entityType[origin]; 118 129 cmd.queued = true; 119 130 cmd.targetClasses = undefined; 120 // send the attack-walk command131 // Send the attack-walk command 121 132 ProcessCommand(0, cmd); 122 133 } 123 134 } … … 130 141 cmpTrigger.DoAfterDelay(nextTime, "StartAnEnemyWave", {}); // The next wave will come in 3 minutes 131 142 }; 132 143 144 /* 145 * The main init function, called at the start 146 */ 133 147 Trigger.prototype.InitGame = function() 134 148 { 135 149 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers(); 136 // Find all of the civic centers , disable some structures150 // Find all of the civic centers and females, disable some structures, setup activity watch 137 151 for (let i = 1; i < numberOfPlayers; ++i) 138 152 { 139 153 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 140 154 let playerEntities = cmpRangeManager.GetEntitiesByPlayer(i); // Get all of each player's entities 141 155 156 let seekersNumber = 1; // Only 1 seeker woman per player 157 let seekers = 0; 142 158 for (let entity of playerEntities) 159 { 143 160 if (TriggerHelper.EntityHasClass(entity, "CivilCentre")) 144 161 cmpTrigger.playerCivicCenter[i] = entity; 162 if (TriggerHelper.EntityHasClass(entity, "Female") && seekers < seekersNumber) 163 { 164 ++seekers; 165 let cmpDamageReceiver = Engine.QueryInterface(entity, IID_DamageReceiver); 166 cmpDamageReceiver.SetInvulnerability(true); 167 168 let cmpHealth = Engine.QueryInterface(entity, IID_Health); 169 cmpHealth.SetUndeletability(true); 170 } 171 } 145 172 } 146 173 147 174 // Fix alliances … … 183 210 let triggerPoints = cmpTrigger.GetTriggerPoints(point); 184 211 for (let point of triggerPoints) 185 212 { 186 let template = treasures[Math.floor(Math.random() * treasures.length)] 187 TriggerHelper.SpawnUnits(point, template, 1, 0); 213 let template = treasures[Math.floor(Math.random() * treasures.length)]; 214 let cmpPosition = Engine.QueryInterface(point, IID_Position); 215 let ent = Engine.AddEntity(template); 216 217 let cmpEntOwnership = Engine.QueryInterface(ent, IID_Ownership); 218 let cmpEntPosition = Engine.QueryInterface(ent, IID_Position); 219 220 if (cmpEntOwnership) 221 cmpEntOwnership.SetOwner(0); 222 223 let xOffset = RandomInt(0, 23); 224 let zOffset = RandomInt(0, 23); 225 226 if (Math.random() >= 0.8) 227 { 228 xOffset += RandomInt(5, 8); 229 zOffset += RandomInt(5, 8); 230 } 231 232 if (Math.round(Math.random()) == 1) 233 xOffset = -xOffset; 234 235 if (Math.round(Math.random()) == 1) 236 zOffset = -zOffset; 237 238 cmpEntPosition.JumpTo(cmpPosition.GetPosition().x + xOffset, cmpPosition.GetPosition().z - zOffset); 188 239 } 189 cmpTrigger.DoAfterDelay(4*60*1000, "PlaceTreasures", {}); //Place more treasures after 4 minutes 240 241 cmpTrigger.DoAfterDelay((treasureTime + Math.random()) * 60 * 1000, "PlaceTreasures", {}); 242 243 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 244 cmpGUIInterface.PushNotification({ 245 "message": markForTranslation("New treasures have been placed!"), 246 "translateMessage": true 247 }); 190 248 }; 191 249 192 250 Trigger.prototype.InitializeEnemyWaves = function() … … 193 251 { 194 252 let time = (5 + Math.round(Math.random() * 10)) * 60 * 1000; 195 253 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 254 cmpGUIInterface.PushNotification({ 255 "message": markForTranslation("Welcome to Survival of the Fittest"), 256 "translateMessage": true 257 }); 258 cmpGUIInterface.PushNotification({ 259 "message": markForTranslation("Collect treasures with your woman to prepare for the enemies."), 260 "translateMessage": true 261 }); 196 262 cmpGUIInterface.AddTimeNotification({ 197 263 "message": markForTranslation("The first wave will start in %(time)s!"), 198 264 "translateMessage": true 199 265 }, time); 266 200 267 cmpTrigger.DoAfterDelay(time, "StartAnEnemyWave", {}); 201 268 }; 202 269 … … 203 270 Trigger.prototype.DefeatPlayerOnceCCIsDestroyed = function(data) 204 271 { 205 272 // Defeat a player that has lost his civic center 206 if (data.entity == cmpTrigger.playerCivicCenter[data.from] )273 if (data.entity == cmpTrigger.playerCivicCenter[data.from] && data.to == -1) 207 274 { 208 275 TriggerHelper.DefeatPlayer(data.from); 209 276 … … 224 291 } 225 292 }; 226 293 294 /* 295 * This function is constantly looping and provides resources to all players. 296 * It starts after provideResourcesOffset 297 */ 298 Trigger.prototype.provideResources = function(data) 299 { 300 ++provideResourcesCount; 301 302 if (provideResourcesCount == 1) 303 { 304 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 305 cmpGUIInterface.PushNotification({ 306 "message": markForTranslation("From now on, all players will receive some resources from time to time."), 307 "translateMessage": true 308 }); 309 } 310 311 let resources = { 312 "food": 50 + Math.round(Math.random() * 100), 313 "wood": 50 + Math.round(Math.random() * 100), 314 "stone": 50 + Math.round(Math.random() * 100), 315 "metal": 50 + Math.round(Math.random() * 100) 316 } 317 318 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers(); 319 for (let i = 1; i < numberOfPlayers; ++i) 320 { 321 let cmpPlayer = QueryPlayerIDInterface(i); 322 cmpPlayer.AddResources(resources); 323 } 324 cmpTrigger.DoAfterDelay((provideResourcesTime + Math.random() / 2) * 60 * 1000, "provideResources" , {}); 325 }; 326 227 327 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 228 328 cmpTrigger.playerCivicCenter = {}; 329 229 330 cmpTrigger.DoAfterDelay(0, "InitGame", {}); 230 331 cmpTrigger.DoAfterDelay(1000, "InitializeEnemyWaves", {}); 332 cmpTrigger.DoAfterDelay(provideResourcesOffset * 60 * 1000, "provideResources" , {}); 231 333 232 334 cmpTrigger.RegisterTrigger("OnOwnershipChanged", "DefeatPlayerOnceCCIsDestroyed", { "enabled": true }); -
binaries/data/mods/public/simulation/components/Health.js
63 63 this.hitpoints = +(this.template.Initial || this.GetMaxHitpoints()); 64 64 this.regenRate = ApplyValueModificationsToEntity("Health/RegenRate", +this.template.RegenRate, this.entity); 65 65 this.idleRegenRate = ApplyValueModificationsToEntity("Health/IdleRegenRate", +this.template.IdleRegenRate, this.entity); 66 this.undeletable = this.template.Undeletable; 66 67 this.CheckRegenTimer(); 67 68 this.UpdateActor(); 68 69 }; … … 123 124 124 125 Health.prototype.IsUndeletable = function() 125 126 { 126 return this. template.Undeletable == "true";127 return this.undeletable; 127 128 }; 128 129 130 Health.prototype.SetUndeletability = function(undeletability) 131 { 132 this.undeletable = undeletability; 133 }; 134 129 135 Health.prototype.GetIdleRegenRate = function() 130 136 { 131 137 return this.idleRegenRate;