#include "game.h"
#include <iomanip>
+#include <cmath>
+#include "client/renderingengine.h"
#include "camera.h"
#include "client.h"
#include "client/inputhandler.h"
#include "clouds.h"
#include "config.h"
#include "content_cao.h"
-#include "drawscene.h"
#include "event_manager.h"
#include "fontengine.h"
#include "itemdef.h"
#include "guiVolumeChange.h"
#include "mainmenumanager.h"
#include "mapblock.h"
+#include "minimap.h"
#include "nodedef.h" // Needed for determining pointing to nodes
#include "nodemetadata.h"
#include "particles.h"
#include "profiler.h"
#include "quicktune_shortcutter.h"
+#include "raycast.h"
#include "server.h"
#include "settings.h"
+#include "shader.h"
#include "sky.h"
#include "subgame.h"
#include "tool.h"
#include "sound_openal.h"
#endif
-extern Settings *g_settings;
-extern Profiler *g_profiler;
/*
Text input system
struct LocalFormspecHandler : public TextDest
{
- LocalFormspecHandler(const std::string &formname):
- m_client(NULL)
+ LocalFormspecHandler(const std::string &formname)
{
m_formname = formname;
}
if (fields.find("btn_exit_os") != fields.end()) {
g_gamecallback->exitToOS();
+#ifndef __ANDROID__
+ RenderingEngine::get_raw_device()->closeDevice();
+#endif
return;
}
}
// Don't disable this part when modding is disabled, it's used in builtin
- m_client->getScript()->on_formspec_input(m_formname, fields);
+ if (m_client && m_client->getScript())
+ m_client->getScript()->on_formspec_input(m_formname, fields);
}
- Client *m_client;
+ Client *m_client = nullptr;
};
/* Form update callback */
setStaticText(guitext_profiler, text.c_str());
guitext_profiler->setVisible(true);
- s32 w = fe->getTextWidth(text.c_str());
+ s32 w = fe->getTextWidth(text);
if (w < 400)
w = 400;
};
std::deque<Piece> m_log;
public:
- u32 m_log_max_size;
+ u32 m_log_max_size = 200;
- ProfilerGraph():
- m_log_max_size(200)
- {}
+ ProfilerGraph() = default;
void put(const Profiler::GraphValues &values)
{
// to be the same for each call to prevent flickering
std::map<std::string, Meta> m_meta;
- for (std::deque<Piece>::const_iterator k = m_log.begin();
- k != m_log.end(); ++k) {
- const Piece &piece = *k;
-
- for (Profiler::GraphValues::const_iterator i = piece.values.begin();
- i != piece.values.end(); ++i) {
- const std::string &id = i->first;
- const float &value = i->second;
+ for (const Piece &piece : m_log) {
+ for (const auto &i : piece.values) {
+ const std::string &id = i.first;
+ const float &value = i.second;
std::map<std::string, Meta>::iterator j = m_meta.find(id);
if (j == m_meta.end()) {
sizeof(usable_colors) / sizeof(*usable_colors);
u32 next_color_i = 0;
- for (std::map<std::string, Meta>::iterator i = m_meta.begin();
- i != m_meta.end(); ++i) {
- Meta &meta = i->second;
+ for (auto &i : m_meta) {
+ Meta &meta = i.second;
video::SColor color(255, 200, 200, 200);
if (next_color_i < usable_colors_count)
float lastscaledvalue = 0.0;
bool lastscaledvalue_exists = false;
- for (std::deque<Piece>::const_iterator j = m_log.begin();
- j != m_log.end(); ++j) {
- const Piece &piece = *j;
+ for (const Piece &piece : m_log) {
float value = 0;
bool value_exists = false;
Profiler::GraphValues::const_iterator k =
minimap_yaw.getAs3Values(minimap_yaw_array);
#endif
m_minimap_yaw.set(minimap_yaw_array, services);
-
}
SamplerLayer_t base_tex = 0,
void setSky(Sky *sky) {
m_sky = sky;
- for (size_t i = 0; i < created_nosky.size(); ++i) {
- created_nosky[i]->setSky(m_sky);
+ for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
+ ggscs->setSky(m_sky);
}
created_nosky.clear();
}
if (!is_valid_position)
return false;
- if (prediction != "" && !nodedef->get(node).rightclickable) {
+ if (!prediction.empty() && !nodedef->get(node).rightclickable) {
verbosestream << "Node placement prediction for "
<< playeritem_def.name << " is "
<< prediction << std::endl;
}
static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
- Client *client, IrrlichtDevice *device, JoystickController *joystick,
+ Client *client, JoystickController *joystick,
IFormSource *fs_src, TextDest *txt_dest)
{
if (*cur_formspec == 0) {
- *cur_formspec = new GUIFormSpecMenu(device, joystick,
- guiroot, -1, &g_menumgr, client, client->getTextureSource(),
- fs_src, txt_dest);
+ *cur_formspec = new GUIFormSpecMenu(joystick, guiroot, -1, &g_menumgr,
+ client, client->getTextureSource(), fs_src, txt_dest);
(*cur_formspec)->doPause = false;
/*
// Get new messages from client
std::wstring message;
-
while (client.getChatMessage(message)) {
chat_backend.addUnparsedMessage(message);
}
s32 chat_y = 5;
if (show_debug)
- chat_y += 2 * line_height;
+ chat_y += 3 * line_height;
// first pass to calculate height of text to be set
+ const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
s32 width = std::min(g_fontengine->getTextWidth(recent_chat.c_str()) + 10,
- porting::getWindowSize().X - 20);
- core::rect<s32> rect(10, chat_y, width, chat_y + porting::getWindowSize().Y);
+ window_size.X - 20);
+ core::rect<s32> rect(10, chat_y, width, chat_y + window_size.Y);
guitext_chat->setRelativePosition(rect);
//now use real height of text and adjust rect according to this size
key[KeyType::DEBUG_STACKS] = getKeySetting("keymap_print_debug_stacks");
+ for (int i = 0; i < 23; i++) {
+ std::string slot_key_name = "keymap_slot" + std::to_string(i + 1);
+ key[KeyType::SLOT_1 + i] = getKeySetting(slot_key_name.c_str());
+ }
+
if (handler) {
// First clear all keys, then re-add the ones we listen for
handler->dontListenForKeys();
- for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) {
- handler->listenForKey(key[i]);
+ for (const KeyPress &k : key) {
+ handler->listenForKey(k);
}
handler->listenForKey(EscapeKey);
handler->listenForKey(CancelKey);
- for (size_t i = 0; i < 10; i++) {
- handler->listenForKey(NumberKey[i]);
- }
}
}
bool digging;
bool ldown_for_dig;
bool dig_instantly;
+ bool digging_blocked;
bool left_punch;
bool update_wielded_item_trigger;
bool reset_jump_timer;
bool startup(bool *kill,
bool random_input,
InputHandler *input,
- IrrlichtDevice *device,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
// Misc
void limitFps(FpsControl *fps_timings, f32 *dtime);
- void showOverlayMessage(const wchar_t *msg, float dtime, int percent,
+ void showOverlayMessage(const char *msg, float dtime, int percent,
bool draw_clouds = true);
static void settingChangedCallback(const std::string &setting_name, void *data);
GameOnDemandSoundFetcher soundfetcher; // useful when testing
ISoundManager *sound;
- bool sound_is_dummy;
+ bool sound_is_dummy = false;
SoundMaker *soundmaker;
ChatBackend *chat_backend;
*/
gui::IGUIStaticText *guitext; // First line of debug text
gui::IGUIStaticText *guitext2; // Second line of debug text
+ gui::IGUIStaticText *guitext3; // Third line of debug text
gui::IGUIStaticText *guitext_info; // At the middle of the screen
gui::IGUIStaticText *guitext_status;
gui::IGUIStaticText *guitext_chat; // Chat text
f32 m_cache_cam_smoothing;
f32 m_cache_fog_start;
- bool m_invert_mouse;
- bool m_first_loop_after_window_activation;
- bool m_camera_offset_changed;
+ bool m_invert_mouse = false;
+ bool m_first_loop_after_window_activation = false;
+ bool m_camera_offset_changed = false;
#ifdef __ANDROID__
bool m_cache_hold_aux1;
itemdef_manager(NULL),
nodedef_manager(NULL),
sound(NULL),
- sound_is_dummy(false),
soundmaker(NULL),
chat_backend(NULL),
current_formspec(NULL),
sky(NULL),
local_inventory(NULL),
hud(NULL),
- mapper(NULL),
- m_invert_mouse(false),
- m_first_loop_after_window_activation(false),
- m_camera_offset_changed(false)
+ mapper(NULL)
{
g_settings->registerChangedCallback("doubletap_jump",
&settingChangedCallback, this);
bool Game::startup(bool *kill,
bool random_input,
InputHandler *input,
- IrrlichtDevice *device,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
bool simple_singleplayer_mode)
{
// "cache"
- this->device = device;
+ this->device = RenderingEngine::get_raw_device();
this->kill = kill;
this->error_message = &error_message;
this->reconnect_requested = reconnect;
keycache.handler = input;
keycache.populate();
- driver = device->getVideoDriver();
- smgr = device->getSceneManager();
+ driver = device->getVideoDriver();
+ smgr = RenderingEngine::get_scene_manager();
- smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
+ RenderingEngine::get_scene_manager()->getParameters()->
+ setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
memset(&runData, 0, sizeof(runData));
runData.time_from_last_punch = 10.0;
Profiler::GraphValues dummyvalues;
g_profiler->graphGet(dummyvalues);
- draw_times.last_time = device->getTimer()->getTime();
+ draw_times.last_time = RenderingEngine::get_timer_time();
set_light_table(g_settings->getFloat("display_gamma"));
irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"),
g_settings->getU16("screen_h"));
- while (device->run()
+ while (RenderingEngine::run()
&& !(*kill || g_gamecallback->shutdown_requested
|| (server && server->getShutdownRequested()))) {
const irr::core::dimension2d<u32> ¤t_screen_size =
- device->getVideoDriver()->getScreenSize();
+ RenderingEngine::get_video_driver()->getScreenSize();
// Verify if window size has changed and save it if it's the case
// Ensure evaluating settings->getBool after verifying screensize
// First condition is cheaper
if (current_formspec)
current_formspec->quitMenu();
- showOverlayMessage(wgettext("Shutting down..."), 0, 0, false);
+ showOverlayMessage("Shutting down...", 0, 0, false);
if (clouds)
clouds->drop();
u16 port,
const SubgameSpec &gamespec)
{
- texture_src = createTextureSource(device);
+ texture_src = createTextureSource();
- showOverlayMessage(wgettext("Loading..."), 0, 0);
+ showOverlayMessage("Loading...", 0, 0);
- shader_src = createShaderSource(device);
+ shader_src = createShaderSource();
itemdef_manager = createItemDefManager();
nodedef_manager = createNodeDefManager();
return false;
// Create a server if not connecting to an existing one
- if (*address == "") {
+ if (address->empty()) {
if (!createSingleplayerServer(map_dir, gamespec, port, address))
return false;
}
bool Game::createSingleplayerServer(const std::string &map_dir,
const SubgameSpec &gamespec, u16 port, std::string *address)
{
- showOverlayMessage(wgettext("Creating server..."), 0, 5);
+ showOverlayMessage("Creating server...", 0, 5);
std::string bind_str = g_settings->get("bind_address");
Address bind_addr(0, 0, 0, 0, port);
bool Game::createClient(const std::string &playername,
const std::string &password, std::string *address, u16 port)
{
- showOverlayMessage(wgettext("Creating client..."), 0, 10);
+ showOverlayMessage("Creating client...", 0, 10);
draw_control = new MapDrawControl;
if (!draw_control)
shader_src->addShaderConstantSetterFactory(scsf);
// Update cached textures, meshes and materials
- client->afterContentReceived(device);
+ client->afterContentReceived();
/* Camera
*/
- camera = new Camera(smgr, *draw_control, client);
+ camera = new Camera(*draw_control, client);
if (!camera || !camera->successfullyCreated(*error_message))
return false;
client->setCamera(camera);
/* Clouds
*/
if (m_cache_enable_clouds) {
- clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, time(0));
+ clouds = new Clouds(smgr, -1, time(0));
if (!clouds) {
*error_message = "Memory allocation error (clouds)";
errorstream << *error_message << std::endl;
/* Skybox
*/
- sky = new Sky(smgr->getRootSceneNode(), smgr, -1, texture_src);
+ sky = new Sky(-1, texture_src);
scsf->setSky(sky);
skybox = NULL; // This is used/set later on in the main run loop
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
- hud = new Hud(driver, smgr, guienv, client, player, local_inventory);
+ hud = new Hud(guienv, client, player, local_inventory);
if (!hud) {
*error_message = "Memory error: could not create HUD";
core::rect<s32>(0, 0, 0, 0),
false, false, guiroot);
+ // Third line of debug text
+ guitext3 = addStaticText(guienv,
+ L"",
+ core::rect<s32>(0, 0, 0, 0),
+ false, false, guiroot);
+
// At the middle of the screen
// Object infos are shown in this
guitext_info = addStaticText(guienv,
*aborted = false;
bool local_server_mode = false;
- showOverlayMessage(wgettext("Resolving address..."), 0, 15);
+ showOverlayMessage("Resolving address...", 0, 15);
Address connect_address(0, 0, 0, 0, port);
return false;
}
- client = new Client(device,
- playername.c_str(), password, *address,
+ client = new Client(playername.c_str(), password, *address,
*draw_control, texture_src, shader_src,
itemdef_manager, nodedef_manager, sound, eventmgr,
connect_address.isIPv6(), &flags);
f32 dtime;
f32 wait_time = 0; // in seconds
- fps_control.last_time = device->getTimer()->getTime();
+ fps_control.last_time = RenderingEngine::get_timer_time();
+ client->loadMods();
client->initMods();
- while (device->run()) {
+ while (RenderingEngine::run()) {
limitFps(&fps_control, &dtime);
wait_time += dtime;
// Only time out if we aren't waiting for the server we started
- if ((*address != "") && (wait_time > 10)) {
+ if ((!address->empty()) && (wait_time > 10)) {
bool sent_old_init = g_settings->getFlag("send_pre_v25_init");
// If no pre v25 init was sent, and no answer was received,
// but the low level connection could be established
}
// Update status
- showOverlayMessage(wgettext("Connecting to server..."), dtime, 20);
+ showOverlayMessage("Connecting to server...", dtime, 20);
}
} catch (con::PeerNotFoundException &e) {
// TODO: Should something be done here? At least an info/error
FpsControl fps_control = { 0 };
f32 dtime; // in seconds
- fps_control.last_time = device->getTimer()->getTime();
+ fps_control.last_time = RenderingEngine::get_timer_time();
- while (device->run()) {
+ while (RenderingEngine::run()) {
limitFps(&fps_control, &dtime);
if (!client->itemdefReceived()) {
const wchar_t *text = wgettext("Item definitions...");
progress = 25;
- draw_load_screen(text, device, guienv, texture_src,
+ RenderingEngine::draw_load_screen(text, guienv, texture_src,
dtime, progress);
delete[] text;
} else if (!client->nodedefReceived()) {
const wchar_t *text = wgettext("Node definitions...");
progress = 30;
- draw_load_screen(text, device, guienv, texture_src,
+ RenderingEngine::draw_load_screen(text, guienv, texture_src,
dtime, progress);
delete[] text;
} else {
}
progress = 30 + client->mediaReceiveProgress() * 35 + 0.5;
- draw_load_screen(utf8_to_wide(message.str()), device,
- guienv, texture_src, dtime, progress);
+ RenderingEngine::draw_load_screen(utf8_to_wide(message.str()), guienv,
+ texture_src, dtime, progress);
}
}
*new_playeritem = *new_playeritem > 0 ? *new_playeritem - 1 : max_item;
// else dir == 0
- /* Item selection using keyboard
+ /* Item selection using hotbar slot keys
*/
- for (u16 i = 0; i < 10; i++) {
- static const KeyPress *item_keys[10] = {
- NumberKey + 1, NumberKey + 2, NumberKey + 3, NumberKey + 4,
- NumberKey + 5, NumberKey + 6, NumberKey + 7, NumberKey + 8,
- NumberKey + 9, NumberKey + 0,
- };
-
- if (input->wasKeyDown(*item_keys[i])) {
+ for (u16 i = 0; i < 23; i++) {
+ if (wasKeyDown((GameKeyType) (KeyType::SLOT_1 + i))) {
if (i < PLAYER_INVENTORY_SIZE && i < player->hud_hotbar_itemcount) {
*new_playeritem = i;
infostream << "Selected item: " << new_playeritem << std::endl;
PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client);
TextDest *txt_dst = new TextDestPlayerInventory(client);
- create_formspec_menu(¤t_formspec, client, device, &input->joystick, fs_src, txt_dst);
+ create_formspec_menu(¤t_formspec, client, &input->joystick, fs_src, txt_dst);
cur_formname = "";
InventoryLocation inventoryloc;
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;
}
flags.show_minimap = true;
void Game::toggleFullViewRange()
{
static const wchar_t *msg[] = {
- L"Disabled full viewing range",
- L"Enabled full viewing range"
+ L"Normal view range",
+ L"Infinite view range"
};
draw_control->range_all = !draw_control->range_all;
break;
case CE_SHOW_FORMSPEC:
- if (*(event.show_formspec.formspec) == "") {
- if (current_formspec && ( *(event.show_formspec.formname) == "" || *(event.show_formspec.formname) == cur_formname) ){
+ if (event.show_formspec.formspec->empty()) {
+ if (current_formspec && (event.show_formspec.formname->empty()
+ || *(event.show_formspec.formname) == cur_formname)) {
current_formspec->quitMenu();
}
} else {
TextDestPlayerInventory *txt_dst =
new TextDestPlayerInventory(client, *(event.show_formspec.formname));
- create_formspec_menu(¤t_formspec, client, device, &input->joystick,
+ create_formspec_menu(¤t_formspec, client, &input->joystick,
fs_src, txt_dst);
cur_formname = *(event.show_formspec.formname);
}
{
FormspecFormSource *fs_src = new FormspecFormSource(*event.show_formspec.formspec);
LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event.show_formspec.formname, client);
- create_formspec_menu(¤t_formspec, client, device, &input->joystick,
+ create_formspec_menu(¤t_formspec, client, &input->joystick,
fs_src, txt_dst);
}
delete event.show_formspec.formspec;
case CE_SPAWN_PARTICLE:
case CE_ADD_PARTICLESPAWNER:
case CE_DELETE_PARTICLESPAWNER:
- client->getParticleManager()->handleParticleEvent(&event, client,
- smgr, player);
+ client->getParticleManager()->handleParticleEvent(&event, client, player);
break;
case CE_HUDADD:
} else if (*event.set_sky.type == "skybox" &&
event.set_sky.params->size() == 6) {
sky->setFallbackBgColor(*event.set_sky.bgcolor);
- skybox = smgr->addSkyBoxSceneNode(
+ skybox = RenderingEngine::get_scene_manager()->addSkyBoxSceneNode(
texture_src->getTextureForMesh((*event.set_sky.params)[0]),
texture_src->getTextureForMesh((*event.set_sky.params)[1]),
texture_src->getTextureForMesh((*event.set_sky.params)[2]),
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
- camera->update(player, dtime, busy_time / 1000.0f, tool_reload_ratio,
- client->getEnv());
+ camera->update(player, dtime, busy_time / 1000.0f, tool_reload_ratio);
camera->step(dtime);
v3f camera_position = camera->getPosition();
hud->updateSelectionMesh(camera_offset);
}
+ if (runData.digging_blocked && !isLeftPressed()) {
+ // allow digging again if button is not pressed
+ runData.digging_blocked = false;
+ }
+
/*
Stop digging when
- releasing left mouse button
soundmaker->m_player_leftpunch_sound.name = "";
- if (isRightPressed())
+ // Prepare for repeating, unless we're not supposed to
+ if (isRightPressed() && !g_settings->getBool("safe_dig_and_place"))
runData.repeat_rightclick_timer += dtime;
else
runData.repeat_rightclick_timer = 0;
static thread_local const bool show_entity_selectionbox = g_settings->getBool(
"show_entity_selectionbox");
- ClientMap &map = client->getEnv().getClientMap();
- INodeDefManager *nodedef=client->getNodeDefManager();
+ ClientEnvironment &env = client->getEnv();
+ ClientMap &map = env.getClientMap();
+ INodeDefManager *nodedef = map.getNodeDefManager();
runData.selected_object = NULL;
- PointedThing result=client->getEnv().getPointedThing(
- shootline, liquids_pointable, look_for_object);
+ RaycastState s(shootline, look_for_object, liquids_pointable);
+ PointedThing result;
+ env.continueRaycast(&s, &result);
if (result.type == POINTEDTHING_OBJECT) {
runData.selected_object = client->getEnv().getActiveObject(result.object_id);
- if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox()) {
- aabb3f *selection_box = runData.selected_object->getSelectionBox();
-
- // Box should exist because object was
- // returned in the first place
-
- assert(selection_box);
-
+ aabb3f selection_box;
+ if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox() &&
+ runData.selected_object->getSelectionBox(&selection_box)) {
v3f pos = runData.selected_object->getPosition();
- selectionboxes->push_back(aabb3f(
- selection_box->MinEdge, selection_box->MaxEdge));
- selectionboxes->push_back(
- aabb3f(selection_box->MinEdge, selection_box->MaxEdge));
+ selectionboxes->push_back(aabb3f(selection_box));
hud->setSelectionPos(pos, camera_offset);
}
} else if (result.type == POINTEDTHING_NODE) {
}
// Update selection mesh light level and vertex colors
- if (selectionboxes->size() > 0) {
+ if (!selectionboxes->empty()) {
v3f pf = hud->getSelectionPos();
v3s16 p = floatToInt(pf, BS);
u16 node_light = getInteriorLight(n, -1, nodedef);
u16 light_level = node_light;
- for (u8 i = 0; i < 6; i++) {
- n = map.getNodeNoEx(p + g_6dirs[i]);
+ for (const v3s16 &dir : g_6dirs) {
+ n = map.getNodeNoEx(p + dir);
node_light = getInteriorLight(n, -1, nodedef);
if (node_light > light_level)
light_level = node_light;
ClientMap &map = client->getEnv().getClientMap();
if (runData.nodig_delay_timer <= 0.0 && isLeftPressed()
+ && !runData.digging_blocked
&& client->checkPrivilege("interact")) {
handleDigging(pointed, nodepos, playeritem_toolcap, dtime);
}
runData.repeat_rightclick_timer = 0;
infostream << "Ground right-clicked" << std::endl;
- if (meta && meta->getString("formspec") != "" && !random_input
+ if (meta && !meta->getString("formspec").empty() && !random_input
&& !isKeyDown(KeyType::SNEAK)) {
+ // Report right click to server
+ if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
+ client->interact(3, pointed);
+ }
+
infostream << "Launching custom inventory view" << std::endl;
InventoryLocation inventoryloc;
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
create_formspec_menu(¤t_formspec, client,
- device, &input->joystick, fs_src, txt_dst);
+ &input->joystick, fs_src, txt_dst);
cur_formname = "";
current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
soundmaker->m_player_rightpunch_sound =
SimpleSoundSpec();
- if (playeritem_def.node_placement_prediction == "" ||
+ if (playeritem_def.node_placement_prediction.empty() ||
nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
client->interact(3, pointed); // Report to server
} else {
utf8_to_wide(runData.selected_object->infoText()));
if (show_debug) {
- if (infotext != L"") {
+ if (!infotext.empty()) {
infotext += L"\n";
}
infotext += unescape_enriched(utf8_to_wide(
runData.dig_time_complete = params.time;
if (m_cache_enable_particles) {
- const ContentFeatures &features =
- client->getNodeDefManager()->get(n);
- client->getParticleManager()->addPunchingParticles(client, smgr,
+ const ContentFeatures &features = client->getNodeDefManager()->get(n);
+ client->getParticleManager()->addPunchingParticles(client,
player, nodepos, n, features);
}
}
if (sound_dig.exists() && params.diggable) {
if (sound_dig.name == "__group") {
- if (params.main_group != "") {
+ if (!params.main_group.empty()) {
soundmaker->m_player_leftpunch_sound.gain = 0.5;
soundmaker->m_player_leftpunch_sound.name =
std::string("default_dig_") +
runData.dig_time = 0;
runData.digging = false;
+ // we successfully dug, now block it from repeating if we want to be safe
+ if (g_settings->getBool("safe_dig_and_place"))
+ runData.digging_blocked = true;
runData.nodig_delay_timer =
runData.dig_time_complete / (float)crack_animation_length;
if (m_cache_enable_particles) {
const ContentFeatures &features =
client->getNodeDefManager()->get(wasnode);
- client->getParticleManager()->addDiggingParticles(client, smgr,
+ client->getParticleManager()->addDiggingParticles(client,
player, nodepos, wasnode, features);
}
Update clouds
*/
if (clouds) {
- v3f player_position = player->getPosition();
if (sky->getCloudsVisible()) {
clouds->setVisible(true);
clouds->step(dtime);
- clouds->update(v2f(player_position.X, player_position.Z),
- sky->getCloudColor());
+ // camera->getPosition is not enough for 3rd person views
+ v3f camera_node_position = camera->getCameraNode()->getPosition();
+ v3s16 camera_offset = camera->getOffset();
+ camera_node_position.X = camera_node_position.X + camera_offset.X * BS;
+ camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS;
+ camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS;
+ clouds->update(camera_node_position,
+ sky->getCloudColor());
+ if (clouds->isCameraInsideCloud() && m_cache_enable_fog &&
+ !flags.force_fog_off) {
+ // if inside clouds, and fog enabled, use that as sky
+ // color(s)
+ video::SColor clouds_dark = clouds->getColor()
+ .getInterpolated(video::SColor(255, 0, 0, 0), 0.9);
+ sky->overrideColors(clouds_dark, clouds->getColor());
+ sky->setBodiesVisible(false);
+ runData.fog_range = std::fmin(runData.fog_range * 0.5f, 32.0f * BS);
+ // do not draw clouds after all
+ clouds->setVisible(false);
+ }
} else {
clouds->setVisible(false);
}
|| runData.update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2
|| m_camera_offset_changed) {
runData.update_draw_list_timer = 0;
- client->getEnv().getClientMap().updateDrawList(driver);
+ client->getEnv().getClientMap().updateDrawList();
runData.update_draw_list_last_cam_dir = camera_direction;
}
/*
Drawing begins
*/
-
const video::SColor &skycolor = sky->getSkyColor();
TimeTaker tt_draw("mainloop: draw");
driver->beginScene(true, true, skycolor);
- draw_scene(driver, smgr, *camera, *client, player, *hud, mapper,
+ RenderingEngine::draw_scene(camera, client, player, hud, mapper,
guienv, screensize, skycolor, flags.show_hud,
flags.show_minimap);
if (flags.show_debug) {
static float drawtime_avg = 0;
drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
-
u16 fps = 1.0 / stats.dtime_jitter.avg;
std::ostringstream os(std::ios_base::binary);
os << std::fixed
<< PROJECT_NAME_C " " << g_version_hash
- << "; " << fps << " FPS"
- << ", (R: range_all=" << draw_control->range_all << ")"
+ << ", FPS = " << fps
+ << ", range_all = " << draw_control->range_all
<< std::setprecision(0)
<< ", drawtime = " << drawtime_avg << " ms"
<< std::setprecision(1)
<< ", dtime_jitter = "
<< (stats.dtime_jitter.max_fraction * 100.0) << " %"
<< std::setprecision(1)
- << ", v_range = " << draw_control->wanted_range
+ << ", view_range = " << draw_control->wanted_range
<< std::setprecision(3)
<< ", RTT = " << client->getRTT() << " s";
setStaticText(guitext, utf8_to_wide(os.str()).c_str());
if (flags.show_debug) {
std::ostringstream os(std::ios_base::binary);
os << std::setprecision(1) << std::fixed
- << "(" << (player_position.X / BS)
+ << "pos = (" << (player_position.X / BS)
<< ", " << (player_position.Y / BS)
<< ", " << (player_position.Z / BS)
- << ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw)) << "°"
+ << "), yaw = " << (wrapDegrees_0_360(cam.camera_yaw)) << "°"
<< " " << yawToDirectionString(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
- << "\", param1 = " << (u64) n.getParam1()
- << ", param2 = " << (u64) n.getParam2()
- << ", tiledef[0] = \"" << features.tiledef[0].name.c_str()
- << "\")";
- }
- }
-
+ << ", seed = " << ((u64)client->getMapSeed());
setStaticText(guitext2, utf8_to_wide(os.str()).c_str());
guitext2->setVisible(true);
+ } else {
+ guitext2->setVisible(false);
+ }
+ if (guitext2->isVisible()) {
core::rect<s32> rect(
5, 5 + g_fontengine->getTextHeight(),
screensize.X, 5 + g_fontengine->getTextHeight() * 2
);
guitext2->setRelativePosition(rect);
+ }
+
+ if (flags.show_debug && 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") {
+ std::ostringstream os(std::ios_base::binary);
+ os << "pointing_at = (" << nodedef->get(n).name
+ << ", param2 = " << (u64) n.getParam2()
+ << ")";
+ setStaticText(guitext3, utf8_to_wide(os.str()).c_str());
+ guitext3->setVisible(true);
+ } else {
+ guitext3->setVisible(false);
+ }
} else {
- guitext2->setVisible(false);
+ guitext3->setVisible(false);
+ }
+
+ if (guitext3->isVisible()) {
+ core::rect<s32> rect(
+ 5, 5 + g_fontengine->getTextHeight() * 2,
+ screensize.X, 5 + g_fontengine->getTextHeight() * 3
+ );
+ guitext3->setRelativePosition(rect);
}
setStaticText(guitext_info, infotext.c_str());
fps_timings->last_time = time;
}
-// Note: This will free (using delete[])! \p msg. If you want to use it later,
-// pass a copy of it to this function
-// Note: \p msg must be allocated using new (not malloc())
-void Game::showOverlayMessage(const wchar_t *msg, float dtime,
- int percent, bool draw_clouds)
+void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds)
{
- draw_load_screen(msg, device, guienv, texture_src, dtime, percent,
+ const wchar_t *wmsg = wgettext(msg);
+ RenderingEngine::draw_load_screen(wmsg, guienv, texture_src, dtime, percent,
draw_clouds);
- delete[] msg;
+ delete[] wmsg;
}
void Game::settingChangedCallback(const std::string &setting_name, void *data)
// Extended resource accounting
infostream << "Irrlicht resources after cleanup:" << std::endl;
infostream << "\tRemaining meshes : "
- << device->getSceneManager()->getMeshCache()->getMeshCount() << std::endl;
+ << RenderingEngine::get_mesh_cache()->getMeshCount() << std::endl;
infostream << "\tRemaining textures : "
<< driver->getTextureCount() << std::endl;
static const std::string mode = strgettext("- Mode: ");
if (!simple_singleplayer_mode) {
Address serverAddress = client->getServerAddress();
- if (address != "") {
+ if (!address.empty()) {
os << mode << strgettext("Remote server") << "\n"
<< strgettext("- Address: ") << address;
} else {
} else {
os << mode << strgettext("Singleplayer") << "\n";
}
- if (simple_singleplayer_mode || address == "") {
+ if (simple_singleplayer_mode || address.empty()) {
static const std::string on = strgettext("On");
static const std::string off = strgettext("Off");
const std::string &damage = g_settings->getBool("enable_damage") ? on : off;
<< strgettext("- Public: ") << announced << "\n";
std::string server_name = g_settings->get("server_name");
str_formspec_escape(server_name);
- if (announced == on && server_name != "")
+ if (announced == on && !server_name.empty())
os << strgettext("- Server Name: ") << server_name;
}
FormspecFormSource *fs_src = new FormspecFormSource(os.str());
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
- create_formspec_menu(¤t_formspec, client, device, &input->joystick, fs_src, txt_dst);
+ create_formspec_menu(¤t_formspec, client, &input->joystick, fs_src, txt_dst);
current_formspec->setFocus("btn_continue");
current_formspec->doPause = true;
}
void the_game(bool *kill,
bool random_input,
InputHandler *input,
- IrrlichtDevice *device,
-
const std::string &map_dir,
const std::string &playername,
const std::string &password,
try {
- if (game.startup(kill, random_input, input, device, map_dir,
+ if (game.startup(kill, random_input, input, map_dir,
playername, password, &server_address, port, error_message,
reconnect_requested, &chat_backend, gamespec,
simple_singleplayer_mode)) {