1
0
forked from 0ad/0ad

Added support for ungarrisoning units by template name and for ungarrisoning from multiple entities at once. Fixes #910.

This was SVN commit r12443.
This commit is contained in:
Deiz 2012-08-16 01:15:04 +00:00
parent b03df364ea
commit 78e9fecf92
4 changed files with 126 additions and 31 deletions

View File

@ -1581,7 +1581,7 @@ function performCommand(entity, commandName)
preSelectedAction = ACTION_REPAIR; preSelectedAction = ACTION_REPAIR;
break; break;
case "unload-all": case "unload-all":
unloadAll(entity); unloadAll();
break; break;
case "focus-rally": case "focus-rally":
// if the selected building has a rally point set, move the camera to it; otherwise, move to the building itself // if the selected building has a rally point set, move the camera to it; otherwise, move to the building itself
@ -1768,7 +1768,33 @@ function unload(garrisonHolder, entities)
Engine.PostNetworkCommand({"type": "unload", "entities": [entities[0]], "garrisonHolder": garrisonHolder}); Engine.PostNetworkCommand({"type": "unload", "entities": [entities[0]], "garrisonHolder": garrisonHolder});
} }
function unloadAll(garrisonHolder) function unloadTemplate(template)
{ {
Engine.PostNetworkCommand({"type": "unload-all", "garrisonHolder": garrisonHolder}); // Filter out all entities that aren't garrisonable.
var garrisonHolders = g_Selection.toList().filter(function(e) {
var state = GetEntityState(e);
if (state && state.garrisonHolder)
return true;
return false;
});
Engine.PostNetworkCommand({
"type": "unload-template",
"all": Engine.HotkeyIsPressed("session.unloadtype"),
"template": template,
"garrisonHolders": garrisonHolders
});
}
function unloadAll()
{
// Filter out all entities that aren't garrisonable.
var garrisonHolders = g_Selection.toList().filter(function(e) {
var state = GetEntityState(e);
if (state && state.garrisonHolder)
return true;
return false;
});
Engine.PostNetworkCommand({"type": "unload-all", "garrisonHolders": garrisonHolders});
} }

View File

@ -174,8 +174,6 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
case GARRISON: case GARRISON:
if (numberOfItems > 16) if (numberOfItems > 16)
numberOfItems = 16; numberOfItems = 16;
//Group garrisoned units based on class
garrisonGroups.add(unitEntState.garrisonHolder.entities);
break; break;
case STANCE: case STANCE:
@ -217,6 +215,23 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
break; break;
} }
switch (guiName)
{
case GARRISON:
case COMMAND:
// Common code for garrison and 'unload all' button counts.
for (var i = 0; i < selection.length; ++i)
{
var state = GetEntityState(selection[i]);
if (state.garrisonHolder)
garrisonGroups.add(state.garrisonHolder.entities)
}
break;
default:
break;
}
var rowLength = 8; var rowLength = 8;
if (guiName == SELECTION) if (guiName == SELECTION)
rowLength = 4; rowLength = 4;
@ -411,7 +426,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
// here, "item" is an object with properties .name (command name), .tooltip and .icon (relative to session/icons/single) // here, "item" is an object with properties .name (command name), .tooltip and .icon (relative to session/icons/single)
if (item.name == "unload-all") if (item.name == "unload-all")
{ {
var count = unitEntState.garrisonHolder.entities.length; var count = garrisonGroups.getTotalCount();
getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 0 ? count : ""); getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 0 ? count : "");
} }
else else
@ -859,9 +874,15 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
if (entState.garrisonHolder) if (entState.garrisonHolder)
{ {
var groups = new EntityGroups(); var groups = new EntityGroups();
groups.add(entState.garrisonHolder.entities); for (var i in selection)
{
state = GetEntityState(selection[i]);
if (state.garrisonHolder)
groups.add(state.garrisonHolder.entities)
}
setupUnitPanel(GARRISON, usedPanels, entState, groups.getTemplateNames(), setupUnitPanel(GARRISON, usedPanels, entState, groups.getTemplateNames(),
function (item) { unload(entState.id, groups.getEntsByName(item)); } ); function (item) { unloadTemplate(item); } );
} }
var formations = Engine.GuiInterfaceCall("GetAvailableFormations"); var formations = Engine.GuiInterfaceCall("GetAvailableFormations");

View File

@ -244,6 +244,50 @@ GarrisonHolder.prototype.Unload = function(entity, forced)
return false; return false;
}; };
/**
* Unload one or all units that match a template from the
* garrisoning entity and order them to move to the Rally Point
* Returns true if successful, false if not
*/
GarrisonHolder.prototype.UnloadTemplate = function(template, all, forced)
{
var ejectedEntities = [];
var success = true;
for (var i = 0; i < this.entities.length; ++i)
{
var entity = this.entities[i];
var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
// Units with multiple ranks are grouped together.
var name = cmpIdentity.GetSelectionGroupName();
if (!name)
{
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
name = cmpTemplateManager.GetCurrentTemplateName(entity);
}
if (name != template)
continue;
if (this.Eject(entity, forced))
{
--i; // Decrement 'i' as Eject() shortens the array.
ejectedEntities.push(entity);
// If 'all' is false, only ungarrison the first matched unit.
if (!all)
break;
}
else
success = false;
}
this.OrderWalkToRallyPoint(ejectedEntities);
this.UpdateGarrisonFlag();
return success;
};
/** /**
* Unload all units from the entity * Unload all units from the entity
* Returns true if all successful, false if not * Returns true if all successful, false if not

View File

@ -289,19 +289,11 @@ function ProcessCommand(player, cmd)
var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder); var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
var notUngarrisoned = 0; var notUngarrisoned = 0;
for each (ent in cmd.entities) for each (ent in cmd.entities)
{
if (!cmpGarrisonHolder || !cmpGarrisonHolder.Unload(ent)) if (!cmpGarrisonHolder || !cmpGarrisonHolder.Unload(ent))
{
notUngarrisoned++; notUngarrisoned++;
}
}
if (notUngarrisoned != 0) if (notUngarrisoned != 0)
{ notifyUnloadFailure(player, cmd.garrisonHolder)
var cmpPlayer = QueryPlayerIDInterface(player, IID_Player);
var notification = {"player": cmpPlayer.GetPlayerID(), "message": (notUngarrisoned == 1 ? "Unable to ungarrison unit" : "Unable to ungarrison units")};
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification(notification);
}
} }
else if (g_DebugCommands) else if (g_DebugCommands)
{ {
@ -309,22 +301,23 @@ function ProcessCommand(player, cmd)
} }
break; break;
case "unload-all": case "unload-template":
// Verify that the building can be controlled by the player var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
if (CanControlUnit(cmd.garrisonHolder, player, controlAllUnits)) for each (var garrisonHolder in selected)
{ {
var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder); var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadAll()) if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all))
{ notifyUnloadFailure(player, garrisonHolder)
var cmpPlayer = QueryPlayerIDInterface(player, IID_Player);
var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Unable to ungarrison all units"};
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification(notification);
}
} }
else if (g_DebugCommands) break;
case "unload-all":
var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in selected)
{ {
warn("Invalid command: unload-all target cannot be controlled by player "+player+": "+uneval(cmd)); var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadAll())
notifyUnloadFailure(player, garrisonHolder)
} }
break; break;
@ -423,6 +416,17 @@ function ProcessCommand(player, cmd)
} }
} }
/**
* Sends a GUI notification about unit(s) that failed to ungarrison.
*/
function notifyUnloadFailure(player, garrisonHolder)
{
var cmpPlayer = QueryPlayerIDInterface(player, IID_Player);
var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Unable to ungarrison unit(s)" };
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification(notification);
}
/** /**
* Get some information about the formations used by entities. * Get some information about the formations used by entities.
* The entities must have a UnitAI component. * The entities must have a UnitAI component.