mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-07-27 04:13:36 +00:00
f29f0b7fd1
Enable recommended rule 'no-prototype-builtins' [1] and manually fix violations. [1] https://eslint.org/docs/latest/rules/no-prototype-builtins Ref: #8068 Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
351 lines
7.7 KiB
JavaScript
351 lines
7.7 KiB
JavaScript
function Diplomacy() {}
|
|
|
|
Diplomacy.prototype.Schema =
|
|
"<element name='SharedLosTech' a:help='Allies will share los when this technology is researched. Leave empty to never share LOS.'>" +
|
|
"<text/>" +
|
|
"</element>" +
|
|
"<element name='SharedDropsitesTech' a:help='Allies will share dropsites when this technology is researched. Leave empty to never share dropsites.'>" +
|
|
"<text/>" +
|
|
"</element>";
|
|
|
|
Diplomacy.prototype.SerializableAttributes = [
|
|
"team",
|
|
"teamLocked",
|
|
"diplomacy",
|
|
"sharedDropsites",
|
|
];
|
|
|
|
Diplomacy.prototype.Serialize = function()
|
|
{
|
|
const state = {};
|
|
for (const key of this.SerializableAttributes)
|
|
if (Object.hasOwn(this, key))
|
|
state[key] = this[key];
|
|
|
|
return state;
|
|
};
|
|
|
|
Diplomacy.prototype.Deserialize = function(state)
|
|
{
|
|
for (const att of this.SerializableAttributes)
|
|
if (att in state)
|
|
this[att] = state[att];
|
|
};
|
|
|
|
Diplomacy.prototype.Init = function()
|
|
{
|
|
// 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.team = -1;
|
|
|
|
// Array of diplomatic stances for this player with respect to other players (including gaia and self).
|
|
this.diplomacy = [];
|
|
};
|
|
|
|
/**
|
|
* @param {Object} color - r, g, b values of the diplomacy colour.
|
|
*/
|
|
Diplomacy.prototype.SetDiplomacyColor = function(color)
|
|
{
|
|
this.diplomacyColor = { "r": color.r / 255, "g": color.g / 255, "b": color.b / 255, "a": 1 };
|
|
};
|
|
|
|
/**
|
|
* @return {Object} -
|
|
*/
|
|
Diplomacy.prototype.GetColor = function()
|
|
{
|
|
return this.diplomacyColor;
|
|
};
|
|
|
|
/**
|
|
* @return {number} -
|
|
*/
|
|
Diplomacy.prototype.GetTeam = function()
|
|
{
|
|
return this.team;
|
|
};
|
|
|
|
/**
|
|
* @param {number} team - The new team number, -1 for no team.
|
|
*/
|
|
Diplomacy.prototype.ChangeTeam = function(team)
|
|
{
|
|
if (this.teamLocked || this.team === team)
|
|
return;
|
|
|
|
const playerID = Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID();
|
|
if (!playerID)
|
|
return;
|
|
|
|
// ToDo: Fix this.
|
|
if (this.team !== -1)
|
|
warn("A change in teams is requested while the player already had a team, previous alliances are maintained.");
|
|
|
|
const oldTeam = this.team;
|
|
this.team = team;
|
|
|
|
if (this.team !== -1)
|
|
{
|
|
const numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers();
|
|
for (let i = 0; i < numPlayers; ++i)
|
|
{
|
|
const cmpDiplomacy = QueryPlayerIDInterface(i, IID_Diplomacy);
|
|
if (this.team !== cmpDiplomacy.GetTeam())
|
|
continue;
|
|
|
|
this.Ally(i);
|
|
cmpDiplomacy.Ally(playerID);
|
|
}
|
|
}
|
|
|
|
Engine.BroadcastMessage(MT_TeamChanged, {
|
|
"player": playerID,
|
|
"oldTeam": oldTeam,
|
|
"newTeam": team
|
|
});
|
|
};
|
|
|
|
Diplomacy.prototype.LockTeam = function()
|
|
{
|
|
this.teamLocked = true;
|
|
};
|
|
|
|
Diplomacy.prototype.UnLockTeam = function()
|
|
{
|
|
delete this.teamLocked;
|
|
};
|
|
|
|
/**
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsTeamLocked = function()
|
|
{
|
|
return !!this.teamLocked;
|
|
};
|
|
|
|
/**
|
|
* @return {number[]} - Current diplomatic stances.
|
|
*/
|
|
Diplomacy.prototype.GetDiplomacy = function()
|
|
{
|
|
return this.diplomacy.slice();
|
|
};
|
|
|
|
/**
|
|
* @param {number[]} dipl - The diplomacy array to set.
|
|
*/
|
|
Diplomacy.prototype.SetDiplomacy = function(dipl)
|
|
{
|
|
const playerID = Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID();
|
|
if (playerID === undefined)
|
|
return;
|
|
|
|
this.diplomacy = dipl.slice();
|
|
|
|
Engine.BroadcastMessage(MT_DiplomacyChanged, {
|
|
"player": playerID,
|
|
"otherPlayer": null
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Helper function for allying etc.
|
|
* @param {number} idx - The player number.
|
|
* @param {number} value - The diplomacy value.
|
|
*/
|
|
Diplomacy.prototype.SetDiplomacyIndex = function(idx, value)
|
|
{
|
|
if (!QueryPlayerIDInterface(idx)?.IsActive())
|
|
return;
|
|
|
|
const cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
|
if (!cmpPlayer?.IsActive())
|
|
return;
|
|
|
|
this.diplomacy[idx] = value;
|
|
|
|
const playerID = cmpPlayer.GetPlayerID();
|
|
Engine.BroadcastMessage(MT_DiplomacyChanged, {
|
|
"player": playerID,
|
|
"otherPlayer": idx,
|
|
"value": value
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Helper function for getting allies etc.
|
|
* @param {string} func - Name of the function to test.
|
|
* @return {number[]} - Player IDs matching the function.
|
|
*/
|
|
Diplomacy.prototype.GetPlayersByDiplomacy = function(func)
|
|
{
|
|
const players = [];
|
|
for (let i = 0; i < this.diplomacy.length; ++i)
|
|
if (this[func](i))
|
|
players.push(i);
|
|
return players;
|
|
};
|
|
|
|
/**
|
|
* @param {number} - id
|
|
*/
|
|
Diplomacy.prototype.Ally = function(id)
|
|
{
|
|
this.SetDiplomacyIndex(id, 1);
|
|
};
|
|
|
|
/**
|
|
* Check if given player is our ally.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsAlly = function(id)
|
|
{
|
|
return this.diplomacy[id] > 0;
|
|
};
|
|
|
|
/**
|
|
* @return {number[]} -
|
|
*/
|
|
Diplomacy.prototype.GetAllies = function()
|
|
{
|
|
return this.GetPlayersByDiplomacy("IsAlly");
|
|
};
|
|
|
|
/**
|
|
* Check if given player is our ally excluding ourself.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsExclusiveAlly = function(id)
|
|
{
|
|
return Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID() !== id && this.IsAlly(id);
|
|
};
|
|
|
|
/**
|
|
* Check if given player is our ally, and we are its ally.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsMutualAlly = function(id)
|
|
{
|
|
const playerID = Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID();
|
|
return playerID !== undefined && this.IsAlly(id) && QueryPlayerIDInterface(id, IID_Diplomacy)?.IsAlly(playerID);
|
|
};
|
|
|
|
/**
|
|
* @return {number[]} -
|
|
*/
|
|
Diplomacy.prototype.GetMutualAllies = function()
|
|
{
|
|
return this.GetPlayersByDiplomacy("IsMutualAlly");
|
|
};
|
|
|
|
/**
|
|
* Check if given player is our ally, and we are its ally, excluding ourself.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsExclusiveMutualAlly = function(id)
|
|
{
|
|
const playerID = Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID();
|
|
return playerID !== id && this.IsMutualAlly(id);
|
|
};
|
|
|
|
/**
|
|
* @param {number} id -
|
|
*/
|
|
Diplomacy.prototype.SetEnemy = function(id)
|
|
{
|
|
this.SetDiplomacyIndex(id, -1);
|
|
};
|
|
|
|
/**
|
|
* Check if given player is our enemy.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsEnemy = function(id)
|
|
{
|
|
return this.diplomacy[id] < 0;
|
|
};
|
|
|
|
/**
|
|
* @return {number[]} -
|
|
*/
|
|
Diplomacy.prototype.GetEnemies = function()
|
|
{
|
|
return this.GetPlayersByDiplomacy("IsEnemy");
|
|
};
|
|
|
|
/**
|
|
* @param {number} id -
|
|
*/
|
|
Diplomacy.prototype.SetNeutral = function(id)
|
|
{
|
|
this.SetDiplomacyIndex(id, 0);
|
|
};
|
|
|
|
/**
|
|
* Check if given player is neutral.
|
|
* @param {number} id -
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.IsNeutral = function(id)
|
|
{
|
|
return this.diplomacy[id] === 0;
|
|
};
|
|
|
|
/**
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.HasSharedDropsites = function()
|
|
{
|
|
return this.sharedDropsites;
|
|
};
|
|
|
|
/**
|
|
* @return {boolean} -
|
|
*/
|
|
Diplomacy.prototype.HasSharedLos = function()
|
|
{
|
|
const cmpTechnologyManager = Engine.QueryInterface(this.entity, IID_TechnologyManager);
|
|
return cmpTechnologyManager && cmpTechnologyManager.IsTechnologyResearched(this.template.SharedLosTech);
|
|
};
|
|
|
|
Diplomacy.prototype.UpdateSharedLos = function()
|
|
{
|
|
const playerID = Engine.QueryInterface(this.entity, IID_Player)?.GetPlayerID();
|
|
if (playerID === undefined)
|
|
return;
|
|
|
|
Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager)?.
|
|
SetSharedLos(playerID, this.HasSharedLos() ? this.GetMutualAllies() : [playerID]);
|
|
};
|
|
|
|
Diplomacy.prototype.OnResearchFinished = function(msg)
|
|
{
|
|
if (msg.tech === this.template.SharedLosTech)
|
|
this.UpdateSharedLos();
|
|
else if (msg.tech === this.template.SharedDropsitesTech)
|
|
this.sharedDropsites = true;
|
|
};
|
|
|
|
Diplomacy.prototype.OnDiplomacyChanged = function(msg)
|
|
{
|
|
this.UpdateSharedLos();
|
|
|
|
if (msg.otherPlayer === null)
|
|
return;
|
|
|
|
const cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
|
if (!cmpPlayer || cmpPlayer.GetPlayerID() != msg.otherPlayer)
|
|
return;
|
|
|
|
// Mutual worsening of relations.
|
|
if (this.diplomacy[msg.player] > msg.value)
|
|
this.SetDiplomacyIndex(msg.player, msg.value);
|
|
};
|
|
|
|
Engine.RegisterComponentType(IID_Diplomacy, "Diplomacy", Diplomacy);
|