Ticket #1432: one_hero_2012_07_12.diff
File one_hero_2012_07_12.diff, 41.1 KB (added by , 12 years ago) |
---|
-
binaries/data/mods/public/gui/session/unit_commands.js
146 146 * @param items Panel-specific data to construct the icons with. 147 147 * @param callback Callback function to argument to execute when an item's icon gets clicked. Takes a single 'item' argument. 148 148 */ 149 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)149 function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, callback) 150 150 { 151 151 usedPanels[guiName] = 1; 152 152 … … 350 350 tooltip += "\n" + getEntitySpeed(template); 351 351 352 352 tooltip += "\n\n[font=\"serif-bold-13\"]Shift-click[/font][font=\"serif-13\"] to train " + trainNum + ".[/font]"; 353 354 353 break; 355 354 356 355 case RESEARCH: … … 499 498 icon.sprite = "stretched:session/icons/" + item.icon; 500 499 501 500 } 501 else if (guiName == TRAINING) 502 { 503 if (template.icon) 504 { 505 var trainingCategory = null; 506 if (template.trainingRestrictions) 507 trainingCategory = template.trainingRestrictions.category; 508 var grayscale = ""; 509 if (trainingCategory && playerState.entityCounts[trainingCategory] >= playerState.entityLimits[trainingCategory]) 510 grayscale = "grayscale:"; 511 icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 512 } 513 } 502 514 else if (guiName == GATE) 503 515 { 504 516 icon.sprite = "stretched:session/icons/production.png"; … … 647 659 } 648 660 649 661 // Sets up "unit barter panel" - special case for setupUnitPanel 650 function setupUnitBarterPanel(unitEntState )662 function setupUnitBarterPanel(unitEntState, playerState) 651 663 { 652 664 // Amount of player's resource to exchange 653 665 var amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; … … 726 738 var player = Engine.GetPlayerID(); 727 739 if (entState.player == player || g_DevSettings.controlAll) 728 740 { 741 // Get player state to check some constraints 742 // e.g. presence of a hero or build limits 743 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 744 var playerState = simState.players[player]; 745 729 746 if (selection.length > 1) 730 setupUnitPanel(SELECTION, usedPanels, entState, g_Selection.groups.getTemplateNames(),747 setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(), 731 748 function (entType) { changePrimarySelectionGroup(entType); } ); 732 749 733 750 var commands = getEntityCommandsList(entState); 734 751 if (commands.length) 735 setupUnitPanel(COMMAND, usedPanels, entState, commands,752 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 736 753 function (item) { performCommand(entState.id, item.name); } ); 737 754 738 755 if (entState.garrisonHolder) 739 756 { 740 757 var groups = new EntityGroups(); 741 758 groups.add(entState.garrisonHolder.entities); 742 setupUnitPanel(GARRISON, usedPanels, entState, groups.getTemplateNames(),759 setupUnitPanel(GARRISON, usedPanels, entState, playerState, groups.getTemplateNames(), 743 760 function (item) { unload(entState.id, groups.getEntsByName(item)); } ); 744 761 } 745 762 746 763 var formations = Engine.GuiInterfaceCall("GetAvailableFormations"); 747 764 if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && formations.length) 748 765 { 749 setupUnitPanel(FORMATION, usedPanels, entState, formations,766 setupUnitPanel(FORMATION, usedPanels, entState, playerState, formations, 750 767 function (item) { performFormation(entState.id, item); } ); 751 768 } 752 769 … … 755 772 var stances = ["violent", "aggressive", "passive", "defensive", "standground"]; 756 773 if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && stances.length) 757 774 { 758 setupUnitPanel(STANCE, usedPanels, entState, stances,775 setupUnitPanel(STANCE, usedPanels, entState, playerState, stances, 759 776 function (item) { performStance(entState.id, item); } ); 760 777 } 761 778 … … 763 780 if (entState.barterMarket) 764 781 { 765 782 usedPanels["Barter"] = 1; 766 setupUnitBarterPanel(entState );783 setupUnitBarterPanel(entState, playerState); 767 784 } 768 785 769 786 var buildableEnts = []; … … 783 800 removeDupes(trainableEnts); 784 801 785 802 if (buildableEnts.length && ((trainableEnts.length && hasClass(entState, "Unit")) || !trainableEnts.length)) 786 setupUnitPanel(CONSTRUCTION, usedPanels, entState, buildableEnts, startBuildingPlacement);803 setupUnitPanel(CONSTRUCTION, usedPanels, entState, playerState, buildableEnts, startBuildingPlacement); 787 804 else if (trainableEnts.length) 788 setupUnitPanel(TRAINING, usedPanels, entState, trainableEnts,805 setupUnitPanel(TRAINING, usedPanels, entState, playerState, trainableEnts, 789 806 function (trainEntType) { addTrainingToQueue(selection, trainEntType); } ); 790 807 791 808 if (entState.production && entState.production.technologies.length && selection.length == 1) 792 809 { 793 setupUnitPanel(RESEARCH, usedPanels, entState, entState.production.technologies,810 setupUnitPanel(RESEARCH, usedPanels, entState, playerState, entState.production.technologies, 794 811 function (researchType) { addResearchToQueue(entState.id, researchType); } ); 795 812 } 796 813 797 814 if (entState.production && entState.production.queue.length) 798 setupUnitPanel(QUEUE, usedPanels, entState, entState.production.queue,815 setupUnitPanel(QUEUE, usedPanels, entState, playerState, entState.production.queue, 799 816 function (item) { removeFromProductionQueue(entState.id, item.id); } ); 800 817 801 818 if (entState.trader) -
binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
1 1 Engine.LoadComponentScript("interfaces/Attack.js"); 2 2 Engine.LoadComponentScript("interfaces/Barter.js"); 3 3 Engine.LoadComponentScript("interfaces/Builder.js"); 4 Engine.LoadComponentScript("interfaces/BuildLimits.js");5 4 Engine.LoadComponentScript("interfaces/DamageReceiver.js"); 5 Engine.LoadComponentScript("interfaces/EntityLimits.js"); 6 6 Engine.LoadComponentScript("interfaces/Foundation.js"); 7 7 Engine.LoadComponentScript("interfaces/GarrisonHolder.js"); 8 8 Engine.LoadComponentScript("interfaces/Heal.js"); … … 66 66 IsEnemy: function() { return true; }, 67 67 }); 68 68 69 AddMock(100, IID_ BuildLimits, {69 AddMock(100, IID_EntityLimits, { 70 70 GetLimits: function() { return {"Foo": 10}; }, 71 71 GetCounts: function() { return {"Foo": 5}; }, 72 72 }); … … 117 117 IsEnemy: function() { return false; }, 118 118 }); 119 119 120 AddMock(101, IID_ BuildLimits, {120 AddMock(101, IID_EntityLimits, { 121 121 GetLimits: function() { return {"Bar": 20}; }, 122 122 GetCounts: function() { return {"Bar": 0}; }, 123 123 }); … … 170 170 phase: "", 171 171 isAlly: [false, false, false], 172 172 isEnemy: [true, true, true], 173 buildLimits: {"Foo": 10},174 buildCounts: {"Foo": 5},173 entityLimits: {"Foo": 10}, 174 entityCounts: {"Foo": 5}, 175 175 techModifications: {}, 176 176 }, 177 177 { … … 188 188 phase: "village", 189 189 isAlly: [true, true, true], 190 190 isEnemy: [false, false, false], 191 buildLimits: {"Bar": 20},192 buildCounts: {"Bar": 0},191 entityLimits: {"Bar": 20}, 192 entityCounts: {"Bar": 0}, 193 193 techModifications: {}, 194 194 } 195 195 ], … … 213 213 phase: "", 214 214 isAlly: [false, false, false], 215 215 isEnemy: [true, true, true], 216 buildLimits: {"Foo": 10},217 buildCounts: {"Foo": 5},216 entityLimits: {"Foo": 10}, 217 entityCounts: {"Foo": 5}, 218 218 techModifications: {}, 219 219 statistics: { 220 220 unitsTrained: 10, … … 247 247 phase: "village", 248 248 isAlly: [true, true, true], 249 249 isEnemy: [false, false, false], 250 buildLimits: {"Bar": 20},251 buildCounts: {"Bar": 0},250 entityLimits: {"Bar": 20}, 251 entityCounts: {"Bar": 0}, 252 252 techModifications: {}, 253 253 statistics: { 254 254 unitsTrained: 10, -
binaries/data/mods/public/simulation/components/ProductionQueue.js
199 199 if (!cmpPlayer.TrySubtractResources(totalCosts)) 200 200 return; 201 201 202 // Update entity count in the EntityLimits component 203 if (template.TrainingRestrictions) 204 { 205 var unitCategory = template.TrainingRestrictions.Category; 206 var cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits); 207 cmpPlayerEntityLimits.IncreaseCount(unitCategory, count); 208 } 209 202 210 this.queue.push({ 203 211 "id": this.nextID++, 204 212 "player": cmpPlayer.GetPlayerID(), … … 292 300 293 301 var cmpPlayer = QueryPlayerIDInterface(item.player, IID_Player); 294 302 303 // Update entity count in the EntityLimits component 304 if (item.unitTemplate) 305 { 306 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 307 var template = cmpTempMan.GetTemplate(item.unitTemplate); 308 if (template.TrainingRestrictions) 309 { 310 var unitCategory = template.TrainingRestrictions.Category; 311 var cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits); 312 cmpPlayerEntityLimits.DecreaseCount(unitCategory, item.count); 313 } 314 } 315 295 316 // Refund the resource cost for this batch 296 317 var totalCosts = {}; 297 318 for each (var r in ["food", "wood", "stone", "metal"]) … … 401 422 // so only create them once and use as needed 402 423 for (var i = 0; i < count; ++i) 403 424 { 404 this.entityCache.push(Engine.AddEntity(templateName)); 425 var ent = Engine.AddEntity(templateName); 426 this.entityCache.push(ent); 427 428 // Decrement entity count in the EntityLimits component 429 // since it will be increased by EntityLimits.OnGlobalOwnershipChanged function, 430 // i.e. we replace a 'trained' entity to an 'alive' one 431 var cmpTrainingRestrictions = Engine.QueryInterface(this.entity, IID_TrainingRestrictions); 432 if (cmpTrainingRestrictions) 433 { 434 var unitCategory = cmpTrainingRestrictions.GetCategory(); 435 var cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits); 436 cmpPlayerEntityLimits.DecrementCount(unitCategory); 437 } 405 438 } 406 439 } 407 440 -
binaries/data/mods/public/simulation/components/Player.js
343 343 Player.prototype.OnGlobalOwnershipChanged = function(msg) 344 344 { 345 345 var isConquestCritical = false; 346 347 346 // Load class list only if we're going to need it 348 347 if (msg.from == this.playerID || msg.to == this.playerID) 349 348 { 350 349 var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity); 351 350 if (cmpIdentity) 352 351 { 353 var classes = cmpIdentity.GetClassesList(); 354 isConquestCritical = classes.indexOf("ConquestCritical") != -1; 352 isConquestCritical = cmpIdentity.HasClass("ConquestCritical"); 355 353 } 356 354 } 357 358 355 if (msg.from == this.playerID) 359 356 { 360 357 if (isConquestCritical) 361 this.conquestCriticalEntitiesCount--; 362 358 this.conquestCriticalEntitiesCount--; 363 359 var cost = Engine.QueryInterface(msg.entity, IID_Cost); 364 360 if (cost) 365 361 { … … 367 363 this.popBonuses -= cost.GetPopBonus(); 368 364 } 369 365 } 370 371 366 if (msg.to == this.playerID) 372 367 { 373 368 if (isConquestCritical) 374 369 this.conquestCriticalEntitiesCount++; 375 376 370 var cost = Engine.QueryInterface(msg.entity, IID_Cost); 377 371 if (cost) 378 372 { -
binaries/data/mods/public/simulation/components/EntityLimits.js
1 function EntityLimits() {} 2 3 EntityLimits.prototype.Schema = 4 "<a:help>Specifies per category limits on number of entities (buildings or units) that can be created for each player.</a:help>" + 5 "<a:example>" + 6 "<Limits>" + 7 "<CivilCentre/>" + 8 "<DefenseTower>25</DefenseTower>" + 9 "<Fortress>10</Fortress>" + 10 "<Hero>1</Hero>" + 11 "<Special>" + 12 "<LimitPerCivCentre>1</LimitPerCivCentre>" + 13 "</Special>" + 14 "</Limits>" + 15 "</a:example>" + 16 "<element name='LimitMultiplier'>" + 17 "<ref name='positiveDecimal'/>" + 18 "</element>" + 19 "<element name='Limits'>" + 20 "<zeroOrMore>" + 21 "<element a:help='Specifies a category of building on which to apply this limit. See BuildRestrictions for list of categories.'>" + 22 "<anyName />" + 23 "<choice>" + 24 "<text />" + 25 "<element name='LimitPerCivCentre' a:help='Specifies that this limit is per number of civil centres.'>" + 26 "<data type='nonNegativeInteger'/>" + 27 "</element>" + 28 "</choice>" + 29 "</element>" + 30 "</zeroOrMore>" + 31 "</element>"; 32 33 /* 34 * TODO: Use an inheriting player_{civ}.xml template for civ-specific limits 35 */ 36 37 EntityLimits.prototype.Init = function() 38 { 39 this.limit = {}; 40 this.count = {}; 41 for (var category in this.template.Limits) 42 { 43 this.limit[category] = this.template.Limits[category]; 44 this.count[category] = 0; 45 } 46 }; 47 48 EntityLimits.prototype.IncreaseCount = function(category, value) 49 { 50 if (this.count[category] !== undefined) 51 { 52 this.count[category] += value; 53 } 54 }; 55 56 EntityLimits.prototype.DecreaseCount = function(category, value) 57 { 58 if (this.count[category] !== undefined) 59 { 60 this.count[category] -= value; 61 } 62 }; 63 64 EntityLimits.prototype.IncrementCount = function(category) 65 { 66 this.IncreaseCount(category, 1); 67 }; 68 69 EntityLimits.prototype.DecrementCount = function(category) 70 { 71 this.DecreaseCount(category, 1); 72 }; 73 74 EntityLimits.prototype.GetLimits = function() 75 { 76 return this.limit; 77 }; 78 79 EntityLimits.prototype.GetCounts = function() 80 { 81 return this.count; 82 }; 83 84 EntityLimits.prototype.AllowedToBuild = function(category) 85 { 86 // TODO: The UI should reflect this before the user tries to place the building, 87 // since the limits are independent of placement location 88 89 // Allow unspecified categories and those with no limit 90 if (this.count[category] === undefined || this.limit[category] === undefined) 91 { 92 return true; 93 } 94 95 // Rather than complicating the schema unecessarily, just handle special cases here 96 if (this.limit[category].LimitPerCivCentre !== undefined) 97 { 98 if (this.count[category] >= this.count["CivilCentre"] * this.limit[category].LimitPerCivCentre) 99 { 100 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); 101 var notification = {"player": cmpPlayer.GetPlayerID(), "message": category+" build limit of "+this.limit[category].LimitPerCivCentre+" per civil centre reached"}; 102 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 103 cmpGUIInterface.PushNotification(notification); 104 105 return false; 106 } 107 } 108 else if (this.count[category] >= this.limit[category]) 109 { 110 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); 111 var notification = {"player": cmpPlayer.GetPlayerID(), "message": category+" train limit of "+this.limit[category]+ " reached"}; 112 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 113 cmpGUIInterface.PushNotification(notification); 114 115 return false; 116 } 117 118 return true; 119 }; 120 121 EntityLimits.prototype.AllowedToTrain = function(category, count) 122 { 123 // Allow unspecified categories and those with no limit 124 if (this.count[category] === undefined || this.limit[category] === undefined) 125 { 126 return true; 127 } 128 if (this.count[category] + count > this.limit[category]) 129 { 130 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); 131 var notification = {"player": cmpPlayer.GetPlayerID(), "message": category+" build limit of "+this.limit[category]+ " reached"}; 132 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 133 cmpGUIInterface.PushNotification(notification); 134 135 return false; 136 } 137 return true; 138 }; 139 140 EntityLimits.prototype.OnGlobalOwnershipChanged = function(msg) 141 { 142 // This automatically updates entity counts 143 var category = null; 144 var cmpBuildRestrictions = Engine.QueryInterface(msg.entity, IID_BuildRestrictions); 145 if (cmpBuildRestrictions) 146 category = cmpBuildRestrictions.GetCategory(); 147 var cmpTrainingRestrictions = Engine.QueryInterface(msg.entity, IID_TrainingRestrictions); 148 if (cmpTrainingRestrictions) 149 category = cmpTrainingRestrictions.GetCategory(); 150 if (category) 151 { 152 var playerID = (Engine.QueryInterface(this.entity, IID_Player)).GetPlayerID(); 153 if (msg.from == playerID) 154 { 155 this.DecrementCount(category); 156 } 157 if (msg.to == playerID) 158 { 159 this.IncrementCount(category); 160 } 161 } 162 }; 163 164 Engine.RegisterComponentType(IID_EntityLimits, "EntityLimits", EntityLimits); -
binaries/data/mods/public/simulation/components/interfaces/BuildLimits.js
1 Engine.RegisterInterface("BuildLimits");2 No newline at end of file -
binaries/data/mods/public/simulation/components/interfaces/EntityLimits.js
1 Engine.RegisterInterface("EntityLimits"); -
binaries/data/mods/public/simulation/components/interfaces/TrainingRestrictions.js
1 Engine.RegisterInterface("TrainingRestrictions"); 2 -
binaries/data/mods/public/simulation/components/TrainingRestrictions.js
1 function TrainingRestrictions() {} 2 3 TrainingRestrictions.prototype.Schema = 4 "<a:help>Specifies unit training restrictions, currently only unit category.</a:help>" + 5 "<a:example>" + 6 "<TrainingRestrictions>" + 7 "<Category>Hero</Category>" + 8 "</TrainingRestrictions>" + 9 "</a:example>" + 10 "<element name='Category' a:help='Specifies the category of this unit, for satisfying special constraints.'>" + 11 "<choice>" + 12 "<value>Hero</value>" + 13 "<value>FemaleCitizen</value>" + 14 "</choice>" + 15 "</element>"; 16 17 TrainingRestrictions.prototype.GetCategory = function() 18 { 19 return this.template.Category; 20 }; 21 22 Engine.RegisterComponentType(IID_TrainingRestrictions, "TrainingRestrictions", TrainingRestrictions); -
binaries/data/mods/public/simulation/components/GuiInterface.js
49 49 for (var i = 0; i < n; ++i) 50 50 { 51 51 var playerEnt = cmpPlayerMan.GetPlayerByID(i); 52 var cmpPlayer BuildLimits = Engine.QueryInterface(playerEnt, IID_BuildLimits);52 var cmpPlayerEntityLimits = Engine.QueryInterface(playerEnt, IID_EntityLimits); 53 53 var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player); 54 54 55 55 // Work out what phase we are in … … 84 84 "phase": phase, 85 85 "isAlly": allies, 86 86 "isEnemy": enemies, 87 " buildLimits": cmpPlayerBuildLimits.GetLimits(),88 " buildCounts": cmpPlayerBuildLimits.GetCounts(),87 "entityLimits": cmpPlayerEntityLimits.GetLimits(), 88 "entityCounts": cmpPlayerEntityLimits.GetCounts(), 89 89 "techModifications": cmpTechnologyManager.GetTechModifications() 90 90 }; 91 91 ret.players.push(playerData); … … 373 373 if (template.BuildRestrictions.Distance.MaxDistance) ret.buildRestrictions.distance.max = +template.BuildRestrictions.Distance.MaxDistance; 374 374 } 375 375 } 376 376 377 if (template.TrainingRestrictions) 378 { 379 ret.trainingRestrictions = { 380 "category": template.TrainingRestrictions.Category, 381 }; 382 } 383 377 384 if (template.Cost) 378 385 { 379 386 ret.cost = {}; … … 442 449 ret.icon = template.Identity.Icon; 443 450 ret.tooltip = template.Identity.Tooltip; 444 451 ret.requiredTechnology = template.Identity.RequiredTechnology; 452 ret.identityClassesString = GetTemplateIdentityClassesString(template); 445 453 } 446 454 447 455 if (template.UnitMotion) -
binaries/data/mods/public/simulation/components/BuildLimits.js
1 function BuildLimits() {}2 3 BuildLimits.prototype.Schema =4 "<a:help>Specifies per category limits on number of buildings that can be constructed for each player.</a:help>" +5 "<a:example>" +6 "<Limits>" +7 "<CivilCentre/>" +8 "<DefenseTower>25</DefenseTower>" +9 "<Fortress>10</Fortress>" +10 "<Special>" +11 "<LimitPerCivCentre>1</LimitPerCivCentre>" +12 "</Special>" +13 "</Limits>" +14 "</a:example>" +15 "<element name='LimitMultiplier'>" +16 "<ref name='positiveDecimal'/>" +17 "</element>" +18 "<element name='Limits'>" +19 "<zeroOrMore>" +20 "<element a:help='Specifies a category of building on which to apply this limit. See BuildRestrictions for list of categories.'>" +21 "<anyName />" +22 "<choice>" +23 "<text />" +24 "<element name='LimitPerCivCentre' a:help='Specifies that this limit is per number of civil centres.'>" +25 "<data type='nonNegativeInteger'/>" +26 "</element>" +27 "</choice>" +28 "</element>" +29 "</zeroOrMore>" +30 "</element>";31 32 /*33 * TODO: Use an inheriting player_{civ}.xml template for civ-specific limits34 */35 36 BuildLimits.prototype.Init = function()37 {38 this.limit = {};39 this.count = {};40 for (var category in this.template.Limits)41 {42 this.limit[category] = this.template.Limits[category];43 this.count[category] = 0;44 }45 };46 47 BuildLimits.prototype.IncrementCount = function(category)48 {49 if (this.count[category] !== undefined)50 {51 this.count[category]++;52 }53 };54 55 BuildLimits.prototype.DecrementCount = function(category)56 {57 if (this.count[category] !== undefined)58 {59 this.count[category]--;60 }61 };62 63 BuildLimits.prototype.GetLimits = function()64 {65 return this.limit;66 };67 68 BuildLimits.prototype.GetCounts = function()69 {70 return this.count;71 };72 73 BuildLimits.prototype.AllowedToBuild = function(category)74 {75 // TODO: The UI should reflect this before the user tries to place the building,76 // since the limits are independent of placement location77 78 // Allow unspecified categories and those with no limit79 if (this.count[category] === undefined || this.limit[category] === undefined)80 {81 return true;82 }83 84 // Rather than complicating the schema unecessarily, just handle special cases here85 if (this.limit[category].LimitPerCivCentre !== undefined)86 {87 if (this.count[category] >= this.count["CivilCentre"] * this.limit[category].LimitPerCivCentre)88 {89 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);90 var notification = {"player": cmpPlayer.GetPlayerID(), "message": category+" build limit of "+this.limit[category].LimitPerCivCentre+" per civil centre reached"};91 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);92 cmpGUIInterface.PushNotification(notification);93 94 return false;95 }96 }97 else if (this.count[category] >= this.limit[category])98 {99 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);100 var notification = {"player": cmpPlayer.GetPlayerID(), "message": category+" build limit of "+this.limit[category]+ " reached"};101 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);102 cmpGUIInterface.PushNotification(notification);103 104 return false;105 }106 107 return true;108 };109 110 BuildLimits.prototype.OnGlobalOwnershipChanged = function(msg)111 {112 // This automatically updates build counts113 var cmpBuildRestrictions = Engine.QueryInterface(msg.entity, IID_BuildRestrictions);114 if (cmpBuildRestrictions)115 {116 var playerID = (Engine.QueryInterface(this.entity, IID_Player)).GetPlayerID();117 if (msg.from == playerID)118 {119 this.DecrementCount(cmpBuildRestrictions.GetCategory());120 }121 if (msg.to == playerID)122 {123 this.IncrementCount(cmpBuildRestrictions.GetCategory());124 }125 }126 };127 128 Engine.RegisterComponentType(IID_BuildLimits, "BuildLimits", BuildLimits); -
binaries/data/mods/public/simulation/ai/jubot/gamestate.js
415 415 * Returns player build limits 416 416 * an object where each key is a category corresponding to a build limit for the player. 417 417 */ 418 get BuildLimits: function()418 getEntityLimits: function() 419 419 { 420 return this.playerData. buildLimits;420 return this.playerData.entityLimits; 421 421 }, 422 422 423 423 /** 424 424 * Returns player build counts 425 425 * an object where each key is a category corresponding to the current building count for the player. 426 426 */ 427 get BuildCounts: function()427 getEntityCounts: function() 428 428 { 429 return this.playerData. buildCounts;429 return this.playerData.entityCounts; 430 430 }, 431 431 432 432 /** 433 433 * Checks if the player's build limit has been reached for the given category. 434 434 * The category comes from the entity tenplate, specifically the BuildRestrictions component. 435 435 */ 436 is BuildLimitReached: function(category)436 isEntityLimitReached: function(category) 437 437 { 438 if (this.playerData. buildLimits[category] === undefined || this.playerData.buildCounts[category] === undefined)438 if (this.playerData.entityLimits[category] === undefined || this.playerData.entityCounts[category] === undefined) 439 439 return false; 440 440 441 441 // There's a special case of build limits per civ centre, so check that first 442 if (this.playerData. buildLimits[category].LimitPerCivCentre !== undefined)443 return (this.playerData. buildCounts[category] >= this.playerData.buildCounts["CivilCentre"]*this.playerData.buildLimits[category].LimitPerCivCentre);442 if (this.playerData.entityLimits[category].LimitPerCivCentre !== undefined) 443 return (this.playerData.entityCounts[category] >= this.playerData.entityCounts["CivilCentre"]*this.playerData.entityLimits[category].LimitPerCivCentre); 444 444 else 445 return (this.playerData. buildCounts[category] >= this.playerData.buildLimits[category]);445 return (this.playerData.entityCounts[category] >= this.playerData.entityLimits[category]); 446 446 }, 447 447 }); -
binaries/data/mods/public/simulation/ai/testbot/gamestate.js
268 268 * Returns player build limits 269 269 * an object where each key is a category corresponding to a build limit for the player. 270 270 */ 271 get BuildLimits: function()271 getEntityLimits: function() 272 272 { 273 return this.playerData. buildLimits;273 return this.playerData.entityLimits; 274 274 }, 275 275 276 276 /** 277 * Returns player buildcounts278 * an object where each key is a category corresponding to the current buildingcount for the player.277 * Returns player entity counts 278 * an object where each key is a category corresponding to the current entity count for the player. 279 279 */ 280 get BuildCounts: function()280 getEntityCounts: function() 281 281 { 282 return this.playerData. buildCounts;282 return this.playerData.entityCounts; 283 283 }, 284 284 285 285 /** 286 * Checks if the player's buildlimit has been reached for the given category.286 * Checks if the player's entity limit has been reached for the given category. 287 287 * The category comes from the entity tenplate, specifically the BuildRestrictions component. 288 288 */ 289 is BuildLimitReached: function(category)289 isEntityLimitReached: function(category) 290 290 { 291 if (this.playerData. buildLimits[category] === undefined || this.playerData.buildCounts[category] === undefined)291 if (this.playerData.entityLimits[category] === undefined || this.playerData.entityCounts[category] === undefined) 292 292 return false; 293 293 294 294 // There's a special case of build limits per civ centre, so check that first 295 if (this.playerData. buildLimits[category].LimitPerCivCentre !== undefined)296 return (this.playerData. buildCounts[category] >= this.playerData.buildCounts["CivilCentre"]*this.playerData.buildLimits[category].LimitPerCivCentre);295 if (this.playerData.entityLimits[category].LimitPerCivCentre !== undefined) 296 return (this.playerData.entityCounts[category] >= this.playerData.entityCounts["CivilCentre"]*this.playerData.entityLimits[category].LimitPerCivCentre); 297 297 else 298 return (this.playerData. buildCounts[category] >= this.playerData.buildLimits[category]);298 return (this.playerData.entityCounts[category] >= this.playerData.entityLimits[category]); 299 299 }, 300 300 }); -
binaries/data/mods/public/simulation/ai/qbot/gamestate.js
300 300 return this.updatingCollection("resource-" + resource, Filters.byResource(resource), this.getEntities()); 301 301 }; 302 302 303 GameState.prototype.get BuildLimits = function() {304 return this.playerData. buildLimits;303 GameState.prototype.getEntityLimits = function() { 304 return this.playerData.entityLimits; 305 305 }; 306 306 307 GameState.prototype.get BuildCounts = function() {308 return this.playerData. buildCounts;307 GameState.prototype.getEntityCounts = function() { 308 return this.playerData.entityCounts; 309 309 }; 310 310 311 311 // Checks whether the maximum number of buildings have been cnstructed for a certain catergory 312 GameState.prototype.is BuildLimitReached = function(category) {313 if(this.playerData. buildLimits[category] === undefined || this.playerData.buildCounts[category] === undefined)312 GameState.prototype.isEntityLimitReached = function(category) { 313 if(this.playerData.entityLimits[category] === undefined || this.playerData.entityCounts[category] === undefined) 314 314 return false; 315 if(this.playerData. buildLimits[category].LimitsPerCivCentre != undefined)316 return (this.playerData. buildCounts[category] >= this.playerData.buildCounts["CivilCentre"]*this.playerData.buildLimits[category].LimitPerCivCentre);315 if(this.playerData.entityLimits[category].LimitsPerCivCentre != undefined) 316 return (this.playerData.entityCounts[category] >= this.playerData.entityCounts["CivilCentre"]*this.playerData.entityLimits[category].LimitPerCivCentre); 317 317 else 318 return (this.playerData. buildCounts[category] >= this.playerData.buildLimits[category]);318 return (this.playerData.entityCounts[category] >= this.playerData.entityLimits[category]); 319 319 }; -
binaries/data/mods/public/simulation/ai/qbot/military.js
324 324 // Adds towers to the defenceBuilding queue 325 325 MilitaryAttackManager.prototype.buildDefences = function(gameState, queues){ 326 326 if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv('structures/{civ}_defense_tower')) 327 + queues.defenceBuilding.totalLength() < gameState.get BuildLimits()["DefenseTower"]) {327 + queues.defenceBuilding.totalLength() < gameState.getEntityLimits()["DefenseTower"]) { 328 328 329 329 330 330 gameState.getOwnEntities().forEach(function(dropsiteEnt) { … … 343 343 numFortresses += gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bFort[i])); 344 344 } 345 345 346 if (numFortresses + queues.defenceBuilding.totalLength() < gameState.get BuildLimits()["Fortress"]) {346 if (numFortresses + queues.defenceBuilding.totalLength() < gameState.getEntityLimits()["Fortress"]) { 347 347 if (gameState.countEntitiesByType(gameState.applyCiv("units/{civ}_support_female_citizen")) > gameState.ai.modules["economy"].targetNumWorkers * 0.5){ 348 348 if (gameState.getTimeElapsed() > 350 * 1000 * numFortresses){ 349 349 if (gameState.ai.pathsToMe && gameState.ai.pathsToMe.length > 0){ -
binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
91 91 <Stamina> 92 92 <Max>500</Max> 93 93 </Stamina> 94 <TrainingRestrictions> 95 <Category>FemaleCitizen</Category> 96 </TrainingRestrictions> 94 97 <UnitMotion> 95 98 <WalkSpeed>8.0</WalkSpeed> 96 99 <Run> -
binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml
68 68 <Stamina> 69 69 <Max>2500</Max> 70 70 </Stamina> 71 <TrainingRestrictions> 72 <Category>Hero</Category> 73 </TrainingRestrictions> 71 74 <UnitMotion> 72 75 <WalkSpeed>11.0</WalkSpeed> 73 76 <Run> -
binaries/data/mods/public/simulation/templates/special/player.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity> 3 < BuildLimits>3 <EntityLimits> 4 4 <LimitMultiplier>1.0</LimitMultiplier> 5 5 <Limits> 6 6 <CivilCentre/> 7 7 <DefenseTower>25</DefenseTower> 8 8 <Fortress>10</Fortress> 9 <FemaleCitizen>6</FemaleCitizen> 10 <Hero>1</Hero> 9 11 </Limits> 10 </ BuildLimits>12 </EntityLimits> 11 13 <Player/> 12 14 <StatisticsTracker/> 13 15 <TechnologyManager/> -
binaries/data/mods/public/simulation/templates/template_unit_hero.xml
61 61 <death>actor/human/death/death.xml</death> 62 62 </SoundGroups> 63 63 </Sound> 64 <TrainingRestrictions> 65 <Category>Hero</Category> 66 </TrainingRestrictions> 64 67 <UnitMotion> 65 68 <WalkSpeed>9.0</WalkSpeed> 66 69 <Run> -
binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_archer.xml
68 68 </Texture> 69 69 </Overlay> 70 70 </Selectable> 71 <TrainingRestrictions> 72 <Category>Hero</Category> 73 </TrainingRestrictions> 71 74 <UnitMotion> 72 75 <WalkSpeed>11.0</WalkSpeed> 73 76 <Run> -
binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_javelinist.xml
58 58 </Texture> 59 59 </Overlay> 60 60 </Selectable> 61 <TrainingRestrictions> 62 <Category>Hero</Category> 63 </TrainingRestrictions> 61 64 <UnitMotion> 62 65 <WalkSpeed>11.5</WalkSpeed> 63 66 <Run> -
binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_archer.xml
60 60 </Texture> 61 61 </Overlay> 62 62 </Selectable> 63 <TrainingRestrictions> 64 <Category>Hero</Category> 65 </TrainingRestrictions> 63 66 </Entity> -
binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_javelinist.xml
64 64 </Texture> 65 65 </Overlay> 66 66 </Selectable> 67 <TrainingRestrictions> 68 <Category>Hero</Category> 69 </TrainingRestrictions> 67 70 </Entity> -
binaries/data/mods/public/simulation/templates/template_unit_hero_infantry.xml
66 66 <Stamina> 67 67 <Max>1500</Max> 68 68 </Stamina> 69 <TrainingRestrictions> 70 <Category>Hero</Category> 71 </TrainingRestrictions> 69 72 <UnitMotion> 70 73 <WalkSpeed>8.5</WalkSpeed> 71 74 <Run> -
binaries/data/mods/public/simulation/templates/template_unit_hero_ranged.xml
42 42 <Minimap> 43 43 <Type>hero</Type> 44 44 </Minimap> 45 <TrainingRestrictions> 46 <Category>Hero</Category> 47 </TrainingRestrictions> 45 48 <UnitMotion> 46 49 <WalkSpeed>8.5</WalkSpeed> 47 50 <Run> -
binaries/data/mods/public/simulation/helpers/Templates.js
1 /** 2 * Return template.Identity.Classes._string if exists 3 */ 4 function GetTemplateIdentityClassesString(template) 5 { 6 var identityClassesString = undefined; 7 if (template.Identity && template.Identity.Classes && "_string" in template.Identity.Classes) 8 identityClassesString = template.Identity.Classes._string; 9 return identityClassesString; 10 } 11 12 /** 13 * Check whether template.Identity.Classes contains specified class 14 */ 15 function TemplateHasIdentityClass(template, className) 16 { 17 var identityClassesString = GetTemplateIdentityClassesString(template); 18 var hasClass = identityClassesString && identityClassesString.indexOf(className) != -1; 19 return hasClass; 20 } 21 22 Engine.RegisterGlobal("GetTemplateIdentityClassesString", GetTemplateIdentityClassesString); 23 Engine.RegisterGlobal("TemplateHasIdentityClass", TemplateHasIdentityClass); 24 -
binaries/data/mods/public/simulation/helpers/Commands.js
142 142 143 143 case "train": 144 144 var entities = FilterEntityList(cmd.entities, player, controlAllUnits); 145 146 // Check entity limits 147 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 148 var template = cmpTempMan.GetTemplate(cmd.template); 149 var unitCategory = null; 150 if (template.TrainingRestrictions) 151 unitCategory = template.TrainingRestrictions.Category; 152 145 153 // Verify that the building(s) can be controlled by the player 146 154 if (entities.length > 0) 147 155 { 148 156 for each (var ent in entities) 149 157 { 158 if (unitCategory) 159 { 160 var cmpPlayerEntityLimits = QueryOwnerInterface(ent, IID_EntityLimits); 161 if (!cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count)) 162 { 163 if (g_DebugCommands) 164 { 165 warn(unitCategory + " train limit is reached: "+uneval(cmd)); 166 } 167 continue; 168 } 169 } 170 150 171 var cmpTechMan = QueryOwnerInterface(ent, IID_TechnologyManager); 151 172 // TODO: Enable this check once the AI gets technology support 152 173 if (cmpTechMan.CanProduce(cmd.template) || true) … … 524 545 return false; 525 546 } 526 547 527 // Check buildlimits528 var cmp BuildLimits = QueryPlayerIDInterface(player, IID_BuildLimits);529 if (!cmp BuildLimits || !cmpBuildLimits.AllowedToBuild(cmpBuildRestrictions.GetCategory()))548 // Check entity limits 549 var cmpEntityLimits = QueryPlayerIDInterface(player, IID_EntityLimits); 550 if (!cmpEntityLimits || !cmpEntityLimits.AllowedToBuild(cmpBuildRestrictions.GetCategory())) 530 551 { 531 552 if (g_DebugCommands) 532 553 {