mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Enable observers to see and send flares
This patch gives observers the possibility to see and send flares. Players keep their color after resigning and "true" observers flare in white. Observers render all flares; the ones sent by any player or observer. Player continue to only see their allies' flares. The flare notification option is converted into a dropdown. -> adding the possibility to only receive them as observer.
This commit is contained in:
parent
9e5e2708f4
commit
a1796ed71f
19 changed files with 97 additions and 43 deletions
|
|
@ -477,7 +477,7 @@ pingduration = 50.0 ; The duration for which an entity will be pin
|
|||
attack = true ; Show a chat notification if you are attacked by another player
|
||||
tribute = true ; Show a chat notification if an ally tributes resources to another team member if teams are locked, and all tributes in observer mode
|
||||
barter = true ; Show a chat notification to observers when a player bartered resources
|
||||
flare = true ; Show a chat notification when a you or an ally sends a flare
|
||||
flare = always ; Show a chat notification when a player sends a flare. Possible values: never, observer, always.
|
||||
phase = completed ; Show a chat notification if you or an ally have started, aborted or completed a new phase, and phases of all players in observer mode. Possible values: none, completed, all.
|
||||
|
||||
[gui.splashscreen]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:11022a8511dfb6779248ae55590973942e6469681f78f78a8e27a9a01c6aed5d
|
||||
size 1653
|
||||
|
|
@ -0,0 +1 @@
|
|||
1 1
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:41432cec030750dc8ba0fd3a1ff496c50a5731e78f6c12164d97fd991b37ae63
|
||||
size 13267
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8f2680500fd122178db80b378e19821eb30baf639edc46eacc3d23c97b19481c
|
||||
size 6214
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:85d985e5b208f4947fe2bf580a5f181990892620c50f1dd356655d879a94aea4
|
||||
size 5356
|
||||
|
|
@ -595,10 +595,15 @@
|
|||
"config": "gui.session.notifications.barter"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"type": "dropdown",
|
||||
"label": "Chat notification flare",
|
||||
"tooltip": "Show a chat notification when you or an ally sends a flare.",
|
||||
"config": "gui.session.notifications.flare"
|
||||
"tooltip": "Show a chat notification when a player sends a flare.",
|
||||
"config": "gui.session.notifications.flare",
|
||||
"list": [
|
||||
{ "value": "never", "label": "Never", "tooltip": "Disable flare chat notifications."},
|
||||
{ "value": "observer", "label": "Only as observer", "tooltip": "Only show flare chat notifications when you are observer."},
|
||||
{ "value": "always", "label": "Always", "tooltip": "Always show flare chat notifications – as player and as observer."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dropdown",
|
||||
|
|
|
|||
|
|
@ -177,12 +177,22 @@ ChatMessageFormatSimulation.tribute = class
|
|||
|
||||
ChatMessageFormatSimulation.flare = class
|
||||
{
|
||||
// We don't need to check whether the player is supposed to see the flare as this function is only ever called in that case
|
||||
// We don't need to check whether the player is supposed to see the flare as this function is only ever called in that case.
|
||||
parse(msg)
|
||||
{
|
||||
if (Engine.ConfigDB_GetValue("user", "gui.session.notifications.flare") != "true")
|
||||
switch (Engine.ConfigDB_GetValue("user", "gui.session.notifications.flare"))
|
||||
{
|
||||
case "never":
|
||||
return "";
|
||||
|
||||
case "observer":
|
||||
if (!g_IsObserver)
|
||||
return "";
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
"text": sprintf(translate("%(icon)s%(player)s has sent a flare."), {
|
||||
"icon": "[icon=\"icon_focusflare\" displace=\"0 1\"]",
|
||||
|
|
|
|||
|
|
@ -101,9 +101,13 @@ 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");
|
||||
Engine.SetCursor(
|
||||
g_IsObserver ?
|
||||
"action-observer-flare" :
|
||||
"action-player-flare"
|
||||
);
|
||||
cursorSet = true;
|
||||
}
|
||||
else if (!mouseIsOverObject && (inputState == INPUT_NORMAL || inputState == INPUT_PRESELECTEDACTION) || g_MiniMapPanel.isMouseOverMiniMap())
|
||||
|
|
@ -825,7 +829,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 +1138,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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
g_DiplomacyColors.getPlayerColor(playerID == -1 ? 0 : playerID)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@
|
|||
size="2 4 117 119"
|
||||
tooltip_style="sessionToolTip"
|
||||
hotkey="session.flareactivate"
|
||||
sprite="stretched:session/minimap-flare.png"
|
||||
sprite_over="stretched:session/minimap-flare-highlight.png"
|
||||
sprite_disabled="stretched:session/minimap-flare-disabled.png"
|
||||
mouse_event_mask="texture:session/minimap-flare.png"
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -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,36 @@ class MiniMapFlareButton
|
|||
|
||||
rebuild()
|
||||
{
|
||||
this.flareButton.enabled = !g_IsObserver;
|
||||
if (g_IsObserver)
|
||||
{
|
||||
this.flareButton.sprite = "stretched:session/minimap-observer-flare.png";
|
||||
this.flareButton.sprite_over = "stretched:session/minimap-observer-flare-highlight.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.flareButton.sprite = "stretched:session/minimap-player-flare.png";
|
||||
this.flareButton.sprite_over = "stretched:session/minimap-player-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.");
|
||||
|
|
|
|||
|
|
@ -1944,7 +1944,8 @@ function displayFlare(position, playerGUID)
|
|||
"template": g_TargetMarker.map_flare,
|
||||
"x": position.x,
|
||||
"z": position.z,
|
||||
"owner": playerID
|
||||
// Set the owner to gaia if the flare was sent by an observer (to make the target marker white).
|
||||
"owner": playerID != -1 ? playerID : 0
|
||||
});
|
||||
g_MiniMapPanel.flare(position, playerID);
|
||||
addChatMessage({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@ var g_DebugCommands = false;
|
|||
|
||||
function ProcessCommand(player, cmd)
|
||||
{
|
||||
if (player == -1)
|
||||
{
|
||||
if (g_ObserverCommands[cmd.type])
|
||||
g_ObserverCommands[cmd.type](player, cmd, {});
|
||||
return;
|
||||
}
|
||||
|
||||
let cmpPlayer = QueryPlayerIDInterface(player);
|
||||
if (!cmpPlayer)
|
||||
return;
|
||||
|
|
@ -908,6 +915,10 @@ var g_Commands = {
|
|||
|
||||
};
|
||||
|
||||
var g_ObserverCommands = {
|
||||
"map-flare": g_Commands["map-flare"]
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a GUI notification about unit(s) that failed to ungarrison.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue