Index: binaries/data/config/default.cfg
===================================================================
--- binaries/data/config/default.cfg
+++ binaries/data/config/default.cfg
@@ -314,6 +314,7 @@
rotate.cw = RightBracket ; Rotate building placement preview clockwise
rotate.ccw = LeftBracket ; Rotate building placement preview anticlockwise
snaptoedges = Ctrl ; Modifier to align new structures with nearby existing structure
+flare = K ; Modifier to send a flare to your allies
; Overlays
showstatusbars = Tab ; Toggle display of status bars
devcommands.toggle = "Alt+D" ; Toggle developer commands panel
Index: binaries/data/mods/public/art/textures/cursors/action-flare.txt
===================================================================
--- /dev/null
+++ binaries/data/mods/public/art/textures/cursors/action-flare.txt
@@ -0,0 +1 @@
+1 1
Index: binaries/data/mods/public/gui/manual/intro.txt
===================================================================
--- binaries/data/mods/public/gui/manual/intro.txt
+++ binaries/data/mods/public/gui/manual/intro.txt
@@ -114,6 +114,7 @@
hotkey.session.attackmove + Right Click with unit(s) selected - Attack move (by default all enemy units and structures along the way are targeted)
hotkey.session.attackmoveUnit + Right Click with unit(s) selected - Attack move, only units along the way are targeted
hotkey.session.snaptoedges + Mouse Move near structures – Align the new structure with an existing nearby structure
+ K + Right Click – Send a flare to your allies
[font="sans-bold-14"]Overlays[font="sans-14"]
hotkey.session.gui.toggle – Toggle the GUI
Index: binaries/data/mods/public/gui/session/input.js
===================================================================
--- binaries/data/mods/public/gui/session/input.js
+++ binaries/data/mods/public/gui/session/input.js
@@ -17,6 +17,7 @@
const ACTION_REPAIR = 2;
const ACTION_GUARD = 3;
const ACTION_PATROL = 4;
+const ACTION_FLARE = 5;
var preSelectedAction = ACTION_NONE;
const INPUT_NORMAL = 0;
@@ -78,6 +79,16 @@
*/
var clickedEntity = INVALID_ENTITY;
+/**
+ * Store the last time the flare functionality was used to prevent overusage.
+ */
+var g_LastFlareTime;
+
+/**
+ * The duration in ms for which we disable flaring after each flare to prevent overusage.
+ */
+const g_FlareCooldown = 1000;
+
// Same double-click behaviour for hotkey presses
const doublePressTime = 500;
var doublePressTimer = 0;
@@ -208,6 +219,10 @@
*/
function determineAction(x, y, fromMiniMap)
{
+ let r = g_MiniMapPanel.preSelectedActionCheck() || g_MiniMapPanel.hotkeyActionCheck();
+ if (r)
+ return r;
+
let selection = g_Selection.toList();
if (!selection.length)
{
@@ -244,7 +259,7 @@
for (let action of g_UnitActionsSortedKeys)
if (g_UnitActions[action].preSelectedActionCheck)
{
- let r = g_UnitActions[action].preSelectedActionCheck(target, selection);
+ r = g_UnitActions[action].preSelectedActionCheck(target, selection);
if (r)
return r;
}
@@ -1251,6 +1266,20 @@
function handleUnitAction(target, action)
{
+ if (action.type == "flare")
+ {
+ let now = Date.now();
+ if (g_LastFlareTime && now < g_LastFlareTime + g_FlareCooldown)
+ return false;
+
+ g_LastFlareTime = now;
+ displayFlare(target, Engine.GetPlayerID());
+ Engine.PostNetworkCommand({
+ "type": "map-flare",
+ "target": target
+ });
+ return true;
+ }
if (!g_UnitActions[action.type] || !g_UnitActions[action.type].execute)
{
error("Invalid action.type " + action.type);
Index: binaries/data/mods/public/gui/session/messages.js
===================================================================
--- binaries/data/mods/public/gui/session/messages.js
+++ binaries/data/mods/public/gui/session/messages.js
@@ -265,6 +265,17 @@
}
global.music.setLocked(notification.lock);
+ },
+ "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()])
+ {
+ displayFlare(notification.target, player);
+
+ // TODO: Create a new sound and play it here
+ Engine.PlayUISound("audio/interface/alarm/alarmally_1.ogg", false);
+ }
}
};
Index: binaries/data/mods/public/gui/session/minimap/MiniMap.js
===================================================================
--- binaries/data/mods/public/gui/session/minimap/MiniMap.js
+++ binaries/data/mods/public/gui/session/minimap/MiniMap.js
@@ -6,9 +6,10 @@
{
constructor()
{
- Engine.GetGUIObjectByName("minimap").onWorldClick = this.onWorldClick.bind(this);
- Engine.GetGUIObjectByName("minimap").onMouseEnter = this.onMouseEnter.bind(this);
- Engine.GetGUIObjectByName("minimap").onMouseLeave = this.onMouseLeave.bind(this);
+ this.miniMap = Engine.GetGUIObjectByName("minimap");
+ this.miniMap.onWorldClick = this.onWorldClick.bind(this);
+ this.miniMap.onMouseEnter = this.onMouseEnter.bind(this);
+ this.miniMap.onMouseLeave = this.onMouseLeave.bind(this);
this.mouseIsOverMiniMap = false;
}
@@ -64,4 +65,9 @@
{
return this.mouseIsOverMiniMap;
}
+
+ flare(target, playerID)
+ {
+ return this.miniMap.flare([target.x, target.z], g_DiplomacyColors.getPlayerColor(playerID));
+ }
}
Index: binaries/data/mods/public/gui/session/minimap/MiniMap.xml
===================================================================
--- binaries/data/mods/public/gui/session/minimap/MiniMap.xml
+++ binaries/data/mods/public/gui/session/minimap/MiniMap.xml
@@ -33,4 +33,14 @@
tooltip_style="sessionToolTip"
hotkey="session.diplomacycolors"
/>
+
+
+
Index: binaries/data/mods/public/gui/session/minimap/MiniMapFlareButton.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/session/minimap/MiniMapFlareButton.js
@@ -0,0 +1,50 @@
+/**
+ * If the button that this class manages is pressed, an idle unit having one of the given classes is selected.
+ */
+class MiniMapFlareButton
+{
+ constructor()
+ {
+ this.flareButton = Engine.GetGUIObjectByName("flareButton");
+ this.flareButton.onPress = this.onPress.bind(this);
+ registerHotkeyChangeHandler(this.onHotkeyChange.bind(this));
+ }
+
+ onHotkeyChange()
+ {
+ this.flareButton.tooltip =
+ colorizeHotkey("%(hotkey)s" + " ", "session.flare") +
+ translate(this.Tooltip);
+ }
+
+ onPress()
+ {
+ inputState = INPUT_PRESELECTEDACTION;
+ preSelectedAction = ACTION_FLARE;
+ }
+
+ getAction(target)
+ {
+ return {
+ "type": "flare",
+ "cursor": "action-flare",
+ "target": target
+ };
+ }
+
+ hotkeyActionCheck(target, selection)
+ {
+ if (!Engine.HotkeyIsPressed("session.flare"))
+ return false;
+ return this.getAction(target);
+ }
+
+ preSelectedActionCheck(target, selection)
+ {
+ if (preSelectedAction != ACTION_FLARE)
+ return false;
+ return this.getAction(target);
+ }
+}
+
+MiniMapFlareButton.prototype.Tooltip = markForTranslation("Send a flare to your allies");
Index: binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js
===================================================================
--- binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js
+++ binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js
@@ -7,9 +7,25 @@
{
this.diplomacyColorsButton = new MiniMapDiplomacyColorsButton(diplomacyColors);
this.idleWorkerButton = new MiniMapIdleWorkerButton(playerViewControl, idleWorkerClasses);
+ this.flareButton = new MiniMapFlareButton();
this.miniMap = new MiniMap();
}
+ hotkeyActionCheck(target, selection)
+ {
+ return this.flareButton.hotkeyActionCheck(target, selection);
+ }
+
+ preSelectedActionCheck(target, selection)
+ {
+ return this.flareButton.preSelectedActionCheck(target, selection);
+ }
+
+ flare(target, playerID)
+ {
+ return this.miniMap.flare(target, playerID);
+ }
+
isMouseOverMiniMap()
{
return this.miniMap.isMouseOverMiniMap();
Index: binaries/data/mods/public/gui/session/unit_actions.js
===================================================================
--- binaries/data/mods/public/gui/session/unit_actions.js
+++ binaries/data/mods/public/gui/session/unit_actions.js
@@ -3,7 +3,9 @@
* given a command type.
*/
var g_TargetMarker = {
- "move": "special/target_marker"
+ "move": "special/target_marker",
+ // TODO: Add proper marker
+ "map_flare": "special/target_marker"
};
/**
@@ -1611,6 +1613,16 @@
});
}
+function displayFlare(target, playerID)
+{
+ Engine.GuiInterfaceCall("AddTargetMarker", {
+ "template": g_TargetMarker.map_flare,
+ "x": target.x,
+ "z": target.z
+ });
+ g_MiniMapPanel.flare(target, playerID)
+}
+
function findGatherType(gatherer, supply)
{
if (!gatherer.resourceGatherRates || !supply)
Index: binaries/data/mods/public/shaders/arb/minimap.fp
===================================================================
--- binaries/data/mods/public/shaders/arb/minimap.fp
+++ binaries/data/mods/public/shaders/arb/minimap.fp
@@ -34,6 +34,14 @@
MOV result.color.a, 1.0;
#endif
+#if MINIMAP_FLARE
+ PARAM color = program.local[1];
+ TEMP texColor;
+ TEX texColor, fragment.texcoord[0], texture[0], 2D;
+ MUL texColor, texColor, color;
+ MOV result.color, texColor;
+#endif
+
#if MINIMAP_LINE
PARAM color = program.local[1];
MOV result.color, color;
Index: binaries/data/mods/public/shaders/arb/minimap.vp
===================================================================
--- binaries/data/mods/public/shaders/arb/minimap.vp
+++ binaries/data/mods/public/shaders/arb/minimap.vp
@@ -19,12 +19,12 @@
DP4 result.position.z, transform[2], position;
DP4 result.position.w, transform[3], position;
-#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK
+#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK || MINIMAP_FLARE
TEMP tex;
MOV tex, vertex.texcoord;
#endif
-#if MINIMAP_BASE || MINIMAP_LOS
+#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_FLARE
DP4 v_tex.x, textureTransform[0], tex;
DP4 v_tex.y, textureTransform[1], tex;
DP4 v_tex.z, textureTransform[2], tex;
Index: binaries/data/mods/public/shaders/arb/minimap.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/minimap.xml
+++ binaries/data/mods/public/shaders/arb/minimap.xml
@@ -3,7 +3,7 @@
-
+
Index: binaries/data/mods/public/shaders/glsl/minimap.fs
===================================================================
--- binaries/data/mods/public/shaders/glsl/minimap.fs
+++ binaries/data/mods/public/shaders/glsl/minimap.fs
@@ -1,6 +1,6 @@
#version 110
-#if MINIMAP_BASE || MINIMAP_LOS
+#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_FLARE
uniform sampler2D baseTex;
varying vec2 v_tex;
#endif
@@ -14,7 +14,7 @@
varying vec3 color;
#endif
-#if MINIMAP_LINE
+#if MINIMAP_LINE || MINIMAP_FLARE
uniform vec4 color;
#endif
@@ -42,6 +42,10 @@
gl_FragColor = vec4(color, 1.0);
#endif
+ #if MINIMAP_FLARE
+ gl_FragColor = texture2D(baseTex, v_tex) * color;
+ #endif
+
#if MINIMAP_LINE
gl_FragColor = color;
#endif
Index: binaries/data/mods/public/shaders/glsl/minimap.vs
===================================================================
--- binaries/data/mods/public/shaders/glsl/minimap.vs
+++ binaries/data/mods/public/shaders/glsl/minimap.vs
@@ -9,12 +9,12 @@
varying vec2 v_maskUV;
#endif
-#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK
+#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK || MINIMAP_FLARE
attribute vec3 a_vertex;
attribute vec2 a_uv0;
#endif
-#if MINIMAP_BASE || MINIMAP_LOS
+#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_FLARE
varying vec2 v_tex;
#endif
@@ -30,7 +30,7 @@
void main()
{
- #if MINIMAP_BASE || MINIMAP_LOS
+ #if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_FLARE
gl_Position = transform * vec4(a_vertex, 1.0);
v_tex = (textureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
#endif
Index: binaries/data/mods/public/shaders/glsl/minimap.xml
===================================================================
--- binaries/data/mods/public/shaders/glsl/minimap.xml
+++ binaries/data/mods/public/shaders/glsl/minimap.xml
@@ -6,7 +6,7 @@
-
+
Index: binaries/data/mods/public/simulation/helpers/Commands.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Commands.js
+++ binaries/data/mods/public/simulation/helpers/Commands.js
@@ -828,6 +828,16 @@
cmpResourceDropsite.SetSharing(cmd.shared);
}
},
+
+ "map-flare": function(player, cmd, data)
+ {
+ let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGuiInterface.PushNotification({
+ "type": "map-flare",
+ "players": [player],
+ "target": cmd.target
+ });
+ },
};
/**
Index: source/gui/GUIObjectTypes.cpp
===================================================================
--- source/gui/GUIObjectTypes.cpp
+++ source/gui/GUIObjectTypes.cpp
@@ -40,6 +40,7 @@
m_ProxyData.insert(JSI_GUIProxy::CreateData(*m_ScriptInterface));
m_ProxyData.insert(JSI_GUIProxy::CreateData(*m_ScriptInterface));
m_ProxyData.insert(JSI_GUIProxy::CreateData(*m_ScriptInterface));
+ m_ProxyData.insert(JSI_GUIProxy::CreateData(*m_ScriptInterface));
m_ProxyData.insert(JSI_GUIProxy::CreateData(*m_ScriptInterface));
AddObjectType("button", &CButton::ConstructObject);
Index: source/gui/ObjectTypes/CMiniMap.h
===================================================================
--- source/gui/ObjectTypes/CMiniMap.h
+++ source/gui/ObjectTypes/CMiniMap.h
@@ -19,16 +19,26 @@
#define INCLUDED_MINIMAP
#include "graphics/ShaderProgramPtr.h"
+#include "graphics/Texture.h"
#include "gui/ObjectBases/IGUIObject.h"
#include "renderer/VertexArray.h"
class CCamera;
class CMatrix3D;
class CTerrain;
+class CVector2D;
+
+struct MapFlare
+{
+ CPos pos;
+ CColor color;
+ double time;
+};
class CMiniMap : public IGUIObject
{
GUI_OBJECT(CMiniMap)
+
public:
CMiniMap(CGUI& pGUI);
virtual ~CMiniMap();
@@ -38,9 +48,13 @@
*/
static float GetShallowPassageHeight();
+ bool Flare(const CVector2D& pos, const CColor& color);
+
protected:
virtual void Draw();
+ virtual void CreateJSObject();
+
/**
* @see IGUIObject#HandleMessage()
*/
@@ -74,9 +88,14 @@
//Whether or not the mouse is currently down
bool m_Clicking;
+ std::deque m_MapFlares;
+
// minimap texture handles
GLuint m_TerrainTexture;
+ static const int flareTextureSize = 16;
+ CTexturePtr m_FlareTextures[flareTextureSize];
+
// texture data
u32* m_TerrainData;
@@ -104,10 +123,14 @@
void DrawTexture(CShaderProgramPtr shader, float coordMax, float angle, float x, float y, float x2, float y2, float z) const;
- void DrawViewRect(CMatrix3D transform) const;
+ void DrawViewRect(const CMatrix3D& transform) const;
+
+ void DrawFlare(CShaderProgramPtr shader, const MapFlare& flare, double cur_time) const;
void GetMouseWorldCoordinates(float& x, float& z) const;
+ CPos GetMapCoordinates(float x, float z) const;
+
float GetAngle() const;
VertexIndexArray m_IndexArray;
Index: source/gui/ObjectTypes/CMiniMap.cpp
===================================================================
--- source/gui/ObjectTypes/CMiniMap.cpp
+++ source/gui/ObjectTypes/CMiniMap.cpp
@@ -29,10 +29,12 @@
#include "gui/CGUI.h"
#include "gui/GUIManager.h"
#include "gui/GUIMatrix.h"
+#include "gui/Scripting/JSInterface_GUIProxy.h"
#include "lib/bits.h"
#include "lib/external_libraries/libsdl.h"
#include "lib/ogl.h"
#include "lib/timer.h"
+#include "ps/CLogger.h"
#include "ps/ConfigDB.h"
#include "ps/Filesystem.h"
#include "ps/Game.h"
@@ -131,6 +133,12 @@
CFG_GET_VAL("gui.session.minimap.blinkduration", blinkDuration);
}
m_HalfBlinkDuration = blinkDuration/2;
+
+ for (int i = 0; i < flareTextureSize; ++i)
+ {
+ CTextureProperties textureProps(L"art/textures/animated/minimap-flare/frame" + CStr(fmt::sprintf("%02d", i)).FromUTF8() + L".png");
+ m_FlareTextures[i] = g_Renderer.GetTextureManager().CreateTexture(textureProps);
+ }
}
CMiniMap::~CMiniMap()
@@ -221,6 +229,14 @@
z = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(py-0.5) + sin(angle)*(px-0.5)) + 0.5);
}
+CPos CMiniMap::GetMapCoordinates(float x, float z) const
+{
+ const float width = m_CachedActualSize.GetWidth();
+ const float height = m_CachedActualSize.GetHeight();
+ const float invTileMapSize = 1.0f / (TERRAIN_TILE_SIZE * m_MapSize);
+ return CPos(width * x * invTileMapSize, height * z * invTileMapSize);
+}
+
void CMiniMap::SetCameraPos()
{
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
@@ -259,14 +275,13 @@
// This sets up and draws the rectangle on the minimap
// which represents the view of the camera in the world.
-void CMiniMap::DrawViewRect(CMatrix3D transform) const
+void CMiniMap::DrawViewRect(const CMatrix3D& transform) const
{
// Compute the camera frustum intersected with a fixed-height plane.
// Use the water height as a fixed base height, which should be the lowest we can go
float h = g_Renderer.GetWaterManager()->m_WaterHeight;
const float width = m_CachedActualSize.GetWidth();
const float height = m_CachedActualSize.GetHeight();
- const float invTileMapSize = 1.0f / float(TERRAIN_TILE_SIZE * m_MapSize);
CVector3D hitPt[4];
hitPt[0] = m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h);
@@ -274,19 +289,16 @@
hitPt[2] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h);
hitPt[3] = m_Camera->GetWorldCoordinates(0, 0, h);
- float ViewRect[4][2];
+ CPos ViewRect[4];
for (int i = 0; i < 4; ++i)
- {
// convert to minimap space
- ViewRect[i][0] = (width * hitPt[i].X * invTileMapSize);
- ViewRect[i][1] = (height * hitPt[i].Z * invTileMapSize);
- }
+ ViewRect[i] = GetMapCoordinates(hitPt[i].X, hitPt[i].Z);
float viewVerts[] = {
- ViewRect[0][0], -ViewRect[0][1],
- ViewRect[1][0], -ViewRect[1][1],
- ViewRect[2][0], -ViewRect[2][1],
- ViewRect[3][0], -ViewRect[3][1]
+ ViewRect[0].x, -ViewRect[0].y,
+ ViewRect[1].x, -ViewRect[1].y,
+ ViewRect[2].x, -ViewRect[2].y,
+ ViewRect[3].x, -ViewRect[3].y
};
// Enable Scissoring to restrict the rectangle to only the minimap.
@@ -318,6 +330,54 @@
glDisable(GL_SCISSOR_TEST);
}
+void CMiniMap::DrawFlare(CShaderProgramPtr shader, const MapFlare& flare, double cur_time) const
+{
+ float step = 35.0;//std::fmod((cur_time - flare.time) * 15, 35);
+ float x = flare.pos.x + step;
+ float y = -flare.pos.y-step;
+ float x2 = flare.pos.x - step;
+ float y2 = -flare.pos.y+step;
+ float z = 0;
+
+ float quadTex[] = {
+ 0, 1,
+ 1, 1,
+ 1, 0,
+
+ 1, 0,
+ 0, 0,
+ 0, 1
+ };
+ float quadVerts[] = {
+ x, y, z,
+ x2, y, z,
+ x2, y2, z,
+
+ x2, y2, z,
+ x, y2, z,
+ x, y, z
+ };
+
+ int flooredStep = floor((cur_time - flare.time) * 16);
+
+ shader->Uniform(str_color, flare.color);
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
+ shader->VertexPointer(3, GL_FLOAT, 0, quadVerts);
+ shader->AssertPointersBound();
+
+ if (g_Renderer.m_SkipSubmit)
+ return;
+
+ shader->BindTexture(str_baseTex, m_FlareTextures[flooredStep % 16]);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ if (flooredStep >= 8)
+ {
+ shader->BindTexture(str_baseTex, m_FlareTextures[(flooredStep - 8) % 16]);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ }
+}
+
struct MinimapUnitVertex
{
// This struct is copyable for convenience and because to move is to copy for primitives.
@@ -342,7 +402,6 @@
++attrPos;
}
-
void CMiniMap::DrawTexture(CShaderProgramPtr shader, float coordMax, float angle, float x, float y, float x2, float y2, float z) const
{
// Rotate the texture coordinates (0,0)-(coordMax,coordMax) around their center point (m,m)
@@ -513,7 +572,7 @@
glDisable(GL_BLEND);
- PROFILE_START("minimap units");
+ PROFILE_START("minimap units and flares");
CShaderDefines pointDefines;
pointDefines.Add(str_MINIMAP_POINT, str_1);
@@ -635,7 +694,35 @@
DrawViewRect(unitMatrix);
- PROFILE_END("minimap units");
+ while (!m_MapFlares.empty() && 6 + m_MapFlares.front().time < cur_time)
+ m_MapFlares.pop_front();
+
+ glEnable(GL_BLEND);
+
+ const float width = m_CachedActualSize.GetWidth();
+ const float height = m_CachedActualSize.GetHeight();
+ glScissor(
+ m_CachedActualSize.left * g_GuiScale,
+ g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale,
+ width * g_GuiScale,
+ height * g_GuiScale);
+ glEnable(GL_SCISSOR_TEST);
+
+ CShaderDefines flareDefines;
+ flareDefines.Add(str_MINIMAP_FLARE, str_1);
+ tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), flareDefines);
+ tech->BeginPass();
+ shader = tech->GetShader();
+
+ shader->Uniform(str_transform, unitMatrix);
+ shader->Uniform(str_textureTransform, baseTextureTransform);
+ for (const MapFlare& flare : m_MapFlares)
+ DrawFlare(shader, flare, cur_time);
+ tech->EndPass();
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+
+ PROFILE_END("minimap units and flares");
// Reset depth mask
glDepthMask(1);
@@ -731,6 +818,20 @@
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize - 1, m_MapSize - 1, GL_RGBA, GL_UNSIGNED_BYTE, m_TerrainData);
}
+bool CMiniMap::Flare(const CVector2D& pos, const CColor& color)
+{
+ m_MapFlares.push_back({GetMapCoordinates(pos.X, pos.Y), color, timer_Time()});
+ return true;
+}
+
+void CMiniMap::CreateJSObject()
+{
+ ScriptRequest rq(m_pGUI.GetScriptInterface());
+
+ using ProxyHandler = JSI_GUIProxy>;
+ ProxyHandler::CreateJSObject(rq, this, GetGUI().GetProxyData(&ProxyHandler::Singleton()), m_JSObject);
+}
+
void CMiniMap::Destroy()
{
if (m_TerrainTexture)
Index: source/gui/Scripting/JSInterface_CMiniMap.cpp
===================================================================
--- /dev/null
+++ source/gui/Scripting/JSInterface_CMiniMap.cpp
@@ -0,0 +1,77 @@
+/* Copyright (C) 2020 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see .
+ */
+
+#include "precompiled.h"
+
+#include "JSInterface_GUIProxy_impl.h"
+//#include "JSInterface_GUIProxy.h"
+
+//#include "gui/CGUI.h"
+//#include "gui/CGUISetting.h"
+//#include "gui/ObjectBases/IGUIObject.h"
+#include "gui/ObjectTypes/CMiniMap.h"
+#include "maths/Vector2D.h"
+#include "ps/CLogger.h"
+//#include "scriptinterface/ScriptConversions.h"
+//#include "scriptinterface/ScriptExtraHeaders.h"
+
+//#include
+
+
+bool CMiniMap_Flare(JSContext* cx, uint argc, JS::Value* vp)
+{
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ CMiniMap* obj = static_cast(js::GetProxyPrivate(args.thisv().toObjectOrNull()).toPrivate());
+ if (!obj)
+ return false;
+
+ if (args.length() != 2)
+ {
+ LOGERROR("CMiniMap::Flare: Got %d arguments, but expected 2.", args.length());
+ return false;
+ }
+
+ ScriptInterface& scriptInterface = *ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+ ScriptRequest rq(scriptInterface);
+ CVector2D pos;
+ CStr colorStr;
+ CColor color;
+ if (!(ScriptInterface::FromJSVal(rq, args.get(0), pos) &&
+ ScriptInterface::FromJSVal(rq, args.get(1), colorStr) &&
+ color.ParseString(colorStr)))
+ return false;
+
+ bool ret = obj->Flare(pos, color);
+ args.rval().set(JS::BooleanValue(ret));
+ return true;
+}
+
+using GUIObjectType = CMiniMap;
+
+template <>
+void JSI_GUIProxy::CreateFunctions(const ScriptRequest& rq, GUIProxyProps* cache)
+{
+#define func(class, func) &JSInterface_GUIProxy::apply_to
+ cache->setFunction(rq, "toString", func(IGUIObject, toString), 0);
+ cache->setFunction(rq, "focus", func(IGUIObject, focus), 0);
+ cache->setFunction(rq, "blur", func(IGUIObject, blur), 0);
+ cache->setFunction(rq, "getComputedSize", func(IGUIObject, getComputedSize), 0);
+#undef func
+ cache->setFunction(rq, "flare", CMiniMap_Flare, 1);
+}
+
+template class JSI_GUIProxy;
Index: source/ps/CStrInternStatic.h
===================================================================
--- source/ps/CStrInternStatic.h
+++ source/ps/CStrInternStatic.h
@@ -39,6 +39,7 @@
X(DISABLE_RECEIVE_SHADOWS)
X(IGNORE_LOS)
X(MINIMAP_BASE)
+X(MINIMAP_FLARE)
X(MINIMAP_LINE)
X(MINIMAP_LOS)
X(MINIMAP_MASK)