From ca4dedbc3eff8cc0128c1b7b4dc74058510fc942 Mon Sep 17 00:00:00 2001 From: leper Date: Tue, 23 Oct 2012 23:13:39 +0000 Subject: [PATCH] Improve neutral and ally combat handling. Refs #7. This was SVN commit r12780. --- .../data/mods/public/gui/session/input.js | 3 +- .../data/mods/public/gui/session/messages.js | 3 +- .../simulation/components/EndGameManager.js | 4 ++- .../public/simulation/components/UnitAI.js | 24 +++++++-------- .../public/simulation/helpers/Commands.js | 2 +- .../mods/public/simulation/helpers/Player.js | 29 +++++++++++++++---- 6 files changed, 43 insertions(+), 22 deletions(-) diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js index 8e6c8dc045..7160e49226 100644 --- a/binaries/data/mods/public/gui/session/input.js +++ b/binaries/data/mods/public/gui/session/input.js @@ -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; } diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index c66c19a493..03bb6a2d16 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -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. diff --git a/binaries/data/mods/public/simulation/components/EndGameManager.js b/binaries/data/mods/public/simulation/components/EndGameManager.js index ac692ed5f9..4e3cc7600a 100644 --- a/binaries/data/mods/public/simulation/components/EndGameManager.js +++ b/binaries/data/mods/public/simulation/components/EndGameManager.js @@ -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; } diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index 3abfed4058..43a2db70e2 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -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; diff --git a/binaries/data/mods/public/simulation/helpers/Commands.js b/binaries/data/mods/public/simulation/helpers/Commands.js index fd84adc0ee..b1435921d5 100644 --- a/binaries/data/mods/public/simulation/helpers/Commands.js +++ b/binaries/data/mods/public/simulation/helpers/Commands.js @@ -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)); diff --git a/binaries/data/mods/public/simulation/helpers/Player.js b/binaries/data/mods/public/simulation/helpers/Player.js index baed07ce0f..e5f9502787 100644 --- a/binaries/data/mods/public/simulation/helpers/Player.js +++ b/binaries/data/mods/public/simulation/helpers/Player.js @@ -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);