#include "util/pointedthing.h"
#include "drawscene.h"
#include "content_cao.h"
+#include "fontengine.h"
#ifdef HAVE_TOUCHSCREENGUI
#include "touchscreengui.h"
for (s16 z = zstart; z <= zend; z++)
for (s16 x = xstart; x <= xend; x++) {
MapNode n;
+ bool is_valid_position;
- try {
- n = map.getNode(v3s16(x, y, z));
- } catch (InvalidPositionException &e) {
+ n = map.getNodeNoEx(v3s16(x, y, z), &is_valid_position);
+ if (!is_valid_position)
continue;
- }
if (!isPointableNode(n, client, liquids_pointable))
continue;
/* Profiler display */
-void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
- gui::IGUIFont *font, u32 text_height, u32 show_profiler,
- u32 show_profiler_max)
+void update_profiler_gui(gui::IGUIStaticText *guitext_profiler, FontEngine *fe,
+ u32 show_profiler, u32 show_profiler_max, s32 screen_height)
{
if (show_profiler == 0) {
guitext_profiler->setVisible(false);
guitext_profiler->setText(text.c_str());
guitext_profiler->setVisible(true);
- s32 w = font->getDimension(text.c_str()).Width;
+ s32 w = fe->getTextWidth(text.c_str());
if (w < 400)
w = 400;
- core::rect<s32> rect(6, 4 + (text_height + 5) * 2, 12 + w,
- 8 + (text_height + 5) * 2 +
- font->getDimension(text.c_str()).Height);
+ unsigned text_height = fe->getTextHeight();
+
+ core::position2di upper_left, lower_right;
+
+ upper_left.X = 6;
+ upper_left.Y = (text_height + 5) * 2;
+ lower_right.X = 12 + w;
+ lower_right.Y = upper_left.Y + (text_height + 1) * MAX_PROFILER_TEXT_ROWS;
+
+ if (lower_right.Y > screen_height * 2 / 3)
+ lower_right.Y = screen_height * 2 / 3;
+
+ core::rect<s32> rect(upper_left, lower_right);
+
guitext_profiler->setRelativePosition(rect);
guitext_profiler->setVisible(true);
}
std::string prediction = playeritem_def.node_placement_prediction;
INodeDefManager *nodedef = client.ndef();
ClientMap &map = client.getEnv().getClientMap();
+ MapNode node;
+ bool is_valid_position;
+
+ node = map.getNodeNoEx(nodepos, &is_valid_position);
+ if (!is_valid_position)
+ return false;
- if (prediction != "" && !nodedef->get(map.getNode(nodepos)).rightclickable) {
+ if (prediction != "" && !nodedef->get(node).rightclickable) {
verbosestream << "Node placement prediction for "
<< playeritem_def.name << " is "
<< prediction << std::endl;
v3s16 p = neighbourpos;
// Place inside node itself if buildable_to
- try {
- MapNode n_under = map.getNode(nodepos);
-
+ MapNode n_under = map.getNodeNoEx(nodepos, &is_valid_position);
+ if (is_valid_position)
+ {
if (nodedef->get(n_under).buildable_to)
p = nodepos;
- else if (!nodedef->get(map.getNode(p)).buildable_to)
- return false;
- } catch (InvalidPositionException &e) {}
+ else {
+ node = map.getNodeNoEx(p, &is_valid_position);
+ if (is_valid_position &&!nodedef->get(node).buildable_to)
+ return false;
+ }
+ }
// Find id of predicted node
content_t id;
else
pp = p + v3s16(0, -1, 0);
- if (!nodedef->get(map.getNode(pp)).walkable)
+ if (!nodedef->get(map.getNodeNoEx(pp)).walkable)
return false;
}
// Dont place node when player would be inside new node
// NOTE: This is to be eventually implemented by a mod as client-side Lua
if (!nodedef->get(n).walkable ||
+ g_settings->getBool("enable_build_where_you_stand") ||
(client.checkPrivilege("noclip") && g_settings->getBool("noclip")) ||
(nodedef->get(n).walkable &&
neighbourpos != player->getStandingNodePos() + v3s16(0, 1, 0) &&
/******************************************************************************/
static void updateChat(Client &client, f32 dtime, bool show_debug,
const v2u32 &screensize, bool show_chat, u32 show_profiler,
- ChatBackend &chat_backend, gui::IGUIStaticText *guitext_chat,
- gui::IGUIFont *font)
+ ChatBackend &chat_backend, gui::IGUIStaticText *guitext_chat)
{
// Add chat log output for errors to be shown in chat
static LogOutputBuffer chat_log_error_buf(LMT_ERROR);
// Display all messages in a static text element
unsigned int recent_chat_count = chat_backend.getRecentBuffer().getLineCount();
std::wstring recent_chat = chat_backend.getRecentChat();
-
- // TODO replace by fontengine fcts
- unsigned int line_height = font->getDimension(L"Ay").Height + font->getKerningHeight();
+ unsigned int line_height = g_fontengine->getLineHeight();
guitext_chat->setText(recent_chat.c_str());
chat_y += line_height;
// first pass to calculate height of text to be set
- s32 width = std::min(font->getDimension(recent_chat.c_str()).Width + 10,
+ s32 width = std::min(g_fontengine->getTextWidth(recent_chat) + 10,
porting::getWindowSize().X - 20);
core::rect<s32> rect(10, chat_y, width, chat_y + porting::getWindowSize().Y);
guitext_chat->setRelativePosition(rect);
}
+/****************************************************************************
+ Fast key cache for main game loop
+ ****************************************************************************/
+
+/* This is faster than using getKeySetting with the tradeoff that functions
+ * using it must make sure that it's initialised before using it and there is
+ * no error handling (for example bounds checking). This is really intended for
+ * use only in the main running loop of the client (the_game()) where the faster
+ * (up to 10x faster) key lookup is an asset. Other parts of the codebase
+ * (e.g. formspecs) should continue using getKeySetting().
+ */
+struct KeyCache {
+
+ KeyCache() { populate(); }
+
+ enum {
+ // Player movement
+ KEYMAP_ID_FORWARD,
+ KEYMAP_ID_BACKWARD,
+ KEYMAP_ID_LEFT,
+ KEYMAP_ID_RIGHT,
+ KEYMAP_ID_JUMP,
+ KEYMAP_ID_SPECIAL1,
+ KEYMAP_ID_SNEAK,
+
+ // Other
+ KEYMAP_ID_DROP,
+ KEYMAP_ID_INVENTORY,
+ KEYMAP_ID_CHAT,
+ KEYMAP_ID_CMD,
+ KEYMAP_ID_CONSOLE,
+ KEYMAP_ID_FREEMOVE,
+ KEYMAP_ID_FASTMOVE,
+ KEYMAP_ID_NOCLIP,
+ KEYMAP_ID_SCREENSHOT,
+ KEYMAP_ID_TOGGLE_HUD,
+ KEYMAP_ID_TOGGLE_CHAT,
+ KEYMAP_ID_TOGGLE_FORCE_FOG_OFF,
+ KEYMAP_ID_TOGGLE_UPDATE_CAMERA,
+ KEYMAP_ID_TOGGLE_DEBUG,
+ KEYMAP_ID_TOGGLE_PROFILER,
+ KEYMAP_ID_CAMERA_MODE,
+ KEYMAP_ID_INCREASE_VIEWING_RANGE,
+ KEYMAP_ID_DECREASE_VIEWING_RANGE,
+ KEYMAP_ID_RANGESELECT,
+
+ KEYMAP_ID_QUICKTUNE_NEXT,
+ KEYMAP_ID_QUICKTUNE_PREV,
+ KEYMAP_ID_QUICKTUNE_INC,
+ KEYMAP_ID_QUICKTUNE_DEC,
+
+ KEYMAP_ID_DEBUG_STACKS,
+
+ // Fake keycode for array size and internal checks
+ KEYMAP_INTERNAL_ENUM_COUNT
+
+
+ };
+
+ void populate();
+
+ KeyPress key[KEYMAP_INTERNAL_ENUM_COUNT];
+};
+
+void KeyCache::populate()
+{
+ key[KEYMAP_ID_FORWARD] = getKeySetting("keymap_forward");
+ key[KEYMAP_ID_BACKWARD] = getKeySetting("keymap_backward");
+ key[KEYMAP_ID_LEFT] = getKeySetting("keymap_left");
+ key[KEYMAP_ID_RIGHT] = getKeySetting("keymap_right");
+ key[KEYMAP_ID_JUMP] = getKeySetting("keymap_jump");
+ key[KEYMAP_ID_SPECIAL1] = getKeySetting("keymap_special1");
+ key[KEYMAP_ID_SNEAK] = getKeySetting("keymap_sneak");
+
+ key[KEYMAP_ID_DROP] = getKeySetting("keymap_drop");
+ key[KEYMAP_ID_INVENTORY] = getKeySetting("keymap_inventory");
+ key[KEYMAP_ID_CHAT] = getKeySetting("keymap_chat");
+ key[KEYMAP_ID_CMD] = getKeySetting("keymap_cmd");
+ key[KEYMAP_ID_CONSOLE] = getKeySetting("keymap_console");
+ key[KEYMAP_ID_FREEMOVE] = getKeySetting("keymap_freemove");
+ key[KEYMAP_ID_FASTMOVE] = getKeySetting("keymap_fastmove");
+ key[KEYMAP_ID_NOCLIP] = getKeySetting("keymap_noclip");
+ key[KEYMAP_ID_SCREENSHOT] = getKeySetting("keymap_screenshot");
+ key[KEYMAP_ID_TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
+ key[KEYMAP_ID_TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
+ key[KEYMAP_ID_TOGGLE_FORCE_FOG_OFF]
+ = getKeySetting("keymap_toggle_force_fog_off");
+ key[KEYMAP_ID_TOGGLE_UPDATE_CAMERA]
+ = getKeySetting("keymap_toggle_update_camera");
+ key[KEYMAP_ID_TOGGLE_DEBUG]
+ = getKeySetting("keymap_toggle_debug");
+ key[KEYMAP_ID_TOGGLE_PROFILER]
+ = getKeySetting("keymap_toggle_profiler");
+ key[KEYMAP_ID_CAMERA_MODE]
+ = getKeySetting("keymap_camera_mode");
+ key[KEYMAP_ID_INCREASE_VIEWING_RANGE]
+ = getKeySetting("keymap_increase_viewing_range_min");
+ key[KEYMAP_ID_DECREASE_VIEWING_RANGE]
+ = getKeySetting("keymap_decrease_viewing_range_min");
+ key[KEYMAP_ID_RANGESELECT]
+ = getKeySetting("keymap_rangeselect");
+
+ key[KEYMAP_ID_QUICKTUNE_NEXT] = getKeySetting("keymap_quicktune_next");
+ key[KEYMAP_ID_QUICKTUNE_PREV] = getKeySetting("keymap_quicktune_prev");
+ key[KEYMAP_ID_QUICKTUNE_INC] = getKeySetting("keymap_quicktune_inc");
+ key[KEYMAP_ID_QUICKTUNE_DEC] = getKeySetting("keymap_quicktune_dec");
+
+ key[KEYMAP_ID_DEBUG_STACKS] = getKeySetting("keymap_print_debug_stacks");
+}
+
/****************************************************************************
- THE GAME
+
****************************************************************************/
const float object_hit_delay = 0.2;
};
+/****************************************************************************
+ THE GAME
+ ****************************************************************************/
+
/* This is not intended to be a public class. If a public class becomes
* desirable then it may be better to create another 'wrapper' class that
* hides most of the stuff in this class (nothing in this class is required
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
- gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
bool checkConnection();
bool handleCallbacks();
void processQueues();
+ void updateProfilers(const GameRunData &run_data, const RunStats &stats,
+ const FpsControl &draw_times, f32 dtime);
void addProfilerGraphs(const RunStats &stats, const FpsControl &draw_times,
f32 dtime);
void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
void updateFrame(std::vector<aabb3f> &highlight_boxes, ProfilerGraph *graph,
RunStats *stats, GameRunData *runData,
f32 dtime, const VolatileRunFlags &flags, const CameraOrientation &cam);
- void updateGui(float *statustext_time, const RunStats &stats, f32 dtime,
- const VolatileRunFlags &flags, const CameraOrientation &cam);
+ void updateGui(float *statustext_time, const RunStats &stats,
+ const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
+ const CameraOrientation &cam);
void updateProfilerGraphs(ProfilerGraph *graph);
// Misc
Client *client;
Server *server;
- gui::IGUIFont *font;
-
IWritableTextureSource *texture_src;
IWritableShaderSource *shader_src;
IrrlichtDevice *device;
video::IVideoDriver *driver;
scene::ISceneManager *smgr;
- u32 text_height;
bool *kill;
std::wstring *error_message;
IGameDef *gamedef; // Convenience (same as *client)
std::wstring infotext;
std::wstring statustext;
+
+ KeyCache keycache;
+
+ IntervalLimiter profiler_interval;
+
+ /* TODO: Add a callback function so these can be updated when a setting
+ * changes. At this point in time it doesn't matter (e.g. /set
+ * is documented to change server settings only)
+ *
+ * TODO: Local caching of settings is not optimal and should at some stage
+ * be updated to use a global settings object for getting thse values
+ * (as opposed to the this local caching). This can be addressed in
+ * a later release.
+ */
+ bool m_cache_doubletap_jump;
+ bool m_cache_enable_node_highlighting;
+ bool m_cache_enable_clouds;
+ bool m_cache_enable_particles;
+ bool m_cache_enable_fog;
+ f32 m_cache_mouse_sensitivity;
+ f32 m_repeat_right_click_time;
};
Game::Game() :
client(NULL),
server(NULL),
- font(NULL),
texture_src(NULL),
shader_src(NULL),
itemdef_manager(NULL),
local_inventory(NULL),
hud(NULL)
{
-
+ m_cache_doubletap_jump = g_settings->getBool("doubletap_jump");
+ m_cache_enable_node_highlighting = g_settings->getBool("enable_node_highlighting");
+ m_cache_enable_clouds = g_settings->getBool("enable_clouds");
+ m_cache_enable_particles = g_settings->getBool("enable_particles");
+ m_cache_enable_fog = g_settings->getBool("enable_fog");
+ m_cache_mouse_sensitivity = g_settings->getFloat("mouse_sensitivity");
+ m_repeat_right_click_time = g_settings->getFloat("repeat_rightclick_time");
}
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
- gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
{
// "cache"
this->device = device;
- this->font = font;
this->kill = kill;
this->error_message = error_message;
this->random_input = random_input;
driver = device->getVideoDriver();
smgr = device->getSceneManager();
- text_height = font->getDimension(L"Random test string").Height;
+
+ smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
if (!init(map_dir, address, port, gamespec))
return false;
infotext = L"";
hud->resizeHotbar();
- addProfilerGraphs(stats, draw_times, dtime);
+
+ updateProfilers(runData, stats, draw_times, dtime);
processUserInput(&flags, &runData, dtime);
// Update camera before player movement to avoid camera lag of one frame
updateCameraDirection(&cam_view, &flags);
}
// Update cached textures, meshes and materials
- client->afterContentReceived(device, font);
+ client->afterContentReceived(device, g_fontengine->getFont());
/* Camera
*/
/* Clouds
*/
- if (g_settings->getBool("enable_clouds")) {
+ if (m_cache_enable_clouds) {
clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, time(0));
if (!clouds) {
*error_message = L"Memory allocation error";
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
- hud = new Hud(driver, smgr, guienv, font, text_height, gamedef,
- player, local_inventory);
+ hud = new Hud(driver, smgr, guienv, gamedef, player, local_inventory);
if (!hud) {
*error_message = L"Memory error: could not create HUD";
// Object infos are shown in this
guitext_info = guienv->addStaticText(
L"",
- core::rect<s32>(0, 0, 400, text_height * 5 + 5) + v2s32(100, 200),
+ core::rect<s32>(0, 0, 400, g_fontengine->getTextHeight() * 5 + 5) + v2s32(100, 200),
false, true, guiroot);
// Status text (displays info when showing and hiding GUI stuff, etc.)
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
- g_touchscreengui->init(tsrc, porting::getDisplayDensity());
+ g_touchscreengui->init(texture_src, porting::getDisplayDensity());
#endif
return false;
}
- client = new Client(device, playername.c_str(), password, *draw_control,
- texture_src, shader_src, itemdef_manager, nodedef_manager, sound,
- eventmgr, connect_address.isIPv6());
+ client = new Client(device,
+ playername.c_str(), password, simple_singleplayer_mode,
+ *draw_control, texture_src, shader_src,
+ itemdef_manager, nodedef_manager, sound, eventmgr,
+ connect_address.isIPv6());
if (!client)
return false;
if (!client->itemdefReceived()) {
wchar_t *text = wgettext("Item definitions...");
progress = 0;
- draw_load_screen(text, device, guienv, font, dtime, progress);
+ draw_load_screen(text, device, guienv, dtime, progress);
delete[] text;
} else if (!client->nodedefReceived()) {
wchar_t *text = wgettext("Node definitions...");
progress = 25;
- draw_load_screen(text, device, guienv, font, dtime, progress);
+ draw_load_screen(text, device, guienv, dtime, progress);
delete[] text;
} else {
std::stringstream message;
progress = 50 + client->mediaReceiveProgress() * 50 + 0.5;
draw_load_screen(narrow_to_wide(message.str().c_str()), device,
- guienv, font, dtime, progress);
+ guienv, dtime, progress);
}
}
g_gamecallback->keyconfig_requested = false;
}
+ if (g_gamecallback->keyconfig_changed) {
+ keycache.populate(); // update the cache with new settings
+ g_gamecallback->keyconfig_changed = false;
+ }
+
return true;
}
}
+void Game::updateProfilers(const GameRunData &run_data, const RunStats &stats,
+ const FpsControl &draw_times, f32 dtime)
+{
+ float profiler_print_interval =
+ g_settings->getFloat("profiler_print_interval");
+ bool print_to_log = true;
+
+ if (profiler_print_interval == 0) {
+ print_to_log = false;
+ profiler_print_interval = 5;
+ }
+
+ if (profiler_interval.step(dtime, profiler_print_interval)) {
+ if (print_to_log) {
+ infostream << "Profiler:" << std::endl;
+ g_profiler->print(infostream);
+ }
+
+ update_profiler_gui(guitext_profiler, g_fontengine,
+ run_data.profiler_current_page, run_data.profiler_max_page,
+ driver->getScreenSize().Height);
+
+ g_profiler->clear();
+ }
+
+ addProfilerGraphs(stats, draw_times, dtime);
+}
+
+
void Game::addProfilerGraphs(const RunStats &stats,
const FpsControl &draw_times, f32 dtime)
{
#endif
// Increase timer for double tap of "keymap_jump"
- if (g_settings->getBool("doubletap_jump") && interact_args->jump_timer <= 0.2)
+ if (m_cache_doubletap_jump && interact_args->jump_timer <= 0.2)
interact_args->jump_timer += dtime;
processKeyboardInput(
u32 *profiler_current_page,
u32 profiler_max_page)
{
- if (input->wasKeyDown(getKeySetting("keymap_drop"))) {
+
+ //TimeTaker tt("process kybd input", NULL, PRECISION_NANO);
+
+ if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DROP])) {
dropSelectedItem();
- } else if (input->wasKeyDown(getKeySetting("keymap_inventory"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INVENTORY])) {
openInventory();
} else if (input->wasKeyDown(EscapeKey) || input->wasKeyDown(CancelKey)) {
show_pause_menu(¤t_formspec, client, gamedef, texture_src, device,
simple_singleplayer_mode);
- } else if (input->wasKeyDown(getKeySetting("keymap_chat"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CHAT])) {
show_chat_menu(¤t_formspec, client, gamedef, texture_src, device,
client, "");
- } else if (input->wasKeyDown(getKeySetting("keymap_cmd"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CMD])) {
show_chat_menu(¤t_formspec, client, gamedef, texture_src, device,
client, "/");
- } else if (input->wasKeyDown(getKeySetting("keymap_console"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CONSOLE])) {
openConsole();
- } else if (input->wasKeyDown(getKeySetting("keymap_freemove"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_FREEMOVE])) {
toggleFreeMove(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_jump"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP])) {
toggleFreeMoveAlt(statustext_time, jump_timer);
*reset_jump_timer = true;
- } else if (input->wasKeyDown(getKeySetting("keymap_fastmove"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_FASTMOVE])) {
toggleFast(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_noclip"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_NOCLIP])) {
toggleNoClip(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_screenshot"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_SCREENSHOT])) {
client->makeScreenshot(device);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_hud"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
toggleHud(statustext_time, &flags->show_hud);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_chat"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_CHAT])) {
toggleChat(statustext_time, &flags->show_chat);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_force_fog_off"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_FORCE_FOG_OFF])) {
toggleFog(statustext_time, &flags->force_fog_off);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_update_camera"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_UPDATE_CAMERA])) {
toggleUpdateCamera(statustext_time, &flags->disable_camera_update);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_debug"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_DEBUG])) {
toggleDebug(statustext_time, &flags->show_debug, &flags->show_profiler_graph);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_profiler"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_PROFILER])) {
toggleProfiler(statustext_time, profiler_current_page, profiler_max_page);
- } else if (input->wasKeyDown(getKeySetting("keymap_increase_viewing_range_min"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INCREASE_VIEWING_RANGE])) {
increaseViewRange(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_decrease_viewing_range_min"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DECREASE_VIEWING_RANGE])) {
decreaseViewRange(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_rangeselect"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_RANGESELECT])) {
toggleFullViewRange(statustext_time);
- }
-
- // Handle QuicktuneShortcutter
- if (input->wasKeyDown(getKeySetting("keymap_quicktune_next")))
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_NEXT]))
quicktune->next();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_prev")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_PREV]))
quicktune->prev();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_inc")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_INC]))
quicktune->inc();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_dec")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_DEC]))
quicktune->dec();
-
- std::string msg = quicktune->getMessage();
- if (msg != "") {
- statustext = narrow_to_wide(msg);
- *statustext_time = 0;
- }
-
- // Print debug stacks
- if (input->wasKeyDown(getKeySetting("keymap_print_debug_stacks"))) {
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DEBUG_STACKS])) {
+ // Print debug stacks
dstream << "-----------------------------------------"
<< std::endl;
dstream << DTIME << "Printing debug stacks:" << std::endl;
*reset_jump_timer = false;
*jump_timer = 0.0;
}
+
+ //tt.stop();
+
+ if (quicktune->hasMessage()) {
+ std::string msg = quicktune->getMessage();
+ statustext = narrow_to_wide(msg);
+ *statustext_time = 0;
+ }
}
void Game::toggleFreeMoveAlt(float *statustext_time, float *jump_timer)
{
- if (g_settings->getBool("doubletap_jump") && *jump_timer < 0.2f)
+ if (m_cache_doubletap_jump && *jump_timer < 0.2f)
toggleFreeMove(statustext_time);
}
*flag = !*flag;
*statustext_time = 0;
statustext = msg[*flag];
- client->setHighlighted(client->getHighlighted(), *flag);
+ if (g_settings->getBool("enable_node_highlighting"))
+ client->setHighlighted(client->getHighlighted(), *flag);
}
*profiler_current_page = (*profiler_current_page + 1) % (profiler_max_page + 1);
// FIXME: This updates the profiler with incomplete values
- update_profiler_gui(guitext_profiler, font, text_height,
- *profiler_current_page, profiler_max_page);
+ update_profiler_gui(guitext_profiler, g_fontengine, *profiler_current_page,
+ profiler_max_page, driver->getScreenSize().Height);
if (*profiler_current_page != 0) {
std::wstringstream sstr;
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
- camera_yaw = g_touchscreengui->getYaw();
- camera_pitch = g_touchscreengui->getPitch();
+ cam->camera_yaw = g_touchscreengui->getYaw();
+ cam->camera_pitch = g_touchscreengui->getPitch();
} else {
#endif
s32 dx = input->getMousePos().X - (driver->getScreenSize().Width / 2);
//infostream<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
- float d = g_settings->getFloat("mouse_sensitivity");
+ float d = m_cache_mouse_sensitivity;
d = rangelim(d, 0.01, 100.0);
cam->camera_yaw -= dx * d;
cam->camera_pitch += dy * d;
void Game::updatePlayerControl(const CameraOrientation &cam)
{
+ //TimeTaker tt("update player control", NULL, PRECISION_NANO);
+
PlayerControl control(
- input->isKeyDown(getKeySetting("keymap_forward")),
- input->isKeyDown(getKeySetting("keymap_backward")),
- input->isKeyDown(getKeySetting("keymap_left")),
- input->isKeyDown(getKeySetting("keymap_right")),
- input->isKeyDown(getKeySetting("keymap_jump")),
- input->isKeyDown(getKeySetting("keymap_special1")),
- input->isKeyDown(getKeySetting("keymap_sneak")),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_FORWARD]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_BACKWARD]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_LEFT]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_RIGHT]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SPECIAL1]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SNEAK]),
input->getLeftState(),
input->getRightState(),
cam.camera_pitch,
client->setPlayerControl(control);
LocalPlayer *player = client->getEnv().getLocalPlayer();
player->keyPressed =
- ( (u32)(input->isKeyDown(getKeySetting("keymap_forward")) & 0x1) << 0) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_backward")) & 0x1) << 1) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_left")) & 0x1) << 2) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_right")) & 0x1) << 3) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_jump")) & 0x1) << 4) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_special1")) & 0x1) << 5) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_sneak")) & 0x1) << 6) |
- ( (u32)(input->getLeftState() & 0x1) << 7) |
- ( (u32)(input->getRightState() & 0x1) << 8
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_FORWARD]) & 0x1) << 0) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_BACKWARD]) & 0x1) << 1) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_LEFT]) & 0x1) << 2) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_RIGHT]) & 0x1) << 3) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP]) & 0x1) << 4) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SPECIAL1]) & 0x1) << 5) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SNEAK]) & 0x1) << 6) |
+ ( (u32)(input->getLeftState() & 0x1) << 7) |
+ ( (u32)(input->getRightState() & 0x1) << 8
);
+ //tt.stop();
}
v3s16 old_camera_offset = camera->getOffset();
- if (input->wasKeyDown(getKeySetting("keymap_camera_mode"))) {
+ if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
camera->toggleCameraMode();
GenericCAO *playercao = player->getCAO();
if (pointed != runData->pointed_old) {
infostream << "Pointing at " << pointed.dump() << std::endl;
- if (g_settings->getBool("enable_node_highlighting")) {
+ if (m_cache_enable_node_highlighting) {
if (pointed.type == POINTEDTHING_NODE) {
client->setHighlighted(pointed.node_undersurface, show_hud);
} else {
if (meta) {
infotext = narrow_to_wide(meta->getString("infotext"));
} else {
- MapNode n = map.getNode(nodepos);
+ MapNode n = map.getNodeNoEx(nodepos);
if (nodedef_manager->get(n).tiledef[0].name == "unknown_node.png") {
infotext = L"Unknown node: ";
}
if ((input->getRightClicked() ||
- runData->repeat_rightclick_timer >=
- g_settings->getFloat("repeat_rightclick_time")) &&
+ runData->repeat_rightclick_timer >= m_repeat_right_click_time) &&
client->checkPrivilege("interact")) {
runData->repeat_rightclick_timer = 0;
infostream << "Ground right-clicked" << std::endl;
}
if (playeritem_def.node_placement_prediction == "" ||
- nodedef_manager->get(map.getNode(nodepos)).rightclickable)
+ nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable)
client->interact(3, pointed); // Report to server
}
}
LocalPlayer *player = client->getEnv().getLocalPlayer();
ClientMap &map = client->getEnv().getClientMap();
- MapNode n = client->getEnv().getClientMap().getNode(nodepos);
+ MapNode n = client->getEnv().getClientMap().getNodeNoEx(nodepos);
// NOTE: Similar piece of code exists on the server side for
// cheat detection.
} else {
runData->dig_time_complete = params.time;
- if (g_settings->getBool("enable_particles")) {
+ if (m_cache_enable_particles) {
const ContentFeatures &features =
client->getNodeDefManager()->get(n);
addPunchingParticles(gamedef, smgr, player,
infostream << "Digging completed" << std::endl;
client->interact(2, pointed);
client->setCrack(-1, v3s16(0, 0, 0));
- MapNode wasnode = map.getNode(nodepos);
- client->removeNode(nodepos);
+ bool is_valid_position;
+ MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position);
+ if (is_valid_position)
+ client->removeNode(nodepos);
- if (g_settings->getBool("enable_particles")) {
+ if (m_cache_enable_particles) {
const ContentFeatures &features =
client->getNodeDefManager()->get(wasnode);
addDiggingParticles
Fog
*/
- if (g_settings->getBool("enable_fog") && !flags.force_fog_off) {
+ if (m_cache_enable_fog && !flags.force_fog_off) {
driver->setFog(
sky->getBgColor(),
video::EFT_FOG_LINEAR,
updateChat(*client, dtime, flags.show_debug, screensize,
flags.show_chat, runData->profiler_current_page,
- *chat_backend, guitext_chat, font);
+ *chat_backend, guitext_chat);
/*
Inventory
runData->update_draw_list_last_cam_dir = camera_direction;
}
- updateGui(&runData->statustext_time, *stats, dtime, flags, cam);
+ updateGui(&runData->statustext_time, *stats, *runData, dtime, flags, cam);
/*
make sure menu is on top
Profiler graph
*/
if (flags.show_profiler_graph)
- graph->draw(10, screensize.Y - 10, driver, font);
+ graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());
/*
Damage flash
}
-void Game::updateGui(float *statustext_time, const RunStats& stats,
- f32 dtime, const VolatileRunFlags &flags, const CameraOrientation &cam)
+void Game::updateGui(float *statustext_time, const RunStats &stats,
+ const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
+ const CameraOrientation &cam)
{
v2u32 screensize = driver->getScreenSize();
LocalPlayer *player = client->getEnv().getLocalPlayer();
if (guitext->isVisible()) {
core::rect<s32> rect(
5, 5,
- screensize.X, 5 + text_height
+ screensize.X, 5 + g_fontengine->getTextHeight()
);
guitext->setRelativePosition(rect);
}
<< ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw))
<< ") (seed = " << ((u64)client->getMapSeed())
<< ")";
+
+ if (runData.pointed_old.type == POINTEDTHING_NODE) {
+ ClientMap &map = client->getEnv().getClientMap();
+ const INodeDefManager *nodedef = client->getNodeDefManager();
+ MapNode n = map.getNodeNoEx(runData.pointed_old.node_undersurface);
+ if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
+ const ContentFeatures &features = nodedef->get(n);
+ os << " (pointing_at = " << nodedef->get(n).name
+ << " - " << features.tiledef[0].name.c_str()
+ << ")";
+ }
+ }
+
guitext2->setText(narrow_to_wide(os.str()).c_str());
guitext2->setVisible(true);
core::rect<s32> rect(
- 5, 5 + text_height,
- screensize.X, 5 + text_height * 2
+ 5, 5 + g_fontengine->getTextHeight(),
+ screensize.X, 5 + g_fontengine->getTextHeight() * 2
);
guitext2->setRelativePosition(rect);
} else {
int percent, bool draw_clouds)
{
wchar_t *text = wgettext(msg);
- draw_load_screen(text, device, guienv, font, dtime, percent, draw_clouds);
+ draw_load_screen(text, device, guienv, dtime, percent, draw_clouds);
delete[] text;
}
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
- gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
try {
- if (game.startup(kill, random_input, input, device, font, map_dir,
+ if (game.startup(kill, random_input, input, device, map_dir,
playername, password, &server_address, port,
&error_message, &chat_backend, gamespec,
simple_singleplayer_mode)) {