Add optional ceasefire time to the game. Patch by elexis. Fixes #2749

This was SVN commit r16624.
This commit is contained in:
sanderd17 2015-05-05 13:38:36 +00:00
parent 7f606250f8
commit d21c0026ec
15 changed files with 308 additions and 33 deletions

View File

@ -26,7 +26,7 @@
sprite="color: 0 0 0 200"
font="mono-stroke-10"
textcolor="white"
size="100%-80 70 100%-10 90"
size="100%-130 50 100%-60 70"
z="199"
>
<action on="Tick">
@ -52,7 +52,7 @@
sprite="color: 0 0 0 200"
font="mono-stroke-10"
textcolor="white"
size="100%-80 100 100%-10 120"
size="100%-130 80 100%-60 100"
z="199"
>
<action on="Tick">

View File

@ -14,6 +14,10 @@ const POPULATION_CAP_DEFAULTIDX = 5;
const STARTING_RESOURCES = [translateWithContext("startingResources", "Very Low"), translateWithContext("startingResources", "Low"), translateWithContext("startingResources", "Medium"), translateWithContext("startingResources", "High"), translateWithContext("startingResources", "Very High"), translateWithContext("startingResources", "Deathmatch")];
const STARTING_RESOURCES_DATA = [100, 300, 500, 1000, 3000, 50000];
const STARTING_RESOURCES_DEFAULTIDX = 1;
// Translation: Ceasefire.
const CEASEFIRE = [translateWithContext("ceasefire", "No ceasefire"), translateWithContext("ceasefire", "5 minutes"), translateWithContext("ceasefire", "10 minutes"), translateWithContext("ceasefire", "15 minutes"), translateWithContext("ceasefire", "20 minutes"), translateWithContext("ceasefire", "30 minutes"), translateWithContext("ceasefire", "45 minutes"), translateWithContext("ceasefire", "60 minutes")];
const CEASEFIRE_DATA = [0, 5, 10, 15, 20, 30, 45, 60];
const CEASEFIRE_DEFAULTIDX = 0;
// Max number of players for any map
const MAX_PLAYERS = 8;
@ -205,6 +209,17 @@ function initMain()
updateGameAttributes();
}
var ceasefireL = Engine.GetGUIObjectByName("ceasefire");
ceasefireL.list = CEASEFIRE;
ceasefireL.list_data = CEASEFIRE_DATA;
ceasefireL.selected = CEASEFIRE_DEFAULTIDX;
ceasefireL.onSelectionChange = function() {
if (this.selected != -1)
g_GameAttributes.settings.Ceasefire = CEASEFIRE_DATA[this.selected];
updateGameAttributes();
}
var victoryConditions = Engine.GetGUIObjectByName("victoryCondition");
var victories = getVictoryConditions();
victoryConditions.list = victories.text;
@ -740,6 +755,12 @@ function loadGameAttributes()
startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);
}
if (mapSettings.Ceasefire)
{
var ceasefireBox = Engine.GetGUIObjectByName("ceasefire");
ceasefireBox.selected = ceasefireBox.list_data.indexOf(mapSettings.Ceasefire);
}
if (attrs.gameSpeed)
{
var gameSpeedBox = Engine.GetGUIObjectByName("gameSpeed");
@ -1143,6 +1164,12 @@ function onGameAttributesChange()
startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);
}
if (mapSettings.Ceasefire)
{
var ceasefireBox = Engine.GetGUIObjectByName("ceasefire");
ceasefireBox.selected = ceasefireBox.list_data.indexOf(mapSettings.Ceasefire);
}
initMapNameList();
}
@ -1158,6 +1185,7 @@ function onGameAttributesChange()
var enableRating = Engine.GetGUIObjectByName("enableRating");
var populationCap = Engine.GetGUIObjectByName("populationCap");
var startingResources = Engine.GetGUIObjectByName("startingResources");
var ceasefire = Engine.GetGUIObjectByName("ceasefire");
var numPlayersText= Engine.GetGUIObjectByName("numPlayersText");
var mapSizeDesc = Engine.GetGUIObjectByName("mapSizeDesc");
@ -1171,6 +1199,7 @@ function onGameAttributesChange()
var enableRatingText = Engine.GetGUIObjectByName("enableRatingText");
var populationCapText = Engine.GetGUIObjectByName("populationCapText");
var startingResourcesText = Engine.GetGUIObjectByName("startingResourcesText");
var ceasefireText = Engine.GetGUIObjectByName("ceasefireText");
var gameSpeedText = Engine.GetGUIObjectByName("gameSpeedText");
var gameSpeedBox = Engine.GetGUIObjectByName("gameSpeed");
@ -1197,6 +1226,8 @@ function onGameAttributesChange()
populationCapText.caption = POPULATION_CAP[populationCap.selected];
startingResources.selected = (mapSettings.StartingResources !== undefined && STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);
startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];
ceasefire.selected = (mapSettings.Ceasefire !== undefined && CEASEFIRE_DATA.indexOf(mapSettings.Ceasefire) != -1 ? CEASEFIRE_DATA.indexOf(mapSettings.Ceasefire) : CEASEFIRE_DEFAULTIDX);
ceasefireText.caption = CEASEFIRE[ceasefire.selected];
// Update map preview
Engine.GetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
@ -1222,6 +1253,7 @@ function onGameAttributesChange()
updateDisplay(lockTeams, lockTeamsText, g_IsController);
updateDisplay(populationCap, populationCapText, g_IsController);
updateDisplay(startingResources, startingResourcesText, g_IsController);
updateDisplay(ceasefire, ceasefireText, g_IsController);
if (g_IsController)
{
@ -1264,6 +1296,7 @@ function onGameAttributesChange()
updateDisplay(lockTeams, lockTeamsText, g_IsController);
updateDisplay(populationCap, populationCapText, g_IsController);
updateDisplay(startingResources, startingResourcesText, g_IsController);
updateDisplay(ceasefire, ceasefireText, g_IsController);
if (g_IsController)
{
@ -1290,25 +1323,27 @@ function onGameAttributesChange()
case "scenario":
// For scenario just reflect settings for the current map
numPlayersSelection.hidden = true;
mapSize.hidden = true;
revealMap.hidden = true;
exploreMap.hidden = true;
disableTreasures.hidden = true;
victoryCondition.hidden = true;
lockTeams.hidden = true;
numPlayersText.hidden = false;
mapSize.hidden = true;
mapSizeText.hidden = true;
mapSizeDesc.hidden = true;
revealMap.hidden = true;
revealMapText.hidden = false;
exploreMap.hidden = true;
exploreMapText.hidden = false;
disableTreasures.hidden = true;
disableTreasuresText.hidden = false;
victoryCondition.hidden = true;
victoryConditionText.hidden = false;
lockTeams.hidden = true;
lockTeamsText.hidden = false;
populationCap.hidden = true;
populationCapText.hidden = false;
startingResources.hidden = true;
startingResourcesText.hidden = false;
populationCap.hidden = true;
populationCapText.hidden = false;
ceasefire.hidden = true;
ceasefireText.hidden = false;
numPlayersText.caption = numPlayers;
mapSizeText.caption = translate("Default");
revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
@ -1316,8 +1351,10 @@ function onGameAttributesChange()
disableTreasuresText.caption = translate("No");
victoryConditionText.caption = victories.text[victoryIdx];
lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
Engine.GetGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;
startingResourcesText.caption = translate("Determined by scenario");
populationCapText.caption = translate("Determined by scenario");
ceasefireText.caption = translate("Determined by scenario");
break;
default:

View File

@ -270,7 +270,7 @@
<!-- More Options -->
<object hidden="true" name="moreOptionsFade" type="image" z="60" sprite="ModernFade"/>
<object name="moreOptions" type="image" sprite="ModernDialog" size="50%-200 50%-195 50%+200 50%+190" z="70" hidden="true">
<object name="moreOptions" type="image" sprite="ModernDialog" size="50%-200 50%-195 50%+200 50%+220" z="70" hidden="true">
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">More Options</translatableAttribute>
</object>
@ -316,6 +316,16 @@
</object>
<object size="14 158 94% 186">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption">Ceasefire:</translatableAttribute>
</object>
<object name="ceasefireText" size="40% 0 100% 100%" type="text" style="ModernLeftLabelText"/>
<object name="ceasefire" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
<translatableAttribute id="tooltip">Set time where no attacks are possible.</translatableAttribute>
</object>
</object>
<object size="14 188 94% 216">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption" comment="Make sure to differentiate between the revealed map and explored map options!">Revealed Map:</translatableAttribute>
</object>
@ -325,7 +335,7 @@
</object>
</object>
<object size="14 188 94% 216">
<object size="14 218 94% 246">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption" comment="Make sure to differentiate between the revealed map and explored map options!">Explored Map:</translatableAttribute>
</object>
@ -335,7 +345,7 @@
</object>
</object>
<object size="14 218 94% 246">
<object size="14 248 94% 276">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption">Disable Treasures:</translatableAttribute>
</object>
@ -345,7 +355,7 @@
</object>
</object>
<object size="14 248 94% 276">
<object size="14 278 94% 306">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption">Teams Locked:</translatableAttribute>
</object>
@ -355,7 +365,7 @@
</object>
</object>
<object name="optionCheats" size="14 278 94% 306" hidden="true">
<object name="optionCheats" size="14 308 94% 336" hidden="true">
<object size="0 0 40% 28" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption">Cheats:</translatableAttribute>
</object>
@ -365,7 +375,7 @@
</object>
</object>
<object name="optionRating" size="14 308 94% 336" hidden="true">
<object name="optionRating" size="14 338 94% 366" hidden="true">
<object size="0 0 40% 28" hidden="false" type="text" style="ModernRightLabelText">
<translatableAttribute id="caption">Rated Game:</translatableAttribute>
</object>
@ -380,7 +390,7 @@
name="hideMoreOptions"
type="button"
style="StoneButton"
size="50%-70 340 50%+70 366"
size="50%-70 370 50%+70 396"
tooltip_style="onscreenToolTip"
>
<translatableAttribute id="caption">OK</translatableAttribute>

View File

@ -13,6 +13,7 @@ var options = {
[translate("FPS Overlay"), translate("Show frames per second in top right corner."), {"config":"overlay.fps"}, "boolean"],
[translate("Realtime Overlay"), translate("Show current system time in top right corner."), {"config":"overlay.realtime"}, "boolean"],
[translate("Gametime Overlay"), translate("Show current simulation time in top right corner."), {"config":"gui.session.timeelapsedcounter"}, "boolean"],
[translate("Ceasefire Time Overlay"), translate("Always show the remaining ceasefire time."), {"config":"gui.session.ceasefirecounter"}, "boolean"],
[translate("Persist match settings"), translate("Save and restore match settings for quick reuse when hosting another game"), {"config":"persistmatchsettings"}, "boolean"],
],
"graphicsSetting":

View File

@ -72,7 +72,9 @@
</object>
</repeat>
</object>
<object name="diplomacyCeasefireCounter" size="32 100%-90 100%-32 100%-62" type="text" style="chatPanel" ghost="true"></object>
<object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton">
<translatableAttribute id="caption">Close</translatableAttribute>
<action on="Press">closeDiplomacy();</action>

View File

@ -343,8 +343,9 @@ function openDiplomacy()
}
// Attack Request
var simState = GetSimState();
let button = Engine.GetGUIObjectByName("diplomacyAttackRequest["+(i-1)+"]");
button.hidden = !(g_Players[i].isEnemy[we]);
button.hidden = simState.ceasefireActive && !(g_Players[i].isEnemy[we]);
button.tooltip = translate("request for your allies to attack this enemy");
button.onpress = (function(i, we){ return function() {
Engine.PostNetworkCommand({"type": "attack-request", "source": we, "target": i});
@ -362,7 +363,7 @@ function openDiplomacy()
button.caption = g_Players[we]["is"+setting][i] ? translate("x") : "";
button.onpress = (function(e){ return function() { setDiplomacy(e) } })({"player": i, "to": setting.toLowerCase()});
button.hidden = false;
button.hidden = simState.ceasefireActive;
}
}

View File

@ -397,7 +397,6 @@ function onTick()
lastTickTime = now;
checkPlayerState();
while (true)
{
var message = Engine.PollNetworkClient();
@ -539,6 +538,7 @@ function onSimulationUpdate()
updateSelectionDetails();
updateBuildingPlacementPreview();
updateTimeElapsedCounter();
updateCeasefireCounter();
updateTimeNotifications();
if (!g_IsObserver)
updateResearchDisplay();
@ -780,6 +780,22 @@ function updateResearchDisplay()
Engine.GetGUIObjectByName("researchStartedButton[" + i + "]").hidden = true;
}
function updateCeasefireCounter()
{
var simState = GetSimState();
var isActive = simState.ceasefireActive;
var remainingTimeString = timeToString(simState.ceasefireTimeRemaining);
var ceasefireCounter = Engine.GetGUIObjectByName("ceasefireCounter");
var diplomacyCeasefireCounter = Engine.GetGUIObjectByName("diplomacyCeasefireCounter");
ceasefireCounter.hidden = !isActive || Engine.ConfigDB_GetValue("user", "gui.session.ceasefirecounter") !== "true";
diplomacyCeasefireCounter.hidden = !isActive;
ceasefireCounter.caption = remainingTimeString;
diplomacyCeasefireCounter.caption = sprintf(translateWithContext("ceasefire", "Time remaining until ceasefire is over: %(time)s."), {"time": remainingTimeString});
}
function updateTimeElapsedCounter()
{
var simState = GetSimState();
@ -1044,6 +1060,8 @@ function reportGame(extendedSimState)
reportObject.civs = playerCivs;
reportObject.teams = teams;
reportObject.teamsLocked = String(teamsLocked);
reportObject.ceasefireActive = String(extendedSimState.ceasefireActive);
reportObject.ceasefireTimeRemaining = String(extendedSimState.ceasefireTimeRemaining);
reportObject.mapName = mapName;
reportObject.economyScore = playerStatistics.economyScore;
reportObject.militaryScore = playerStatistics.militaryScore;

View File

@ -147,7 +147,7 @@
<!-- Time elapsed counter -->
<!-- ================================ ================================ -->
<object size="100%-120 45 100%-10 65" type="text" name="timeElapsedCounter" style="SettingsText" hotkey="timeelapsedcounter.toggle" hidden="true">
<object size="100%-250 45 100%-140 65" type="text" name="timeElapsedCounter" style="SettingsText" hotkey="timeelapsedcounter.toggle" hidden="true">
<action on="Tick">
this.hidden = Engine.ConfigDB_GetValue("user", "gui.session.timeelapsedcounter") !== "true";
</action>
@ -155,6 +155,11 @@
Engine.ConfigDB_CreateValue("user", "gui.session.timeelapsedcounter", ""+this.hidden);
</action>
</object>
<object size="100%-250 80 100%-140 100" type="text" name="ceasefireCounter" style="SettingsText" hotkey="ceasefirecounter.toggle" hidden="true">
<action on="Press">
Engine.ConfigDB_CreateValue("user", "gui.session.ceasefirecounter", ""+this.hidden);
</action>
</object>
<!-- ================================ ================================ -->
<!-- Pause Overlay -->

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<object size="100%-50 85 100%-10 100%-200">
<object size="100%-50 40 100%-10 100%-200">
<repeat count="10">
<object name="researchStartedButton[n]" hidden="true" style="iconButton" type="button" size="0 0 40 40" tooltip_style="sessionToolTipBottom">
<object name="researchStartedIcon[n]" ghost="true" type="image" size="3 3 37 37"/>

View File

@ -123,7 +123,7 @@ m.DefenseManager.prototype.checkEnemyUnits = function(gameState)
{
var nbPlayers = gameState.sharedScript.playersData.length;
var i = gameState.ai.playedTurn % nbPlayers;
if (i === PlayerID || gameState.isPlayerAlly(i))
if (i === PlayerID || !gameState.isPlayerEnemy(i))
return;
// loop through enemy units
@ -214,7 +214,7 @@ m.DefenseManager.prototype.checkEnemyArmies = function(gameState, events)
var army = this.armies[i];
army.recalculatePosition(gameState);
var owner = this.territoryMap.getOwner(army.foePosition);
if (gameState.isPlayerAlly(owner))
if (!gameState.isPlayerEnemy(owner))
continue;
else if (owner !== 0) // enemy army back in its territory
{

View File

@ -69,7 +69,7 @@ Capturable.prototype.Reduce = function(amount, playerID)
if (cmpFogging)
cmpFogging.Activate();
var enemiesFilter = function(v, i) { return v > 0 && !cmpPlayerSource.IsAlly(i); };
var enemiesFilter = function(v, i) { return v > 0 && cmpPlayerSource.IsEnemy(i); };
var numberOfEnemies = this.cp.filter(enemiesFilter).length;
if (numberOfEnemies == 0)
@ -79,7 +79,7 @@ Capturable.prototype.Reduce = function(amount, playerID)
var distributedAmount = amount / numberOfEnemies;
for (let i in this.cp)
{
if (cmpPlayerSource.IsAlly(i))
if (!cmpPlayerSource.IsEnemy(i))
continue;
if (this.cp[i] > distributedAmount)
this.cp[i] -= distributedAmount;
@ -121,7 +121,7 @@ Capturable.prototype.CanCapture = function(playerID)
var cp = this.GetCapturePoints()
var sourceEnemyCp = 0;
for (let i in this.GetCapturePoints())
if (!cmpPlayerSource.IsAlly(i))
if (cmpPlayerSource.IsEnemy(i))
sourceEnemyCp += cp[i];
return sourceEnemyCp > 0;
};

View File

@ -0,0 +1,174 @@
function CeasefireManager() {}
CeasefireManager.prototype.Schema =
"<a:help>Lists the sound groups associated with this unit.</a:help>" +
"<a:example>" +
"<SoundGroups>" +
"<ceasefire>interface/alarm/alarm_alert_0.xml</ceasefire>" +
"</SoundGroups>" +
"</a:example>" +
"<element name='SoundGroups'>" +
"<zeroOrMore>" + /* TODO: make this more specific, like a list of specific elements */
"<element>" +
"<anyName/>" +
"<text/>" +
"</element>" +
"</zeroOrMore>" +
"</element>";
CeasefireManager.prototype.Init = function()
{
// Weather or not ceasefire is active currently.
this.ceasefireIsActive = false;
// Ceasefire timeout in milliseconds
this.ceasefireTime = 0;
// Time elapsed when the ceasefire was started
this.ceasefireStartedTime = 0;
// diplomacy states before the ceasefire started
this.diplomacyBeforeCeasefire = [];
// Message duration for the countdown in milliseconds
this.countdownMessageDuration = 10000;
// Duration for the post ceasefire message in milliseconds
this.postCountdownMessageDuration = 5000;
};
CeasefireManager.prototype.IsCeasefireActive = function()
{
return this.ceasefireIsActive;
};
CeasefireManager.prototype.GetCeasefireStartedTime = function()
{
return this.ceasefireStartedTime;
};
CeasefireManager.prototype.GetCeasefireTime = function()
{
return this.ceasefireTime;
};
CeasefireManager.prototype.GetDiplomacyBeforeCeasefire = function()
{
return this.diplomacyBeforeCeasefire;
};
CeasefireManager.prototype.StartCeasefire = function(ceasefireTime)
{
// If invalid timeout given, return
if (ceasefireTime <= 0)
return;
// Remove existing timers
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
if (this.ceasefireCountdownMessageTimer)
cmpTimer.CancelTimer(this.ceasefireCountdownMessageTimer);
if (this.stopCeasefireTimer)
cmpTimer.CancelTimer(this.stopCeasefireTimer);
// Remove existing messages
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
if (this.ceasefireCountdownMessage)
cmpGuiInterface.DeleteTimeNotification(this.ceasefireCountdownMessage);
if (this.ceasefireEndedMessage)
cmpGuiInterface.DeleteTimeNotification(this.ceasefireEndedMessage);
// Save diplomacy and set everyone neutral
if (!this.ceasefireIsActive)
{
// Save diplomacy
var playerEntities = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayerEntities();
for (var i = 1; i < playerEntities.length; i++)
{
// Copy array with slice(), otherwise it will change
var cmpPlayer = Engine.QueryInterface(playerEntities[i], IID_Player);
this.diplomacyBeforeCeasefire.push(cmpPlayer.GetDiplomacy().slice());
}
// Set every enemy (except gaia) to neutral
for (var i = 1; i < playerEntities.length; i++)
{
var cmpPlayer = Engine.QueryInterface(playerEntities[i], IID_Player);
for (var j = 1; j < playerEntities.length; j++)
{
if (this.diplomacyBeforeCeasefire[i-1][j] < 0)
cmpPlayer.SetNeutral(j);
}
}
}
// Save other data
this.ceasefireIsActive = true;
this.ceasefireTime = ceasefireTime;
this.ceasefireStartedTime = cmpTimer.GetTime();
// Send message
Engine.PostMessage(SYSTEM_ENTITY, MT_CeasefireStarted);
// Add timers for countdown message and reseting diplomacy
this.stopCeasefireTimer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_CeasefireManager, "StopCeasefire", this.ceasefireTime);
this.ceasefireCountdownMessageTimer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_CeasefireManager, "ShowCeasefireCountdownMessage",
this.ceasefireTime - this.countdownMessageDuration, this.countdownMessageDuration);
};
CeasefireManager.prototype.ShowCeasefireCountdownMessage = function(duration)
{
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
this.ceasefireCountdownMessage = cmpGuiInterface.AddTimeNotification({
"message": markForTranslation("You can attack in %(time)s"),
"translateMessage": true
}, duration);
};
CeasefireManager.prototype.StopCeasefire = function()
{
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
// Remove previous message
if (this.ceasefireCountdownMessage)
cmpGuiInterface.DeleteTimeNotification(this.ceasefireCountdownMessage);
// Show new message
this.ceasefireEndedMessage = cmpGuiInterface.AddTimeNotification({
"message": markForTranslation("You can attack now!"),
"translateMessage": true
}, this.postCountdownMessageDuration);
// Reset diplomacies to original settings
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var playerEntities = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayerEntities();
for (var i = 1; i < playerEntities.length; i++)
{
var cmpPlayer = Engine.QueryInterface(playerEntities[i], IID_Player);
cmpPlayer.SetDiplomacy(this.diplomacyBeforeCeasefire[i-1]);
}
// Send chat notifications and update the diplomacy screen
for (var i = 1; i < playerEntities.length; i++)
{
var cmpPlayer = Engine.QueryInterface(playerEntities[i], IID_Player);
for (var j = 1; j < playerEntities.length; j++)
{
if (i != j && this.diplomacyBeforeCeasefire[i-1][j] == -1)
cmpGuiInterface.PushNotification({"type": "diplomacy", "players": [j], "player1": [i], "status": "enemy"});
}
}
// Reset values
this.ceasefireIsActive = false;
this.ceasefireTime = 0;
this.ceasefireStartedTime = 0;
this.diplomacyBeforeCeasefire = [];
// Send message
Engine.PostMessage(SYSTEM_ENTITY, MT_CeasefireEnded);
};
Engine.RegisterSystemComponentType(IID_CeasefireManager, "CeasefireManager", CeasefireManager);

View File

@ -118,7 +118,7 @@ GuiInterface.prototype.GetSimulationState = function(player)
};
ret.players.push(playerData);
}
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
if (cmpRangeManager)
ret.circularMap = cmpRangeManager.GetLosCircular();
@ -130,7 +130,15 @@ GuiInterface.prototype.GetSimulationState = function(player)
// Add timeElapsed
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
ret.timeElapsed = cmpTimer.GetTime();
// Add ceasefire info
var cmpCeasefireManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager);
if (cmpCeasefireManager)
{
ret.ceasefireActive = cmpCeasefireManager.IsCeasefireActive();
ret.ceasefireTimeRemaining = cmpCeasefireManager.GetCeasefireStartedTime() + cmpCeasefireManager.GetCeasefireTime() - ret.timeElapsed;
}
// Add the game type
var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
ret.gameType = cmpEndGameManager.GetGameType();
@ -687,6 +695,17 @@ GuiInterface.prototype.AddTimeNotification = function(notification, duration = 1
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
notification.endTime = duration + cmpTimer.GetTime();
notification.id = ++this.timeNotificationID;
// Let all players receive the notification by default
if (notification.players == undefined)
{
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
var numPlayers = cmpPlayerManager.GetNumPlayers();
notification.players = [];
for (var i = 1; i < numPlayers; i++)
notification.players.push(i);
}
this.timeNotifications.push(notification);
this.timeNotifications.sort(function (n1, n2){return n2.endTime - n1.endTime});
@ -1735,7 +1754,7 @@ GuiInterface.prototype.CanAttack = function(player, data)
return false;
// if the owner is an enemy, it's up to the attack component to decide
if (!cmpEntityPlayer.IsAlly(cmpTargetPlayer.GetPlayerID()))
if (cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()))
return cmpAttack.CanAttack(data.target);
return false;
};

View File

@ -0,0 +1,4 @@
Engine.RegisterInterface("CeasefireManager");
Engine.RegisterMessageType("CeasefireStarted");
Engine.RegisterMessageType("CeasefireEnded");

View File

@ -61,6 +61,10 @@ function LoadMapSettings(settings)
cmpGarrisonHolder.initGarrison = settings.Garrison[holder];
}
}
var cmpCeasefireManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager);
if (settings.Ceasefire)
cmpCeasefireManager.StartCeasefire(settings.Ceasefire * 60 * 1000);
}
Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);