Ticket #1432: one_hero_2012_05_26.diff
File one_hero_2012_05_26.diff, 12.7 KB (added by , 12 years ago) |
---|
-
binaries/data/mods/public/gui/session/unit_commands.js
145 145 * @param items Panel-specific data to construct the icons with. 146 146 * @param callback Callback function to argument to execute when an item's icon gets clicked. Takes a single 'item' argument. 147 147 */ 148 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)148 function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, callback) 149 149 { 150 150 usedPanels[guiName] = 1; 151 151 … … 343 343 tooltip += "\n" + getEntitySpeed(template); 344 344 345 345 tooltip += "\n\n[font=\"serif-bold-13\"]Shift-click[/font][font=\"serif-13\"] to train " + trainNum + ".[/font]"; 346 347 346 break; 348 347 349 348 case RESEARCH: … … 492 491 icon.sprite = "stretched:session/icons/" + item.icon; 493 492 494 493 } 494 else if (guiName == "Training") 495 { 496 if (template.icon) 497 { 498 var isHero = template.identityClassesString.indexOf("Hero") != -1; 499 var grayscale = isHero && playerState.hasHero ? "grayscale:" : ""; 500 icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 501 } 502 } 495 503 else if (template.icon) 496 504 { 497 505 var grayscale = ""; … … 636 644 } 637 645 638 646 // Sets up "unit barter panel" - special case for setupUnitPanel 639 function setupUnitBarterPanel(unitEntState )647 function setupUnitBarterPanel(unitEntState, playerState) 640 648 { 641 649 // Amount of player's resource to exchange 642 650 var amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; … … 714 722 var player = Engine.GetPlayerID(); 715 723 if (entState.player == player || g_DevSettings.controlAll) 716 724 { 725 // Get player state to check some constraints 726 // e.g. presence of a hero or build limits 727 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 728 var playerState = simState.players[player]; 729 717 730 if (selection.length > 1) 718 setupUnitPanel(SELECTION, usedPanels, entState, g_Selection.groups.getTemplateNames(),731 setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(), 719 732 function (entType) { changePrimarySelectionGroup(entType); } ); 720 733 721 734 var commands = getEntityCommandsList(entState); 722 735 if (commands.length) 723 setupUnitPanel(COMMAND, usedPanels, entState, commands,736 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 724 737 function (item) { performCommand(entState.id, item.name); } ); 725 738 726 739 if (entState.garrisonHolder) 727 740 { 728 741 var groups = new EntityGroups(); 729 742 groups.add(entState.garrisonHolder.entities); 730 setupUnitPanel(GARRISON, usedPanels, entState, groups.getTemplateNames(),743 setupUnitPanel(GARRISON, usedPanels, entState, playerState, groups.getTemplateNames(), 731 744 function (item) { unload(entState.id, groups.getEntsByName(item)); } ); 732 745 } 733 746 734 747 var formations = Engine.GuiInterfaceCall("GetAvailableFormations"); 735 748 if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && formations.length) 736 749 { 737 setupUnitPanel(FORMATION, usedPanels, entState, formations,750 setupUnitPanel(FORMATION, usedPanels, entState, playerState, formations, 738 751 function (item) { performFormation(entState.id, item); } ); 739 752 } 740 753 … … 743 756 var stances = ["violent", "aggressive", "passive", "defensive", "standground"]; 744 757 if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && stances.length) 745 758 { 746 setupUnitPanel(STANCE, usedPanels, entState, stances,759 setupUnitPanel(STANCE, usedPanels, entState, playerState, stances, 747 760 function (item) { performStance(entState.id, item); } ); 748 761 } 749 762 … … 751 764 if (entState.barterMarket) 752 765 { 753 766 usedPanels["Barter"] = 1; 754 setupUnitBarterPanel(entState );767 setupUnitBarterPanel(entState, playerState); 755 768 } 756 769 757 770 var buildableEnts = []; … … 771 784 removeDupes(trainableEnts); 772 785 773 786 if (buildableEnts.length && ((trainableEnts.length && hasClass(entState, "Unit")) || !trainableEnts.length)) 774 setupUnitPanel(CONSTRUCTION, usedPanels, entState, buildableEnts, startBuildingPlacement);787 setupUnitPanel(CONSTRUCTION, usedPanels, entState, playerState, buildableEnts, startBuildingPlacement); 775 788 else if (trainableEnts.length) 776 setupUnitPanel(TRAINING, usedPanels, entState, trainableEnts,789 setupUnitPanel(TRAINING, usedPanels, entState, playerState, trainableEnts, 777 790 function (trainEntType) { addTrainingToQueue(selection, trainEntType); } ); 778 791 779 792 if (entState.production && entState.production.technologies.length && selection.length == 1) 780 793 { 781 setupUnitPanel(RESEARCH, usedPanels, entState, entState.production.technologies,794 setupUnitPanel(RESEARCH, usedPanels, entState, playerState, entState.production.technologies, 782 795 function (researchType) { addResearchToQueue(entState.id, researchType); } ); 783 796 } 784 797 785 798 if (entState.production && entState.production.queue.length) 786 setupUnitPanel(QUEUE, usedPanels, entState, entState.production.queue,799 setupUnitPanel(QUEUE, usedPanels, entState, playerState, entState.production.queue, 787 800 function (item) { removeFromProductionQueue(entState.id, item.id); } ); 788 801 789 802 if (entState.trader) -
binaries/data/mods/public/simulation/components/GuiInterface.js
82 82 "state": cmpPlayer.GetState(), 83 83 "team": cmpPlayer.GetTeam(), 84 84 "phase": phase, 85 "hasHero": cmpPlayer.HasHero(), 85 86 "isAlly": allies, 86 87 "isEnemy": enemies, 87 88 "buildLimits": cmpPlayerBuildLimits.GetLimits(), … … 426 427 ret.icon = template.Identity.Icon; 427 428 ret.tooltip = template.Identity.Tooltip; 428 429 ret.requiredTechnology = template.Identity.RequiredTechnology; 430 ret.identityClassesString = GetTemplateIdentityClassesString(template); 429 431 } 430 432 431 433 if (template.UnitMotion) -
binaries/data/mods/public/simulation/components/ProductionQueue.js
199 199 if (!cmpPlayer.TrySubtractResources(totalCosts)) 200 200 return; 201 201 202 // If we train a hero, state this in player compoment 203 var isHero = TemplateHasIdentityClass(template, "Hero"); 204 if (isHero) 205 cmpPlayer.IncreaseHeroesCount(); 206 202 207 this.queue.push({ 203 208 "id": this.nextID++, 204 209 "player": cmpPlayer.GetPlayerID(), … … 292 297 293 298 var cmpPlayer = QueryPlayerIDInterface(item.player, IID_Player); 294 299 300 // If we trained a hero, state this in player compoment 301 if (item.unitTemplate) 302 { 303 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 304 var template = cmpTempMan.GetTemplate(item.unitTemplate); 305 var isHero = TemplateHasIdentityClass(template, "Hero"); 306 if (isHero) 307 cmpPlayer.DecreaseHeroesCount(); 308 } 309 295 310 // Refund the resource cost for this batch 296 311 var totalCosts = {}; 297 312 for each (var r in ["food", "wood", "stone", "metal"]) … … 401 416 // so only create them once and use as needed 402 417 for (var i = 0; i < count; ++i) 403 418 { 404 this.entityCache.push(Engine.AddEntity(templateName)); 419 var ent = Engine.AddEntity(templateName); 420 this.entityCache.push(ent); 421 // If we create a hero entity - decrease heroes count, since it will be 422 // increased by Player.OnGlobalOwnershipChanged function, 423 // i.e. we replace 'trained' hero to a 'alive' one 424 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 425 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 426 var isHero = cmpIdentity.HasClass('Hero'); 427 if (isHero) 428 cmpPlayer.DecreaseHeroesCount(); 405 429 } 406 430 } 407 431 -
binaries/data/mods/public/simulation/components/Player.js
24 24 this.state = "active"; // game state - one of "active", "defeated", "won" 25 25 this.diplomacy = []; // array of diplomatic stances for this player with respect to other players (including gaia and self) 26 26 this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class 27 this.heroesCount = 0; // number of owned units with Hero class 27 28 this.phase = "village"; 28 29 this.formations = []; 29 30 this.startCam = undefined; … … 328 329 Player.prototype.OnGlobalOwnershipChanged = function(msg) 329 330 { 330 331 var isConquestCritical = false; 331 332 var isHero = false; 332 333 // Load class list only if we're going to need it 333 334 if (msg.from == this.playerID || msg.to == this.playerID) 334 335 { 335 336 var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity); 336 337 if (cmpIdentity) 337 338 { 338 var classes = cmpIdentity.GetClassesList();339 is ConquestCritical = classes.indexOf("ConquestCritical") != -1;339 isConquestCritical = cmpIdentity.HasClass("ConquestCritical"); 340 isHero = cmpIdentity.HasClass("Hero"); 340 341 } 341 342 } 342 343 343 if (msg.from == this.playerID) 344 344 { 345 345 if (isConquestCritical) 346 this.conquestCriticalEntitiesCount--; 347 346 this.conquestCriticalEntitiesCount--; 347 if (isHero) 348 this.heroesCount--; 348 349 var cost = Engine.QueryInterface(msg.entity, IID_Cost); 349 350 if (cost) 350 351 { … … 352 353 this.popBonuses -= cost.GetPopBonus(); 353 354 } 354 355 } 355 356 356 if (msg.to == this.playerID) 357 357 { 358 358 if (isConquestCritical) 359 359 this.conquestCriticalEntitiesCount++; 360 360 if (isHero) 361 this.heroesCount++; 361 362 var cost = Engine.QueryInterface(msg.entity, IID_Cost); 362 363 if (cost) 363 364 { … … 382 383 } 383 384 }; 384 385 386 Player.prototype.IncreaseHeroesCount = function() 387 { 388 this.heroesCount++; 389 } 390 391 Player.prototype.DecreaseHeroesCount = function() 392 { 393 this.heroesCount--; 394 } 395 396 Player.prototype.HasHero = function() 397 { 398 return this.heroesCount != 0; 399 } 400 385 401 Engine.RegisterComponentType(IID_Player, "Player", Player); -
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 hero restrictions 147 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 148 var template = cmpTempMan.GetTemplate(cmd.template); 149 var isHero = TemplateHasIdentityClass(template, "Hero"); 150 if (isHero && +cmd.count > 1) 151 { 152 if (g_DebugCommands) 153 { 154 warn("Invalid command: batch training isn't allowed for heroes: "+uneval(cmd)); 155 } 156 return; 157 } 158 145 159 // Verify that the building(s) can be controlled by the player 146 160 if (entities.length > 0) 147 161 { 148 162 for each (var ent in entities) 149 163 { 164 if (isHero) 165 { 166 var cmpPlayer = QueryOwnerInterface(ent, IID_Player); 167 if (cmpPlayer.HasHero()) 168 { 169 if (g_DebugCommands) 170 { 171 warn("Invalid command: can't train hero because player already has one: "+uneval(cmd)); 172 } 173 continue; 174 } 175 } 176 150 177 var cmpTechMan = QueryOwnerInterface(ent, IID_TechnologyManager); 151 178 // TODO: Enable this check once the AI gets technology support 152 179 if (cmpTechMan.CanProduce(cmd.template) || true)