diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js
index 29d4fe272a..27041b2cf7 100644
--- a/binaries/data/mods/public/simulation/components/Player.js
+++ b/binaries/data/mods/public/simulation/components/Player.js
@@ -22,11 +22,12 @@ Player.prototype.Init = function()
this.team = -1; // team number of the player, players on the same team will always have ally diplomatic status - also this is useful for team emblems, scoring, etc.
this.state = "active"; // game state - one of "active", "defeated", "won"
- this.diplomacy = []; // array of diplomatic stances for this player with respect to other players (including self)
+ this.diplomacy = []; // array of diplomatic stances for this player with respect to other players (including gaia and self)
this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class
this.phase = "village";
this.startCam = undefined;
this.controlAllUnits = false;
+ this.isAI = false;
};
Player.prototype.SetPlayerID = function(id)
@@ -235,56 +236,90 @@ Player.prototype.SetPhase = function(p)
Player.prototype.GetStartingCameraPos = function()
{
return this.startCam.position;
-}
+};
Player.prototype.GetStartingCameraRot = function()
{
return this.startCam.rotation;
-}
+};
Player.prototype.SetStartingCamera = function(pos, rot)
{
this.startCam = {"position": pos, "rotation": rot};
-}
+};
Player.prototype.HasStartingCamera = function()
{
return (this.startCam !== undefined);
-}
+};
Player.prototype.SetControlAllUnits = function(c)
{
this.controlAllUnits = c;
-}
+};
Player.prototype.CanControlAllUnits = function()
{
return this.controlAllUnits;
-}
+};
+
+Player.prototype.SetAI = function(flag)
+{
+ this.isAI = flag;
+};
+
+Player.prototype.IsAI = function()
+{
+ return this.isAI;
+};
+
+Player.prototype.SetAlly = function(id)
+{
+ if (id >= 0 && id != this.playerID)
+ {
+ this.diplomacy[id] = 1;
+ }
+};
/**
* Check if given player is our ally
*/
Player.prototype.IsAlly = function(id)
{
- return (id >= 0 && (id == this.playerID || this.diplomacy[id] > 0));
-}
+ return (id >= 0 && id < this.diplomacy.length && (id == this.playerID || this.diplomacy[id] > 0));
+};
+
+Player.prototype.SetEnemy = function(id)
+{
+ if (id >= 0 && id != this.playerID)
+ {
+ this.diplomacy[id] = -1;
+ }
+};
/**
* Check if given player is our enemy
*/
Player.prototype.IsEnemy = function(id)
{
- return (id >= 0 && id != this.playerID && this.diplomacy[id] < 0);
-}
+ return (id >= 0 && id < this.diplomacy.length && id != this.playerID && this.diplomacy[id] < 0);
+};
+
+Player.prototype.SetNeutral = function(id)
+{
+ if (id >= 0 && id != this.playerID)
+ {
+ this.diplomacy[id] = 0;
+ }
+};
/**
* Check if given player is neutral
*/
Player.prototype.IsNeutral = function(id)
{
- return (id >= 0 && id != this.playerID && this.diplomacy[id] == 0);
-}
+ return (id >= 0 && id < this.diplomacy.length && id != this.playerID && this.diplomacy[id] == 0);
+};
/**
* Keep track of population effects of all entities that
@@ -345,6 +380,6 @@ Player.prototype.OnPlayerDefeated = function()
var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
cmpOwnership.SetOwner(0);
}
-}
+};
Engine.RegisterComponentType(IID_Player, "Player", Player);
diff --git a/binaries/data/mods/public/simulation/components/PlayerManager.js b/binaries/data/mods/public/simulation/components/PlayerManager.js
index 4be71ae5c8..3a05d8f8e8 100644
--- a/binaries/data/mods/public/simulation/components/PlayerManager.js
+++ b/binaries/data/mods/public/simulation/components/PlayerManager.js
@@ -3,13 +3,6 @@ function PlayerManager() {}
PlayerManager.prototype.Schema =
"";
-// Diplomatic stance constants
-PlayerManager.prototype.Diplomacy = {
- "ENEMY" : -1,
- "NEUTRAL" : 0,
- "ALLY" : 1
-};
-
PlayerManager.prototype.Init = function()
{
this.playerEntities = []; // list of player entity IDs
diff --git a/binaries/data/mods/public/simulation/helpers/Commands.js b/binaries/data/mods/public/simulation/helpers/Commands.js
index 08d72d0408..9049fc0488 100644
--- a/binaries/data/mods/public/simulation/helpers/Commands.js
+++ b/binaries/data/mods/public/simulation/helpers/Commands.js
@@ -143,45 +143,44 @@ function ProcessCommand(player, cmd)
cmpPosition.JumpTo(cmd.x, cmd.z);
cmpPosition.SetYRotation(cmd.angle);
- // Check whether it's obstructed by other entities or invalid terrain
- var cmpBuildRestrictions = Engine.QueryInterface(ent, IID_BuildRestrictions);
- if (!cmpBuildRestrictions || !cmpBuildRestrictions.CheckPlacement(player))
+ // TODO: Build restrctions disabled for AI since it lacks a mechanism for checking most of them
+ if (!cmpPlayer.IsAI())
{
- var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
- cmpGuiInterface.PushNotification({ "player": player, "message": "Building site was obstructed" });
+ // Check whether it's obstructed by other entities or invalid terrain
+ var cmpBuildRestrictions = Engine.QueryInterface(ent, IID_BuildRestrictions);
+ if (!cmpBuildRestrictions || !cmpBuildRestrictions.CheckPlacement(player))
+ {
+ var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGuiInterface.PushNotification({ "player": player, "message": "Building site was obstructed" });
- // Remove the foundation because the construction was aborted
- Engine.DestroyEntity(ent);
- break;
- }
-
- // Check build limits
- var cmpBuildLimits = QueryPlayerIDInterface(player, IID_BuildLimits);
- if (!cmpBuildLimits || !cmpBuildLimits.AllowedToBuild(cmpBuildRestrictions.GetCategory()))
- {
- // TODO: The UI should tell the user they can't build this (but we still need this check)
+ // Remove the foundation because the construction was aborted
+ Engine.DestroyEntity(ent);
+ break;
+ }
- // Remove the foundation because the construction was aborted
- Engine.DestroyEntity(ent);
- break;
+ // Check build limits
+ var cmpBuildLimits = QueryPlayerIDInterface(player, IID_BuildLimits);
+ if (!cmpBuildLimits || !cmpBuildLimits.AllowedToBuild(cmpBuildRestrictions.GetCategory()))
+ {
+ // TODO: The UI should tell the user they can't build this (but we still need this check)
+
+ // Remove the foundation because the construction was aborted
+ Engine.DestroyEntity(ent);
+ break;
+ }
+
+ // Check whether it's in a visible region
+ var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ var visible = (cmpRangeManager.GetLosVisibility(ent, player) == "visible");
+ if (!visible)
+ {
+ // TODO: report error to player (the building site was not visible)
+ print("Building site was not visible\n");
+
+ Engine.DestroyEntity(ent);
+ break;
+ }
}
-
- /* TODO: the AI isn't smart enough to explore before building, so we'll
- * just disable the requirement that the location is visible. Should we
- * fix that, or let players build in fog too, or something?
-
- // Check whether it's in a visible region
- var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- var visible = (cmpRangeManager.GetLosVisibility(ent, player) == "visible");
- if (!visible)
- {
- // TODO: report error to player (the building site was not visible)
- print("Building site was not visible\n");
-
- Engine.DestroyEntity(ent);
- break;
- }
- */
var cmpCost = Engine.QueryInterface(ent, IID_Cost);
if (!cmpPlayer.TrySubtractResources(cmpCost.GetResourceCosts()))
diff --git a/binaries/data/mods/public/simulation/helpers/Player.js b/binaries/data/mods/public/simulation/helpers/Player.js
index 45d20ac3f8..a08bbe964d 100644
--- a/binaries/data/mods/public/simulation/helpers/Player.js
+++ b/binaries/data/mods/public/simulation/helpers/Player.js
@@ -25,7 +25,7 @@ function LoadPlayerSettings(settings)
var numPlayers = 8;
if (settings.PlayerData)
- { //Get number of players including gaia
+ { // Get number of players including gaia
numPlayers = settings.PlayerData.length + 1;
}
else
@@ -35,36 +35,6 @@ function LoadPlayerSettings(settings)
// Get player manager
var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
-
- var teams = [];
- var diplomacy = [];
-
- // Build team + diplomacy data
- for (var i = 0; i < numPlayers; ++i)
- {
- diplomacy[i] = cmpPlayerMan.Diplomacy.ENEMY;
-
- // Skip gaia
- if (i > 0)
- {
- var pData = settings.PlayerData ? settings.PlayerData[i-1] : {};
- var pDefs = playerDefaults ? playerDefaults[i] : {};
- var team = getSetting(pData, pDefs, "Team");
-
- // If team defined, add player to the team
- if (team !== undefined && team != -1)
- {
- if (!teams[team])
- {
- teams[team] = [i];
- }
- else
- {
- teams[team].push(i);
- }
- }
- }
- }
for (var i = 0; i < numPlayers; ++i)
{
@@ -72,13 +42,13 @@ function LoadPlayerSettings(settings)
var entID = Engine.AddEntity("special/player");
// Retrieve entity
- var player = Engine.QueryInterface(entID, IID_Player);
- if (!player)
+ var cmpPlayer = Engine.QueryInterface(entID, IID_Player);
+ if (!cmpPlayer)
{
throw("Player.js: Error creating player entity "+i);
}
- player.SetPlayerID(i);
+ cmpPlayer.SetPlayerID(i);
var pDefs = playerDefaults ? playerDefaults[i] : {};
@@ -88,63 +58,66 @@ function LoadPlayerSettings(settings)
var pData = settings.PlayerData ? settings.PlayerData[i-1] : {};
// Copy player data
- player.SetName(getSetting(pData, pDefs, "Name"));
- player.SetCiv(getSetting(pData, pDefs, "Civ"));
+ cmpPlayer.SetName(getSetting(pData, pDefs, "Name"));
+ cmpPlayer.SetCiv(getSetting(pData, pDefs, "Civ"));
+ cmpPlayer.SetAI(pData.AI && pData.AI != "");
var colour = getSetting(pData, pDefs, "Colour");
- player.SetColour(colour.r, colour.g, colour.b);
+ cmpPlayer.SetColour(colour.r, colour.g, colour.b);
if (getSetting(pData, pDefs, "PopulationLimit") !== undefined)
{
- player.SetMaxPopulation(getSetting(pData, pDefs, "PopulationLimit"));
+ cmpPlayer.SetMaxPopulation(getSetting(pData, pDefs, "PopulationLimit"));
}
if (getSetting(pData, pDefs, "Resources") !== undefined)
{
- player.SetResourceCounts(getSetting(pData, pDefs, "Resources"));
+ cmpPlayer.SetResourceCounts(getSetting(pData, pDefs, "Resources"));
}
- var team = getSetting(pData, pDefs, "Team");
-
- //If diplomacy array exists use that, otherwise use team data or default diplomacy
+ // If diplomacy explicitly defined, use that; otherwise use teams
if (getSetting(pData, pDefs, "Diplomacy") !== undefined)
{
- player.SetDiplomacy(getSetting(pData, pDefs, "Diplomacy"));
- }
- else if (team !== undefined && team != -1)
- {
- //Team exists, copy default diplomacy
- var teamDiplomacy = [];
- for (var p in diplomacy)
- {
- teamDiplomacy[p] = diplomacy[p];
- }
- // Set teammates to allies
- var myTeam = teams[team];
- for (var n in myTeam)
- {
- teamDiplomacy[myTeam[n]] = cmpPlayerMan.Diplomacy.ALLY; //Set ally
- }
-
- player.SetDiplomacy(teamDiplomacy);
+ cmpPlayer.SetDiplomacy(getSetting(pData, pDefs, "Diplomacy"));
}
else
- { //Set default
- player.SetDiplomacy(diplomacy);
+ {
+ var myTeam = getSetting(pData, pDefs, "Team");
+ for (var j = 0; j < numPlayers; ++j)
+ {
+ // Check if player is on same team
+ if (j > 0)
+ {
+ var theirTeam = getSetting(settings.PlayerData[j-1], playerDefaults[j], "Team");
+ if (myTeam !== undefined && myTeam != -1
+ && theirTeam !== undefined && theirTeam != -1
+ && myTeam == theirTeam)
+ {
+ cmpPlayer.SetAlly(j);
+ continue;
+ }
+ }
+ // Gaia, different team, or no team defined
+ cmpPlayer.SetEnemy(j);
+ }
}
var startCam = getSetting(pData, pDefs, "StartingCamera");
if (startCam !== undefined)
{
- player.SetStartingCamera(startCam.Position, startCam.Rotation);
+ cmpPlayer.SetStartingCamera(startCam.Position, startCam.Rotation);
}
}
else
{ // Copy gaia data from defaults
- player.SetName(pDefs.Name);
- player.SetCiv(pDefs.Civ);
- player.SetColour(pDefs.Colour.r, pDefs.Colour.g, pDefs.Colour.b);
- player.SetDiplomacy(diplomacy);
+ cmpPlayer.SetName(pDefs.Name);
+ cmpPlayer.SetCiv(pDefs.Civ);
+ cmpPlayer.SetColour(pDefs.Colour.r, pDefs.Colour.g, pDefs.Colour.b);
+
+ for (var j = 0; j < numPlayers; ++j)
+ { // Gaia is everyone's enemy
+ cmpPlayer.SetEnemy(j);
+ }
}
// Add player to player manager
@@ -219,7 +192,6 @@ function IsOwnedByAllyOfEntity(entity, target)
if (cmpOwnershipTarget)
targetOwner = cmpOwnershipTarget.GetOwner();
- // Get our diplomacy array
var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(owner), IID_Player);
@@ -250,7 +222,6 @@ function IsOwnedByAllyOfPlayer(player, target)
if (cmpOwnershipTarget)
targetOwner = cmpOwnershipTarget.GetOwner();
- // Get our diplomacy array
var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);
@@ -272,7 +243,6 @@ function IsOwnedByEnemyOfPlayer(player, target)
if (cmpOwnershipTarget)
targetOwner = cmpOwnershipTarget.GetOwner();
- // Get our diplomacy array
var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);