Index: ps/trunk/binaries/data/mods/public/gui/session/input.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/input.js +++ ps/trunk/binaries/data/mods/public/gui/session/input.js @@ -1013,11 +1013,6 @@ // Select units matching exact template name (same rank) templateToMatch = GetEntityState(selectedEntity).template; - // Remove the player prefix (e.g. "p3&") - let index = templateToMatch.indexOf("&"); - if (index != -1) - templateToMatch = templateToMatch.slice(index+1); - // TODO: Should we handle "control all units" here as well? ents = Engine.PickSimilarPlayerEntities(templateToMatch, showOffscreen, matchRank, false); } @@ -1718,7 +1713,7 @@ Engine.PostNetworkCommand({ "type": "unload", "entities": [entities[0]], "garrisonHolder": garrisonHolder }); } -function unloadTemplate(template) +function unloadTemplate(template, owner) { // Filter out all entities that aren't garrisonable. var garrisonHolders = g_Selection.toList().filter(e => { @@ -1732,6 +1727,7 @@ "type": "unload-template", "all": Engine.HotkeyIsPressed("session.unloadtype"), "template": template, + "owner": owner, "garrisonHolders": garrisonHolders }); } Index: ps/trunk/binaries/data/mods/public/gui/session/selection.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/selection.js +++ ps/trunk/binaries/data/mods/public/gui/session/selection.js @@ -48,46 +48,43 @@ { for (let ent of ents) { - if (!this.ents[ent]) - { - var entState = GetEntityState(ent); + if (this.ents[ent]) + continue; + var entState = GetEntityState(ent); - // When this function is called during group rebuild, deleted - // entities will not yet have been removed, so entities might - // still be present in the group despite not existing. - if (!entState) - continue; + // When this function is called during group rebuild, deleted + // entities will not yet have been removed, so entities might + // still be present in the group despite not existing. + if (!entState) + continue; - var templateName = entState.template; - var key = GetTemplateData(templateName).selectionGroupName || templateName; + var templateName = entState.template; + var key = GetTemplateData(templateName).selectionGroupName || templateName; - // TODO ugly hack, just group them by player too. - // Prefix garrisoned unit's selection name with the player they belong to - var index = templateName.indexOf("&"); - if (index != -1 && key.indexOf("&") == -1) - key = templateName.slice(0, index+1) + key; - - if (this.groups[key]) - this.groups[key] += 1; - else - this.groups[key] = 1; + // Group the ents by player and template + if (entState.player !== undefined) + key = "p" + entState.player + "&" + key; + + if (this.groups[key]) + this.groups[key] += 1; + else + this.groups[key] = 1; - this.ents[ent] = key; - } + this.ents[ent] = key; } }; EntityGroups.prototype.removeEnt = function(ent) { - var templateName = this.ents[ent]; + var key = this.ents[ent]; // Remove the entity delete this.ents[ent]; - --this.groups[templateName]; + --this.groups[key]; // Remove the entire group - if (this.groups[templateName] == 0) - delete this.groups[templateName]; + if (this.groups[key] == 0) + delete this.groups[key]; }; EntityGroups.prototype.rebuildGroup = function(renamed) @@ -102,55 +99,55 @@ this.add(toAdd); }; -EntityGroups.prototype.getCount = function(templateName) +EntityGroups.prototype.getCount = function(key) { - return this.groups[templateName]; + return this.groups[key]; }; EntityGroups.prototype.getTotalCount = function() { let totalCount = 0; - for (let templateName in this.groups) - totalCount += this.groups[templateName]; + for (let key in this.groups) + totalCount += this.groups[key]; return totalCount; }; -EntityGroups.prototype.getTemplateNames = function() +EntityGroups.prototype.getKeys = function() { //Preserve order even when shuffling units around //Can be optimized by moving the sorting elsewhere return Object.keys(this.groups).sort(); }; -EntityGroups.prototype.getEntsByName = function(templateName) +EntityGroups.prototype.getEntsByKey = function(key) { var ents = []; for (var ent in this.ents) - if (this.ents[ent] == templateName) + if (this.ents[ent] == key) ents.push(+ent); return ents; }; /** - * get a list of entities grouped by templateName + * get a list of entities grouped by a key */ EntityGroups.prototype.getEntsGrouped = function() { - return this.getTemplateNames().map(template => ({ - "ents": this.getEntsByName(template), - "template": template + return this.getKeys().map(key => ({ + "ents": this.getEntsByKey(key), + "key": key })); }; /** * Gets all ents in every group except ones of the specified group */ -EntityGroups.prototype.getEntsByNameInverse = function(templateName) +EntityGroups.prototype.getEntsByKeyInverse = function(key) { var ents = []; for (var ent in this.ents) - if (this.ents[ent] != templateName) + if (this.ents[ent] != key) ents.push(+ent); return ents; @@ -176,13 +173,13 @@ } /** - * Deselect everything but entities of the chosen type if the modifier is true otherwise deselect just the chosen entity + * Deselect everything but entities of the chosen type if inverse is true otherwise deselect just the chosen entity */ -EntitySelection.prototype.makePrimarySelection = function(templateName, modifierKey) +EntitySelection.prototype.makePrimarySelection = function(key, inverse) { - let ents = modifierKey ? - this.groups.getEntsByNameInverse(templateName) : - this.groups.getEntsByName(templateName); + let ents = inverse ? + this.groups.getEntsByKeyInverse(key) : + this.groups.getEntsByKey(key); this.reset(); this.addList(ents); Index: ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js +++ ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js @@ -451,17 +451,19 @@ }, "setupButton": function(data) { - let template = GetTemplateData(data.item.template); + let entState = GetEntityState(data.item.ents[0]); + + let template = GetTemplateData(entState.template); if (!template) return false; data.button.onPress = function() { - unloadTemplate(data.item.template); + unloadTemplate(template.selectionGroupName || entState.template, entState.player); }; data.countDisplay.caption = data.item.ents.length || ""; - let garrisonedUnitOwner = GetEntityState(data.item.ents[0]).player; + let garrisonedUnitOwner = entState.player; let canUngarrison = g_ViewedPlayer == data.player || @@ -935,7 +937,8 @@ }, "setupButton": function(data) { - let template = GetTemplateData(data.item.template); + let entState = GetEntityState(data.item.ents[0]); + let template = GetTemplateData(entState.template); if (!template) return false; @@ -989,8 +992,8 @@ data.countDisplay.caption = data.item.ents.length || ""; - data.button.onPress = function() { changePrimarySelectionGroup(data.item.template, false); }; - data.button.onPressRight = function() { changePrimarySelectionGroup(data.item.template, true); }; + data.button.onPress = function() { changePrimarySelectionGroup(data.item.key, false); }; + data.button.onPressRight = function() { changePrimarySelectionGroup(data.item.key, true); }; if (template.icon) data.icon.sprite = "stretched:session/portraits/" + template.icon; Index: ps/trunk/binaries/data/mods/public/gui/session/session.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/session.js +++ ps/trunk/binaries/data/mods/public/gui/session/session.js @@ -938,9 +938,9 @@ g_Groups.update(); // Determine the sum of the costs of a given template - let getCostSum = (template) => + let getCostSum = (ent) => { - let cost = GetTemplateData(template).cost; + let cost = GetTemplateData(GetEntityState(ent).template).cost; return cost ? Object.keys(cost).map(key => cost[key]).reduce((sum, cur) => sum + cur) : 0; }; @@ -957,11 +957,11 @@ // Chose icon of the most common template (or the most costly if it's not unique) if (g_Groups.groups[i].getTotalCount() > 0) { - let icon = GetTemplateData(g_Groups.groups[i].getEntsGrouped().reduce((pre, cur) => { + let icon = GetTemplateData(GetEntityState(g_Groups.groups[i].getEntsGrouped().reduce((pre, cur) => { if (pre.ents.length == cur.ents.length) - return getCostSum(pre.template) > getCostSum(cur.template) ? pre : cur; + return getCostSum(pre.ents[0]) > getCostSum(cur.ents[0]) ? pre : cur; return pre.ents.length > cur.ents.length ? pre : cur; - }).template).icon; + }).ents[0]).template).icon; Engine.GetGUIObjectByName("unitGroupIcon[" + i + "]").sprite = icon ? ("stretched:session/portraits/" + icon) : "groupsIcon"; Index: ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -449,18 +449,9 @@ * Unload one or all units that match a template and owner from * the garrisoning entity and order them to move to the Rally Point * Returns true if successful, false if not - * - * extendedTemplate has the format "p"+ownerid+"&"+template */ -GarrisonHolder.prototype.UnloadTemplate = function(extendedTemplate, all, forced) +GarrisonHolder.prototype.UnloadTemplate = function(template, owner, all, forced) { - var index = extendedTemplate.indexOf("&"); - if (index == -1) - return false; - - var owner = +extendedTemplate.slice(1,index); - var template = extendedTemplate.slice(index+1); - var entities = []; var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); for (var entity of this.entities) Index: ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js +++ ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -375,7 +375,6 @@ let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); if (cmpUnitAI) - { ret.unitAI = { "state": cmpUnitAI.GetCurrentState(), "orders": cmpUnitAI.GetOrders(), @@ -385,10 +384,6 @@ "possibleStances": cmpUnitAI.GetPossibleStances(), "isIdle":cmpUnitAI.IsIdle(), }; - // Add some information to differentiate between owner - if (ret.player !== undefined) - ret.template = "p" + ret.player + "&" + ret.template; - } let cmpGuard = Engine.QueryInterface(ent, IID_Guard); if (cmpGuard) @@ -621,13 +616,8 @@ return cmpRangeManager.GetElevationAdaptedRange(pos, rot, range, elevationBonus, 2*Math.PI); }; -GuiInterface.prototype.GetTemplateData = function(player, extendedName) +GuiInterface.prototype.GetTemplateData = function(player, name) { - let name = extendedName; - // Special case for garrisoned units which have a extended template - if (extendedName.indexOf("&") != -1) - name = extendedName.slice(extendedName.indexOf("&")+1); - let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); let template = cmpTemplateManager.GetTemplate(name); Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js @@ -495,10 +495,6 @@ "unload-template": function(player, cmd, data) { - var index = cmd.template.indexOf("&"); // Templates for garrisoned units are extended - if (index == -1) - return; - var entities = FilterEntityListWithAllies(cmd.garrisonHolders, player, data.controlAllUnits); for (let garrisonHolder of entities) { @@ -507,10 +503,10 @@ { // Only the owner of the garrisonHolder may unload entities from any owners if (!IsOwnedByPlayer(player, garrisonHolder) && !data.controlAllUnits - && player != +cmd.template.slice(1,index)) + && player != +cmd.owner) continue; - if (!cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all)) + if (!cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.owner, cmd.all)) notifyUnloadFailure(player, garrisonHolder); } }