1
0
forked from 0ad/0ad

Compare commits

...

2 Commits

Author SHA1 Message Date
23a8db11de Enable observers to see and send flares 2024-09-11 11:35:58 +02:00
c73d727cf9 Add observer flares 2024-09-10 18:12:40 +02:00
15 changed files with 63 additions and 34 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -101,9 +101,10 @@ function updateCursorAndTooltip()
let cursorSet = false;
let tooltipSet = false;
let informationTooltip = Engine.GetGUIObjectByName("informationTooltip");
if (inputState == INPUT_FLARE || inputState == INPUT_NORMAL && Engine.HotkeyIsPressed("session.flare") && !g_IsObserver)
if (inputState == INPUT_FLARE || inputState == INPUT_NORMAL && Engine.HotkeyIsPressed("session.flare"))
{
Engine.SetCursor("action-flare");
const playerOrObserver = g_IsObserver ? "observer" : "player";
Engine.SetCursor("action-" + playerOrObserver + "-flare");
cursorSet = true;
}
else if (!mouseIsOverObject && (inputState == INPUT_NORMAL || inputState == INPUT_PRESELECTEDACTION) || g_MiniMapPanel.isMouseOverMiniMap())
@ -825,7 +826,7 @@ function handleInputAfterGui(ev)
return false;
case "mousebuttondown":
if (Engine.HotkeyIsPressed("session.flare") && controlsPlayer(g_ViewedPlayer))
if (Engine.HotkeyIsPressed("session.flare"))
{
triggerFlareAction(Engine.GetTerrainAtScreenPoint(ev.x, ev.y));
return true;
@ -1134,7 +1135,7 @@ function handleInputAfterGui(ev)
case INPUT_FLARE:
if (ev.type == "mousebuttondown")
{
if (ev.button == SDL_BUTTON_LEFT && controlsPlayer(g_ViewedPlayer))
if (ev.button == SDL_BUTTON_LEFT)
{
triggerFlareAction(Engine.GetTerrainAtScreenPoint(ev.x, ev.y));
inputState = INPUT_NORMAL;

View File

@ -290,24 +290,26 @@ var g_NotificationsTypes =
},
"map-flare": function(notification, player)
{
// Don't display for the player that did the flare because they will see it immediately
if (player != Engine.GetPlayerID() && g_Players[player].isMutualAlly[Engine.GetPlayerID()])
{
let now = Date.now();
if (g_FlareRateLimitLastTimes.length)
{
g_FlareRateLimitLastTimes = g_FlareRateLimitLastTimes.filter(t => now - t < g_FlareRateLimitScope * 1000);
if (g_FlareRateLimitLastTimes.length >= g_FlareRateLimitMaximumFlares)
{
warn("Received too many flares. Dropping a flare request by '" + g_Players[player].name + "'.");
return;
}
}
g_FlareRateLimitLastTimes.push(now);
const shouldSeeFlare = g_IsObserver || g_Players[player]?.isMutualAlly[Engine.GetPlayerID()];
displayFlare(notification.position, notification.guid);
Engine.PlayUISound(g_FlareSound, false);
// Don't display for the player that did the flare because they will see it immediately.
if (!shouldSeeFlare || notification.guid == Engine.GetPlayerGUID())
return;
let now = Date.now();
if (g_FlareRateLimitLastTimes.length)
{
g_FlareRateLimitLastTimes = g_FlareRateLimitLastTimes.filter(t => now - t < g_FlareRateLimitScope * 1000);
if (g_FlareRateLimitLastTimes.length >= g_FlareRateLimitMaximumFlares)
{
warn("Received too many flares. Dropping a flare request by '" + g_Players[player].name + "'.");
return;
}
}
g_FlareRateLimitLastTimes.push(now);
displayFlare(notification.position, notification.guid);
Engine.PlayUISound(g_FlareSound, false);
}
};

View File

@ -28,7 +28,7 @@ class MiniMap
{
// Partly duplicated from handleInputAfterGui(), but with the input being
// world coordinates instead of screen coordinates.
if (inputState == INPUT_NORMAL && controlsPlayer(g_ViewedPlayer) && Engine.HotkeyIsPressed("session.flare"))
if (inputState == INPUT_NORMAL && Engine.HotkeyIsPressed("session.flare"))
{
triggerFlareAction(target);
return true;
@ -97,6 +97,10 @@ class MiniMap
flare(target, playerID)
{
return this.miniMap.flare({ "x": target.x, "y": target.z }, g_DiplomacyColors.getPlayerColor(playerID));
return this.miniMap.flare(
{ "x": target.x, "y": target.z },
// Observers flare in white.
playerID == -1 ? "255 255 255" : g_DiplomacyColors.getPlayerColor(playerID)
);
}
}

View File

@ -1,5 +1,5 @@
/**
* If the button that this class manages is pressed, an idle unit having one of the given classes is selected.
* If the button that this class manages is pressed, the input state is switched to 'flare', letting the player send a flare by left-clicking on the map.
*/
class MiniMapFlareButton
{
@ -13,23 +13,29 @@ class MiniMapFlareButton
rebuild()
{
this.flareButton.enabled = !g_IsObserver;
const playerOrObserver = g_IsObserver ? "observer" : "player";
this.flareButton.sprite = "stretched:session/minimap-" + playerOrObserver + "-flare.png";
this.flareButton.sprite_over = "stretched:session/minimap-" + playerOrObserver + "-flare-highlight.png";
this.updateTooltip();
}
onHotkeyChange()
{
this.flareButton.tooltip =
colorizeHotkey("%(hotkey)s" + " ", "session.flare") +
translate(this.Tooltip);
this.colorizedHotkey = colorizeHotkey("%(hotkey)s" + " ", "session.flare");
this.updateTooltip();
}
updateTooltip()
{
this.flareButton.tooltip = this.colorizedHotkey + (g_IsObserver ? this.ObserverTooltip : this.PlayerTooltip);
}
onPress()
{
if (g_IsObserver)
return;
if (inputState == INPUT_NORMAL)
inputState = INPUT_FLARE;
}
}
MiniMapFlareButton.prototype.Tooltip = markForTranslation("Send a flare to your allies");
MiniMapFlareButton.prototype.PlayerTooltip = markForTranslation("Send a flare to your allies.");
MiniMapFlareButton.prototype.ObserverTooltip = markForTranslation("Send a flare to other observers.");

View File

@ -1944,7 +1944,8 @@ function displayFlare(position, playerGUID)
"template": g_TargetMarker.map_flare,
"x": position.x,
"z": position.z,
"owner": playerID
// If the flare was sent by an observer we set the owner to gaia to color the target marker in white.
"owner": playerID != -1 ? playerID : 0
});
g_MiniMapPanel.flare(position, playerID);
addChatMessage({

View File

@ -6,7 +6,11 @@ function ProcessCommand(player, cmd)
{
let cmpPlayer = QueryPlayerIDInterface(player);
if (!cmpPlayer)
{
if (player == -1 && g_ObserverCommands[cmd.type])
g_ObserverCommands[cmd.type](player, cmd, {});
return;
}
let data = {
"cmpPlayer": cmpPlayer,
@ -908,6 +912,10 @@ var g_Commands = {
};
var g_ObserverCommands = {
"map-flare": g_Commands["map-flare"]
};
/**
* Sends a GUI notification about unit(s) that failed to ungarrison.
*/