2011-04-23 08:31:31 -07:00
|
|
|
/*
|
2013-02-24 09:40:43 -08:00
|
|
|
Minetest
|
2013-02-24 10:38:45 -08:00
|
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
2011-04-23 08:31:31 -07:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
2012-06-05 07:56:56 -07:00
|
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
2011-04-23 08:31:31 -07:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2012-06-05 07:56:56 -07:00
|
|
|
GNU Lesser General Public License for more details.
|
2011-04-23 08:31:31 -07:00
|
|
|
|
2012-06-05 07:56:56 -07:00
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
2011-04-23 08:31:31 -07:00
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2017-08-17 13:19:39 -07:00
|
|
|
#pragma once
|
2011-04-23 08:31:31 -07:00
|
|
|
|
2020-06-23 08:43:47 -07:00
|
|
|
#include <iomanip>
|
|
|
|
#include <cmath>
|
|
|
|
#include "client/renderingengine.h"
|
|
|
|
#include "camera.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "client/clientevent.h"
|
|
|
|
//#include "client/gameui.h"
|
|
|
|
#include "client/inputhandler.h"
|
|
|
|
#include "client/sound.h"
|
|
|
|
#include "client/tile.h" // For TextureSource
|
|
|
|
#include "client/keys.h"
|
|
|
|
#include "client/joystick_controller.h"
|
|
|
|
#include "clientmap.h"
|
|
|
|
#include "clouds.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "content_cao.h"
|
|
|
|
#include "client/event_manager.h"
|
|
|
|
#include "fontengine.h"
|
|
|
|
#include "itemdef.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "filesys.h"
|
|
|
|
#include "gettext.h"
|
|
|
|
#include "gui/guiChatConsole.h"
|
|
|
|
#include "gui/guiConfirmRegistration.h"
|
|
|
|
#include "gui/guiFormSpecMenu.h"
|
|
|
|
#include "gui/guiKeyChangeMenu.h"
|
|
|
|
#include "gui/guiPasswordChange.h"
|
|
|
|
#include "gui/guiVolumeChange.h"
|
|
|
|
#include "gui/mainmenumanager.h"
|
|
|
|
#include "gui/profilergraph.h"
|
|
|
|
#include "mapblock.h"
|
|
|
|
#include "minimap.h"
|
|
|
|
#include "nodedef.h" // Needed for determining pointing to nodes
|
|
|
|
#include "nodemetadata.h"
|
|
|
|
#include "particles.h"
|
|
|
|
#include "porting.h"
|
|
|
|
#include "profiler.h"
|
|
|
|
#include "raycast.h"
|
|
|
|
#include "server.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "shader.h"
|
|
|
|
#include "sky.h"
|
|
|
|
#include "translation.h"
|
|
|
|
#include "util/basic_macros.h"
|
|
|
|
#include "util/directiontables.h"
|
|
|
|
#include "util/pointedthing.h"
|
|
|
|
#include "util/quicktune_shortcutter.h"
|
|
|
|
#include "irrlicht_changes/static_text.h"
|
|
|
|
#include "version.h"
|
|
|
|
#include "script/scripting_client.h"
|
|
|
|
#include "hud.h"
|
2017-06-26 11:11:17 -07:00
|
|
|
#include "irrlichttypes.h"
|
2011-04-23 08:31:31 -07:00
|
|
|
#include <string>
|
|
|
|
|
2017-05-13 02:05:16 -07:00
|
|
|
class InputHandler;
|
2011-12-03 00:01:14 -08:00
|
|
|
class ChatBackend; /* to avoid having to include chat.h */
|
2012-03-11 05:54:23 -07:00
|
|
|
struct SubgameSpec;
|
2011-12-03 00:01:14 -08:00
|
|
|
|
2018-01-03 08:28:57 -08:00
|
|
|
struct Jitter {
|
|
|
|
f32 max, min, avg, counter, max_sample, min_sample, max_fraction;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RunStats {
|
|
|
|
u32 drawtime;
|
|
|
|
|
|
|
|
Jitter dtime_jitter, busy_time_jitter;
|
|
|
|
};
|
|
|
|
|
2018-01-04 10:52:40 -08:00
|
|
|
struct CameraOrientation {
|
|
|
|
f32 camera_yaw; // "right/left"
|
|
|
|
f32 camera_pitch; // "up/down"
|
|
|
|
};
|
|
|
|
|
Refactor the_game() to make it more understandable and maintainable.
The following is a record of 31 commits before squashing:
Revert "Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism"
This reverts commit b49e5cfc7013cef7e9af79d17e04f7e7e4c377d4.
Basic reformatting with astyle
-- additional formatting will be modified, manually, as the need for it is encountered
Start "outlining" what a MinetestApp class might look like
Add MinetestApp::shutdown()
Converted class member functions to camelCase and created protos for new functions
First stage of connect to server done
Add get itemdefs/nodedefs/media code
Init clouds, camera, sky, init GUI, HUD
Input handling
Client events, camera, sound, draw
Fix wield hand getting stuck digging and add debug text back
Fix FPS
Added profiler graph back
Fix FPS issue
Need to work out what went wrong and clean up the copy/paste stuff
Annotate
Various:
Rewrote limitFps()
Limited scope of some variables
Jitter calcs
Reduce scope of objects
Move some stuff out of ::run and minor formatting cleanup
Scope reduction
Function splits
Removed old (broken) limitFps()
Added exception handling back
Fixed some formatting
Reverted commented out unit tests (uncommented them)
Slow clouds down on loading and media screens so the behaviour is like the original the_game()
Formatting/style (no functional changes)
Manually reapply upstream b49e5cf: Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism
Fixed silly errors on my part
Minor formatting cleanups
Removed strange differentiation in FPS limiting when loading
FPS limiting was done differently if cloud_menu_background was true, which does not make sense
Cleaning up
Add some comments
2014-10-31 05:13:04 -07:00
|
|
|
void the_game(bool *kill,
|
|
|
|
bool random_input,
|
|
|
|
InputHandler *input,
|
|
|
|
const std::string &map_dir,
|
|
|
|
const std::string &playername,
|
|
|
|
const std::string &password,
|
|
|
|
const std::string &address, // If "", local server is used
|
|
|
|
u16 port,
|
2015-03-27 17:24:04 -07:00
|
|
|
std::string &error_message,
|
Refactor the_game() to make it more understandable and maintainable.
The following is a record of 31 commits before squashing:
Revert "Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism"
This reverts commit b49e5cfc7013cef7e9af79d17e04f7e7e4c377d4.
Basic reformatting with astyle
-- additional formatting will be modified, manually, as the need for it is encountered
Start "outlining" what a MinetestApp class might look like
Add MinetestApp::shutdown()
Converted class member functions to camelCase and created protos for new functions
First stage of connect to server done
Add get itemdefs/nodedefs/media code
Init clouds, camera, sky, init GUI, HUD
Input handling
Client events, camera, sound, draw
Fix wield hand getting stuck digging and add debug text back
Fix FPS
Added profiler graph back
Fix FPS issue
Need to work out what went wrong and clean up the copy/paste stuff
Annotate
Various:
Rewrote limitFps()
Limited scope of some variables
Jitter calcs
Reduce scope of objects
Move some stuff out of ::run and minor formatting cleanup
Scope reduction
Function splits
Removed old (broken) limitFps()
Added exception handling back
Fixed some formatting
Reverted commented out unit tests (uncommented them)
Slow clouds down on loading and media screens so the behaviour is like the original the_game()
Formatting/style (no functional changes)
Manually reapply upstream b49e5cf: Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism
Fixed silly errors on my part
Minor formatting cleanups
Removed strange differentiation in FPS limiting when loading
FPS limiting was done differently if cloud_menu_background was true, which does not make sense
Cleaning up
Add some comments
2014-10-31 05:13:04 -07:00
|
|
|
ChatBackend &chat_backend,
|
2015-07-17 07:40:41 -07:00
|
|
|
bool *reconnect_requested,
|
Refactor the_game() to make it more understandable and maintainable.
The following is a record of 31 commits before squashing:
Revert "Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism"
This reverts commit b49e5cfc7013cef7e9af79d17e04f7e7e4c377d4.
Basic reformatting with astyle
-- additional formatting will be modified, manually, as the need for it is encountered
Start "outlining" what a MinetestApp class might look like
Add MinetestApp::shutdown()
Converted class member functions to camelCase and created protos for new functions
First stage of connect to server done
Add get itemdefs/nodedefs/media code
Init clouds, camera, sky, init GUI, HUD
Input handling
Client events, camera, sound, draw
Fix wield hand getting stuck digging and add debug text back
Fix FPS
Added profiler graph back
Fix FPS issue
Need to work out what went wrong and clean up the copy/paste stuff
Annotate
Various:
Rewrote limitFps()
Limited scope of some variables
Jitter calcs
Reduce scope of objects
Move some stuff out of ::run and minor formatting cleanup
Scope reduction
Function splits
Removed old (broken) limitFps()
Added exception handling back
Fixed some formatting
Reverted commented out unit tests (uncommented them)
Slow clouds down on loading and media screens so the behaviour is like the original the_game()
Formatting/style (no functional changes)
Manually reapply upstream b49e5cf: Remove m_ext_ptr in GUIFormSpecMenu, replaced by refcount mechanism
Fixed silly errors on my part
Minor formatting cleanups
Removed strange differentiation in FPS limiting when loading
FPS limiting was done differently if cloud_menu_background was true, which does not make sense
Cleaning up
Add some comments
2014-10-31 05:13:04 -07:00
|
|
|
const SubgameSpec &gamespec, // Used for local game
|
|
|
|
bool simple_singleplayer_mode);
|
2020-06-23 08:43:47 -07:00
|
|
|
struct TextDestNodeMetadata : public TextDest
|
|
|
|
{
|
|
|
|
TextDestNodeMetadata(v3s16 p, Client *client)
|
|
|
|
{
|
|
|
|
m_p = p;
|
|
|
|
m_client = client;
|
|
|
|
}
|
|
|
|
// This is deprecated I guess? -celeron55
|
|
|
|
void gotText(const std::wstring &text)
|
|
|
|
{
|
|
|
|
std::string ntext = wide_to_utf8(text);
|
|
|
|
infostream << "Submitting 'text' field of node at (" << m_p.X << ","
|
|
|
|
<< m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
|
|
|
|
StringMap fields;
|
|
|
|
fields["text"] = ntext;
|
|
|
|
m_client->sendNodemetaFields(m_p, "", fields);
|
|
|
|
}
|
|
|
|
void gotText(const StringMap &fields)
|
|
|
|
{
|
|
|
|
m_client->sendNodemetaFields(m_p, "", fields);
|
|
|
|
}
|
|
|
|
|
|
|
|
v3s16 m_p;
|
|
|
|
Client *m_client;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TextDestPlayerInventory : public TextDest
|
|
|
|
{
|
|
|
|
TextDestPlayerInventory(Client *client)
|
|
|
|
{
|
|
|
|
m_client = client;
|
|
|
|
m_formname = "";
|
|
|
|
}
|
|
|
|
TextDestPlayerInventory(Client *client, const std::string &formname)
|
|
|
|
{
|
|
|
|
m_client = client;
|
|
|
|
m_formname = formname;
|
|
|
|
}
|
|
|
|
void gotText(const StringMap &fields)
|
|
|
|
{
|
|
|
|
m_client->sendInventoryFields(m_formname, fields);
|
|
|
|
}
|
|
|
|
|
|
|
|
Client *m_client;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LocalFormspecHandler : public TextDest
|
|
|
|
{
|
|
|
|
LocalFormspecHandler(const std::string &formname)
|
|
|
|
{
|
|
|
|
m_formname = formname;
|
|
|
|
}
|
|
|
|
|
|
|
|
LocalFormspecHandler(const std::string &formname, Client *client):
|
|
|
|
m_client(client)
|
|
|
|
{
|
|
|
|
m_formname = formname;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gotText(const StringMap &fields)
|
|
|
|
{
|
|
|
|
if (m_formname == "MT_PAUSE_MENU") {
|
|
|
|
if (fields.find("btn_sound") != fields.end()) {
|
|
|
|
g_gamecallback->changeVolume();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("btn_key_config") != fields.end()) {
|
|
|
|
g_gamecallback->keyConfig();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("btn_exit_menu") != fields.end()) {
|
|
|
|
g_gamecallback->disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("btn_exit_os") != fields.end()) {
|
|
|
|
g_gamecallback->exitToOS();
|
|
|
|
#ifndef __ANDROID__
|
|
|
|
RenderingEngine::get_raw_device()->closeDevice();
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("btn_change_password") != fields.end()) {
|
|
|
|
g_gamecallback->changePassword();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("quit") != fields.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields.find("btn_continue") != fields.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_formname == "MT_DEATH_SCREEN") {
|
|
|
|
assert(m_client != 0);
|
|
|
|
m_client->sendRespawn();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_client && m_client->modsLoaded())
|
|
|
|
m_client->getScript()->on_formspec_input(m_formname, fields);
|
|
|
|
}
|
|
|
|
|
|
|
|
Client *m_client = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Form update callback */
|
|
|
|
|
|
|
|
class NodeMetadataFormSource: public IFormSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NodeMetadataFormSource(ClientMap *map, v3s16 p):
|
|
|
|
m_map(map),
|
|
|
|
m_p(p)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
const std::string &getForm() const
|
|
|
|
{
|
|
|
|
static const std::string empty_string = "";
|
|
|
|
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
|
|
|
|
|
|
|
if (!meta)
|
|
|
|
return empty_string;
|
|
|
|
|
|
|
|
return meta->getString("formspec");
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual std::string resolveText(const std::string &str)
|
|
|
|
{
|
|
|
|
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
|
|
|
|
|
|
|
if (!meta)
|
|
|
|
return str;
|
|
|
|
|
|
|
|
return meta->resolveString(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
ClientMap *m_map;
|
|
|
|
v3s16 m_p;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlayerInventoryFormSource: public IFormSource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PlayerInventoryFormSource(Client *client):
|
|
|
|
m_client(client)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string &getForm() const
|
|
|
|
{
|
|
|
|
LocalPlayer *player = m_client->getEnv().getLocalPlayer();
|
|
|
|
return player->inventory_formspec;
|
|
|
|
}
|
|
|
|
|
|
|
|
Client *m_client;
|
|
|
|
};
|
|
|
|
|
|
|
|
class NodeDugEvent: public MtEvent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
v3s16 p;
|
|
|
|
MapNode n;
|
|
|
|
|
|
|
|
NodeDugEvent(v3s16 p, MapNode n):
|
|
|
|
p(p),
|
|
|
|
n(n)
|
|
|
|
{}
|
|
|
|
MtEvent::Type getType() const
|
|
|
|
{
|
|
|
|
return MtEvent::NODE_DUG;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class SoundMaker
|
|
|
|
{
|
|
|
|
ISoundManager *m_sound;
|
|
|
|
const NodeDefManager *m_ndef;
|
|
|
|
public:
|
|
|
|
bool makes_footstep_sound;
|
|
|
|
float m_player_step_timer;
|
|
|
|
|
|
|
|
SimpleSoundSpec m_player_step_sound;
|
|
|
|
SimpleSoundSpec m_player_leftpunch_sound;
|
|
|
|
SimpleSoundSpec m_player_rightpunch_sound;
|
|
|
|
|
|
|
|
SoundMaker(ISoundManager *sound, const NodeDefManager *ndef):
|
|
|
|
m_sound(sound),
|
|
|
|
m_ndef(ndef),
|
|
|
|
makes_footstep_sound(true),
|
|
|
|
m_player_step_timer(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void playPlayerStep()
|
|
|
|
{
|
|
|
|
if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
|
|
|
|
m_player_step_timer = 0.03;
|
|
|
|
if (makes_footstep_sound)
|
|
|
|
m_sound->playSound(m_player_step_sound, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void viewBobbingStep(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->playPlayerStep();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void playerRegainGround(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->playPlayerStep();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void playerJump(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
//SoundMaker *sm = (SoundMaker*)data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cameraPunchLeft(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cameraPunchRight(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nodeDug(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
NodeDugEvent *nde = (NodeDugEvent *)e;
|
|
|
|
sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void playerDamage(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void playerFallingDamage(MtEvent *e, void *data)
|
|
|
|
{
|
|
|
|
SoundMaker *sm = (SoundMaker *)data;
|
|
|
|
sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void registerReceiver(MtEventManager *mgr)
|
|
|
|
{
|
|
|
|
mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
|
|
|
|
mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
|
|
|
|
mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
|
|
|
|
mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
|
|
|
|
mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
|
|
|
|
mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
|
|
|
|
mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
|
|
|
|
mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void step(float dtime)
|
|
|
|
{
|
|
|
|
m_player_step_timer -= dtime;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Locally stored sounds don't need to be preloaded because of this
|
|
|
|
class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
|
|
|
|
{
|
|
|
|
std::set<std::string> m_fetched;
|
|
|
|
private:
|
|
|
|
void paths_insert(std::set<std::string> &dst_paths,
|
|
|
|
const std::string &base,
|
|
|
|
const std::string &name)
|
|
|
|
{
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg");
|
|
|
|
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
void fetchSounds(const std::string &name,
|
|
|
|
std::set<std::string> &dst_paths,
|
|
|
|
std::set<std::string> &dst_datas)
|
|
|
|
{
|
|
|
|
if (m_fetched.count(name))
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_fetched.insert(name);
|
|
|
|
|
|
|
|
paths_insert(dst_paths, porting::path_share, name);
|
|
|
|
paths_insert(dst_paths, porting::path_user, name);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// before 1.8 there isn't a "integer interface", only float
|
|
|
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
|
|
|
typedef f32 SamplerLayer_t;
|
|
|
|
#else
|
|
|
|
typedef s32 SamplerLayer_t;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
|
|
|
{
|
|
|
|
Sky *m_sky;
|
|
|
|
bool *m_force_fog_off;
|
|
|
|
f32 *m_fog_range;
|
|
|
|
bool m_fog_enabled;
|
|
|
|
CachedPixelShaderSetting<float, 4> m_sky_bg_color;
|
|
|
|
CachedPixelShaderSetting<float> m_fog_distance;
|
|
|
|
CachedVertexShaderSetting<float> m_animation_timer_vertex;
|
|
|
|
CachedPixelShaderSetting<float> m_animation_timer_pixel;
|
|
|
|
CachedPixelShaderSetting<float, 3> m_day_light;
|
|
|
|
CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
|
|
|
|
CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
|
|
|
|
CachedPixelShaderSetting<float, 3> m_minimap_yaw;
|
|
|
|
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
|
|
|
|
CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
|
|
|
|
CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
|
|
|
|
CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
|
|
|
|
CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
|
|
|
|
Client *m_client;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void onSettingsChange(const std::string &name)
|
|
|
|
{
|
|
|
|
if (name == "enable_fog")
|
|
|
|
m_fog_enabled = g_settings->getBool("enable_fog");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void settingsCallback(const std::string &name, void *userdata)
|
|
|
|
{
|
|
|
|
reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setSky(Sky *sky) { m_sky = sky; }
|
|
|
|
|
|
|
|
GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
|
|
|
|
f32 *fog_range, Client *client) :
|
|
|
|
m_sky(sky),
|
|
|
|
m_force_fog_off(force_fog_off),
|
|
|
|
m_fog_range(fog_range),
|
|
|
|
m_sky_bg_color("skyBgColor"),
|
|
|
|
m_fog_distance("fogDistance"),
|
|
|
|
m_animation_timer_vertex("animationTimer"),
|
|
|
|
m_animation_timer_pixel("animationTimer"),
|
|
|
|
m_day_light("dayLight"),
|
|
|
|
m_eye_position_pixel("eyePosition"),
|
|
|
|
m_eye_position_vertex("eyePosition"),
|
|
|
|
m_minimap_yaw("yawVec"),
|
|
|
|
m_camera_offset_pixel("cameraOffset"),
|
|
|
|
m_camera_offset_vertex("cameraOffset"),
|
|
|
|
m_base_texture("baseTexture"),
|
|
|
|
m_normal_texture("normalTexture"),
|
|
|
|
m_texture_flags("textureFlags"),
|
|
|
|
m_client(client)
|
|
|
|
{
|
|
|
|
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
|
|
|
|
m_fog_enabled = g_settings->getBool("enable_fog");
|
|
|
|
}
|
|
|
|
|
|
|
|
~GameGlobalShaderConstantSetter()
|
|
|
|
{
|
|
|
|
g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
|
|
|
bool is_highlevel)
|
|
|
|
{
|
|
|
|
if (!is_highlevel)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Background color
|
|
|
|
video::SColor bgcolor = m_sky->getBgColor();
|
|
|
|
video::SColorf bgcolorf(bgcolor);
|
|
|
|
float bgcolorfa[4] = {
|
|
|
|
bgcolorf.r,
|
|
|
|
bgcolorf.g,
|
|
|
|
bgcolorf.b,
|
|
|
|
bgcolorf.a,
|
|
|
|
};
|
|
|
|
m_sky_bg_color.set(bgcolorfa, services);
|
|
|
|
|
|
|
|
// Fog distance
|
|
|
|
float fog_distance = 10000 * BS;
|
|
|
|
|
|
|
|
if (m_fog_enabled && !*m_force_fog_off)
|
|
|
|
fog_distance = *m_fog_range;
|
|
|
|
|
|
|
|
m_fog_distance.set(&fog_distance, services);
|
|
|
|
|
|
|
|
u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
|
|
|
|
video::SColorf sunlight;
|
|
|
|
get_sunlight_color(&sunlight, daynight_ratio);
|
|
|
|
float dnc[3] = {
|
|
|
|
sunlight.r,
|
|
|
|
sunlight.g,
|
|
|
|
sunlight.b };
|
|
|
|
m_day_light.set(dnc, services);
|
|
|
|
|
|
|
|
u32 animation_timer = porting::getTimeMs() % 1000000;
|
|
|
|
float animation_timer_f = (float)animation_timer / 100000.f;
|
|
|
|
m_animation_timer_vertex.set(&animation_timer_f, services);
|
|
|
|
m_animation_timer_pixel.set(&animation_timer_f, services);
|
|
|
|
|
|
|
|
float eye_position_array[3];
|
|
|
|
v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
|
|
|
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
|
|
|
eye_position_array[0] = epos.X;
|
|
|
|
eye_position_array[1] = epos.Y;
|
|
|
|
eye_position_array[2] = epos.Z;
|
|
|
|
#else
|
|
|
|
epos.getAs3Values(eye_position_array);
|
|
|
|
#endif
|
|
|
|
m_eye_position_pixel.set(eye_position_array, services);
|
|
|
|
m_eye_position_vertex.set(eye_position_array, services);
|
|
|
|
|
|
|
|
if (m_client->getMinimap()) {
|
|
|
|
float minimap_yaw_array[3];
|
|
|
|
v3f minimap_yaw = m_client->getMinimap()->getYawVec();
|
|
|
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
|
|
|
minimap_yaw_array[0] = minimap_yaw.X;
|
|
|
|
minimap_yaw_array[1] = minimap_yaw.Y;
|
|
|
|
minimap_yaw_array[2] = minimap_yaw.Z;
|
|
|
|
#else
|
|
|
|
minimap_yaw.getAs3Values(minimap_yaw_array);
|
|
|
|
#endif
|
|
|
|
m_minimap_yaw.set(minimap_yaw_array, services);
|
|
|
|
}
|
|
|
|
|
|
|
|
float camera_offset_array[3];
|
|
|
|
v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
|
|
|
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
|
|
|
camera_offset_array[0] = offset.X;
|
|
|
|
camera_offset_array[1] = offset.Y;
|
|
|
|
camera_offset_array[2] = offset.Z;
|
|
|
|
#else
|
|
|
|
offset.getAs3Values(camera_offset_array);
|
|
|
|
#endif
|
|
|
|
m_camera_offset_pixel.set(camera_offset_array, services);
|
|
|
|
m_camera_offset_vertex.set(camera_offset_array, services);
|
|
|
|
|
|
|
|
SamplerLayer_t base_tex = 0,
|
|
|
|
normal_tex = 1,
|
|
|
|
flags_tex = 2;
|
|
|
|
m_base_texture.set(&base_tex, services);
|
|
|
|
m_normal_texture.set(&normal_tex, services);
|
|
|
|
m_texture_flags.set(&flags_tex, services);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
|
|
|
|
{
|
|
|
|
Sky *m_sky;
|
|
|
|
bool *m_force_fog_off;
|
|
|
|
f32 *m_fog_range;
|
|
|
|
Client *m_client;
|
|
|
|
std::vector<GameGlobalShaderConstantSetter *> created_nosky;
|
|
|
|
public:
|
|
|
|
GameGlobalShaderConstantSetterFactory(bool *force_fog_off,
|
|
|
|
f32 *fog_range, Client *client) :
|
|
|
|
m_sky(NULL),
|
|
|
|
m_force_fog_off(force_fog_off),
|
|
|
|
m_fog_range(fog_range),
|
|
|
|
m_client(client)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void setSky(Sky *sky) {
|
|
|
|
m_sky = sky;
|
|
|
|
for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
|
|
|
|
ggscs->setSky(m_sky);
|
|
|
|
}
|
|
|
|
created_nosky.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual IShaderConstantSetter* create()
|
|
|
|
{
|
|
|
|
GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter(
|
|
|
|
m_sky, m_force_fog_off, m_fog_range, m_client);
|
|
|
|
if (!m_sky)
|
|
|
|
created_nosky.push_back(scs);
|
|
|
|
return scs;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
#define SIZE_TAG "size[11,5.5]"
|
|
|
|
#else
|
|
|
|
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
const float object_hit_delay = 0.2;
|
|
|
|
|
|
|
|
struct FpsControl {
|
|
|
|
u32 last_time, busy_time, sleep_time;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* The reason the following structs are not anonymous structs within the
|
|
|
|
* class is that they are not used by the majority of member functions and
|
|
|
|
* many functions that do require objects of thse types do not modify them
|
|
|
|
* (so they can be passed as a const qualified parameter)
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct GameRunData {
|
|
|
|
u16 dig_index;
|
|
|
|
u16 new_playeritem;
|
|
|
|
PointedThing pointed_old;
|
|
|
|
bool digging;
|
|
|
|
bool ldown_for_dig;
|
|
|
|
bool dig_instantly;
|
|
|
|
bool digging_blocked;
|
|
|
|
bool left_punch;
|
|
|
|
bool reset_jump_timer;
|
|
|
|
float nodig_delay_timer;
|
|
|
|
float dig_time;
|
|
|
|
float dig_time_complete;
|
|
|
|
float repeat_rightclick_timer;
|
|
|
|
float object_hit_delay_timer;
|
|
|
|
float time_from_last_punch;
|
|
|
|
ClientActiveObject *selected_object;
|
|
|
|
|
|
|
|
float jump_timer;
|
|
|
|
float damage_flash;
|
|
|
|
float update_draw_list_timer;
|
|
|
|
|
|
|
|
f32 fog_range;
|
|
|
|
|
|
|
|
v3f update_draw_list_last_cam_dir;
|
|
|
|
|
|
|
|
float time_of_day_smooth;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Game;
|
|
|
|
|
|
|
|
struct ClientEventHandler
|
|
|
|
{
|
|
|
|
void (Game::*handler)(ClientEvent *, CameraOrientation *);
|
|
|
|
};
|
|
|
|
|
|
|
|
class Game {
|
|
|
|
public:
|
|
|
|
Game();
|
|
|
|
~Game();
|
|
|
|
|
|
|
|
bool startup(bool *kill,
|
|
|
|
bool random_input,
|
|
|
|
InputHandler *input,
|
|
|
|
const std::string &map_dir,
|
|
|
|
const std::string &playername,
|
|
|
|
const std::string &password,
|
|
|
|
// If address is "", local server is used and address is updated
|
|
|
|
std::string *address,
|
|
|
|
u16 port,
|
|
|
|
std::string &error_message,
|
|
|
|
bool *reconnect,
|
|
|
|
ChatBackend *chat_backend,
|
|
|
|
const SubgameSpec &gamespec, // Used for local game
|
|
|
|
bool simple_singleplayer_mode);
|
|
|
|
|
|
|
|
void run();
|
|
|
|
void shutdown();
|
|
|
|
|
|
|
|
|
|
|
|
void extendedResourceCleanup();
|
|
|
|
|
|
|
|
// Basic initialisation
|
|
|
|
bool init(const std::string &map_dir, std::string *address,
|
|
|
|
u16 port,
|
|
|
|
const SubgameSpec &gamespec);
|
|
|
|
bool initSound();
|
|
|
|
bool createSingleplayerServer(const std::string &map_dir,
|
|
|
|
const SubgameSpec &gamespec, u16 port, std::string *address);
|
|
|
|
|
|
|
|
// Client creation
|
|
|
|
bool createClient(const std::string &playername,
|
|
|
|
const std::string &password, std::string *address, u16 port);
|
|
|
|
bool initGui();
|
|
|
|
|
|
|
|
// Client connection
|
|
|
|
bool connectToServer(const std::string &playername,
|
|
|
|
const std::string &password, std::string *address, u16 port,
|
|
|
|
bool *connect_ok, bool *aborted);
|
|
|
|
bool getServerContent(bool *aborted);
|
|
|
|
|
|
|
|
// Main loop
|
|
|
|
|
|
|
|
void updateInteractTimers(f32 dtime);
|
|
|
|
bool checkConnection();
|
|
|
|
bool handleCallbacks();
|
|
|
|
void processQueues();
|
|
|
|
void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
|
|
|
|
void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
|
|
|
|
void updateProfilerGraphs(ProfilerGraph *graph);
|
|
|
|
|
|
|
|
// Input related
|
|
|
|
void processUserInput(f32 dtime);
|
|
|
|
void processKeyInput();
|
|
|
|
void processItemSelection(u16 *new_playeritem);
|
|
|
|
|
|
|
|
void dropSelectedItem(bool single_item = false);
|
|
|
|
void openInventory();
|
|
|
|
void openConsole(float scale, const wchar_t *line=NULL);
|
|
|
|
void toggleFreeMove();
|
|
|
|
void toggleFreeMoveAlt();
|
|
|
|
void togglePitchMove();
|
|
|
|
void toggleFast();
|
|
|
|
void toggleNoClip();
|
|
|
|
void toggleCinematic();
|
|
|
|
void toggleAutoforward();
|
|
|
|
|
|
|
|
void toggleMinimap(bool shift_pressed);
|
|
|
|
void toggleFog();
|
|
|
|
void toggleDebug();
|
|
|
|
void toggleUpdateCamera();
|
|
|
|
|
|
|
|
void increaseViewRange();
|
|
|
|
void decreaseViewRange();
|
|
|
|
void toggleFullViewRange();
|
|
|
|
void checkZoomEnabled();
|
|
|
|
|
|
|
|
void updateCameraDirection(CameraOrientation *cam, float dtime);
|
|
|
|
void updateCameraOrientation(CameraOrientation *cam, float dtime);
|
|
|
|
void updatePlayerControl(const CameraOrientation &cam);
|
|
|
|
void step(f32 *dtime);
|
|
|
|
void processClientEvents(CameraOrientation *cam);
|
|
|
|
void updateCamera(u32 busy_time, f32 dtime);
|
|
|
|
void updateSound(f32 dtime);
|
|
|
|
void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
|
|
|
|
/*!
|
|
|
|
* Returns the object or node the player is pointing at.
|
|
|
|
* Also updates the selected thing in the Hud.
|
|
|
|
*
|
|
|
|
* @param[in] shootline the shootline, starting from
|
|
|
|
* the camera position. This also gives the maximal distance
|
|
|
|
* of the search.
|
|
|
|
* @param[in] liquids_pointable if false, liquids are ignored
|
|
|
|
* @param[in] look_for_object if false, objects are ignored
|
|
|
|
* @param[in] camera_offset offset of the camera
|
|
|
|
* @param[out] selected_object the selected object or
|
|
|
|
* NULL if not found
|
|
|
|
*/
|
|
|
|
PointedThing updatePointedThing(
|
|
|
|
const core::line3d<f32> &shootline, bool liquids_pointable,
|
|
|
|
bool look_for_object, const v3s16 &camera_offset);
|
|
|
|
void handlePointingAtNothing(const ItemStack &playerItem);
|
|
|
|
void handlePointingAtNode(const PointedThing &pointed,
|
|
|
|
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
|
|
|
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
|
|
|
|
const v3f &player_position, bool show_debug);
|
|
|
|
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
|
|
|
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
|
|
|
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
|
|
|
const CameraOrientation &cam);
|
|
|
|
|
|
|
|
// Misc
|
|
|
|
void limitFps(FpsControl *fps_timings, f32 *dtime);
|
|
|
|
|
|
|
|
void showOverlayMessage(const char *msg, float dtime, int percent,
|
|
|
|
bool draw_clouds = true);
|
|
|
|
|
|
|
|
static void settingChangedCallback(const std::string &setting_name, void *data);
|
|
|
|
void readSettings();
|
|
|
|
|
|
|
|
inline bool isKeyDown(GameKeyType k)
|
|
|
|
{
|
|
|
|
return input->isKeyDown(k);
|
|
|
|
}
|
|
|
|
inline bool wasKeyDown(GameKeyType k)
|
|
|
|
{
|
|
|
|
return input->wasKeyDown(k);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
void handleAndroidChatInput();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct Flags {
|
|
|
|
bool force_fog_off = false;
|
|
|
|
bool disable_camera_update = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
void showDeathFormspec();
|
|
|
|
void showPauseMenu();
|
|
|
|
|
|
|
|
// ClientEvent handlers
|
|
|
|
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
|
|
|
|
CameraOrientation *cam);
|
|
|
|
void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
|
|
|
CameraOrientation *cam);
|
|
|
|
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
|
|
|
|
|
|
|
void updateChat(f32 dtime, const v2u32 &screensize);
|
|
|
|
|
|
|
|
bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
|
|
|
|
const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
|
|
|
|
const NodeMetadata *meta);
|
|
|
|
static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
|
|
|
|
|
|
|
|
InputHandler *input = nullptr;
|
|
|
|
|
|
|
|
Client *client = nullptr;
|
|
|
|
Server *server = nullptr;
|
|
|
|
|
|
|
|
IWritableTextureSource *texture_src = nullptr;
|
|
|
|
IWritableShaderSource *shader_src = nullptr;
|
|
|
|
|
|
|
|
// When created, these will be filled with data received from the server
|
|
|
|
IWritableItemDefManager *itemdef_manager = nullptr;
|
|
|
|
NodeDefManager *nodedef_manager = nullptr;
|
|
|
|
|
|
|
|
GameOnDemandSoundFetcher soundfetcher; // useful when testing
|
|
|
|
ISoundManager *sound = nullptr;
|
|
|
|
bool sound_is_dummy = false;
|
|
|
|
SoundMaker *soundmaker = nullptr;
|
|
|
|
|
|
|
|
ChatBackend *chat_backend = nullptr;
|
|
|
|
|
|
|
|
EventManager *eventmgr = nullptr;
|
|
|
|
QuicktuneShortcutter *quicktune = nullptr;
|
|
|
|
bool registration_confirmation_shown = false;
|
|
|
|
|
|
|
|
std::unique_ptr<GameUI> m_game_ui;
|
|
|
|
GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
|
|
|
|
MapDrawControl *draw_control = nullptr;
|
|
|
|
Camera *camera = nullptr;
|
|
|
|
Clouds *clouds = nullptr; // Free using ->Drop()
|
|
|
|
Sky *sky = nullptr; // Free using ->Drop()
|
|
|
|
Hud *hud = nullptr;
|
|
|
|
Minimap *mapper = nullptr;
|
|
|
|
|
|
|
|
GameRunData runData;
|
|
|
|
Flags m_flags;
|
|
|
|
|
|
|
|
/* 'cache'
|
|
|
|
This class does take ownership/responsibily for cleaning up etc of any of
|
|
|
|
these items (e.g. device)
|
|
|
|
*/
|
|
|
|
IrrlichtDevice *device;
|
|
|
|
video::IVideoDriver *driver;
|
|
|
|
scene::ISceneManager *smgr;
|
|
|
|
bool *kill;
|
|
|
|
std::string *error_message;
|
|
|
|
bool *reconnect_requested;
|
|
|
|
scene::ISceneNode *skybox;
|
|
|
|
|
|
|
|
bool random_input;
|
|
|
|
bool simple_singleplayer_mode;
|
|
|
|
/* End 'cache' */
|
|
|
|
|
|
|
|
/* Pre-calculated values
|
|
|
|
*/
|
|
|
|
int crack_animation_length;
|
|
|
|
|
|
|
|
IntervalLimiter profiler_interval;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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_clouds;
|
|
|
|
bool m_cache_enable_joysticks;
|
|
|
|
bool m_cache_enable_particles;
|
|
|
|
bool m_cache_enable_fog;
|
|
|
|
bool m_cache_enable_noclip;
|
|
|
|
bool m_cache_enable_free_move;
|
|
|
|
f32 m_cache_mouse_sensitivity;
|
|
|
|
f32 m_cache_joystick_frustum_sensitivity;
|
|
|
|
f32 m_repeat_right_click_time;
|
|
|
|
f32 m_cache_cam_smoothing;
|
|
|
|
f32 m_cache_fog_start;
|
|
|
|
|
|
|
|
bool m_invert_mouse = false;
|
|
|
|
bool m_first_loop_after_window_activation = false;
|
|
|
|
bool m_camera_offset_changed = false;
|
|
|
|
|
|
|
|
bool m_does_lost_focus_pause_game = false;
|
|
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
bool m_cache_hold_aux1;
|
|
|
|
bool m_android_chat_open;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
extern Game *g_game;
|