Changeset View
Standalone View
source/gui/MiniMap.cpp
/* Copyright (C) 2017 Wildfire Games. | /* Copyright (C) 2019 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 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 | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
CMiniMap::CMiniMap() : | CMiniMap::CMiniMap() : | ||||
m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f), | m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f), | ||||
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), | m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), | ||||
m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0) | m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0) | ||||
{ | { | ||||
AddSetting(GUIST_CColor, "fov_wedge_color"); | AddSetting(GUIST_CColor, "fov_wedge_color"); | ||||
AddSetting(GUIST_CStrW, "tooltip"); | AddSetting(GUIST_CStrW, "tooltip"); | ||||
AddSetting(GUIST_CStr, "tooltip_style"); | AddSetting(GUIST_CStr, "tooltip_style"); | ||||
AddSetting(GUIST_float, "ping_x"); | |||||
AddSetting(GUIST_float, "ping_z"); | |||||
AddSetting(GUIST_CColor, "ping_color"); | |||||
AddSetting(GUIST_bool, "ping"); | |||||
elexis: (`AddSetting<bool>` etc following rP22604) | |||||
m_Clicking = false; | m_Clicking = false; | ||||
m_MouseHovering = false; | m_MouseHovering = false; | ||||
// Register Relax NG validator | // Register Relax NG validator | ||||
CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng"); | CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng"); | ||||
// Get the maximum height for unit passage in water. | // Get the maximum height for unit passage in water. | ||||
CParamNode externalParamNode; | CParamNode externalParamNode; | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | void CMiniMap::HandleMessage(SGUIMessage& Message) | ||||
case GUIM_MOUSE_ENTER: | case GUIM_MOUSE_ENTER: | ||||
m_MouseHovering = true; | m_MouseHovering = true; | ||||
break; | break; | ||||
case GUIM_MOUSE_LEAVE: | case GUIM_MOUSE_LEAVE: | ||||
m_Clicking = false; | m_Clicking = false; | ||||
m_MouseHovering = false; | m_MouseHovering = false; | ||||
break; | break; | ||||
case GUIM_MOUSE_RELEASE_RIGHT: | case GUIM_MOUSE_RELEASE_RIGHT: | ||||
CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 1); | FireWorldClickEvent("mouserightrelease"); | ||||
Done Inline ActionsI suppose the CMiniMap:: prefix is not needed here, because it's not the derived or the global function. vladislavbelov: I suppose the `CMiniMap::` prefix is not needed here, because it's not the derived or the… | |||||
Done Inline ActionsTrue. Imarok: True. | |||||
break; | break; | ||||
case GUIM_MOUSE_DBLCLICK_RIGHT: | case GUIM_MOUSE_DBLCLICK_RIGHT: | ||||
CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 2); | FireWorldClickEvent("mouserightdoubleclick"); | ||||
break; | |||||
case GUIM_MOUSE_RELEASE_MIDDLE: | |||||
FireWorldClickEvent("mousemiddlerelease"); | |||||
break; | |||||
case GUIM_MOUSE_DBLCLICK_MIDDLE: | |||||
FireWorldClickEvent("mousemiddledoubleclick"); | |||||
break; | break; | ||||
case GUIM_MOUSE_MOTION: | case GUIM_MOUSE_MOTION: | ||||
if (m_MouseHovering && m_Clicking) | if (m_MouseHovering && m_Clicking) | ||||
SetCameraPos(); | SetCameraPos(); | ||||
break; | break; | ||||
case GUIM_MOUSE_WHEEL_DOWN: | case GUIM_MOUSE_WHEEL_DOWN: | ||||
case GUIM_MOUSE_WHEEL_UP: | case GUIM_MOUSE_WHEEL_UP: | ||||
Message.Skip(); | Message.Skip(); | ||||
break; | break; | ||||
case GUIM_SETTINGS_UPDATED: | |||||
if (Message.value == "ping") | |||||
Not Done Inline ActionsWhy not use the script interface instead of XML params? vladislavbelov: Why not use the script interface instead of XML params? | |||||
Done Inline ActionsI'd like to do that, but I found no way to call a function of the minimap without hardcoding a specific instance of the minimap. Imarok: I'd like to do that, but I found no way to call a function of the minimap without hardcoding a… | |||||
Not Done Inline ActionsA GUI Setting is intended to be a value that can be read from and written to, should not represent an event, so this is definitely a workaround / hack. elexis: A GUI Setting is intended to be a value that can be read from and written to, should not… | |||||
Not Done Inline ActionsSettings should be used for settings, functions for functios. Have a look at https://trac.wildfiregames.com/browser/ps/trunk/source/gui/scripting/JSInterface_IGUITextOwner.cpp?rev=22596 from rP22596 and how JSI_IGUITextOwner::RegisterScriptFunctions is called. (If this was a setting, then it would have been cleaner to implement a ScriptInterface::FromJSVal<MapPingObj> for your existing MapPingObj with the content below, also registering the setting with AddSetting<MapPingObj> if it was a setting) elexis: Settings should be used for settings, functions for functios.
Have a look at https://trac. | |||||
{ | |||||
bool doPing = false; | |||||
GUI<bool>::GetSetting(this, "ping", doPing); | |||||
if (doPing) | |||||
{ | |||||
GUI<bool>::SetSetting(this, "ping", false); | |||||
float pingX; | |||||
GUI<float>::GetSetting(this, "ping_x", pingX); | |||||
float pingZ; | |||||
GUI<float>::GetSetting(this, "ping_z", pingZ); | |||||
CColor pingColor; | |||||
GUI<CColor>::GetSetting(this, "ping_color", pingColor); | |||||
m_MapPings.push_back({GetMapCoordinates(pingX, pingZ), pingColor, timer_Time()}); | |||||
} | |||||
} | |||||
break; | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
bool CMiniMap::MouseOver() | bool CMiniMap::MouseOver() | ||||
{ | { | ||||
// Get the mouse position. | // Get the mouse position. | ||||
Show All 20 Lines | void CMiniMap::GetMouseWorldCoordinates(float& x, float& z) | ||||
float angle = GetAngle(); | float angle = GetAngle(); | ||||
// Scale world coordinates for shrunken square map | // Scale world coordinates for shrunken square map | ||||
x = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(px-0.5) - sin(angle)*(py-0.5)) + 0.5); | x = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(px-0.5) - sin(angle)*(py-0.5)) + 0.5); | ||||
z = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(py-0.5) + sin(angle)*(px-0.5)) + 0.5); | 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); | |||||
Done Inline ActionsActually the float cast isn't not needed here, because you already have the 1.0f before. vladislavbelov: Actually the `float` cast isn't not needed here, because you already have the `1.0f` before. | |||||
return CPos(width * x * invTileMapSize, height * z * invTileMapSize); | |||||
} | |||||
void CMiniMap::SetCameraPos() | void CMiniMap::SetCameraPos() | ||||
{ | { | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | ||||
CVector3D target; | CVector3D target; | ||||
GetMouseWorldCoordinates(target.X, target.Z); | GetMouseWorldCoordinates(target.X, target.Z); | ||||
target.Y = terrain->GetExactGroundLevel(target.X, target.Z); | target.Y = terrain->GetExactGroundLevel(target.X, target.Z); | ||||
g_Game->GetView()->MoveCameraTarget(target); | g_Game->GetView()->MoveCameraTarget(target); | ||||
} | } | ||||
float CMiniMap::GetAngle() | float CMiniMap::GetAngle() | ||||
{ | { | ||||
CVector3D cameraIn = m_Camera->m_Orientation.GetIn(); | CVector3D cameraIn = m_Camera->m_Orientation.GetIn(); | ||||
return -atan2(cameraIn.X, cameraIn.Z); | return -atan2(cameraIn.X, cameraIn.Z); | ||||
} | } | ||||
void CMiniMap::FireWorldClickEvent(int UNUSED(button), int UNUSED(clicks)) | void CMiniMap::FireWorldClickEvent(const CStr& eventType) | ||||
{ | { | ||||
JSContext* cx = g_GUI->GetActiveGUI()->GetScriptInterface()->GetContext(); | JSContext* cx = g_GUI->GetActiveGUI()->GetScriptInterface()->GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
float x, z; | float x, z; | ||||
GetMouseWorldCoordinates(x, z); | GetMouseWorldCoordinates(x, z); | ||||
JS::RootedValue coords(cx); | JS::RootedValue target(cx); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &coords); | g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &target); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords, "x", x, false); | g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(target, "x", x, false); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords, "z", z, false); | g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(target, "z", z, false); | ||||
ScriptEvent("worldclick", coords); | JS::RootedValue data(cx); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &data); | |||||
elexisUnsubmitted Not Done Inline ActionsThe eval is a hack, JS::RootedObject data(cx, JS_NewPlainObject(cx)); elexis: The eval is a hack, `JS::RootedObject data(cx, JS_NewPlainObject(cx));` | |||||
ImarokAuthorUnsubmitted Done Inline ActionsHmm, true. But we're using this hack quite often ;) Imarok: Hmm, true. But we're using this hack quite often ;)
(43 times to be concrete) | |||||
elexisUnsubmitted Not Done Inline ActionsScriptInterface::CreateObject(target, "x", x, "z", z) following rP22528. elexis: `ScriptInterface::CreateObject(target, "x", x, "z", z)` following rP22528. | |||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(data, "target", target, false); | |||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(data, "type", eventType, false); | |||||
ScriptEvent("worldclick", data); | |||||
} | } | ||||
// This sets up and draws the rectangle on the minimap | // This sets up and draws the rectangle on the minimap | ||||
// which represents the view of the camera in the world. | // which represents the view of the camera in the world. | ||||
void CMiniMap::DrawViewRect(CMatrix3D transform) | void CMiniMap::DrawViewRect(const CMatrix3D& transform) | ||||
{ | { | ||||
// Compute the camera frustum intersected with a fixed-height plane. | // 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 | // Use the water height as a fixed base height, which should be the lowest we can go | ||||
float h = g_Renderer.GetWaterManager()->m_WaterHeight; | float h = g_Renderer.GetWaterManager()->m_WaterHeight; | ||||
const float width = m_CachedActualSize.GetWidth(); | const float width = m_CachedActualSize.GetWidth(); | ||||
const float height = m_CachedActualSize.GetHeight(); | const float height = m_CachedActualSize.GetHeight(); | ||||
const float invTileMapSize = 1.0f / float(TERRAIN_TILE_SIZE * m_MapSize); | |||||
CVector3D hitPt[4]; | CVector3D hitPt[4]; | ||||
hitPt[0] = m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h); | hitPt[0] = m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h); | ||||
hitPt[1] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h); | hitPt[1] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h); | ||||
hitPt[2] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h); | hitPt[2] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h); | ||||
hitPt[3] = m_Camera->GetWorldCoordinates(0, 0, h); | hitPt[3] = m_Camera->GetWorldCoordinates(0, 0, h); | ||||
float ViewRect[4][2]; | CPos ViewRect[4]; | ||||
for (int i = 0; i < 4; ++i) | for (int i = 0; i < 4; ++i) | ||||
{ | |||||
// convert to minimap space | // convert to minimap space | ||||
ViewRect[i][0] = (width * hitPt[i].X * invTileMapSize); | ViewRect[i] = GetMapCoordinates(hitPt[i].X, hitPt[i].Z); | ||||
ViewRect[i][1] = (height * hitPt[i].Z * invTileMapSize); | |||||
} | |||||
float viewVerts[] = { | float viewVerts[] = { | ||||
ViewRect[0][0], -ViewRect[0][1], | ViewRect[0].x, -ViewRect[0].y, | ||||
ViewRect[1][0], -ViewRect[1][1], | ViewRect[1].x, -ViewRect[1].y, | ||||
ViewRect[2][0], -ViewRect[2][1], | ViewRect[2].x, -ViewRect[2].y, | ||||
ViewRect[3][0], -ViewRect[3][1] | ViewRect[3].x, -ViewRect[3].y | ||||
}; | }; | ||||
// Enable Scissoring to restrict the rectangle to only the minimap. | // Enable Scissoring to restrict the rectangle to only the minimap. | ||||
glScissor( | glScissor( | ||||
m_CachedActualSize.left * g_GuiScale, | m_CachedActualSize.left * g_GuiScale, | ||||
g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | ||||
width * g_GuiScale, | width * g_GuiScale, | ||||
height * g_GuiScale); | height * g_GuiScale); | ||||
Show All 15 Lines | if (!g_Renderer.m_SkipSubmit) | ||||
glDrawArrays(GL_LINE_LOOP, 0, 4); | glDrawArrays(GL_LINE_LOOP, 0, 4); | ||||
tech->EndPass(); | tech->EndPass(); | ||||
glLineWidth(1.0f); | glLineWidth(1.0f); | ||||
glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
} | } | ||||
// TODO: Hacky and ugly copypasta | |||||
Done Inline ActionsIt's not so bad copy-pasted, because the original code is used for a long time :) vladislavbelov: It's not so bad copy-pasted, because the original code is used for a long time :) | |||||
void CMiniMap::DrawPing(const CMatrix3D& transform, const MapPingObj& ping, double cur_time) | |||||
Done Inline ActionsI think it's better to use float instead of int for the step, because of more smooth animation. Since you don't need such precision on edges, but only attention to the center of the animation. vladislavbelov: I think it's better to use `float` instead of `int` for the step, because of more smooth… | |||||
Not Done Inline ActionsCan still move the copied part to a helper function with the color as an argument elexis: Can still move the copied part to a helper function with the color as an argument | |||||
{ | |||||
float step = std::fmod((cur_time - ping.time) * 10, 10); | |||||
float viewVerts[] = { | |||||
ping.pos.x + step, -ping.pos.y-step, | |||||
Done Inline ActionsIndent. vladislavbelov: Indent. | |||||
ping.pos.x - step, -ping.pos.y-step, | |||||
ping.pos.x - step, -ping.pos.y+step, | |||||
ping.pos.x + step, -ping.pos.y+step | |||||
}; | |||||
const float width = m_CachedActualSize.GetWidth(); | |||||
const float height = m_CachedActualSize.GetHeight(); | |||||
// Enable Scissoring to restrict the rectangle to only the minimap. | |||||
glScissor( | |||||
m_CachedActualSize.left * g_GuiScale, | |||||
g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | |||||
width * g_GuiScale, | |||||
height * g_GuiScale); | |||||
glEnable(GL_SCISSOR_TEST); | |||||
glLineWidth(2.0f); | |||||
CShaderDefines lineDefines; | |||||
lineDefines.Add(str_MINIMAP_LINE, str_1); | |||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), lineDefines); | |||||
tech->BeginPass(); | |||||
CShaderProgramPtr shader = tech->GetShader(); | |||||
shader->Uniform(str_transform, transform); | |||||
shader->Uniform(str_color, ping.color.r, ping.color.g, ping.color.b, ping.color.a); | |||||
shader->VertexPointer(2, GL_FLOAT, 0, viewVerts); | |||||
shader->AssertPointersBound(); | |||||
if (!g_Renderer.m_SkipSubmit) | |||||
glDrawArrays(GL_LINE_LOOP, 0, 4); | |||||
tech->EndPass(); | |||||
glLineWidth(1.0f); | |||||
glDisable(GL_SCISSOR_TEST); | |||||
} | |||||
struct MinimapUnitVertex | struct MinimapUnitVertex | ||||
{ | { | ||||
u8 r, g, b, a; | u8 r, g, b, a; | ||||
float x, y; | float x, y; | ||||
}; | }; | ||||
// Adds a vertex to the passed VertexArray | // Adds a vertex to the passed VertexArray | ||||
static void inline addVertex(const MinimapUnitVertex& v, | static void inline addVertex(const MinimapUnitVertex& v, | ||||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | void CMiniMap::Draw() | ||||
// Apply the gui matrix. | // Apply the gui matrix. | ||||
unitMatrix *= GetDefaultGuiMatrix(); | unitMatrix *= GetDefaultGuiMatrix(); | ||||
// Load the transform into the shader. | // Load the transform into the shader. | ||||
shader->Uniform(str_transform, unitMatrix); | shader->Uniform(str_transform, unitMatrix); | ||||
const float sx = (float)m_Width / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); | const float sx = (float)m_Width / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); | ||||
const float sy = (float)m_Height / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); | const float sy = (float)m_Height / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); | ||||
CSimulation2::InterfaceList ents = sim->GetEntitiesWithInterface(IID_Minimap); | CSimulation2::InterfaceList ents = sim->GetEntitiesWithInterface(IID_Minimap); | ||||
elexisUnsubmitted Not Done Inline ActionsGUI Minimap pulls rendering data from the simulation here elexis: GUI Minimap pulls rendering data from the simulation here | |||||
if (doUpdate) | if (doUpdate) | ||||
{ | { | ||||
VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>(); | VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>(); | ||||
VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>(); | VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>(); | ||||
m_EntitiesDrawn = 0; | m_EntitiesDrawn = 0; | ||||
MinimapUnitVertex v; | MinimapUnitVertex v; | ||||
Show All 15 Lines | for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) | ||||
ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(it->first, g_Game->GetSimulation2()->GetSimContext().GetCurrentDisplayedPlayer()); | ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(it->first, g_Game->GetSimulation2()->GetSimContext().GetCurrentDisplayedPlayer()); | ||||
if (vis != ICmpRangeManager::VIS_HIDDEN) | if (vis != ICmpRangeManager::VIS_HIDDEN) | ||||
{ | { | ||||
v.a = 255; | v.a = 255; | ||||
v.x = posX.ToFloat() * sx; | v.x = posX.ToFloat() * sx; | ||||
v.y = -posZ.ToFloat() * sy; | v.y = -posZ.ToFloat() * sy; | ||||
// Check minimap pinging to indicate something | // Check minimap pinging to indicate something | ||||
if (m_BlinkState && cmpMinimap->CheckPing(cur_time, m_PingDuration)) | if (m_BlinkState && cmpMinimap->CheckPing(cur_time, m_PingDuration)) | ||||
elexisUnsubmitted Not Done Inline ActionsMinimap ping code here confusing the reader elexis: Minimap ping code here confusing the reader | |||||
{ | { | ||||
v.r = 255; // ping color is white | v.r = 255; // ping color is white | ||||
v.g = 255; | v.g = 255; | ||||
v.b = 255; | v.b = 255; | ||||
pingingVertices.push_back(v); | pingingVertices.push_back(v); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) | ||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | ||||
#endif | #endif | ||||
} | } | ||||
tech->EndPass(); | tech->EndPass(); | ||||
DrawViewRect(unitMatrix); | DrawViewRect(unitMatrix); | ||||
while (!m_MapPings.empty() && 3 + m_MapPings.front().time < cur_time) | |||||
Done Inline ActionsWith my comments above it'd look like: while (!m_MapPings.empty() && m_MapPings.front().IsOver()) m_MapPings.pop_front(); for (const MapPingObj& obj : m_MapPings) DrawPing(unitMatrix, obj); vladislavbelov: With my comments above it'd look like:
```lang=cpp
while (!m_MapPings.empty() && m_MapPings. | |||||
Not Done Inline Actions3 -> constant? elexis: 3 -> constant? | |||||
Done Inline ActionsThis is still ugly wip draw code. ;P Imarok: This is still ugly wip draw code. ;P | |||||
m_MapPings.pop_front(); | |||||
for (const MapPingObj& ping : m_MapPings) | |||||
DrawPing(unitMatrix, ping, cur_time); | |||||
PROFILE_END("minimap units"); | PROFILE_END("minimap units"); | ||||
// Reset depth mask | // Reset depth mask | ||||
glDepthMask(1); | glDepthMask(1); | ||||
} | } | ||||
void CMiniMap::CreateTextures() | void CMiniMap::CreateTextures() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 98 Lines • Show Last 20 Lines |
(AddSetting<bool> etc following rP22604)