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"
72 #include "script/scripting_client.h"
74 #include "irrlichttypes.h"
78 class ChatBackend; /* to avoid having to include chat.h */
84 f32 max, min, avg, counter, max_sample, min_sample, max_fraction;
91 Jitter dtime_jitter, busy_time_jitter;
94 struct CameraOrientation
96 f32 camera_yaw; // "right/left"
97 f32 camera_pitch; // "up/down"
104 struct TextDestNodeMetadata : public TextDest
106 TextDestNodeMetadata(v3s16 p, Client *client)
111 // This is deprecated I guess? -celeron55
112 void gotText(const std::wstring &text)
114 std::string ntext = wide_to_utf8(text);
115 infostream << "Submitting 'text' field of node at (" << m_p.X << ","
116 << m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
118 fields["text"] = ntext;
119 m_client->sendNodemetaFields(m_p, "", fields);
121 void gotText(const StringMap &fields)
123 m_client->sendNodemetaFields(m_p, "", fields);
130 struct TextDestPlayerInventory : public TextDest
132 TextDestPlayerInventory(Client *client)
137 TextDestPlayerInventory(Client *client, const std::string &formname)
140 m_formname = formname;
142 void gotText(const StringMap &fields)
144 m_client->sendInventoryFields(m_formname, fields);
150 struct LocalFormspecHandler : public TextDest
152 LocalFormspecHandler(const std::string &formname) { m_formname = formname; }
154 LocalFormspecHandler(const std::string &formname, Client *client) :
157 m_formname = formname;
160 void gotText(const StringMap &fields)
162 if (m_formname == "MT_PAUSE_MENU") {
163 if (fields.find("btn_sound") != fields.end()) {
164 g_gamecallback->changeVolume();
168 if (fields.find("btn_key_config") != fields.end()) {
169 g_gamecallback->keyConfig();
173 if (fields.find("btn_exit_menu") != fields.end()) {
174 g_gamecallback->disconnect();
178 if (fields.find("btn_exit_os") != fields.end()) {
179 g_gamecallback->exitToOS();
181 RenderingEngine::get_raw_device()->closeDevice();
186 if (fields.find("btn_change_password") != fields.end()) {
187 g_gamecallback->changePassword();
191 if (fields.find("quit") != fields.end()) {
195 if (fields.find("btn_continue") != fields.end()) {
200 if (m_formname == "MT_DEATH_SCREEN") {
201 assert(m_client != 0);
202 m_client->sendRespawn();
206 if (m_client && m_client->modsLoaded())
207 m_client->getScript()->on_formspec_input(m_formname, fields);
210 Client *m_client = nullptr;
213 /* Form update callback */
215 class NodeMetadataFormSource : public IFormSource
218 NodeMetadataFormSource(ClientMap *map, v3s16 p) : m_map(map), m_p(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) : m_client(client) {}
249 const std::string &getForm() const
251 LocalPlayer *player = m_client->getEnv().getLocalPlayer();
252 return player->inventory_formspec;
258 class NodeDugEvent : public MtEvent
264 NodeDugEvent(v3s16 p, MapNode n) : p(p), n(n) {}
265 MtEvent::Type getType() const { return MtEvent::NODE_DUG; }
270 ISoundManager *m_sound;
271 const NodeDefManager *m_ndef;
274 bool makes_footstep_sound;
275 float m_player_step_timer;
276 float m_player_jump_timer;
278 SimpleSoundSpec m_player_step_sound;
279 SimpleSoundSpec m_player_leftpunch_sound;
280 SimpleSoundSpec m_player_rightpunch_sound;
282 SoundMaker(ISoundManager *sound, const NodeDefManager *ndef) :
283 m_sound(sound), m_ndef(ndef), makes_footstep_sound(true),
284 m_player_step_timer(0), m_player_jump_timer(0.0f)
288 void playPlayerStep()
290 if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
291 m_player_step_timer = 0.03;
292 if (makes_footstep_sound)
293 m_sound->playSound(m_player_step_sound, false);
297 void playPlayerJump()
299 if (m_player_jump_timer <= 0.0f) {
300 m_player_jump_timer = 0.2f;
301 m_sound->playSound(SimpleSoundSpec("player_jump", 0.5f), false);
305 static void viewBobbingStep(MtEvent *e, void *data)
307 SoundMaker *sm = (SoundMaker *)data;
308 sm->playPlayerStep();
311 static void playerRegainGround(MtEvent *e, void *data)
313 SoundMaker *sm = (SoundMaker *)data;
314 sm->playPlayerStep();
317 static void playerJump(MtEvent *e, void *data)
319 SoundMaker *sm = (SoundMaker *)data;
320 sm->playPlayerJump();
323 static void cameraPunchLeft(MtEvent *e, void *data)
325 SoundMaker *sm = (SoundMaker *)data;
326 sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
329 static void cameraPunchRight(MtEvent *e, void *data)
331 SoundMaker *sm = (SoundMaker *)data;
332 sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
335 static void nodeDug(MtEvent *e, void *data)
337 SoundMaker *sm = (SoundMaker *)data;
338 NodeDugEvent *nde = (NodeDugEvent *)e;
339 sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
342 static void playerDamage(MtEvent *e, void *data)
344 SoundMaker *sm = (SoundMaker *)data;
345 sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
348 static void playerFallingDamage(MtEvent *e, void *data)
350 SoundMaker *sm = (SoundMaker *)data;
351 sm->m_sound->playSound(
352 SimpleSoundSpec("player_falling_damage", 0.5), false);
355 void registerReceiver(MtEventManager *mgr)
357 mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
358 mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround,
360 mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
361 mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
362 mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
363 mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
364 mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
365 mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage,
369 void step(float dtime)
371 m_player_step_timer -= dtime;
372 m_player_jump_timer -= dtime;
376 // Locally stored sounds don't need to be preloaded because of this
377 class GameOnDemandSoundFetcher : public OnDemandSoundFetcher
379 std::set<std::string> m_fetched;
382 void paths_insert(std::set<std::string> &dst_paths, const std::string &base,
383 const std::string &name)
385 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
386 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
388 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
390 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
392 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
394 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
396 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
398 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
400 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
402 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
404 dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name +
409 void fetchSounds(const std::string &name, std::set<std::string> &dst_paths,
410 std::set<std::string> &dst_datas)
412 if (m_fetched.count(name))
415 m_fetched.insert(name);
417 paths_insert(dst_paths, porting::path_share, name);
418 paths_insert(dst_paths, porting::path_user, name);
422 // before 1.8 there isn't a "integer interface", only float
423 #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
424 typedef f32 SamplerLayer_t;
426 typedef s32 SamplerLayer_t;
429 class GameGlobalShaderConstantSetter : public IShaderConstantSetter
432 bool *m_force_fog_off;
435 CachedPixelShaderSetting<float, 4> m_sky_bg_color;
436 CachedPixelShaderSetting<float> m_fog_distance;
437 CachedVertexShaderSetting<float> m_animation_timer_vertex;
438 CachedPixelShaderSetting<float> m_animation_timer_pixel;
439 CachedPixelShaderSetting<float, 3> m_day_light;
440 CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
441 CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
442 CachedPixelShaderSetting<float, 3> m_minimap_yaw;
443 CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
444 CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
445 CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
446 CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
447 CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
451 void onSettingsChange(const std::string &name)
453 if (name == "enable_fog")
454 m_fog_enabled = g_settings->getBool("enable_fog");
457 static void settingsCallback(const std::string &name, void *userdata)
459 reinterpret_cast<GameGlobalShaderConstantSetter *>(userdata)
460 ->onSettingsChange(name);
463 void setSky(Sky *sky) { m_sky = sky; }
465 GameGlobalShaderConstantSetter(
466 Sky *sky, bool *force_fog_off, f32 *fog_range, Client *client) :
468 m_force_fog_off(force_fog_off), m_fog_range(fog_range),
469 m_sky_bg_color("skyBgColor"), m_fog_distance("fogDistance"),
470 m_animation_timer_vertex("animationTimer"),
471 m_animation_timer_pixel("animationTimer"),
472 m_day_light("dayLight"), m_eye_position_pixel("eyePosition"),
473 m_eye_position_vertex("eyePosition"), m_minimap_yaw("yawVec"),
474 m_camera_offset_pixel("cameraOffset"),
475 m_camera_offset_vertex("cameraOffset"),
476 m_base_texture("baseTexture"), m_normal_texture("normalTexture"),
477 m_texture_flags("textureFlags"), m_client(client)
479 g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
480 m_fog_enabled = g_settings->getBool("enable_fog");
483 ~GameGlobalShaderConstantSetter()
485 g_settings->deregisterChangedCallback(
486 "enable_fog", settingsCallback, this);
489 virtual void onSetConstants(
490 video::IMaterialRendererServices *services, bool is_highlevel)
496 video::SColor bgcolor = m_sky->getBgColor();
497 video::SColorf bgcolorf(bgcolor);
498 float bgcolorfa[4] = {
504 m_sky_bg_color.set(bgcolorfa, services);
507 float fog_distance = 10000 * BS;
509 if (m_fog_enabled && !*m_force_fog_off)
510 fog_distance = *m_fog_range;
512 m_fog_distance.set(&fog_distance, services);
514 u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
515 video::SColorf sunlight;
516 get_sunlight_color(&sunlight, daynight_ratio);
517 float dnc[3] = {sunlight.r, sunlight.g, sunlight.b};
518 m_day_light.set(dnc, services);
520 u32 animation_timer = porting::getTimeMs() % 1000000;
521 float animation_timer_f = (float)animation_timer / 100000.f;
522 m_animation_timer_vertex.set(&animation_timer_f, services);
523 m_animation_timer_pixel.set(&animation_timer_f, services);
525 float eye_position_array[3];
526 v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
527 #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
528 eye_position_array[0] = epos.X;
529 eye_position_array[1] = epos.Y;
530 eye_position_array[2] = epos.Z;
532 epos.getAs3Values(eye_position_array);
534 m_eye_position_pixel.set(eye_position_array, services);
535 m_eye_position_vertex.set(eye_position_array, services);
537 if (m_client->getMinimap()) {
538 float minimap_yaw_array[3];
539 v3f minimap_yaw = m_client->getMinimap()->getYawVec();
540 #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
541 minimap_yaw_array[0] = minimap_yaw.X;
542 minimap_yaw_array[1] = minimap_yaw.Y;
543 minimap_yaw_array[2] = minimap_yaw.Z;
545 minimap_yaw.getAs3Values(minimap_yaw_array);
547 m_minimap_yaw.set(minimap_yaw_array, services);
550 float camera_offset_array[3];
551 v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
552 #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
553 camera_offset_array[0] = offset.X;
554 camera_offset_array[1] = offset.Y;
555 camera_offset_array[2] = offset.Z;
557 offset.getAs3Values(camera_offset_array);
559 m_camera_offset_pixel.set(camera_offset_array, services);
560 m_camera_offset_vertex.set(camera_offset_array, services);
562 SamplerLayer_t base_tex = 0, normal_tex = 1, flags_tex = 2;
563 m_base_texture.set(&base_tex, services);
564 m_normal_texture.set(&normal_tex, services);
565 m_texture_flags.set(&flags_tex, services);
569 class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
572 bool *m_force_fog_off;
575 std::vector<GameGlobalShaderConstantSetter *> created_nosky;
578 GameGlobalShaderConstantSetterFactory(
579 bool *force_fog_off, f32 *fog_range, Client *client) :
581 m_force_fog_off(force_fog_off), m_fog_range(fog_range),
586 void setSky(Sky *sky)
589 for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
590 ggscs->setSky(m_sky);
592 created_nosky.clear();
595 virtual IShaderConstantSetter *create()
597 GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter(
598 m_sky, m_force_fog_off, m_fog_range, m_client);
600 created_nosky.push_back(scs);
606 #define SIZE_TAG "size[11,5.5]"
608 #define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
611 /****************************************************************************
613 ****************************************************************************/
615 const float object_hit_delay = 0.2;
619 u32 last_time, busy_time, sleep_time;
622 /* The reason the following structs are not anonymous structs within the
623 * class is that they are not used by the majority of member functions and
624 * many functions that do require objects of thse types do not modify them
625 * (so they can be passed as a const qualified parameter)
632 PointedThing pointed_old;
636 bool digging_blocked;
638 bool reset_jump_timer;
639 float nodig_delay_timer;
641 float dig_time_complete;
642 float repeat_rightclick_timer;
643 float object_hit_delay_timer;
644 float time_from_last_punch;
645 ClientActiveObject *selected_object;
649 float update_draw_list_timer;
653 v3f update_draw_list_last_cam_dir;
655 float time_of_day_smooth;
660 struct ClientEventHandler
662 void (Game::*handler)(ClientEvent *, CameraOrientation *);
671 bool startup(bool *kill, InputHandler *input, const GameStartData &game_params,
672 std::string &error_message, bool *reconnect,
673 ChatBackend *chat_backend);
678 void extendedResourceCleanup();
680 // Basic initialisation
681 bool init(const std::string &map_dir, const std::string &address, u16 port,
682 const SubgameSpec &gamespec);
684 bool createSingleplayerServer(const std::string &map_dir,
685 const SubgameSpec &gamespec, u16 port);
688 bool createClient(const GameStartData &start_data);
692 bool connectToServer(
693 const GameStartData &start_data, bool *connect_ok, bool *aborted);
694 bool getServerContent(bool *aborted);
698 void updateInteractTimers(f32 dtime);
699 bool checkConnection();
700 bool handleCallbacks();
701 void processQueues();
702 void updateProfilers(
703 const RunStats &stats, const FpsControl &draw_times, f32 dtime);
704 void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
705 void updateProfilerGraphs(ProfilerGraph *graph);
708 void processUserInput(f32 dtime);
709 void processKeyInput();
710 void processItemSelection(u16 *new_playeritem);
712 void dropSelectedItem(bool single_item = false);
713 void openInventory();
714 void openEnderchest();
715 void openConsole(float scale, const wchar_t *line = NULL);
716 void toggleFreeMove();
717 void toggleFreeMoveAlt();
718 void togglePitchMove();
721 void toggleKillaura();
722 void toggleFreecam();
723 void toggleScaffold();
724 void toggleNextItem();
725 void toggleCinematic();
726 void toggleAutoforward();
728 void toggleMinimap(bool shift_pressed);
731 void toggleUpdateCamera();
732 void updatePlayerCAOVisibility();
734 void increaseViewRange();
735 void decreaseViewRange();
736 void toggleFullViewRange();
737 void checkZoomEnabled();
739 void updateCameraDirection(CameraOrientation *cam, float dtime);
740 void updateCameraOrientation(CameraOrientation *cam, float dtime);
741 void updatePlayerControl(const CameraOrientation &cam);
742 void step(f32 *dtime);
743 void processClientEvents(CameraOrientation *cam);
744 void updateCamera(u32 busy_time, f32 dtime);
745 void updateSound(f32 dtime);
746 void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
748 * Returns the object or node the player is pointing at.
749 * Also updates the selected thing in the Hud.
751 * @param[in] shootline the shootline, starting from
752 * the camera position. This also gives the maximal distance
754 * @param[in] liquids_pointable if false, liquids are ignored
755 * @param[in] look_for_object if false, objects are ignored
756 * @param[in] camera_offset offset of the camera
757 * @param[out] selected_object the selected object or
760 PointedThing updatePointedThing(const core::line3d<f32> &shootline,
761 bool liquids_pointable, bool look_for_object,
762 const v3s16 &camera_offset);
763 void handlePointingAtNothing(const ItemStack &playerItem);
764 void handlePointingAtNode(const PointedThing &pointed,
765 const ItemStack &selected_item, const ItemStack &hand_item,
767 void handlePointingAtObject(const PointedThing &pointed,
768 const ItemStack &playeritem, const v3f &player_position,
770 void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
771 const ItemStack &selected_item, const ItemStack &hand_item,
773 void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
774 const CameraOrientation &cam);
777 void limitFps(FpsControl *fps_timings, f32 *dtime);
779 void showOverlayMessage(const char *msg, float dtime, int percent,
780 bool draw_clouds = true);
782 static void freecamChangedCallback(const std::string &setting_name, void *data);
783 static void settingChangedCallback(const std::string &setting_name, void *data);
784 static void updateAllMapBlocksCallback(
785 const std::string &setting_name, void *data);
788 inline bool isKeyDown(GameKeyType k) { return input->isKeyDown(k); }
789 inline bool wasKeyDown(GameKeyType k) { return input->wasKeyDown(k); }
792 void handleAndroidChatInput();
797 bool force_fog_off = false;
798 bool disable_camera_update = false;
801 void showDeathFormspec();
802 void showPauseMenu();
804 // ClientEvent handlers
805 void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
806 void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
807 void handleClientEvent_PlayerForceMove(
808 ClientEvent *event, CameraOrientation *cam);
809 void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
810 void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
811 void handleClientEvent_ShowLocalFormSpec(
812 ClientEvent *event, CameraOrientation *cam);
813 void handleClientEvent_HandleParticleEvent(
814 ClientEvent *event, CameraOrientation *cam);
815 void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
816 void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
817 void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
818 void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
819 void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
820 void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
821 void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
822 void handleClientEvent_OverrideDayNigthRatio(
823 ClientEvent *event, CameraOrientation *cam);
824 void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
826 void updateChat(f32 dtime, const v2u32 &screensize);
828 bool nodePlacement(const ItemDefinition &selected_def,
829 const ItemStack &selected_item, const v3s16 &nodepos,
830 const v3s16 &neighbourpos, const PointedThing &pointed,
831 const NodeMetadata *meta);
832 static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
834 InputHandler *input = nullptr;
836 Client *client = nullptr;
837 Server *server = nullptr;
839 IWritableTextureSource *texture_src = nullptr;
840 IWritableShaderSource *shader_src = nullptr;
842 // When created, these will be filled with data received from the server
843 IWritableItemDefManager *itemdef_manager = nullptr;
844 NodeDefManager *nodedef_manager = nullptr;
846 GameOnDemandSoundFetcher soundfetcher; // useful when testing
847 ISoundManager *sound = nullptr;
848 bool sound_is_dummy = false;
849 SoundMaker *soundmaker = nullptr;
851 ChatBackend *chat_backend = nullptr;
852 LogOutputBuffer m_chat_log_buf;
854 EventManager *eventmgr = nullptr;
855 QuicktuneShortcutter *quicktune = nullptr;
856 bool registration_confirmation_shown = false;
858 std::unique_ptr<GameUI> m_game_ui;
859 GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
860 CheatMenu *m_cheat_menu = nullptr;
861 MapDrawControl *draw_control = nullptr;
862 Camera *camera = nullptr;
863 Clouds *clouds = nullptr; // Free using ->Drop()
864 Sky *sky = nullptr; // Free using ->Drop()
866 Minimap *mapper = nullptr;
872 This class does take ownership/responsibily for cleaning up etc of any of
873 these items (e.g. device)
875 IrrlichtDevice *device;
876 video::IVideoDriver *driver;
877 scene::ISceneManager *smgr;
879 std::string *error_message;
880 bool *reconnect_requested;
881 scene::ISceneNode *skybox;
884 bool simple_singleplayer_mode;
887 /* Pre-calculated values
889 int crack_animation_length;
891 IntervalLimiter profiler_interval;
894 * TODO: Local caching of settings is not optimal and should at some stage
895 * be updated to use a global settings object for getting thse values
896 * (as opposed to the this local caching). This can be addressed in
899 bool m_cache_doubletap_jump;
900 bool m_cache_enable_clouds;
901 bool m_cache_enable_joysticks;
902 bool m_cache_enable_particles;
903 bool m_cache_enable_fog;
904 bool m_cache_enable_noclip;
905 bool m_cache_enable_free_move;
906 f32 m_cache_mouse_sensitivity;
907 f32 m_cache_joystick_frustum_sensitivity;
908 f32 m_repeat_right_click_time;
909 f32 m_cache_cam_smoothing;
910 f32 m_cache_fog_start;
912 bool m_invert_mouse = false;
913 bool m_first_loop_after_window_activation = false;
914 bool m_camera_offset_changed = false;
916 bool m_does_lost_focus_pause_game = false;
918 CameraOrientation cam_view_target = {0};
919 CameraOrientation cam_view = {0};
922 bool m_cache_hold_aux1;
923 bool m_android_chat_open;
928 void the_game(bool *kill, InputHandler *input, const GameStartData &start_data,
929 std::string &error_message, ChatBackend &chat_backend,
930 bool *reconnect_requested);