Allow mutual allies to garrison in each others buildings. Patch by mimo. Fixes #1807.

This was SVN commit r13357.
This commit is contained in:
leper 2013-04-14 00:34:14 +00:00
parent 2a3f1cb412
commit d0a695f7fb
11 changed files with 326 additions and 119 deletions

View File

@ -213,6 +213,7 @@ function getActionInfo(action, target)
var playerState = simState.players[entState.player];
var playerOwned = (targetState.player == entState.player);
var allyOwned = playerState.isAlly[targetState.player];
var mutualAllyOwned = playerState.isMutualAlly[targetState.player];
var enemyOwned = playerState.isEnemy[targetState.player];
var gaiaOwned = (targetState.player == 0);
@ -221,7 +222,7 @@ function getActionInfo(action, target)
// default to walking there
var data = {command: "walk"};
if (targetState.garrisonHolder && playerOwned)
if (targetState.garrisonHolder && (playerOwned || mutualAllyOwned))
{
data.command = "garrison";
data.target = target;
@ -296,6 +297,7 @@ function getActionInfo(action, target)
var playerState = simState.players[entState.player];
var playerOwned = (targetState.player == entState.player);
var allyOwned = playerState.isAlly[targetState.player];
var mutualAllyOwned = playerState.isMutualAlly[targetState.player];
var neutralOwned = playerState.isNeutral[targetState.player];
var enemyOwned = playerState.isEnemy[targetState.player];
var gaiaOwned = (targetState.player == 0);
@ -307,7 +309,7 @@ function getActionInfo(action, target)
switch (action)
{
case "garrison":
if (hasClass(entState, "Unit") && targetState.garrisonHolder && playerOwned)
if (hasClass(entState, "Unit") && targetState.garrisonHolder && (playerOwned || mutualAllyOwned))
{
var allowedClasses = targetState.garrisonHolder.allowedClasses;
for each (var unitClass in entState.identity.classes)
@ -1731,6 +1733,8 @@ function performCommand(entity, commandName)
var unitName = getEntityName(template);
var playerID = Engine.GetPlayerID();
var simState = GetSimState();
if (entState.player == playerID || g_DevSettings.controlAll)
{
switch (commandName)
@ -1779,6 +1783,18 @@ function performCommand(entity, commandName)
break;
}
}
else if (simState.players[playerID].isMutualAlly[entState.player])
{
switch (commandName)
{
case "garrison":
inputState = INPUT_PRESELECTEDACTION;
preSelectedAction = ACTION_GARRISON;
break;
default:
break;
}
}
}
}

View File

@ -59,9 +59,12 @@ EntityGroups.prototype.add = function(ents)
continue;
var templateName = entState.template;
var template = GetTemplateData(templateName);
var key = template.selectionGroupName || templateName;
// Special handling for garrisoned units
if (templateName && templateName.indexOf("&") != -1)
var key = templateName;
else
var key = GetTemplateData(templateName).selectionGroupName || templateName;
if (this.groups[key])
this.groups[key] += 1;
else
@ -221,7 +224,7 @@ EntitySelection.prototype.update = function()
// Remove deleted units
if (!entState)
{
delete this.selected[ent];
delete this.selected[ent];
this.groups.removeEnt(ent);
this.dirty = true;
continue;

View File

@ -677,7 +677,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
var techName = getEntityNames(GetTechnologyData(template.requiredTechnology));
button.tooltip += "\nRequires " + techName;
grayscale = "grayscale:";
affordableMask.hidden = false;
affordableMask.hidden = false;
affordableMask.sprite = "colour: 0 0 0 127";
}
@ -686,9 +686,26 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
button.enabled = false;
button.tooltip += "\n" + GetTechnologyData(entType).requirementsTooltip;
grayscale = "grayscale:";
affordableMask.hidden = false;
affordableMask.hidden = false;
affordableMask.sprite = "colour: 0 0 0 127";
}
if (guiName == GARRISON)
{
var ents = garrisonGroups.getEntsByName(item);
var entplayer = GetEntityState(ents[0]).player;
button.sprite = "colour: " + g_Players[entplayer].color.r + " " + g_Players[entplayer].color.g + " " + g_Players[entplayer].color.b;
var player = Engine.GetPlayerID();
if(player != unitEntState.player && !g_DevSettings.controlAll)
{
if (entplayer != player)
{
button.enabled = false;
grayscale = "grayscale:";
}
}
}
icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon;
@ -724,7 +741,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
button1.enabled = false;
button1.tooltip += "\n" + GetTechnologyData(entType1).requirementsTooltip;
grayscale = "grayscale:";
affordableMask1.hidden = false;
affordableMask1.hidden = false;
affordableMask1.sprite = "colour: 0 0 0 127";
}
icon1.sprite = "stretched:" + grayscale + "session/portraits/" +template1.icon;
@ -769,7 +786,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
playerState.entityCounts[trainingCategory] >= playerState.entityLimits[trainingCategory])
{
grayscale = "grayscale:";
affordableMask.hidden = false;
affordableMask.hidden = false;
affordableMask.sprite = "colour: 0 0 0 100";
}
icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon;
@ -1003,13 +1020,14 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
// If the selection is friendly units, add the command panels
var player = Engine.GetPlayerID();
// Get player state to check some constraints
// e.g. presence of a hero or build limits
var simState = GetSimState();
var playerState = simState.players[player];
if (entState.player == player || g_DevSettings.controlAll)
{
// Get player state to check some constraints
// e.g. presence of a hero or build limits
var simState = GetSimState();
var playerState = simState.players[player];
if (selection.length > 1)
setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(),
function (entType, rightPressed) { changePrimarySelectionGroup(entType, rightPressed); } );
@ -1024,7 +1042,7 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
var groups = new EntityGroups();
for (var i in selection)
{
state = GetEntityState(selection[i]);
var state = GetEntityState(selection[i]);
if (state.garrisonHolder)
groups.add(state.garrisonHolder.entities)
}
@ -1191,6 +1209,30 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
supplementalDetailsPanel.hidden = false;
commandsPanel.hidden = false;
}
else if (playerState.isMutualAlly[entState.player]) // owned by allied player
{
if (entState.garrisonHolder)
{
var groups = new EntityGroups();
for (var i in selection)
{
var state = GetEntityState(selection[i]);
if (state.garrisonHolder)
groups.add(state.garrisonHolder.entities)
}
setupUnitPanel(GARRISON, usedPanels, entState, playerState, groups.getTemplateNames(),
function (item) { unloadTemplate(item); } );
supplementalDetailsPanel.hidden = false;
}
else
{
supplementalDetailsPanel.hidden = true;
}
commandsPanel.hidden = true;
}
else // owned by another player
{
supplementalDetailsPanel.hidden = true;

View File

@ -62,6 +62,7 @@ function getPlayerData(playerAssignments)
"teamsLocked": playerState.teamsLocked,
"state": playerState.state,
"isAlly": playerState.isAlly,
"isMutualAlly": playerState.isMutualAlly,
"isNeutral": playerState.isNeutral,
"isEnemy": playerState.isEnemy,
"guid": undefined, // network guid for players controlled by hosts

View File

@ -573,14 +573,15 @@ var Entity = Class({
unload: function(id) {
if (!this._template.GarrisonHolder)
return undefined;
Engine.PostCommand({"type": "unload", "garrisonHolder": this.id(), "entity": id});
Engine.PostCommand({"type": "unload", "garrisonHolder": this.id(), "entities": [id]});
return this;
},
// Unloads all owned units, don't unload allies
unloadAll: function() {
if (!this._template.GarrisonHolder)
return undefined;
Engine.PostCommand({"type": "unload-all", "garrisonHolders": [this.id()]});
Engine.PostCommand({"type": "unload-all-own", "garrisonHolders": [this.id()]});
return this;
},

View File

@ -220,99 +220,113 @@ GarrisonHolder.prototype.OrderWalkToRallyPoint = function(entities)
};
/**
* Unload units from the garrisoning entity and order them
* to move to the Rally Point
* Ejects units and orders them to move to the Rally Point.
* Returns true if successful, false if not
*/
GarrisonHolder.prototype.Unload = function(entity, forced)
GarrisonHolder.prototype.PerformEject = function(entities, forced)
{
if (this.Eject(entity, forced))
{
this.OrderWalkToRallyPoint([entity]);
this.UpdateGarrisonFlag();
return true;
}
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
* Returns true if all successful, false if not
*/
GarrisonHolder.prototype.UnloadAll = function(forced)
{
// Make copy of entity list
var entities = [];
for each (var entity in this.entities)
{
entities.push(entity);
}
var ejectedEntities = [];
var success = true;
for each (var entity in entities)
{
if (this.Eject(entity, forced))
{
ejectedEntities.push(entity);
}
else
{
success = false;
}
}
this.OrderWalkToRallyPoint(ejectedEntities);
this.UpdateGarrisonFlag();
return success;
};
/**
* Unload unit from the garrisoning entity and order them
* to move to the Rally Point
* Returns true if successful, false if not
*/
GarrisonHolder.prototype.Unload = function(entity, forced)
{
return this.PerformEject([entity], forced);
};
/**
* 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)
{
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 each (var entity in this.entities)
{
var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
// Units with multiple ranks are grouped together.
var name = cmpIdentity.GetSelectionGroupName()
|| cmpTemplateManager.GetCurrentTemplateName(entity);
if (name != template)
continue;
if (owner != Engine.QueryInterface(entity, IID_Ownership).GetOwner())
continue;
entities.push(entity);
// If 'all' is false, only ungarrison the first matched unit.
if (!all)
break;
}
return this.PerformEject(entities, forced);
};
/**
* Unload all units with same owner as the entity
* and order them to move to the Rally Point
* Returns true if all successful, false if not
*/
GarrisonHolder.prototype.UnloadAllOwn = function(forced)
{
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return false;
var owner = cmpOwnership.GetOwner();
// Make copy of entity list
var entities = [];
for each (var entity in this.entities)
{
var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
if (cmpOwnership && cmpOwnership.GetOwner() == owner)
entities.push(entity);
}
return this.PerformEject(entities, forced);
};
/**
* Unload all units from the entity
* and order them to move to the Rally Point
* Returns true if all successful, false if not
*/
GarrisonHolder.prototype.UnloadAll = function(forced)
{
var entities = this.entities.slice(0);
return this.PerformEject(entities, forced);
};
/**
* Used to check if the garrisoning entity's health has fallen below
* a certain limit after which all garrisoned units are unloaded
@ -469,5 +483,19 @@ GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
}
};
/**
* Eject all foreign garrisoned entities which are no more allied
*/
GarrisonHolder.prototype.OnDiplomacyChanged = function()
{
for (var i = this.entities.length; i > 0; --i)
{
if (!IsOwnedByMutualAllyOfEntity(this.entity, this.entities[i-1]))
this.Eject(this.entities[i-1], true);
}
this.UpdateGarrisonFlag();
};
Engine.RegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder);

View File

@ -64,11 +64,13 @@ GuiInterface.prototype.GetSimulationState = function(player)
// store player ally/neutral/enemy data as arrays
var allies = [];
var mutualAllies = [];
var neutrals = [];
var enemies = [];
for (var j = 0; j < n; ++j)
{
allies[j] = cmpPlayer.IsAlly(j);
mutualAllies[j] = cmpPlayer.IsMutualAlly(j);
neutrals[j] = cmpPlayer.IsNeutral(j);
enemies[j] = cmpPlayer.IsEnemy(j);
}
@ -87,6 +89,7 @@ GuiInterface.prototype.GetSimulationState = function(player)
"teamsLocked": cmpPlayer.GetLockTeams(),
"phase": phase,
"isAlly": allies,
"isMutualAlly": mutualAllies,
"isNeutral": neutrals,
"isEnemy": enemies,
"entityLimits": cmpPlayerEntityLimits.GetLimits(),
@ -314,6 +317,9 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
"state": cmpUnitAI.GetCurrentState(),
"orders": cmpUnitAI.GetOrders(),
};
// Add some information needed for ungarrisoning
if (cmpUnitAI.isGarrisoned && ret.player)
ret.template = "p" + ret.player + "&" + ret.template;
}
var cmpGate = Engine.QueryInterface(ent, IID_Gate);
@ -345,8 +351,13 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
return ret;
};
GuiInterface.prototype.GetTemplateData = function(player, name)
GuiInterface.prototype.GetTemplateData = function(player, extendedName)
{
var name = extendedName;
// Special case for garrisoned units which have a extended template
if (extendedName.indexOf("&") != -1)
name = extendedName.slice(extendedName.indexOf("&")+1);
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var template = cmpTemplateManager.GetTemplate(name);

View File

@ -357,12 +357,8 @@ Player.prototype.UpdateSharedLos = function()
var sharedLos = [];
for (var i = 0; i < cmpPlayerManager.GetNumPlayers(); ++i)
if (this.IsAlly(i))
{
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
if (cmpPlayer && cmpPlayer.IsAlly(this.playerID))
sharedLos.push(i);
}
if (this.IsMutualAlly(i))
sharedLos.push(i);
cmpRangeManager.SetSharedLos(this.playerID, sharedLos);
};
@ -430,6 +426,19 @@ Player.prototype.IsAlly = function(id)
return this.diplomacy[id] > 0;
};
/**
* Check if given player is our ally, and we are its ally
*/
Player.prototype.IsMutualAlly = function(id)
{
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
if (!cmpPlayerManager)
return false;
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(id), IID_Player);
return this.IsAlly(id) && cmpPlayer && cmpPlayer.IsAlly(this.playerID);
};
Player.prototype.SetEnemy = function(id)
{
this.SetDiplomacyIndex(id, -1);

View File

@ -4212,9 +4212,9 @@ UnitAI.prototype.CanGarrison = function(target)
if (!cmpGarrisonHolder)
return false;
// Verify that the target is owned by this entity's player
// Verify that the target is owned by this entity's player or a mutual ally of this player
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership || !IsOwnedByPlayer(cmpOwnership.GetOwner(), target))
if (!cmpOwnership || !(IsOwnedByPlayer(cmpOwnership.GetOwner(), target) || IsOwnedByMutualAllyOfPlayer(cmpOwnership.GetOwner(), target)))
return false;
// Don't let animals garrison for now

View File

@ -314,8 +314,8 @@ function ProcessCommand(player, cmd)
break;
case "garrison":
// Verify that the building can be controlled by the player
if (CanControlUnit(cmd.target, player, controlAllUnits))
// Verify that the building can be controlled by the player or is mutualAlly
if (CanControlUnitOrIsAlly(cmd.target, player, controlAllUnits))
{
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
@ -324,7 +324,7 @@ function ProcessCommand(player, cmd)
}
else if (g_DebugCommands)
{
warn("Invalid command: garrison target cannot be controlled by player "+player+": "+uneval(cmd));
warn("Invalid command: garrison target cannot be controlled by player "+player+" (or ally): "+uneval(cmd));
}
break;
@ -336,12 +336,17 @@ function ProcessCommand(player, cmd)
break;
case "unload":
// Verify that the building can be controlled by the player
if (CanControlUnit(cmd.garrisonHolder, player, controlAllUnits))
// Verify that the building can be controlled by the player or is mutualAlly
if (CanControlUnitOrIsAlly(cmd.garrisonHolder, player, controlAllUnits))
{
var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
var notUngarrisoned = 0;
for each (ent in cmd.entities)
if (IsOwnedByPlayer(player, cmd.garrisonHolder))
var entities = cmd.entities;
else
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
for each (var ent in entities)
if (!cmpGarrisonHolder || !cmpGarrisonHolder.Unload(ent))
notUngarrisoned++;
@ -350,23 +355,45 @@ function ProcessCommand(player, cmd)
}
else if (g_DebugCommands)
{
warn("Invalid command: unload target cannot be controlled by player "+player+": "+uneval(cmd));
warn("Invalid command: unload target cannot be controlled by player "+player+" (or ally): "+uneval(cmd));
}
break;
case "unload-template":
var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in selected)
var index = cmd.template.indexOf("&"); // Templates for garrisoned units are extended
if (index == -1)
break;
var entities = FilterEntityListWithAllies(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in entities)
{
var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all))
if (cmpGarrisonHolder)
{
// Only the owner of the garrisonHolder may unload entities from any owners
if (!IsOwnedByPlayer(player, garrisonHolder) && !controlAllUnits
&& player != +cmd.template.slice(1,index))
continue;
if (!cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all))
notifyUnloadFailure(player, garrisonHolder);
}
}
break;
case "unload-all-own":
var entities = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in entities)
{
var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadAllOwn())
notifyUnloadFailure(player, garrisonHolder)
}
break;
case "unload-all":
var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in selected)
var entities = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);
for each (var garrisonHolder in entities)
{
var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadAll())
@ -1272,14 +1299,25 @@ function CanMoveEntsIntoFormation(ents, formationName)
/**
* Check if player can control this entity
* returns: true if the entity is valid and owned by the player if
* or control all units is activated for the player, else false
* returns: true if the entity is valid and owned by the player
* or control all units is activated, else false
*/
function CanControlUnit(entity, player, controlAll)
{
return (IsOwnedByPlayer(player, entity) || controlAll);
}
/**
* Check if player can control this entity
* returns: true if the entity is valid and owned by the player
* or the entity is owned by an mutualAlly
* or control all units is activated, else false
*/
function CanControlUnitOrIsAlly(entity, player, controlAll)
{
return (IsOwnedByPlayer(player, entity) || IsOwnedByMutualAllyOfPlayer(player, entity) || controlAll);
}
/**
* Filter entities which the player can control
*/
@ -1288,6 +1326,14 @@ function FilterEntityList(entities, player, controlAll)
return entities.filter(function(ent) { return CanControlUnit(ent, player, controlAll);} );
}
/**
* Filter entities which the player can control or are mutualAlly
*/
function FilterEntityListWithAllies(entities, player, controlAll)
{
return entities.filter(function(ent) { return CanControlUnitOrIsAlly(ent, player, controlAll);} );
}
/**
* Try to transform a wall to a gate
*/

View File

@ -214,7 +214,7 @@ function IsOwnedByAllyOfEntity(entity, target)
if (cmpOwnership)
owner = cmpOwnership.GetOwner();
// Figure out which player controls the foundation being built
// Figure out which player controls the target entity
var targetOwner = 0;
var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
if (cmpOwnershipTarget)
@ -230,6 +230,34 @@ function IsOwnedByAllyOfEntity(entity, target)
return false;
}
/**
* Returns true if the entity 'target' is owned by a mutual ally of
* the owner of 'entity'.
*/
function IsOwnedByMutualAllyOfEntity(entity, target)
{
// Figure out which player controls us
var owner = 0;
var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
if (cmpOwnership)
owner = cmpOwnership.GetOwner();
// Figure out which player controls the target entity
var targetOwner = 0;
var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
if (cmpOwnershipTarget)
targetOwner = cmpOwnershipTarget.GetOwner();
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(owner), IID_Player);
// Check for mutual allied diplomacy status
if (cmpPlayer.IsMutualAlly(targetOwner))
return true;
return false;
}
/**
* Returns true if the entity 'target' is owned by player
*/
@ -268,6 +296,26 @@ function IsOwnedByAllyOfPlayer(player, target)
return false;
}
/**
* Returns true if the entity 'target' is owned by a mutual ally of player
*/
function IsOwnedByMutualAllyOfPlayer(player, target)
{
var targetOwner = 0;
var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
if (cmpOwnershipTarget)
targetOwner = cmpOwnershipTarget.GetOwner();
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player);
// Check for mutual allied diplomacy status
if (cmpPlayer.IsMutualAlly(targetOwner))
return true;
return false;
}
/**
* Returns true if the entity 'target' is owned by someone neutral to player
*/
@ -312,8 +360,10 @@ Engine.RegisterGlobal("LoadPlayerSettings", LoadPlayerSettings);
Engine.RegisterGlobal("QueryOwnerInterface", QueryOwnerInterface);
Engine.RegisterGlobal("QueryPlayerIDInterface", QueryPlayerIDInterface);
Engine.RegisterGlobal("IsOwnedByAllyOfEntity", IsOwnedByAllyOfEntity);
Engine.RegisterGlobal("IsOwnedByMutualAllyOfEntity", IsOwnedByMutualAllyOfEntity);
Engine.RegisterGlobal("IsOwnedByPlayer", IsOwnedByPlayer);
Engine.RegisterGlobal("IsOwnedByGaia", IsOwnedByGaia);
Engine.RegisterGlobal("IsOwnedByAllyOfPlayer", IsOwnedByAllyOfPlayer);
Engine.RegisterGlobal("IsOwnedByMutualAllyOfPlayer", IsOwnedByMutualAllyOfPlayer);
Engine.RegisterGlobal("IsOwnedByNeutralOfPlayer", IsOwnedByNeutralOfPlayer);
Engine.RegisterGlobal("IsOwnedByEnemyOfPlayer", IsOwnedByEnemyOfPlayer);