Ticket #1432: one_hero_2012_05_24.diff

File one_hero_2012_05_24.diff, 12.2 KB (added by fcxSanya, 12 years ago)

my old unfinished patch

  • binaries/data/mods/public/gui/session/unit_commands.js

     
    129129}
    130130
    131131// Sets up "unit panels" - the panels with rows of icons (Helper function for updateUnitDisplay)
    132 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
     132function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, callback)
    133133{
    134134    usedPanels[guiName] = 1;
    135135    var numberOfItems = items.length;
     
    253253                    tooltip += "\n" + getEntitySpeed(template);
    254254
    255255                tooltip += "\n\n[font=\"serif-bold-13\"]Shift-click[/font][font=\"serif-13\"] to train " + trainNum + ".[/font]";
    256 
    257256                break;
    258257
    259258            case CONSTRUCTION:
     
    338337            icon.sprite = "stretched:session/icons/single/" + item.icon;
    339338
    340339        }
     340        else if (guiName == "Training")
     341        {
     342            if (template.icon)
     343            {
     344                icon.sprite = "stretched:session/portraits/" + template.icon;
     345            }
     346        }
    341347        else if (template.icon)
    342348        {
    343349            icon.sprite = "stretched:session/portraits/" + template.icon;
     
    390396}
    391397
    392398// Sets up "unit barter panel" - special case for setupUnitPanel
    393 function setupUnitBarterPanel(unitEntState)
     399function setupUnitBarterPanel(unitEntState, playerState)
    394400{
    395401    // Amount of player's resource to exchange
    396402    var amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL;
     
    460466    var player = Engine.GetPlayerID();
    461467    if (entState.player == player || g_DevSettings.controlAll)
    462468    {
     469        // Get player state to check some constraints
     470        // e.g. presence of a hero or build limits
     471        var simState = Engine.GuiInterfaceCall("GetSimulationState");
     472        var playerState = simState.players[player];
     473
    463474        if (entState.attack) // TODO - this should be based on some AI properties
    464475        {
    465476            //usedPanels["Stance"] = 1;
     
    472483        }
    473484
    474485        if (selection.length > 1)
    475             setupUnitPanel("Selection", usedPanels, entState, g_Selection.groups.getTemplateNames(),
     486            setupUnitPanel("Selection", usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(),
    476487                function (entType) { changePrimarySelectionGroup(entType); } );
    477488
    478489        var commands = getEntityCommandsList(entState);
    479490        if (commands.length)
    480             setupUnitPanel("Command", usedPanels, entState, commands,
     491            setupUnitPanel("Command", usedPanels, entState, playerState, commands,
    481492                function (item) { performCommand(entState.id, item.name); } );
    482493
    483494        if (entState.garrisonHolder)
    484495        {
    485496            var groups = new EntityGroups();
    486497            groups.add(entState.garrisonHolder.entities);
    487             setupUnitPanel("Garrison", usedPanels, entState, groups.getTemplateNames(),
     498            setupUnitPanel("Garrison", usedPanels, entState, playerState, groups.getTemplateNames(),
    488499                function (item) { unload(entState.id, groups.getEntsByName(item)[0]); } );
    489500        }
    490501
    491502        var formations = getEntityFormationsList(entState);
    492503        if (isUnit(entState) && !isAnimal(entState) && !entState.garrisonHolder && formations.length)
    493504        {
    494             setupUnitPanel("Formation", usedPanels, entState, formations,
     505            setupUnitPanel("Formation", usedPanels, entState, playerState, formations,
    495506                function (item) { performFormation(entState.id, item); } );
    496507        }
    497508
     
    500511        var stances = ["violent", "aggressive", "passive", "defensive", "stand"];
    501512        if (isUnit(entState) && !isAnimal(entState) && !entState.garrisonHolder && stances.length)
    502513        {
    503             setupUnitPanel("Stance", usedPanels, entState, stances,
     514            setupUnitPanel("Stance", usedPanels, entState, playerState, stances,
    504515                function (item) { performStance(entState.id, item); } );
    505516        }
    506517
     
    508519        if (entState.barterMarket)
    509520        {
    510521            usedPanels["Barter"] = 1;
    511             setupUnitBarterPanel(entState);
     522            setupUnitBarterPanel(entState, playerState);
    512523        }
    513524
    514525        if (entState.buildEntities && entState.buildEntities.length)
    515526        {
    516             setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement);
     527            setupUnitPanel("Construction", usedPanels, entState, playerState, entState.buildEntities, startBuildingPlacement);
    517528//          isInvisible = false;
    518529        }
    519530
    520531        if (entState.training && entState.training.entities.length)
    521532        {
    522             setupUnitPanel("Training", usedPanels, entState, entState.training.entities,
     533            setupUnitPanel("Training", usedPanels, entState, playerState, entState.training.entities,
    523534                function (trainEntType) { addToTrainingQueue(entState.id, trainEntType); } );
    524535//          isInvisible = false;
    525536        }
    526537
    527538        if (entState.training && entState.training.queue.length)
    528             setupUnitPanel("Queue", usedPanels, entState, entState.training.queue,
     539            setupUnitPanel("Queue", usedPanels, entState, playerState, entState.training.queue,
    529540                function (item) { removeFromTrainingQueue(entState.id, item.id); } );
    530541
    531542//      supplementalDetailsPanel.hidden = false;
  • binaries/data/mods/public/simulation/components/Player.js

     
    2424    this.state = "active"; // game state - one of "active", "defeated", "won"
    2525    this.diplomacy = [];    // array of diplomatic stances for this player with respect to other players (including gaia and self)
    2626    this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class
     27    this.heroesCount = 0; // number of owned units with Hero class
    2728    this.phase = "village";
    2829    this.startCam = undefined;
    2930    this.controlAllUnits = false;
     
    328329Player.prototype.OnGlobalOwnershipChanged = function(msg)
    329330{
    330331    var isConquestCritical = false;
    331 
     332    var isHero = false;
    332333    // Load class list only if we're going to need it
    333334    if (msg.from == this.playerID || msg.to == this.playerID)
    334335    {
    335336        var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity);
    336337        if (cmpIdentity)
    337338        {
    338             var classes = cmpIdentity.GetClassesList();
    339             isConquestCritical = classes.indexOf("ConquestCritical") != -1;
     339            isConquestCritical = cmpIdentity.HasClass("ConquestCritical");
     340            isHero = cmpIdentity.HasClass("Hero");
    340341        }
    341342    }
    342    
    343343    if (msg.from == this.playerID)
    344344    {
    345345        if (isConquestCritical)
    346             this.conquestCriticalEntitiesCount--;   
    347 
     346            this.conquestCriticalEntitiesCount--;
     347        if (isHero)
     348            this.heroesCount--;
    348349        var cost = Engine.QueryInterface(msg.entity, IID_Cost);
    349350        if (cost)
    350351        {
     
    352353            this.popBonuses -= cost.GetPopBonus();
    353354        }
    354355    }
    355    
    356356    if (msg.to == this.playerID)
    357357    {
    358358        if (isConquestCritical)
    359359            this.conquestCriticalEntitiesCount++;
    360            
     360        if (isHero)
     361            this.heroesCount++;
    361362        var cost = Engine.QueryInterface(msg.entity, IID_Cost);
    362363        if (cost)
    363364        {
     
    382383    }
    383384};
    384385
     386Player.prototype.IncreaseHeroesCount = function()
     387{
     388    this.heroesCount++;
     389}
     390
     391Player.prototype.DecreaseHeroesCount = function()
     392{
     393    this.heroesCount--;
     394}
     395
     396Player.prototype.HasHero = function()
     397{
     398    return this.heroesCount != 0;
     399}
     400
    385401Engine.RegisterComponentType(IID_Player, "Player", Player);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    7070            "state": cmpPlayer.GetState(),
    7171            "team": cmpPlayer.GetTeam(),
    7272            "phase": cmpPlayer.GetPhase(),
     73            "hasHero": cmpPlayer.HasHero(),
    7374            "isAlly": allies,
    7475            "isEnemy": enemies,
    7576            "buildLimits": cmpPlayerBuildLimits.GetLimits(),
  • binaries/data/mods/public/simulation/components/TrainingQueue.js

     
    9090        if (!cmpPlayer.TrySubtractResources(totalCosts))
    9191            return;
    9292
     93        // If we train a hero, state this in player compoment
     94        var isHero = TemplateHasIdentityClass(template, "Hero");
     95        if (isHero)
     96            cmpPlayer.IncreaseHeroesCount();
     97
    9398        this.queue.push({
    9499            "id": this.nextID++,
    95100            "player": cmpPlayer.GetPlayerID(),
     
    102107            "timeTotal": time*1000,
    103108            "timeRemaining": time*1000,
    104109        });
     110
    105111        Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });
    106112
    107113        // If this is the first item in the queue, start the timer
     
    142148
    143149        var cmpPlayer = QueryPlayerIDInterface(item.player, IID_Player);
    144150
     151        // If we trained a hero, state this in player compoment
     152        var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     153        var template = cmpTempMan.GetTemplate(item.template);
     154        var isHero = TemplateHasIdentityClass(template, "Hero");
     155        if (isHero)
     156            cmpPlayer.DecreaseHeroesCount();
     157
    145158        // Refund the resource cost for this batch
    146159        var totalCosts = {};
    147160        for each (var r in ["food", "wood", "stone", "metal"])
     
    243256        //  so only create them once and use as needed
    244257        for (var i = 0; i < count; ++i)
    245258        {
    246             this.entityCache.push(Engine.AddEntity(templateName));
     259            var ent = Engine.AddEntity(templateName);
     260            this.entityCache.push(ent);
     261            // If we create a hero entity - decrease heroes count, since it will be
     262            // increased by Player.OnGlobalOwnershipChanged function,
     263            // i.e. we replace 'trained' hero to a 'alive' one
     264            var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
     265            var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
     266            var isHero = cmpIdentity.HasClass('Hero');
     267            if (isHero)
     268                cmpPlayer.DecreaseHeroesCount();
    247269        }
    248270    }
    249271
  • binaries/data/mods/public/simulation/helpers/Templates.js

     
     1/**
     2 * Check whether template.Identity.Classes contains specified class
     3 */
     4function TemplateHasIdentityClass(template, className)
     5{
     6    var hasClass = template.Identity && template.Identity.Classes && "_string" in template.Identity.Classes && template.Identity.Classes._string.indexOf(className) != -1;
     7    return hasClass;
     8}
     9
     10Engine.RegisterGlobal("TemplateHasIdentityClass", TemplateHasIdentityClass);
     11
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    119119
    120120    case "train":
    121121        // Verify that the building can be controlled by the player
    122         if (CanControlUnit(cmd.entity, player, controlAllUnits))
     122        if (!CanControlUnit(cmd.entity, player, controlAllUnits))
    123123        {
    124             var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
    125             if (queue)
    126                 queue.AddBatch(cmd.template, +cmd.count, cmd.metadata);
     124            if (g_DebugCommands)
     125            {
     126                warn("Invalid command: training building cannot be controlled by player "+player+": "+uneval(cmd));
     127            }
     128            break;
    127129        }
    128         else if (g_DebugCommands)
     130        // Check hero restrictions
     131        var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     132        var template = cmpTempMan.GetTemplate(cmd.template);
     133        var isHero = TemplateHasIdentityClass(template, "Hero");
     134        if (isHero)
    129135        {
    130             warn("Invalid command: training building cannot be controlled by player "+player+": "+uneval(cmd));
     136            var cmpPlayer = QueryOwnerInterface(cmd.entity, IID_Player);
     137            if (+cmd.count > 1)
     138            {
     139                if (g_DebugCommands)
     140                {
     141                    warn("Invalid command: batch training isn't allowed for heroes: "+uneval(cmd));
     142                }
     143                break;
     144            }
     145            if (cmpPlayer.HasHero())
     146            {
     147                if (g_DebugCommands)
     148                {
     149                    warn("Invalid command: can't train hero because player already has one: "+uneval(cmd));
     150                }
     151                break;
     152            }
    131153        }
     154
     155        var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
     156        if (queue)
     157            queue.AddBatch(cmd.template, +cmd.count, cmd.metadata);
    132158        break;
    133159
    134160    case "stop-train":