1
0
forked from 0ad/0ad

Basic diplomacy. Refs #7.

This was SVN commit r12778.
This commit is contained in:
leper 2012-10-23 16:31:07 +00:00
parent 8208b52faf
commit a21e01150a
13 changed files with 612 additions and 269 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<sprites>
<!--
==========================================
SESSION GUI - ICONS - BACKGROUNDS

View File

@ -285,6 +285,7 @@ function initMain()
getGUIObjectByName("enableCheatsText").hidden = false;
}
}
// Settings for all possible player slots
var boxSpacing = 32;
for (var i = 0; i < MAX_PLAYERS; ++i)
@ -986,7 +987,7 @@ function onGameAttributesChange()
victoryConditionText.caption = "Victory condition:";
victoryCondition.selected = victoryIdx;
lockTeamsText.caption = "Teams locked:";
lockTeams.checked = (mapSettings.LockTeams === undefined || mapSettings.LockTeams ? true : false);
lockTeams.checked = (mapSettings.LockTeams ? true : false);
}
else
{
@ -1007,7 +1008,7 @@ function onGameAttributesChange()
mapSizeText.caption = g_MapSizes.names[sizeIdx];
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
lockTeamsText.caption = (mapSettings.LockTeams === undefined || mapSettings.LockTeams ? "Yes" : "No");
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
}
break;
@ -1035,8 +1036,9 @@ function onGameAttributesChange()
mapSizeText.caption = "Default";
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
lockTeamsText.caption = (mapSettings.LockTeams === undefined || mapSettings.LockTeams ? "Yes" : "No");
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
getGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;
break;
default:

View File

@ -32,6 +32,8 @@ const MENU_SPEED = 1.2;
var isMenuOpen = false;
var menu;
var isDiplomacyOpen = false;
// Ignore size defined in XML and set the actual menu size here
function initMenuPosition()
{
@ -111,6 +113,13 @@ function chatMenuButton()
openChat();
}
function diplomacyMenuButton()
{
closeMenu();
closeOpenDialogs();
openDiplomacy();
}
function pauseMenuButton()
{
togglePause();
@ -206,6 +215,102 @@ function toggleChatWindow(teamChat)
chatWindow.hidden = !chatWindow.hidden;
}
function setDiplomacy(data)
{
Engine.PostNetworkCommand({"type": "diplomacy", "to": data.to, "player": data.player});
}
function tributeResource(data)
{
Engine.PostNetworkCommand({"type": "tribute", "player": data.player, "amounts": data.amounts});
}
function openDiplomacy()
{
isDiplomacyOpen = true;
var we = Engine.GetPlayerID();
var players = getPlayerData(g_PlayerAssignments);
// Get offset for one line
var onesize = getGUIObjectByName("diplomacyPlayer[0]").size;
var rowsize = onesize.bottom - onesize.top;
// We don't include gaia
for (var i = 1; i < players.length; i++)
{
// Apply offset
var row = getGUIObjectByName("diplomacyPlayer["+(i-1)+"]");
var size = row.size;
size.top = rowsize*(i-1);
size.bottom = rowsize*i;
row.size = size;
// Set background colour
var playerColor = players[i].color.r+" "+players[i].color.g+" "+players[i].color.b;
row.sprite = "colour: "+playerColor + " 32";
getGUIObjectByName("diplomacyPlayerName["+(i-1)+"]").caption = "[color=\"" + playerColor + "\"]" + players[i].name + "[/color]";
getGUIObjectByName("diplomacyPlayerCiv["+(i-1)+"]").caption = g_CivData[players[i].civ].Name;
getGUIObjectByName("diplomacyPlayerTeam["+(i-1)+"]").caption = (players[i].team < 0) ? "None" : players[i].team+1;
// Don't display this for ourself and our locked team members
if (i != we && !(players[we].teamsLocked && players[we].team != -1 && players[we].team == players[i].team))
{
getGUIObjectByName("diplomacyPlayerTheirs["+(i-1)+"]").caption = (players[i].isAlly[we] ? "Ally" : (players[i].isNeutral[we] ? "Neutral" : "Enemy") );
// Set up the buttons
for each (var setting in ["ally", "neutral", "enemy"])
{
var button = getGUIObjectByName("diplomacyPlayer"+toTitleCase(setting)+"["+(i-1)+"]");
// Disable the button with the current setting
// TODO: Needs new graphics for the button (enabled/disabled) to make it
// look more like a checkbox
button.enabled = !((setting=="ally" && players[we].isAlly[i])
|| (setting=="neutral" && players[we].isNeutral[i])
|| (setting=="enemy" && players[we].isEnemy[i]));
button.onpress = (function(e){ return function() { setDiplomacy(e) } })({"player": i, "to": setting});
button.hidden = false;
}
}
// Tributes (you can't tribute to yourself)
if (i != we)
{
for each (var resource in ["food", "wood", "stone", "metal"])
{
var button = getGUIObjectByName("diplomacyPlayerTribute"+toTitleCase(resource)+"["+(i-1)+"]");
// TODO: Make amounts changeable or change to 500 if shift is pressed
var amounts = {
"food": (resource=="food")?100:0,
"wood": (resource=="wood")?100:0,
"stone": (resource=="stone")?100:0,
"metal": (resource=="metal")?100:0,
};
button.onpress = (function(e){ return function() { tributeResource(e) } })({"player": i, "amounts": amounts});
button.hidden = false;
}
}
}
getGUIObjectByName("diplomacyDialogPanel").hidden = false;
}
function closeDiplomacy()
{
isDiplomacyOpen = false;
getGUIObjectByName("diplomacyDialogPanel").hidden = true;
}
function toggleDiplomacy()
{
if (isDiplomacyOpen)
closeDiplomacy();
else
openDiplomacy();
};
function pauseGame()
{
getGUIObjectByName("pauseButtonText").caption = RESUME;
@ -254,6 +359,7 @@ function closeOpenDialogs()
{
closeMenu();
closeChat();
closeDiplomacy();
closeSettings(false);
}

View File

@ -36,6 +36,19 @@ function handleNotifications()
"player": notification.player
});
}
else if (notification.type == "diplomacy")
{
addChatMessage({
"type": "diplomacy",
"player": notification.player,
"player1": notification.player1,
"status": notification.status
});
// If the diplomacy panel is open refresh it.
if (isDiplomacyOpen)
openDiplomacy();
}
else if (notification.type == "quit")
{
// Used for AI testing
@ -272,6 +285,23 @@ function addChatMessage(msg, playerAssignments)
var verb = (!g_IsNetworked && msg.player == Engine.GetPlayerID()) ? "have" : "has";
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] " + verb + " been defeated.";
break;
case "diplomacy":
username= escapeText(g_Players[msg.player1].name);
// 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.
return;
break;
case "message":
// May have been hidden by the 'team' command.
if (msg.hide)

View File

@ -239,6 +239,62 @@
</object>
</object>
<!-- ================================ ================================ -->
<!-- Diplomacy Window -->
<!-- ================================ ================================ -->
<object name="diplomacyDialogPanel"
size="50%-300 50%-200 50%+300 50%+150"
type="image"
hidden="true"
sprite="StoneDialog"
>
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">Diplomacy</object>
<object name="diplomacyHeader" size="32 32 100%-32 64">
<object name="diplomacyHeaderName" size="0 0 150 100%" type="text" style="chatPanel" ghost="true" caption="Name"/>
<object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style="chatPanel" ghost="true" caption="Civilization"/>
<object name="diplomacyHeaderTheirs" size="250 0 310 100%" type="text" style="chatPanel" ghost="true" caption="Theirs"/>
<object name="diplomacyHeaderTeam" size="310 0 360 100%" type="text" style="chatPanel" ghost="true" caption="Team"/>
<object name="diplomacyHeaderAlly" size="100%-180 0 100%-160 100%" type="text" style="chatPanel" caption="A" tooltip="Ally" tooltip_style="sessionToolTipBold"/>
<object name="diplomacyHeaderNeutral" size="100%-160 0 100%-140 100%" type="text" style="chatPanel" caption="N" tooltip="Neutral" tooltip_style="sessionToolTipBold"/>
<object name="diplomacyHeaderEnemy" size="100%-140 0 100%-120 100%" type="text" style="chatPanel" caption="E" tooltip="Enemy" tooltip_style="sessionToolTipBold"/>
<object name="diplomacyHeaderTribute" size="100%-110 0 100% 100%" type="text" style="chatPanel" caption="Tribute"/>
</object>
<object size="32 64 100%-32 384">
<repeat count="16">
<object name="diplomacyPlayer[n]" size="0 0 100% 20" type="image" hidden="false">
<object name="diplomacyPlayerName[n]" size="0 0 150 100%" type="text" style="chatPanel" ghost="true"/>
<object name="diplomacyPlayerCiv[n]" size="150 0 250 100%" type="text" style="chatPanel" ghost="true"/>
<object name="diplomacyPlayerTheirs[n]" size="250 0 310 100%" type="text" style="chatPanel" ghost="true"/>
<object name="diplomacyPlayerTeam[n]" size="310 0 360 100%" type="text" style="chatPanel" ghost="true"/>
<!-- TODO add tooltips to those 3 ? -->
<object name="diplomacyPlayerAlly[n]" size="100%-180 0 100%-160 100%" type="button" style="StoneButton" hidden="true"/>
<object name="diplomacyPlayerNeutral[n]" size="100%-160 0 100%-140 100%" type="button" style="StoneButton" hidden="true"/>
<object name="diplomacyPlayerEnemy[n]" size="100%-140 0 100%-120 100%" type="button" style="StoneButton" hidden="true"/>
<object name="diplomacyPlayerTributeFood[n]" size="100%-110 0 100%-90 100%" type="button" style="iconButton" tooltip="Food" hidden="true">
<object name="diplomacyPlayerTributeFoodImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/food.png" ghost="true"/>
</object>
<object name="diplomacyPlayerTributeWood[n]" size="100%-90 0 100%-70 100%" type="button" style="iconButton" tooltip="Wood" hidden="true">
<object name="diplomacyPlayerTributeWoodImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/wood.png" ghost="true"/>
</object>
<object name="diplomacyPlayerTributeStone[n]" size="100%-70 0 100%-50 100%" type="button" style="iconButton" tooltip="Stone" hidden="true">
<object name="diplomacyPlayerTributeStoneImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/stone.png" ghost="true"/>
</object>
<object name="diplomacyPlayerTributeMetal[n]" size="100%-50 0 100%-30 100%" type="button" style="iconButton" tooltip="Metal" hidden="true">
<object name="diplomacyPlayerTributeMetalImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/metal.png" ghost="true"/>
</object>
</object>
</repeat>
</object>
<object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton">
Close
<action on="Press">closeDiplomacy();</action>
</object>
</object>
<!-- ================================ ================================ -->
<!-- Settings Window -->
<!-- ================================ ================================ -->
@ -384,6 +440,23 @@
</object>
</object>
<!-- ================================ ================================ -->
<!-- Diplomacy Button -->
<!-- ================================ ================================ -->
<object type="button"
name="diplomacyButton1"
size="100%-196 0 100%-164 32"
style="iconButton"
tooltip_style="sessionToolTip"
tooltip="Diplomacy"
>
<!-- TODO make the button less ugly -->
<object size="0 0 100% 100%" name="diplomacyButtonImage" type="image" sprite="stretched:session/icons/diplomacy.png" ghost="true"/>
<action on="Press">
toggleDiplomacy();
</action>
</object>
<!-- ================================ ================================ -->
<!-- Menu Button -->
<!-- ================================ ================================ -->

View File

@ -25,7 +25,6 @@ function toTitleCase(word)
{
titleCased += word.substring(1).toLowerCase();
}
return titleCased;
}
@ -59,7 +58,11 @@ function getPlayerData(playerAssignments)
"civ": civ,
"color": color,
"team": playerState.team,
"teamsLocked": playerState.teamsLocked,
"state": playerState.state,
"isAlly": playerState.isAlly,
"isNeutral": playerState.isNeutral,
"isEnemy": playerState.isEnemy,
"guid": undefined, // network guid for players controlled by hosts
"disconnected": false // flag for host-controlled players who have left the game
};
@ -237,9 +240,9 @@ function getEntityCommandsList(entState)
if (entState.rallyPoint)
{
commands.push({
"name": "focus-rally",
"tooltip": "Focus on Rally Point",
"icon": "focus-rally.png"
"name": "delete",
"tooltip": "Delete",
"icon": "kill_small.png"
});
}

View File

@ -62,12 +62,14 @@ GuiInterface.prototype.GetSimulationState = function(player)
else if (cmpTechnologyManager.IsTechnologyResearched("phase_village"))
phase = "village";
// store player ally/enemy data as arrays
// store player ally/neutral/enemy data as arrays
var allies = [];
var neutrals = [];
var enemies = [];
for (var j = 0; j <= n; ++j)
{
allies[j] = cmpPlayer.IsAlly(j);
neutrals[j] = cmpPlayer.IsNeutral(j);
enemies[j] = cmpPlayer.IsEnemy(j);
}
var playerData = {
@ -81,8 +83,10 @@ GuiInterface.prototype.GetSimulationState = function(player)
"trainingBlocked": cmpPlayer.IsTrainingBlocked(),
"state": cmpPlayer.GetState(),
"team": cmpPlayer.GetTeam(),
"teamsLocked": cmpPlayer.GetLockTeams(),
"phase": phase,
"isAlly": allies,
"isNeutral": neutrals,
"isEnemy": enemies,
"buildLimits": cmpPlayerBuildLimits.GetLimits(),
"buildCounts": cmpPlayerBuildLimits.GetCounts(),

View File

@ -21,6 +21,7 @@ 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.teamsLocked = false;
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 gaia and self)
this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class
@ -228,8 +229,38 @@ Player.prototype.GetTeam = function()
};
Player.prototype.SetTeam = function(team)
{
if (!this.teamsLocked)
{
this.team = team;
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
if (cmpPlayerManager && this.team != -1)
{
// Set all team members as allies
for (var i = 0; i < this.diplomacy.length; ++i)
{
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
if (this.team == cmpPlayer.GetTeam())
{
this.SetAlly(i);
cmpPlayer.SetAlly(this.playerID);
}
}
}
Engine.BroadcastMessage(MT_DiplomacyChanged, {"player": this.playerID});
}
};
Player.prototype.SetLockTeams = function(value)
{
this.teamsLocked = value;
};
Player.prototype.GetLockTeams = function()
{
return this.teamsLocked;
};
Player.prototype.GetDiplomacy = function()
@ -239,15 +270,33 @@ Player.prototype.GetDiplomacy = function()
Player.prototype.SetDiplomacy = function(dipl)
{
// Should we check for teamsLocked here?
this.diplomacy = dipl;
this.UpdateSharedLos();
Engine.BroadcastMessage(MT_DiplomacyChanged, {"player": this.playerID});
};
Player.prototype.SetDiplomacyIndex = function(idx, value)
{
// TODO: send a message too?
// You can have alliances with other players,
if (this.teamsLocked)
{
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
if (cmpPlayerManager)
{
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(idx), IID_Player);
// but can't stab your team members in the back
if (this.team == -1 || cmpPlayer && this.team != cmpPlayer.GetTeam())
{
this.diplomacy[idx] = value;
this.UpdateSharedLos();
Engine.BroadcastMessage(MT_DiplomacyChanged, {"player": this.playerID});
}
}
}
else
{
this.diplomacy[idx] = value;
Engine.BroadcastMessage(MT_DiplomacyChanged, {"player": this.playerID});
}
};
Player.prototype.UpdateSharedLos = function()
@ -256,12 +305,18 @@ Player.prototype.UpdateSharedLos = function()
if (!cmpRangeManager)
return;
// TODO: only check our alliances currently, more advanced checks
// will be needed when we have full diplomacy
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
if (!cmpPlayerManager)
return;
var sharedLos = [];
for (var i = 0; i < this.diplomacy.length; ++i)
if (this.IsAlly(i))
{
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
if (cmpPlayer && cmpPlayer.IsAlly(this.playerID))
sharedLos.push(i);
}
cmpRangeManager.SetSharedLos(this.playerID, sharedLos);
};
@ -405,6 +460,8 @@ Player.prototype.OnPlayerDefeated = function(msg)
{
this.state = "defeated";
// TODO: Tribute all resources to this player's active allies (if any)
// Reassign all player's entities to Gaia
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
var entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID);
@ -432,15 +489,38 @@ Player.prototype.OnPlayerDefeated = function(msg)
cmpGUIInterface.PushNotification(notification);
};
Player.prototype.OnDiplomacyChanged = function()
{
this.UpdateSharedLos();
};
Player.prototype.SetCheatEnabled = function(flag)
{
this.cheatsEnabled = flag;
}
};
Player.prototype.GetCheatEnabled = function(flag)
{
return this.cheatsEnabled;
};
Player.prototype.TributeResource = function(player, amounts)
{
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
if (!cmpPlayerManager)
return;
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player);
if (cmpPlayer && !this.GetNeededResources(amounts))
{
for (var type in amounts)
this.resourceCount[type] -= amounts[type];
cmpPlayer.AddResources(amounts);
// TODO: notify the receiver
}
// else not enough resources... TODO: send gui notification
};
Engine.RegisterComponentType(IID_Player, "Player", Player);

View File

@ -1926,6 +1926,13 @@ UnitAI.prototype.OnCreate = function()
UnitFsm.Init(this, "INDIVIDUAL.IDLE");
};
UnitAI.prototype.OnDiplomacyChanged = function(msg)
{
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (cmpOwnership && cmpOwnership.GetOwner() == msg.player)
this.SetupRangeQuery();
};
UnitAI.prototype.OnOwnershipChanged = function(msg)
{
this.SetupRangeQueries();

View File

@ -7,3 +7,4 @@
*/
Engine.RegisterMessageType("EntityRenamed");
Engine.RegisterMessageType("DiplomacyChanged");

View File

@ -61,9 +61,11 @@ AddMock(100, IID_Player, {
IsTrainingBlocked: function() { return false; },
GetState: function() { return "active"; },
GetTeam: function() { return -1; },
GetLockTeams: function() { return false; },
GetDiplomacy: function() { return [-1, 1]; },
GetConquestCriticalEntitiesCount: function() { return 1; },
IsAlly: function() { return false; },
IsNeutral: function() { return false; },
IsEnemy: function() { return true; },
});
@ -112,9 +114,11 @@ AddMock(101, IID_Player, {
IsTrainingBlocked: function() { return false; },
GetState: function() { return "active"; },
GetTeam: function() { return -1; },
GetLockTeams: function() {return false; },
GetDiplomacy: function() { return [-1, 1]; },
GetConquestCriticalEntitiesCount: function() { return 1; },
IsAlly: function() { return true; },
IsNeutral: function() { return false; },
IsEnemy: function() { return false; },
});
@ -168,8 +172,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
trainingBlocked: false,
state: "active",
team: -1,
teamsLocked: false,
phase: "",
isAlly: [false, false, false],
isNeutral: [false, false, false],
isEnemy: [true, true, true],
buildLimits: {"Foo": 10},
buildCounts: {"Foo": 5},
@ -186,8 +192,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
trainingBlocked: false,
state: "active",
team: -1,
teamsLocked: false,
phase: "village",
isAlly: [true, true, true],
isNeutral: [false, false, false],
isEnemy: [false, false, false],
buildLimits: {"Bar": 20},
buildCounts: {"Bar": 0},
@ -211,8 +219,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
trainingBlocked: false,
state: "active",
team: -1,
teamsLocked:false,
phase: "",
isAlly: [false, false, false],
isNeutral: [false, false, false],
isEnemy: [true, true, true],
buildLimits: {"Foo": 10},
buildCounts: {"Foo": 5},
@ -245,8 +255,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
trainingBlocked: false,
state: "active",
team: -1,
teamsLocked:false,
phase: "village",
isAlly: [true, true, true],
isNeutral: [false, false, false],
isEnemy: [false, false, false],
buildLimits: {"Bar": 20},
buildCounts: {"Bar": 0},

View File

@ -47,6 +47,29 @@ function ProcessCommand(player, cmd)
cmpGuiInterface.PushNotification({"type": "quit"});
break;
case "diplomacy":
switch(cmd.to)
{
case "ally":
cmpPlayer.SetAlly(cmd.player);
break;
case "neutral":
cmpPlayer.SetNeutral(cmd.player);
break;
case "enemy":
cmpPlayer.SetEnemy(cmd.player);
break;
default:
warn("Invalid command: Could not set "+player+" diplomacy status of player "+cmd.player+" to "+cmd.to);
}
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGuiInterface.PushNotification({"type": "diplomacy", "player": player, "player1": cmd.player, "status": cmd.to});
break;
case "tribute":
cmpPlayer.TributeResource(cmd.player, cmd.amounts);
break;
case "control-all":
cmpPlayer.SetControlAllUnits(cmd.flag);
break;

View File

@ -87,22 +87,16 @@ function LoadPlayerSettings(settings, newPlayers)
// Init diplomacy
cmpPlayer.SetDiplomacy(new Array(numPlayers));
var myTeam = getSetting(pData, pDefs, "Team");
cmpPlayer.SetTeam(myTeam);
// Set all but self as enemies as SetTeam takes care of allies
for (var j = 0; j < numPlayers; ++j)
{
if (j > 0)
{
// We are always our own ally, else check if player is on the same team
var theirTeam = getSetting(settings.PlayerData[j-1], playerDefaults[j], "Team");
if (i == j || (myTeam !== undefined && myTeam != -1 && theirTeam !== undefined && myTeam == theirTeam))
{
if (i == j)
cmpPlayer.SetAlly(j);
continue;
}
}
// Gaia, different team, or no team defined
else
cmpPlayer.SetEnemy(j);
}
cmpPlayer.SetTeam(myTeam);
}
// If formations explicitly defined, use that; otherwise use civ defaults
@ -137,6 +131,15 @@ function LoadPlayerSettings(settings, newPlayers)
cmpPlayer.SetEnemy(j);
}
}
// NOTE: We need to do the team locking here, as otherwise
// SetTeam can't ally the players.
if (settings.LockTeams)
for (var i = 0; i < numPlayers; ++i)
{
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
cmpPlayer.SetLockTeams(true);
}
}
// Get a setting if it exists or return default