Skip to content

Commit

Permalink
Minimap as HUD element with API control
Browse files Browse the repository at this point in the history
Features:
 * Define Minimap available modes (surface/radar, scale) from Lua, using player:set_minimap_modes()
 * New HUD elements for displaying minimap with custom size and placing
 * New minimap mode for displaying a texture instead of the map
  • Loading branch information
pyrollo authored and SmallJoker committed Oct 4, 2020
1 parent 3068853 commit 81c66d6
Show file tree
Hide file tree
Showing 20 changed files with 471 additions and 145 deletions.
33 changes: 32 additions & 1 deletion doc/lua_api.txt
Expand Up @@ -1484,6 +1484,15 @@ Displays an image oriented or translated according to current heading direction.

If translation is chosen, texture is repeated horizontally to fill the whole element.

### `minimap`

Displays a minimap on the HUD.

* `size`: Size of the minimap to display. Minimap should be a square to avoid
distortion.
* `alignment`: The alignment of the minimap.
* `offset`: offset in pixels from position.

Representations of simple things
================================

Expand Down Expand Up @@ -6366,6 +6375,27 @@ object you are working with still exists.
* `hud_set_hotbar_selected_image(texturename)`
* sets image for selected item of hotbar
* `hud_get_hotbar_selected_image`: returns texturename
* `set_minimap_modes({mode, mode, ...}, selected_mode)`
* Overrides the available minimap modes (and toggle order), and changes the
selected mode.
* `mode` is a table consisting of up to four fields:
* `type`: Available type:
* `off`: Minimap off
* `surface`: Minimap in surface mode
* `radar`: Minimap in radar mode
* `texture`: Texture to be displayed instead of terrain map
(texture is centered around 0,0 and can be scaled).
Texture size is limited to 512 x 512 pixel.
* `label`: Optional label to display on minimap mode toggle
The translation must be handled within the mod.
* `size`: Sidelength or diameter, in number of nodes, of the terrain
displayed in minimap
* `texture`: Only for texture type, name of the texture to display
* `scale`: Only for texture type, scale of the texture map in nodes per
pixel (for example a `scale` of 2 means each pixel represents a 2x2
nodes square)
* `selected_mode` is the mode index to be selected after modes have been changed
(0 is the first mode).
* `set_sky(parameters)`
* `parameters` is a table with the following optional fields:
* `base_color`: ColorSpec, changes fog in "skybox" and "plain".
Expand Down Expand Up @@ -8047,7 +8077,8 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`.

{
hud_elem_type = "image", -- See HUD element types
-- Type of element, can be "image", "text", "statbar", "inventory" or "compass"
-- Type of element, can be "image", "text", "statbar", "inventory",
-- "compass" or "minimap"

position = {x=0.5, y=0.5},
-- Left corner position of element
Expand Down
1 change: 1 addition & 0 deletions src/client/client.cpp
Expand Up @@ -129,6 +129,7 @@ Client::Client(
if (g_settings->getBool("enable_minimap")) {
m_minimap = new Minimap(this);
}

m_cache_save_interval = g_settings->getU16("server_map_save_interval");
}

Expand Down
1 change: 1 addition & 0 deletions src/client/client.h
Expand Up @@ -223,6 +223,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
void handleCommand_PlayerSpeed(NetworkPacket *pkt);
void handleCommand_MediaPush(NetworkPacket *pkt);
void handleCommand_MinimapModes(NetworkPacket *pkt);

void ProcessData(NetworkPacket *pkt);

Expand Down
75 changes: 29 additions & 46 deletions src/client/game.cpp
Expand Up @@ -1416,11 +1416,9 @@ bool Game::createClient(const GameStartData &start_data)
}

mapper = client->getMinimap();
if (mapper) {
mapper->setMinimapMode(MINIMAP_MODE_OFF);
if (client->modsLoaded())
client->getScript()->on_minimap_ready(mapper);
}

if (mapper && client->modsLoaded())
client->getScript()->on_minimap_ready(mapper);

return true;
}
Expand Down Expand Up @@ -2222,52 +2220,37 @@ void Game::toggleMinimap(bool shift_pressed)
if (!mapper || !m_game_ui->m_flags.show_hud || !g_settings->getBool("enable_minimap"))
return;

if (shift_pressed) {
if (shift_pressed)
mapper->toggleMinimapShape();
return;
}
else
mapper->nextMode();

// TODO: When legacy minimap is deprecated, keep only HUD minimap stuff here

// Not so satisying code to keep compatibility with old fixed mode system
// -->
u32 hud_flags = client->getEnv().getLocalPlayer()->hud_flags;

MinimapMode mode = MINIMAP_MODE_OFF;
if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) {
mode = mapper->getMinimapMode();
mode = (MinimapMode)((int)mode + 1);
// If radar is disabled and in, or switching to, radar mode
if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE) && mode > 3)
mode = MINIMAP_MODE_OFF;
}
if (!(hud_flags & HUD_FLAG_MINIMAP_VISIBLE)) {
m_game_ui->m_flags.show_minimap = false;
} else {

m_game_ui->m_flags.show_minimap = true;
switch (mode) {
case MINIMAP_MODE_SURFACEx1:
m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x1");
break;
case MINIMAP_MODE_SURFACEx2:
m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x2");
break;
case MINIMAP_MODE_SURFACEx4:
m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x4");
break;
case MINIMAP_MODE_RADARx1:
m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x1");
break;
case MINIMAP_MODE_RADARx2:
m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x2");
break;
case MINIMAP_MODE_RADARx4:
m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x4");
break;
default:
mode = MINIMAP_MODE_OFF;
m_game_ui->m_flags.show_minimap = false;
if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE)
m_game_ui->showTranslatedStatusText("Minimap hidden");
else
m_game_ui->showTranslatedStatusText("Minimap currently disabled by game or mod");
}
// If radar is disabled, try to find a non radar mode or fall back to 0
if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE))
while (mapper->getModeIndex() &&
mapper->getModeDef().type == MINIMAP_TYPE_RADAR)
mapper->nextMode();

mapper->setMinimapMode(mode);
m_game_ui->m_flags.show_minimap = mapper->getModeDef().type !=
MINIMAP_TYPE_OFF;
}
// <--
// End of 'not so satifying code'
if ((hud_flags & HUD_FLAG_MINIMAP_VISIBLE) ||
(hud && hud->hasElementOfType(HUD_ELEM_MINIMAP)))
m_game_ui->showStatusText(utf8_to_wide(mapper->getModeDef().label));
else
m_game_ui->showTranslatedStatusText("Minimap currently disabled by game or mod");
}

void Game::toggleFog()
Expand Down Expand Up @@ -3954,7 +3937,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
/*
Update minimap pos and rotation
*/
if (mapper && m_game_ui->m_flags.show_minimap && m_game_ui->m_flags.show_hud) {
if (mapper && m_game_ui->m_flags.show_hud) {
mapper->setPos(floatToInt(player->getPosition(), BS));
mapper->setAngle(player->getYaw());
}
Expand Down
30 changes: 29 additions & 1 deletion src/client/hud.cpp
Expand Up @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mesh.h"
#include "wieldmesh.h"
#include "client/renderingengine.h"
#include "client/minimap.h"

#ifdef HAVE_TOUCHSCREENGUI
#include "gui/touchscreengui.h"
Expand Down Expand Up @@ -297,6 +298,18 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
}
}

bool Hud::hasElementOfType(HudElementType type)
{
for (size_t i = 0; i != player->maxHudId(); i++) {
HudElement *e = player->getHud(i);
if (!e)
continue;
if (e->type == type)
return true;
}
return false;
}

// Calculates screen position of waypoint. Returns true if waypoint is visible (in front of the player), else false.
bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *pos)
{
Expand Down Expand Up @@ -491,7 +504,22 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
default:
break;
}

break; }
case HUD_ELEM_MINIMAP: {
if (e->size.X <= 0 || e->size.Y <= 0)
break;
if (!client->getMinimap())
break;
// Draw a minimap of size "size"
v2s32 dstsize(e->size.X * m_scale_factor,
e->size.Y * m_scale_factor);
// (no percent size as minimap would likely be anamorphosed)
v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
(e->align.Y - 1.0) * dstsize.Y / 2);
core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
rect += pos + offset + v2s32(e->offset.X * m_scale_factor,
e->offset.Y * m_scale_factor);
client->getMinimap()->drawMinimap(rect);
break; }
default:
infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
Expand Down
2 changes: 2 additions & 0 deletions src/client/hud.h
Expand Up @@ -81,6 +81,8 @@ class Hud
m_selected_face_normal = face_normal;
}

bool hasElementOfType(HudElementType type);

void drawLuaElements(const v3s16 &camera_offset);

private:
Expand Down
2 changes: 1 addition & 1 deletion src/client/mapblock_mesh.cpp
Expand Up @@ -1044,7 +1044,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_use_tangent_vertices = data->m_use_tangent_vertices;
m_enable_vbo = g_settings->getBool("enable_vbo");

if (g_settings->getBool("enable_minimap")) {
if (data->m_client->getMinimap()) {
m_minimap_mapblock = new MinimapMapblock;
m_minimap_mapblock->getMinimapNodes(
&data->m_vmanip, data->m_blockpos * MAP_BLOCKSIZE);
Expand Down

0 comments on commit 81c66d6

Please sign in to comment.