X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fenvironment.h;h=b4884fdb3849ae38f3ab4a9f97ef7ae06383688d;hb=393c8392821bf3357d2ada3ac0afe065758acc53;hp=9e282476fd82a34399c10f06ac6d0e2cf7b4d462;hpb=89f7dc1efd6b0062b4b9e5c3509c301ccadb7a13;p=dragonfireclient.git diff --git a/src/environment.h b/src/environment.h index 9e282476f..b4884fdb3 100644 --- a/src/environment.h +++ b/src/environment.h @@ -17,8 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef ENVIRONMENT_HEADER -#define ENVIRONMENT_HEADER +#pragma once /* This class is the game's environment. @@ -30,32 +29,27 @@ with this program; if not, write to the Free Software Foundation, Inc., - etc. */ -#include #include +#include #include +#include +#include #include "irr_v3d.h" -#include "activeobject.h" -#include "util/numeric.h" -#include "mapnode.h" -#include "mapblock.h" +#include "network/networkprotocol.h" // for AccessDeniedCode +#include "util/basic_macros.h" -class ServerEnvironment; -class ActiveBlockModifier; -class ServerActiveObject; -class ITextureSource; class IGameDef; class Map; -class ServerMap; -class ClientMap; -class GameScripting; -class Player; +struct PointedThing; +class RaycastState; class Environment { public: // Environment will delete the map passed to the constructor - Environment(); - virtual ~Environment(); + Environment(IGameDef *gamedef); + virtual ~Environment() = default; + DISABLE_CLASS_COPY(Environment); /* Step everything in environment. @@ -65,459 +59,98 @@ class Environment */ virtual void step(f32 dtime) = 0; - virtual Map & getMap() = 0; + virtual Map &getMap() = 0; - virtual void addPlayer(Player *player); - void removePlayer(u16 peer_id); - Player * getPlayer(u16 peer_id); - Player * getPlayer(const char *name); - Player * getRandomConnectedPlayer(); - Player * getNearestConnectedPlayer(v3f pos); - std::list getPlayers(); - std::list getPlayers(bool ignore_disconnected); - u32 getDayNightRatio(); // 0-23999 - virtual void setTimeOfDay(u32 time) - { - m_time_of_day = time; - m_time_of_day_f = (float)time / 24000.0; - } - - u32 getTimeOfDay() - { return m_time_of_day; } - - float getTimeOfDayF() - { return m_time_of_day_f; } + virtual void setTimeOfDay(u32 time); + u32 getTimeOfDay(); + float getTimeOfDayF(); void stepTimeOfDay(float dtime); - void setTimeOfDaySpeed(float speed) - { m_time_of_day_speed = speed; } - - float getTimeOfDaySpeed() - { return m_time_of_day_speed; } - - void setDayNightRatioOverride(bool enable, u32 value) - { - m_enable_day_night_ratio_override = enable; - m_day_night_ratio_override = value; - } + void setTimeOfDaySpeed(float speed); + + void setDayNightRatioOverride(bool enable, u32 value); + + u32 getDayCount(); + + /*! + * Returns false if the given line intersects with a + * non-air node, true otherwise. + * \param pos1 start of the line + * \param pos2 end of the line + * \param p output, position of the first non-air node + * the line intersects + */ + bool line_of_sight(v3f pos1, v3f pos2, v3s16 *p = nullptr); + + /*! + * Gets the objects pointed by the shootline as + * pointed things. + * If this is a client environment, the local player + * won't be returned. + * @param[in] shootline_on_map the shootline for + * the test in world coordinates + * + * @param[out] objects found objects + */ + virtual void getSelectedActiveObjects(const core::line3d &shootline_on_map, + std::vector &objects) = 0; + + /*! + * Returns the next node or object the shootline meets. + * @param state current state of the raycast + * @result output, will contain the next pointed thing + */ + void continueRaycast(RaycastState *state, PointedThing *result); + + // counter used internally when triggering ABMs + u32 m_added_objects; + + IGameDef *getGameDef() { return m_gamedef; } protected: - // peer_ids in here should be unique, except that there may be many 0s - std::list m_players; - // Time of day in milli-hours (0-23999); determines day and night + std::atomic m_time_of_day_speed; + + /* + * Below: values managed by m_time_lock + */ + // Time of day in milli-hours (0-23999), determines day and night u32 m_time_of_day; // Time of day in 0...1 float m_time_of_day_f; - float m_time_of_day_speed; - // Used to buffer dtime for adding to m_time_of_day - float m_time_counter; + // Stores the skew created by the float -> u32 conversion + // to be applied at next conversion, so that there is no real skew. + float m_time_conversion_skew = 0.0f; // Overriding the day-night ratio is useful for custom sky visuals - bool m_enable_day_night_ratio_override; - u32 m_day_night_ratio_override; -}; - -/* - Active block modifier interface. - - These are fed into ServerEnvironment at initialization time; - ServerEnvironment handles deleting them. -*/ - -class ActiveBlockModifier -{ -public: - ActiveBlockModifier(){}; - virtual ~ActiveBlockModifier(){}; - - // Set of contents to trigger on - virtual std::set getTriggerContents()=0; - // Set of required neighbors (trigger doesn't happen if none are found) - // Empty = do not check neighbors - virtual std::set getRequiredNeighbors() - { return std::set(); } - // Trigger interval in seconds - virtual float getTriggerInterval() = 0; - // Random chance of (1 / return value), 0 is disallowed - virtual u32 getTriggerChance() = 0; - // This is called usually at interval for 1/chance of the nodes - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){}; - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, - u32 active_object_count, u32 active_object_count_wider){}; -}; - -struct ABMWithState -{ - ActiveBlockModifier *abm; - float timer; - - ABMWithState(ActiveBlockModifier *abm_); -}; - -/* - List of active blocks, used by ServerEnvironment -*/ - -class ActiveBlockList -{ -public: - void update(std::list &active_positions, - s16 radius, - std::set &blocks_removed, - std::set &blocks_added); - - bool contains(v3s16 p){ - return (m_list.find(p) != m_list.end()); - } - - void clear(){ - m_list.clear(); - } - - std::set m_list; - std::set m_forceloaded_list; - -private: -}; - -/* - The server-side environment. - - This is not thread-safe. Server uses an environment mutex. -*/ - -class ServerEnvironment : public Environment -{ -public: - ServerEnvironment(ServerMap *map, GameScripting *scriptIface, - IGameDef *gamedef); - ~ServerEnvironment(); - - Map & getMap(); - - ServerMap & getServerMap(); - - //TODO find way to remove this fct! - GameScripting* getScriptIface() - { return m_script; } - - IGameDef *getGameDef() - { return m_gamedef; } - - float getSendRecommendedInterval() - { return m_recommended_send_interval; } - - /* - Save players - */ - void serializePlayers(const std::string &savedir); - void deSerializePlayers(const std::string &savedir); - - /* - Save and load time of day and game timer - */ - void saveMeta(const std::string &savedir); - void loadMeta(const std::string &savedir); - - /* - External ActiveObject interface - ------------------------------------------- - */ - - ServerActiveObject* getActiveObject(u16 id); - - /* - Add an active object to the environment. - Environment handles deletion of object. - Object may be deleted by environment immediately. - If id of object is 0, assigns a free id to it. - Returns the id of the object. - Returns 0 if not added and thus deleted. - */ - u16 addActiveObject(ServerActiveObject *object); - - /* - Add an active object as a static object to the corresponding - MapBlock. - Caller allocates memory, ServerEnvironment frees memory. - Return value: true if succeeded, false if failed. - (note: not used, pending removal from engine) - */ - //bool addActiveObjectAsStatic(ServerActiveObject *object); - - /* - Find out what new objects have been added to - inside a radius around a position - */ - void getAddedActiveObjects(v3s16 pos, s16 radius, - std::set ¤t_objects, - std::set &added_objects); - - /* - Find out what new objects have been removed from - inside a radius around a position - */ - void getRemovedActiveObjects(v3s16 pos, s16 radius, - std::set ¤t_objects, - std::set &removed_objects); - - /* - Get the next message emitted by some active object. - Returns a message with id=0 if no messages are available. - */ - ActiveObjectMessage getActiveObjectMessage(); - - /* - Activate objects and dynamically modify for the dtime determined - from timestamp and additional_dtime - */ - void activateBlock(MapBlock *block, u32 additional_dtime=0); - - /* - ActiveBlockModifiers - ------------------------------------------- - */ + bool m_enable_day_night_ratio_override = false; + u32 m_day_night_ratio_override = 0.0f; + // Days from the server start, accounts for time shift + // in game (e.g. /time or bed usage) + std::atomic m_day_count; + /* + * Above: values managed by m_time_lock + */ + + /* TODO: Add a callback function so these can be updated when a setting + * changes. At this point in time it doesn't matter (e.g. /set + * is documented to change server settings only) + * + * TODO: Local caching of settings is not optimal and should at some stage + * be updated to use a global settings object for getting thse values + * (as opposed to the this local caching). This can be addressed in + * a later release. + */ + bool m_cache_enable_shaders; + float m_cache_active_block_mgmt_interval; + float m_cache_abm_interval; + float m_cache_nodetimer_interval; + float m_cache_abm_time_budget; - void addActiveBlockModifier(ActiveBlockModifier *abm); - - /* - Other stuff - ------------------------------------------- - */ - - // Script-aware node setters - bool setNode(v3s16 p, const MapNode &n); - bool removeNode(v3s16 p); - bool swapNode(v3s16 p, const MapNode &n); - - // Find all active objects inside a radius around a point - std::set getObjectsInsideRadius(v3f pos, float radius); - - // Clear all objects, loading and going through every MapBlock - void clearAllObjects(); - - // This makes stuff happen - void step(f32 dtime); - - //check if there's a line of sight between two positions - bool line_of_sight(v3f pos1, v3f pos2, float stepsize=1.0, v3s16 *p=NULL); - - u32 getGameTime() { return m_game_time; } - - void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } - float getMaxLagEstimate() { return m_max_lag_estimate; } - - // is weather active in this environment? - bool m_use_weather; - - std::set* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }; - -private: - - /* - Internal ActiveObject interface - ------------------------------------------- - */ - - /* - Add an active object to the environment. - - Called by addActiveObject. - - Object may be deleted by environment immediately. - If id of object is 0, assigns a free id to it. - Returns the id of the object. - Returns 0 if not added and thus deleted. - */ - u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed, u32 dtime_s); - - /* - Remove all objects that satisfy (m_removed && m_known_by_count==0) - */ - void removeRemovedObjects(); - - /* - Convert stored objects from block to active - */ - void activateObjects(MapBlock *block, u32 dtime_s); - - /* - Convert objects that are not in active blocks to static. - - If m_known_by_count != 0, active object is not deleted, but static - data is still updated. - - If force_delete is set, active object is deleted nevertheless. It - shall only be set so in the destructor of the environment. - */ - void deactivateFarObjects(bool force_delete); - - /* - Member variables - */ - - // The map - ServerMap *m_map; - // Lua state - GameScripting* m_script; - // Game definition IGameDef *m_gamedef; - // Active object list - std::map m_active_objects; - // Outgoing network message buffer for active objects - std::list m_active_object_messages; - // Some timers - float m_random_spawn_timer; // used for experimental code - float m_send_recommended_timer; - IntervalLimiter m_object_management_interval; - // List of active blocks - ActiveBlockList m_active_blocks; - IntervalLimiter m_active_blocks_management_interval; - IntervalLimiter m_active_block_modifier_interval; - IntervalLimiter m_active_blocks_nodemetadata_interval; - int m_active_block_interval_overload_skip; - // Time from the beginning of the game in seconds. - // Incremented in step(). - u32 m_game_time; - // A helper variable for incrementing the latter - float m_game_time_fraction_counter; - std::list m_abms; - // An interval for generally sending object positions and stuff - float m_recommended_send_interval; - // Estimate for general maximum lag as determined by server. - // Can raise to high values like 15s with eg. map generation mods. - float m_max_lag_estimate; -}; -#ifndef SERVER - -#include "clientobject.h" -class ClientSimpleObject; - -/* - The client-side environment. - - This is not thread-safe. - Must be called from main (irrlicht) thread (uses the SceneManager) - Client uses an environment mutex. -*/ - -enum ClientEnvEventType -{ - CEE_NONE, - CEE_PLAYER_DAMAGE, - CEE_PLAYER_BREATH -}; - -struct ClientEnvEvent -{ - ClientEnvEventType type; - union { - struct{ - } none; - struct{ - u8 amount; - bool send_to_server; - } player_damage; - struct{ - u16 amount; - } player_breath; - }; -}; - -class ClientEnvironment : public Environment -{ -public: - ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, - ITextureSource *texturesource, IGameDef *gamedef, - IrrlichtDevice *device); - ~ClientEnvironment(); - - Map & getMap(); - ClientMap & getClientMap(); - - IGameDef *getGameDef() - { return m_gamedef; } - - void step(f32 dtime); - - virtual void addPlayer(Player *player); - LocalPlayer * getLocalPlayer(); - - /* - ClientSimpleObjects - */ - - void addSimpleObject(ClientSimpleObject *simple); - - /* - ActiveObjects - */ - - ClientActiveObject* getActiveObject(u16 id); - - /* - Adds an active object to the environment. - Environment handles deletion of object. - Object may be deleted by environment immediately. - If id of object is 0, assigns a free id to it. - Returns the id of the object. - Returns 0 if not added and thus deleted. - */ - u16 addActiveObject(ClientActiveObject *object); - - void addActiveObject(u16 id, u8 type, const std::string &init_data); - void removeActiveObject(u16 id); - - void processActiveObjectMessage(u16 id, const std::string &data); - - /* - Callbacks for activeobjects - */ - - void damageLocalPlayer(u8 damage, bool handle_hp=true); - void updateLocalPlayerBreath(u16 breath); - - /* - Client likes to call these - */ - - // Get all nearby objects - void getActiveObjects(v3f origin, f32 max_d, - std::vector &dest); - - // Get event from queue. CEE_NONE is returned if queue is empty. - ClientEnvEvent getClientEvent(); - - std::vector > attachment_list; // X is child ID, Y is parent ID - - std::list getPlayerNames() - { return m_player_names; } - void addPlayerName(std::string name) - { m_player_names.push_back(name); } - void removePlayerName(std::string name) - { m_player_names.remove(name); } - private: - ClientMap *m_map; - scene::ISceneManager *m_smgr; - ITextureSource *m_texturesource; - IGameDef *m_gamedef; - IrrlichtDevice *m_irr; - std::map m_active_objects; - std::list m_simple_objects; - std::list m_client_event_queue; - IntervalLimiter m_active_object_light_update_interval; - IntervalLimiter m_lava_hurt_interval; - IntervalLimiter m_drowning_interval; - IntervalLimiter m_breathing_interval; - std::list m_player_names; + std::mutex m_time_lock; }; - -#endif - -#endif -