Improve neutral and ally combat handling. Refs #7.
This was SVN commit r12780.
This commit is contained in:
parent
c98a97924d
commit
ca4dedbc3e
@ -286,6 +286,7 @@ function getActionInfo(action, target)
|
||||
var playerState = simState.players[entState.player];
|
||||
var playerOwned = (targetState.player == entState.player);
|
||||
var allyOwned = playerState.isAlly[targetState.player];
|
||||
var neutralOwned = playerState.isNeutral[targetState.player];
|
||||
var enemyOwned = playerState.isEnemy[targetState.player];
|
||||
var gaiaOwned = (targetState.player == 0);
|
||||
|
||||
@ -388,7 +389,7 @@ function getActionInfo(action, target)
|
||||
return {"possible": true};
|
||||
break;
|
||||
case "attack":
|
||||
if (entState.attack && targetState.hitpoints && enemyOwned)
|
||||
if (entState.attack && targetState.hitpoints && (enemyOwned || neutralOwned))
|
||||
return {"possible": Engine.GuiInterfaceCall("CanAttack", {"entity": entState.id, "target": target})};
|
||||
break;
|
||||
}
|
||||
|
@ -287,16 +287,15 @@ function addChatMessage(msg, playerAssignments)
|
||||
break;
|
||||
case "diplomacy":
|
||||
username= escapeText(g_Players[msg.player1].name);
|
||||
playerColor = g_Players[msg.player1].color.r + " " + g_Players[msg.player1].color.g + " " + g_Players[msg.player1].color.b;
|
||||
|
||||
// TODO: Proper wording for all cases
|
||||
if (msg.player == Engine.GetPlayerID())
|
||||
{
|
||||
playerColor = g_Players[msg.player1].color.r + " " + g_Players[msg.player1].color.g + " " + g_Players[msg.player1].color.b;
|
||||
formatted = "You are now "+msg.status+" with [color=\"" + playerColor + "\"]"+username + "[/color].";
|
||||
}
|
||||
else if (msg.player1 == Engine.GetPlayerID())
|
||||
{
|
||||
playerColor = g_Players[msg.player].color.r + " " + g_Players[msg.player].color.g + " " + g_Players[msg.player].color.b;
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] is now " + msg.status + " with you."
|
||||
}
|
||||
else // No need for other players to know of this.
|
||||
|
@ -96,7 +96,9 @@ EndGameManager.prototype.UpdatePlayerStates = function()
|
||||
{ //Active player
|
||||
for (var j = 0; j < numPlayers && onlyAlliesLeft; j++)
|
||||
{
|
||||
if (cmpPlayers[j].GetState() == "active" && (cmpPlayers[i].IsEnemy(j+1) || cmpPlayers[j].IsEnemy(i+1)))
|
||||
if (cmpPlayers[j].GetState() == "active"
|
||||
&& (cmpPlayers[i].IsEnemy(j+1) || cmpPlayers[j].IsEnemy(i+1)
|
||||
|| cmpPlayers[i].IsNeutral(j+1) || cmpPlayers[j].IsNeutral(i+1)))
|
||||
{ // Only need to find an active non-allied player
|
||||
onlyAlliesLeft = false;
|
||||
}
|
||||
|
@ -923,7 +923,7 @@ var UnitFsmSpec = {
|
||||
"Timer": function(msg) {
|
||||
var target = this.order.data.target;
|
||||
// Check the target is still alive and attackable
|
||||
if (this.TargetIsAlive(target) && this.CanAttack(target))
|
||||
if (this.TargetIsAlive(target) && this.CanAttack(target, this.order.data.forceResponse || null))
|
||||
{
|
||||
// Check we can still reach the target
|
||||
if (this.CheckTargetRange(target, IID_Attack, this.attackType))
|
||||
@ -2725,13 +2725,13 @@ UnitAI.prototype.GetBestAttackAgainst = function(target)
|
||||
* and start attacking it.
|
||||
* Returns true if it found something to attack.
|
||||
*/
|
||||
UnitAI.prototype.AttackVisibleEntity = function(ents)
|
||||
UnitAI.prototype.AttackVisibleEntity = function(ents, forceResponse)
|
||||
{
|
||||
for each (var target in ents)
|
||||
{
|
||||
if (this.CanAttack(target))
|
||||
if (this.CanAttack(target, forceResponse))
|
||||
{
|
||||
this.PushOrderFront("Attack", { "target": target, "force": false });
|
||||
this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2743,14 +2743,14 @@ UnitAI.prototype.AttackVisibleEntity = function(ents)
|
||||
* and which is close to the hold position, and start attacking it.
|
||||
* Returns true if it found something to attack.
|
||||
*/
|
||||
UnitAI.prototype.AttackEntityInZone = function(ents)
|
||||
UnitAI.prototype.AttackEntityInZone = function(ents, forceResponse)
|
||||
{
|
||||
for each (var target in ents)
|
||||
{
|
||||
var type = this.GetBestAttackAgainst(target);
|
||||
if (this.CanAttack(target) && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, type))
|
||||
if (this.CanAttack(target, forceResponse) && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, type))
|
||||
{
|
||||
this.PushOrderFront("Attack", { "target": target, "force": false });
|
||||
this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2768,13 +2768,13 @@ UnitAI.prototype.RespondToTargetedEntities = function(ents)
|
||||
return false;
|
||||
|
||||
if (this.GetStance().respondChase)
|
||||
return this.AttackVisibleEntity(ents);
|
||||
return this.AttackVisibleEntity(ents, true);
|
||||
|
||||
if (this.GetStance().respondStandGround)
|
||||
return this.AttackVisibleEntity(ents);
|
||||
return this.AttackVisibleEntity(ents, true);
|
||||
|
||||
if (this.GetStance().respondHoldGround)
|
||||
return this.AttackEntityInZone(ents);
|
||||
return this.AttackEntityInZone(ents, true);
|
||||
|
||||
if (this.GetStance().respondFlee)
|
||||
{
|
||||
@ -3402,7 +3402,7 @@ UnitAI.prototype.WalkToHeldPosition = function()
|
||||
|
||||
//// Helper functions ////
|
||||
|
||||
UnitAI.prototype.CanAttack = function(target)
|
||||
UnitAI.prototype.CanAttack = function(target, forceResponse)
|
||||
{
|
||||
// Formation controllers should always respond to commands
|
||||
// (then the individual units can make up their own minds)
|
||||
@ -3424,7 +3424,7 @@ UnitAI.prototype.CanAttack = function(target)
|
||||
// Verify that the target is owned by an enemy of this entity's player,
|
||||
// or that it's an attackable resource supply like a domestic animal
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership || (!this.MustKillGatherTarget(target) && !IsOwnedByEnemyOfPlayer(cmpOwnership.GetOwner(), target)))
|
||||
if (!cmpOwnership || (!this.MustKillGatherTarget(target) && !(IsOwnedByEnemyOfPlayer(cmpOwnership.GetOwner(), target) || IsOwnedByNeutralOfPlayer(cmpOwnership.GetOwner(), target) || forceResponse)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -89,7 +89,7 @@ function ProcessCommand(player, cmd)
|
||||
break;
|
||||
|
||||
case "attack":
|
||||
if (g_DebugCommands && !IsOwnedByEnemyOfPlayer(player, cmd.target))
|
||||
if (g_DebugCommands && !(IsOwnedByEnemyOfPlayer(player, cmd.target) || IsOwnedByNeutralOfPlayer(player, cmd.target)))
|
||||
{
|
||||
// This check is for debugging only!
|
||||
warn("Invalid command: attack target is not owned by enemy of player "+player+": "+uneval(cmd));
|
||||
|
@ -246,7 +246,6 @@ function IsOwnedByGaia(target)
|
||||
*/
|
||||
function IsOwnedByAllyOfPlayer(player, target)
|
||||
{
|
||||
// Figure out which player controls the foundation being built
|
||||
var targetOwner = 0;
|
||||
var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
|
||||
if (cmpOwnershipTarget)
|
||||
@ -263,11 +262,10 @@ function IsOwnedByAllyOfPlayer(player, target)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the entity 'target' is owned by an enemy of player
|
||||
* Returns true if the entity 'target' is owned by someone neutral to player
|
||||
*/
|
||||
function IsOwnedByEnemyOfPlayer(player, target)
|
||||
function IsOwnedByNeutralOfPlayer(player,target)
|
||||
{
|
||||
// Figure out which player controls the foundation being built
|
||||
var targetOwner = 0;
|
||||
var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
|
||||
if (cmpOwnershipTarget)
|
||||
@ -276,7 +274,27 @@ function IsOwnedByEnemyOfPlayer(player, target)
|
||||
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player);
|
||||
|
||||
// Check for allied diplomacy status
|
||||
// Check for neutral diplomacy status
|
||||
if (cmpPlayer.IsNeutral(targetOwner))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the entity 'target' is owned by an enemy of player
|
||||
*/
|
||||
function IsOwnedByEnemyOfPlayer(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 enemy diplomacy status
|
||||
if (cmpPlayer.IsEnemy(targetOwner))
|
||||
return true;
|
||||
|
||||
@ -290,4 +308,5 @@ Engine.RegisterGlobal("IsOwnedByAllyOfEntity", IsOwnedByAllyOfEntity);
|
||||
Engine.RegisterGlobal("IsOwnedByPlayer", IsOwnedByPlayer);
|
||||
Engine.RegisterGlobal("IsOwnedByGaia", IsOwnedByGaia);
|
||||
Engine.RegisterGlobal("IsOwnedByAllyOfPlayer", IsOwnedByAllyOfPlayer);
|
||||
Engine.RegisterGlobal("IsOwnedByNeutralOfPlayer", IsOwnedByNeutralOfPlayer);
|
||||
Engine.RegisterGlobal("IsOwnedByEnemyOfPlayer", IsOwnedByEnemyOfPlayer);
|
||||
|
Loading…
Reference in New Issue
Block a user