3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "client/renderingengine.h"
27 #include "client/clientevent.h"
28 //#include "client/gameui.h"
29 #include "client/inputhandler.h"
30 #include "client/sound.h"
31 #include "client/tile.h" // For TextureSource
32 #include "client/keys.h"
33 #include "client/joystick_controller.h"
34 #include "clientmap.h"
37 #include "content_cao.h"
38 #include "client/event_manager.h"
39 #include "fontengine.h"
44 #include "gui/cheatMenu.h"
45 #include "gui/guiChatConsole.h"
46 #include "gui/guiConfirmRegistration.h"
47 #include "gui/guiFormSpecMenu.h"
48 #include "gui/guiKeyChangeMenu.h"
49 #include "gui/guiPasswordChange.h"
50 #include "gui/guiVolumeChange.h"
51 #include "gui/mainmenumanager.h"
52 #include "gui/profilergraph.h"
55 #include "nodedef.h" // Needed for determining pointing to nodes
56 #include "nodemetadata.h"
57 #include "particles.h"
65 #include "translation.h"
66 #include "util/basic_macros.h"
67 #include "util/directiontables.h"
68 #include "util/pointedthing.h"
69 #include "util/quicktune_shortcutter.h"
70 #include "irrlicht_changes/static_text.h"
73 #include "script/scripting_client.h"
75 #include "irrlichttypes.h"
80 class RenderingEngine;
85 f32 max, min, avg, counter, max_sample, min_sample, max_fraction;
91 Jitter dtime_jitter, busy_time_jitter;
94 struct CameraOrientation {
95 f32 camera_yaw; // "right/left"
96 f32 camera_pitch; // "up/down"
103 struct TextDestNodeMetadata : public TextDest
105 TextDestNodeMetadata(v3s16 p, Client *client)
110 // This is deprecated I guess? -celeron55
111 void gotText(const std::wstring &text)
113 std::string ntext = wide_to_utf8(text);
114 infostream << "Submitting 'text' field of node at (" << m_p.X << ","
115 << m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
117 fields["text"] = ntext;
118 m_client->sendNodemetaFields(m_p, "", fields);
120 void gotText(const StringMap &fields)
122 m_client->sendNodemetaFields(m_p, "", fields);
129 struct TextDestPlayerInventory : public TextDest
131 TextDestPlayerInventory(Client *client)
136 TextDestPlayerInventory(Client *client, const std::string &formname)
139 m_formname = formname;
141 void gotText(const StringMap &fields)
143 m_client->sendInventoryFields(m_formname, fields);
149 struct LocalFormspecHandler : public TextDest
151 LocalFormspecHandler(const std::string &formname)
153 m_formname = formname;
156 LocalFormspecHandler(const std::string &formname, Client *client):
159 m_formname = formname;
162 void gotText(const StringMap &fields)
164 if (m_formname == "MT_PAUSE_MENU") {
165 if (fields.find("btn_sound") != fields.end()) {
166 g_gamecallback->changeVolume();
170 if (fields.find("btn_key_config") != fields.end()) {
171 g_gamecallback->keyConfig();
175 if (fields.find("btn_exit_menu") != fields.end()) {
176 g_gamecallback->disconnect();
180 if (fields.find("btn_exit_os") != fields.end()) {
181 g_gamecallback->exitToOS();
183 RenderingEngine::get_raw_device()->closeDevice();
188 if (fields.find("btn_change_password") != fields.end()) {
189 g_gamecallback->changePassword();
196 if (m_formname == "MT_DEATH_SCREEN") {
197 assert(m_client != 0);
198 m_client->sendRespawn();
202 if (m_client->modsLoaded())
203 m_client->getScript()->on_formspec_input(m_formname, fields);
206 Client *m_client = nullptr;
209 /* Form update callback */
211 class NodeMetadataFormSource: public IFormSource
214 NodeMetadataFormSource(ClientMap *map, v3s16 p):
219 const std::string &getForm() const
221 static const std::string empty_string = "";
222 NodeMetadata *meta = m_map->getNodeMetadata(m_p);
227 return meta->getString("formspec");
230 virtual std::string resolveText(const std::string &str)
232 NodeMetadata *meta = m_map->getNodeMetadata(m_p);
237 return meta->resolveString(str);
244 class PlayerInventoryFormSource: public IFormSource
247 PlayerInventoryFormSource(Client *client):
252 const std::string &getForm() const
254 LocalPlayer *player = m_client->getEnv().getLocalPlayer();
255 return player->inventory_formspec;
261 class NodeDugEvent: public MtEvent
267 NodeDugEvent(v3s16 p, MapNode n):
271 MtEvent::Type getType() const
273 return MtEvent::NODE_DUG;
279 ISoundManager *m_sound;
280 const NodeDefManager *m_ndef;
282 bool makes_footstep_sound;
283 float m_player_step_timer;
284 float m_player_jump_timer;
286 SimpleSoundSpec m_player_step_sound;
287 SimpleSoundSpec m_player_leftpunch_sound;
288 SimpleSoundSpec m_player_rightpunch_sound;
290 SoundMaker(ISoundManager *sound, const NodeDefManager *ndef):
293 makes_footstep_sound(true),
294 m_player_step_timer(0.0f),
295 m_player_jump_timer(0.0f)
299 void playPlayerStep()
301 if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
302 m_player_step_timer = 0.03;
303 if (makes_footstep_sound)
304 m_sound->playSound(m_player_step_sound, false);
308 void playPlayerJump()
310 if (m_player_jump_timer <= 0.0f) {
311 m_player_jump_timer = 0.2f;
312 m_sound->playSound(SimpleSoundSpec("player_jump", 0.5f), false);
316 static void viewBobbingStep(MtEvent *e, void *data)
318 SoundMaker *sm = (SoundMaker *)data;
319 sm->playPlayerStep();
322 static void playerRegainGround(MtEvent *e, void *data)
324 SoundMaker *sm = (SoundMaker *)data;
325 sm->playPlayerStep();
328 static void playerJump(MtEvent *e, void *data)
330 SoundMaker *sm = (SoundMaker *)data;
331 sm->playPlayerJump();
334 static void cameraPunchLeft(MtEvent *e, void *data)
336 SoundMaker *sm = (SoundMaker *)data;
337 sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
340 static void cameraPunchRight(MtEvent *e, void *data)
342 SoundMaker *sm = (SoundMaker *)data;
343 sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
346 static void nodeDug(MtEvent *e, void *data)
348 SoundMaker *sm = (SoundMaker *)data;
349 NodeDugEvent *nde = (NodeDugEvent *)e;
350 sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
353 static void playerDamage(MtEvent *e, void *data)
355 SoundMaker *sm = (SoundMaker *)data;
356 sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
359 static void playerFallingDamage(MtEvent *e, void *data)
361 SoundMaker *sm = (SoundMaker *)data;
362 sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5), false);
365 void registerReceiver(MtEventManager *mgr)
367 mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
368 mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
369 mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
370 mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
371 mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
372 mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
373 mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
374 mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
377 void step(float dtime)
379 m_player_step_timer -= dtime;
380 m_player_jump_timer -= dtime;
384 // Locally stored sounds don't need to be preloaded because of this
385 class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
387 std::set<std::string> m_fetched;
389 void paths_insert(std::set<std::string> &dst_paths,
390 const std::string &base,
391 const std::string &name)
393 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
394 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg");
395 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg");
396 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg");
397 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg");
398 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg");
399 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg");
400 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg");
401 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg");
402 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg");
403 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg");
406 void fetchSounds(const std::string &name,
407 std::set<std::string> &dst_paths,
408 std::set<std::string> &dst_datas)
410 if (m_fetched.count(name))
413 m_fetched.insert(name);
415 paths_insert(dst_paths, porting::path_share, name);
416 paths_insert(dst_paths, porting::path_user, name);
421 typedef s32 SamplerLayer_t;
424 class GameGlobalShaderConstantSetter : public IShaderConstantSetter
427 bool *m_force_fog_off;
430 CachedPixelShaderSetting<float, 4> m_sky_bg_color;
431 CachedPixelShaderSetting<float> m_fog_distance;
432 CachedVertexShaderSetting<float> m_animation_timer_vertex;
433 CachedPixelShaderSetting<float> m_animation_timer_pixel;
434 CachedPixelShaderSetting<float, 3> m_day_light;
435 CachedPixelShaderSetting<float, 4> m_star_color;
436 CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
437 CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
438 CachedPixelShaderSetting<float, 3> m_minimap_yaw;
439 CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
440 CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
441 CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
442 CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
446 void onSettingsChange(const std::string &name)
448 if (name == "enable_fog")
449 m_fog_enabled = g_settings->getBool("enable_fog");
452 static void settingsCallback(const std::string &name, void *userdata)
454 reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name);
457 void setSky(Sky *sky) { m_sky = sky; }
459 GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
460 f32 *fog_range, Client *client) :
462 m_force_fog_off(force_fog_off),
463 m_fog_range(fog_range),
464 m_sky_bg_color("skyBgColor"),
465 m_fog_distance("fogDistance"),
466 m_animation_timer_vertex("animationTimer"),
467 m_animation_timer_pixel("animationTimer"),
468 m_day_light("dayLight"),
469 m_star_color("starColor"),
470 m_eye_position_pixel("eyePosition"),
471 m_eye_position_vertex("eyePosition"),
472 m_minimap_yaw("yawVec"),
473 m_camera_offset_pixel("cameraOffset"),
474 m_camera_offset_vertex("cameraOffset"),
475 m_base_texture("baseTexture"),
476 m_normal_texture("normalTexture"),
479 g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
480 m_fog_enabled = g_settings->getBool("enable_fog");
483 ~GameGlobalShaderConstantSetter()
485 g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
488 void onSetConstants(video::IMaterialRendererServices *services) override
491 video::SColor bgcolor = m_sky->getBgColor();
492 video::SColorf bgcolorf(bgcolor);
493 float bgcolorfa[4] = {
499 m_sky_bg_color.set(bgcolorfa, services);
502 float fog_distance = 10000 * BS;
504 if (m_fog_enabled && !*m_force_fog_off)
505 fog_distance = *m_fog_range;
507 m_fog_distance.set(&fog_distance, services);
509 u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
510 video::SColorf sunlight;
511 get_sunlight_color(&sunlight, daynight_ratio);
516 m_day_light.set(dnc, services);
518 video::SColorf star_color = m_sky->getCurrentStarColor();
519 float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a};
520 m_star_color.set(clr, services);
522 u32 animation_timer = porting::getTimeMs() % 1000000;
523 float animation_timer_f = (float)animation_timer / 100000.f;
524 m_animation_timer_vertex.set(&animation_timer_f, services);
525 m_animation_timer_pixel.set(&animation_timer_f, services);
527 float eye_position_array[3];
528 v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
529 epos.getAs3Values(eye_position_array);
530 m_eye_position_pixel.set(eye_position_array, services);
531 m_eye_position_vertex.set(eye_position_array, services);
533 if (m_client->getMinimap()) {
534 float minimap_yaw_array[3];
535 v3f minimap_yaw = m_client->getMinimap()->getYawVec();
536 minimap_yaw.getAs3Values(minimap_yaw_array);
537 m_minimap_yaw.set(minimap_yaw_array, services);
540 float camera_offset_array[3];
541 v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
542 offset.getAs3Values(camera_offset_array);
543 m_camera_offset_pixel.set(camera_offset_array, services);
544 m_camera_offset_vertex.set(camera_offset_array, services);
546 SamplerLayer_t base_tex = 0, normal_tex = 1;
547 m_base_texture.set(&base_tex, services);
548 m_normal_texture.set(&normal_tex, services);
553 class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
556 bool *m_force_fog_off;
559 std::vector<GameGlobalShaderConstantSetter *> created_nosky;
561 GameGlobalShaderConstantSetterFactory(bool *force_fog_off,
562 f32 *fog_range, Client *client) :
564 m_force_fog_off(force_fog_off),
565 m_fog_range(fog_range),
569 void setSky(Sky *sky) {
571 for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
572 ggscs->setSky(m_sky);
574 created_nosky.clear();
577 virtual IShaderConstantSetter* create()
579 auto *scs = new GameGlobalShaderConstantSetter(
580 m_sky, m_force_fog_off, m_fog_range, m_client);
582 created_nosky.push_back(scs);
587 #ifdef HAVE_TOUCHSCREENGUI
588 #define SIZE_TAG "size[11,5.5]"
590 #define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
593 /****************************************************************************
594 ****************************************************************************/
596 const float object_hit_delay = 0.2;
599 FpsControl() : last_time(0), busy_time(0), sleep_time(0) {}
603 void limit(IrrlichtDevice *device, f32 *dtime);
605 u32 getBusyMs() const { return busy_time / 1000; }
607 // all values in microseconds (us)
608 u64 last_time, busy_time, sleep_time;
612 /* The reason the following structs are not anonymous structs within the
613 * class is that they are not used by the majority of member functions and
614 * many functions that do require objects of thse types do not modify them
615 * (so they can be passed as a const qualified parameter)
621 PointedThing pointed_old;
624 bool btn_down_for_dig;
626 bool digging_blocked;
627 bool reset_jump_timer;
628 float nodig_delay_timer;
630 float dig_time_complete;
631 float repeat_place_timer;
632 float object_hit_delay_timer;
633 float time_from_last_punch;
634 ClientActiveObject *selected_object;
638 float update_draw_list_timer;
642 v3f update_draw_list_last_cam_dir;
644 float time_of_day_smooth;
649 struct ClientEventHandler
651 void (Game::*handler)(ClientEvent *, CameraOrientation *);
654 using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>;
661 bool startup(bool *kill,
663 RenderingEngine *rendering_engine,
664 const GameStartData &game_params,
665 std::string &error_message,
667 ChatBackend *chat_backend);
673 // Basic initialisation
674 bool init(const std::string &map_dir, const std::string &address,
675 u16 port, const SubgameSpec &gamespec);
677 bool createSingleplayerServer(const std::string &map_dir,
678 const SubgameSpec &gamespec, u16 port);
681 bool createClient(const GameStartData &start_data);
685 bool connectToServer(const GameStartData &start_data,
686 bool *connect_ok, bool *aborted);
687 bool getServerContent(bool *aborted);
691 void updateInteractTimers(f32 dtime);
692 bool checkConnection();
693 bool handleCallbacks();
694 void processQueues();
695 void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
696 void updateDebugState();
697 void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
698 void updateProfilerGraphs(ProfilerGraph *graph);
701 void processUserInput(f32 dtime);
702 void processKeyInput();
703 void processItemSelection(u16 *new_playeritem);
705 void dropSelectedItem(bool single_item = false);
706 void openInventory();
707 void openEnderchest();
708 void openConsole(float scale, const wchar_t *line=NULL);
709 void toggleFreeMove();
710 void toggleFreeMoveAlt();
711 void togglePitchMove();
714 void toggleKillaura();
715 void toggleFreecam();
716 void toggleScaffold();
717 void toggleNextItem();
718 void toggleCinematic();
719 void toggleBlockBounds();
720 void toggleAutoforward();
722 void toggleMinimap(bool shift_pressed);
725 void toggleUpdateCamera();
726 void updatePlayerCAOVisibility();
728 void increaseViewRange();
729 void decreaseViewRange();
730 void toggleFullViewRange();
731 void checkZoomEnabled();
733 void updateCameraDirection(CameraOrientation *cam, float dtime);
734 void updateCameraOrientation(CameraOrientation *cam, float dtime);
735 void updatePlayerControl(const CameraOrientation &cam);
736 void step(f32 *dtime);
737 void processClientEvents(CameraOrientation *cam);
738 void updateCamera(f32 dtime);
739 void updateSound(f32 dtime);
740 void processPlayerInteraction(f32 dtime, bool show_hud);
742 * Returns the object or node the player is pointing at.
743 * Also updates the selected thing in the Hud.
745 * @param[in] shootline the shootline, starting from
746 * the camera position. This also gives the maximal distance
748 * @param[in] liquids_pointable if false, liquids are ignored
749 * @param[in] look_for_object if false, objects are ignored
750 * @param[in] camera_offset offset of the camera
751 * @param[out] selected_object the selected object or
754 PointedThing updatePointedThing(
755 const core::line3d<f32> &shootline, bool liquids_pointable,
756 bool look_for_object, const v3s16 &camera_offset);
757 void handlePointingAtNothing(const ItemStack &playerItem);
758 void handlePointingAtNode(const PointedThing &pointed,
759 const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
760 void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
761 const v3f &player_position, bool show_debug);
762 void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
763 const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
764 void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
765 const CameraOrientation &cam);
766 void updateShadows();
769 void showOverlayMessage(const char *msg, float dtime, int percent,
770 bool draw_clouds = true);
772 static void freecamChangedCallback(const std::string &setting_name, void *data);
773 static void settingChangedCallback(const std::string &setting_name, void *data);
774 static void updateAllMapBlocksCallback(const std::string &setting_name, void *data);
777 bool isKeyDown(GameKeyType k);
778 bool wasKeyDown(GameKeyType k);
779 bool wasKeyPressed(GameKeyType k);
780 bool wasKeyReleased(GameKeyType k);
783 void handleAndroidChatInput();
787 bool force_fog_off = false;
788 bool disable_camera_update = false;
791 void showDeathFormspec();
792 void showPauseMenu();
794 void pauseAnimation();
795 void resumeAnimation();
797 // ClientEvent handlers
798 void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
799 void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
800 void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
801 void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
802 void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
803 void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
804 void handleClientEvent_HandleParticleEvent(ClientEvent *event,
805 CameraOrientation *cam);
806 void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
807 void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
808 void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
809 void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
810 void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
811 void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
812 void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
813 void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
814 CameraOrientation *cam);
815 void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
817 void updateChat(f32 dtime);
819 bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
820 const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
821 const NodeMetadata *meta, bool force = false);
822 static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
824 f32 getSensitivityScaleFactor() const;
826 InputHandler *input = nullptr;
828 Client *client = nullptr;
829 Server *server = nullptr;
831 IWritableTextureSource *texture_src = nullptr;
832 IWritableShaderSource *shader_src = nullptr;
834 // When created, these will be filled with data received from the server
835 IWritableItemDefManager *itemdef_manager = nullptr;
836 NodeDefManager *nodedef_manager = nullptr;
838 GameOnDemandSoundFetcher soundfetcher; // useful when testing
839 ISoundManager *sound = nullptr;
840 bool sound_is_dummy = false;
841 SoundMaker *soundmaker = nullptr;
843 ChatBackend *chat_backend = nullptr;
844 LogOutputBuffer m_chat_log_buf;
846 EventManager *eventmgr = nullptr;
847 QuicktuneShortcutter *quicktune = nullptr;
848 bool registration_confirmation_shown = false;
850 std::unique_ptr<GameUI> m_game_ui;
851 GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
852 CheatMenu *m_cheat_menu = nullptr;
853 MapDrawControl *draw_control = nullptr;
854 Camera *camera = nullptr;
855 Clouds *clouds = nullptr; // Free using ->Drop()
856 Sky *sky = nullptr; // Free using ->Drop()
858 Minimap *mapper = nullptr;
860 // Map server hud ids to client hud ids
861 std::unordered_map<u32, u32> m_hud_server_to_client;
867 This class does take ownership/responsibily for cleaning up etc of any of
868 these items (e.g. device)
870 IrrlichtDevice *device;
871 RenderingEngine *m_rendering_engine;
872 video::IVideoDriver *driver;
873 scene::ISceneManager *smgr;
875 std::string *error_message;
876 bool *reconnect_requested;
877 scene::ISceneNode *skybox;
878 PausedNodesList paused_animated_nodes;
880 bool simple_singleplayer_mode;
883 /* Pre-calculated values
885 int crack_animation_length;
887 IntervalLimiter profiler_interval;
890 * TODO: Local caching of settings is not optimal and should at some stage
891 * be updated to use a global settings object for getting thse values
892 * (as opposed to the this local caching). This can be addressed in
895 bool m_cache_doubletap_jump;
896 bool m_cache_enable_clouds;
897 bool m_cache_enable_joysticks;
898 bool m_cache_enable_particles;
899 bool m_cache_enable_fog;
900 bool m_cache_enable_noclip;
901 bool m_cache_enable_free_move;
902 f32 m_cache_mouse_sensitivity;
903 f32 m_cache_joystick_frustum_sensitivity;
904 f32 m_repeat_place_time;
905 f32 m_cache_cam_smoothing;
906 f32 m_cache_fog_start;
908 bool m_invert_mouse = false;
909 bool m_first_loop_after_window_activation = false;
910 bool m_camera_offset_changed = false;
912 bool m_does_lost_focus_pause_game = false;
914 CameraOrientation cam_view_target = {}; // added by dragonfireclient
915 CameraOrientation cam_view = {}; // added by dragonfireclient
917 #if IRRLICHT_VERSION_MT_REVISION < 5
918 int m_reset_HW_buffer_counter = 0;
921 #ifdef HAVE_TOUCHSCREENGUI
922 bool m_cache_hold_aux1;
925 bool m_android_chat_open;
930 void the_game(bool *kill,
932 RenderingEngine *rendering_engine,
933 const GameStartData &start_data,
934 std::string &error_message,
935 ChatBackend &chat_backend,
936 bool *reconnect_requested);