From 63c892eedfe21cbca2e2369d28e5e4d4e62ca1bd Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 16 Jan 2017 13:08:59 +0000 Subject: Rename ObjectRef methods to be consistent and predictable --- src/script/lua_api/l_object.h | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 09f10e417..06b1bb79b 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -57,15 +57,15 @@ private: // remove(self) static int l_remove(lua_State *L); - // getpos(self) + // get_pos(self) // returns: {x=num, y=num, z=num} - static int l_getpos(lua_State *L); + static int l_get_pos(lua_State *L); - // setpos(self, pos) - static int l_setpos(lua_State *L); + // set_pos(self, pos) + static int l_set_pos(lua_State *L); - // moveto(self, pos, continuous=false) - static int l_moveto(lua_State *L); + // move_to(self, pos, continuous=false) + static int l_move_to(lua_State *L); // punch(self, puncher, time_from_last_punch, tool_capabilities, dir) static int l_punch(lua_State *L); @@ -143,30 +143,30 @@ private: /* LuaEntitySAO-only */ - // setvelocity(self, {x=num, y=num, z=num}) - static int l_setvelocity(lua_State *L); + // set_velocity(self, {x=num, y=num, z=num}) + static int l_set_velocity(lua_State *L); - // getvelocity(self) - static int l_getvelocity(lua_State *L); + // get_velocity(self) + static int l_get_velocity(lua_State *L); - // setacceleration(self, {x=num, y=num, z=num}) - static int l_setacceleration(lua_State *L); + // set_acceleration(self, {x=num, y=num, z=num}) + static int l_set_acceleration(lua_State *L); - // getacceleration(self) - static int l_getacceleration(lua_State *L); + // get_acceleration(self) + static int l_get_acceleration(lua_State *L); - // setyaw(self, radians) - static int l_setyaw(lua_State *L); + // set_yaw(self, radians) + static int l_set_yaw(lua_State *L); - // getyaw(self) - static int l_getyaw(lua_State *L); + // get_yaw(self) + static int l_get_yaw(lua_State *L); - // settexturemod(self, mod) - static int l_settexturemod(lua_State *L); + // set_texture_mod(self, mod) + static int l_set_texture_mod(lua_State *L); - // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2, + // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2, // select_horiz_by_yawpitch=false) - static int l_setsprite(lua_State *L); + static int l_set_sprite(lua_State *L); // DEPRECATED // get_entity_name(self) -- cgit v1.2.3 From c57b4ff9b592617539aa978374c13cdd5f1603a6 Mon Sep 17 00:00:00 2001 From: sapier Date: Sat, 14 Jan 2017 19:32:10 +0100 Subject: Add Entity get_texture_mod() to Lua API Send texture modifier to clients connecting later too --- doc/lua_api.txt | 1 + src/content_cao.cpp | 26 ++++++++++++++++++++------ src/content_cao.h | 4 +++- src/content_sao.cpp | 12 +++++++++++- src/content_sao.h | 2 ++ src/script/lua_api/l_object.cpp | 13 +++++++++++++ src/script/lua_api/l_object.h | 3 +++ 7 files changed, 53 insertions(+), 8 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index aada851a1..e5a3362ee 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2848,6 +2848,7 @@ This is basically a reference to a C++ `ServerActiveObject` * `set_yaw(radians)` * `get_yaw()`: returns number in radians * `set_texture_mod(mod)` +* `get_texture_mod()` returns current texture modifier * `set_sprite(p={x=0,y=0}, num_frames=1, framelength=0.2, select_horiz_by_yawpitch=false)` * Select sprite from spritesheet with optional animation and DM-style diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 93ac1f785..e829fc761 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -574,6 +574,8 @@ GenericCAO::GenericCAO(Client *client, ClientEnvironment *env): m_anim_framelength(0.2), m_anim_timer(0), m_reset_textures_timer(-1), + m_previous_texture_modifier(""), + m_current_texture_modifier(""), m_visuals_expired(false), m_step_distance_counter(0), m_last_light(255), @@ -952,7 +954,10 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, infostream<<"GenericCAO::addToScene(): \""<= 0) { m_reset_textures_timer -= dtime; - if(m_reset_textures_timer <= 0){ + if(m_reset_textures_timer <= 0) { m_reset_textures_timer = -1; - updateTextures(""); + updateTextures(m_previous_texture_modifier); } } if(getParent() == NULL && fabs(m_prop.automatic_rotate) > 0.001) @@ -1301,7 +1306,7 @@ void GenericCAO::updateTexturePos() } } -void GenericCAO::updateTextures(const std::string &mod) +void GenericCAO::updateTextures(const std::string mod) { ITextureSource *tsrc = m_client->tsrc(); @@ -1309,6 +1314,9 @@ void GenericCAO::updateTextures(const std::string &mod) bool use_bilinear_filter = g_settings->getBool("bilinear_filter"); bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter"); + m_previous_texture_modifier = m_current_texture_modifier; + m_current_texture_modifier = mod; + if(m_spritenode) { if(m_prop.visual == "sprite") @@ -1611,6 +1619,12 @@ void GenericCAO::processMessage(const std::string &data) updateNodePos(); } else if (cmd == GENERIC_CMD_SET_TEXTURE_MOD) { std::string mod = deSerializeString(is); + + // immediatly reset a engine issued texture modifier if a mod sends a different one + if (m_reset_textures_timer > 0) { + m_reset_textures_timer = -1; + updateTextures(m_previous_texture_modifier); + } updateTextures(mod); } else if (cmd == GENERIC_CMD_SET_SPRITE) { v2s16 p = readV2S16(is); @@ -1734,7 +1748,7 @@ void GenericCAO::processMessage(const std::string &data) m_reset_textures_timer = 0.05; if(damage >= 2) m_reset_textures_timer += 0.05 * damage; - updateTextures("^[brighten"); + updateTextures(m_current_texture_modifier + "^[brighten"); } } } else if (cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { @@ -1802,7 +1816,7 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem, m_reset_textures_timer = 0.05; if(result.damage >= 2) m_reset_textures_timer += 0.05 * result.damage; - updateTextures("^[brighten"); + updateTextures(m_current_texture_modifier + "^[brighten"); } return false; diff --git a/src/content_cao.h b/src/content_cao.h index 846e0690a..f30e90e21 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -102,6 +102,8 @@ private: float m_anim_timer; ItemGroupList m_armor_groups; float m_reset_textures_timer; + std::string m_previous_texture_modifier; // stores texture modifier before punch update + std::string m_current_texture_modifier; // last applied texture modifier bool m_visuals_expired; float m_step_distance_counter; u8 m_last_light; @@ -198,7 +200,7 @@ public: void updateTexturePos(); - void updateTextures(const std::string &mod); + void updateTextures(const std::string mod); void updateAnimation(); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index d6581144f..f0973082d 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -257,7 +257,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, m_last_sent_position(0,0,0), m_last_sent_velocity(0,0,0), m_last_sent_position_timer(0), - m_last_sent_move_precision(0) + m_last_sent_move_precision(0), + m_current_texture_modifier("") { // Only register type if no environment supplied if(env == NULL){ @@ -511,6 +512,9 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) } } + msg_os << serializeLongString(gob_cmd_set_texture_mod(m_current_texture_modifier)); + message_count++; + writeU8(os, message_count); os.write(msg_os.str().c_str(), msg_os.str().size()); } @@ -687,11 +691,17 @@ v3f LuaEntitySAO::getAcceleration() void LuaEntitySAO::setTextureMod(const std::string &mod) { std::string str = gob_cmd_set_texture_mod(mod); + m_current_texture_modifier = mod; // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); } +std::string LuaEntitySAO::getTextureMod() const +{ + return m_current_texture_modifier; +} + void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch) { diff --git a/src/content_sao.h b/src/content_sao.h index 884f0f406..56a26fb0d 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -122,6 +122,7 @@ public: v3f getAcceleration(); void setTextureMod(const std::string &mod); + std::string getTextureMod() const; void setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch); std::string getName(); @@ -143,6 +144,7 @@ private: v3f m_last_sent_velocity; float m_last_sent_position_timer; float m_last_sent_move_precision; + std::string m_current_texture_modifier; }; /* diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index f579c0b86..1fa3663ca 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -900,6 +900,19 @@ int ObjectRef::l_set_texture_mod(lua_State *L) return 0; } +// get_texture_mod(self) +int ObjectRef::l_get_texture_mod(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (co == NULL) return 0; + // Do it + std::string mod = co->getTextureMod(); + lua_pushstring(L, mod.c_str()); + return 1; +} + // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2, // select_horiz_by_yawpitch=false) int ObjectRef::l_set_sprite(lua_State *L) diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 06b1bb79b..96d0abae8 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -164,6 +164,9 @@ private: // set_texture_mod(self, mod) static int l_set_texture_mod(lua_State *L); + // l_get_texture_mod(self) + static int l_get_texture_mod(lua_State *L); + // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2, // select_horiz_by_yawpitch=false) static int l_set_sprite(lua_State *L); -- cgit v1.2.3 From b7a98e98500402c3bbdb6d56d0fe42b4f5b3cedb Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Fri, 27 Jan 2017 08:59:30 +0100 Subject: Implement player attribute backend (#4155) * This backend permit mods to store extra players attributes to a common interface. * Add the obj:set_attribute(attr, value) Lua call * Add the obj:get_attribute(attr) Lua call Examples: * player:set_attribute("home:home", "10,25,-78") * player:get_attribute("default:mana") Attributes are saved as a json in the player file in extended_attributes key They are saved only if a modification on the attributes occurs and loaded when emergePlayer is called (they are attached to PlayerSAO). --- doc/lua_api.txt | 2 ++ src/content_sao.cpp | 1 + src/content_sao.h | 37 +++++++++++++++++++++++++++++++++++++ src/remoteplayer.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/remoteplayer.h | 5 ++++- src/script/lua_api/l_object.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/script/lua_api/l_object.h | 6 ++++++ src/server.h | 1 - src/serverenvironment.cpp | 3 ++- 9 files changed, 128 insertions(+), 6 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 62a7b81f7..ee7d57c2f 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2899,6 +2899,8 @@ This is basically a reference to a C++ `ServerActiveObject` * `0`: player is drowning, * `1`-`10`: remaining number of bubbles * `11`: bubbles bar is not shown +* `set_attribute(attribute, value)`: sets an extra attribute with value on player +* `get_attribute(attribute)`: returns value for extra attribute. Returns nil if no attribute found. * `set_inventory_formspec(formspec)` * Redefine player's inventory form * Should usually be called in on_joinplayer diff --git a/src/content_sao.cpp b/src/content_sao.cpp index bb62aea7d..35133490e 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -791,6 +791,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer m_pitch(0), m_fov(0), m_wanted_range(0), + m_extended_attributes_modified(false), // public m_physics_override_speed(1), m_physics_override_jump(1), diff --git a/src/content_sao.h b/src/content_sao.h index c3674fa2d..bbf244742 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -180,6 +180,7 @@ public: } }; +typedef UNORDERED_MAP PlayerAttributes; class RemotePlayer; class PlayerSAO : public UnitSAO @@ -249,6 +250,39 @@ public: int getWieldIndex() const; void setWieldIndex(int i); + /* + Modding interface + */ + inline void setExtendedAttribute(const std::string &attr, const std::string &value) + { + m_extra_attributes[attr] = value; + m_extended_attributes_modified = true; + } + + inline bool getExtendedAttribute(const std::string &attr, std::string *value) + { + if (m_extra_attributes.find(attr) == m_extra_attributes.end()) + return false; + + *value = m_extra_attributes[attr]; + return true; + } + + inline const PlayerAttributes &getExtendedAttributes() + { + return m_extra_attributes; + } + + inline bool extendedAttributesModified() const + { + return m_extended_attributes_modified; + } + + inline void setExtendedAttributeModified(bool v) + { + m_extended_attributes_modified = v; + } + /* PlayerSAO-specific */ @@ -343,6 +377,9 @@ private: f32 m_pitch; f32 m_fov; s16 m_wanted_range; + + PlayerAttributes m_extra_attributes; + bool m_extended_attributes_modified; public: float m_physics_override_speed; float m_physics_override_jump; diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 18bfa1030..6853ad6d9 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -19,13 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "remoteplayer.h" +#include #include "content_sao.h" #include "filesys.h" #include "gamedef.h" #include "porting.h" // strlcpy +#include "server.h" #include "settings.h" - /* RemotePlayer */ @@ -112,9 +113,23 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) } infostream << "Didn't find free file for player " << m_name << std::endl; - return; } +void RemotePlayer::serializeExtraAttributes(std::string &output) +{ + assert(m_sao); + Json::Value json_root; + const PlayerAttributes &attrs = m_sao->getExtendedAttributes(); + for (PlayerAttributes::const_iterator it = attrs.begin(); it != attrs.end(); ++it) { + json_root[(*it).first] = (*it).second; + } + + Json::FastWriter writer; + output = writer.write(json_root); + m_sao->setExtendedAttributeModified(false); +} + + void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao) { @@ -150,6 +165,20 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, try { sao->setBreath(args.getS32("breath"), false); } catch (SettingNotFoundException &e) {} + + try { + std::string extended_attributes = args.get("extended_attributes"); + Json::Reader reader; + Json::Value attr_root; + reader.parse(extended_attributes, attr_root); + + const Json::Value::Members attr_list = attr_root.getMemberNames(); + for (Json::Value::Members::const_iterator it = attr_list.begin(); + it != attr_list.end(); ++it) { + Json::Value attr_value = attr_root[*it]; + sao->setExtendedAttribute(*it, attr_value.asString()); + } + } catch (SettingNotFoundException &e) {} } inventory.deSerialize(is); @@ -175,7 +204,6 @@ void RemotePlayer::serialize(std::ostream &os) Settings args; args.setS32("version", 1); args.set("name", m_name); - //args.set("password", m_password); // This should not happen assert(m_sao); @@ -185,6 +213,10 @@ void RemotePlayer::serialize(std::ostream &os) args.setFloat("yaw", m_sao->getYaw()); args.setS32("breath", m_sao->getBreath()); + std::string extended_attrs = ""; + serializeExtraAttributes(extended_attrs); + args.set("extended_attributes", extended_attrs); + args.writeLines(os); os<<"PlayerArgsEnd\n"; diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 61b5a23de..f44fb9332 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -25,11 +25,13 @@ with this program; if not, write to the Free Software Foundation, Inc., class PlayerSAO; -enum RemotePlayerChatResult { +enum RemotePlayerChatResult +{ RPLAYER_CHATRESULT_OK, RPLAYER_CHATRESULT_FLOODING, RPLAYER_CHATRESULT_KICK, }; + /* Player on the server */ @@ -135,6 +137,7 @@ private: deSerialize stops reading exactly at the right point. */ void serialize(std::ostream &os); + void serializeExtraAttributes(std::string &output); PlayerSAO *m_sao; bool m_dirty; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index be4451704..9352812ab 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1181,6 +1181,45 @@ int ObjectRef::l_get_breath(lua_State *L) return 1; } +// set_attribute(self, attribute, value) +int ObjectRef::l_set_attribute(lua_State *L) +{ + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* co = getplayersao(ref); + if (co == NULL) { + return 0; + } + + std::string attr = luaL_checkstring(L, 2); + std::string value = luaL_checkstring(L, 3); + + if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + co->setExtendedAttribute(attr, value); + } + return 1; +} + +// get_attribute(self, attribute) +int ObjectRef::l_get_attribute(lua_State *L) +{ + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* co = getplayersao(ref); + if (co == NULL) { + return 0; + } + + std::string attr = luaL_checkstring(L, 2); + + std::string value = ""; + if (co->getExtendedAttribute(attr, &value)) { + lua_pushstring(L, value.c_str()); + return 1; + } + + return 0; +} + + // set_inventory_formspec(self, formspec) int ObjectRef::l_set_inventory_formspec(lua_State *L) { @@ -1839,6 +1878,8 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, set_look_pitch), luamethod(ObjectRef, get_breath), luamethod(ObjectRef, set_breath), + luamethod(ObjectRef, get_attribute), + luamethod(ObjectRef, set_attribute), luamethod(ObjectRef, set_inventory_formspec), luamethod(ObjectRef, get_inventory_formspec), luamethod(ObjectRef, get_player_control), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 96d0abae8..2c9aa559a 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -226,6 +226,12 @@ private: // get_breath(self, breath) static int l_get_breath(lua_State *L); + // set_attribute(self, attribute, value) + static int l_set_attribute(lua_State *L); + + // get_attribute(self, attribute) + static int l_get_attribute(lua_State *L); + // set_inventory_formspec(self, formspec) static int l_set_inventory_formspec(lua_State *L); diff --git a/src/server.h b/src/server.h index e5121bdc3..8f553ce38 100644 --- a/src/server.h +++ b/src/server.h @@ -576,7 +576,6 @@ private: float m_time_of_day_send_timer; // Uptime of server in seconds MutexedVariable m_uptime; - /* Client interface */ diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 01dc3ff10..7a5cfafd6 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -500,7 +500,8 @@ void ServerEnvironment::saveLoadedPlayers() for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { - if ((*it)->checkModified()) { + if ((*it)->checkModified() || + ((*it)->getPlayerSAO() && (*it)->getPlayerSAO()->extendedAttributesModified())) { (*it)->save(players_path, m_server); } } -- cgit v1.2.3 From 41c54830242269de073e4a0c10d1775dfdf6811d Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Sat, 8 Apr 2017 09:28:37 +0200 Subject: Replace luaL_reg with luaL_Reg as recent LuaJIT dropped the Lua 5.0 compat (#5541) We are bundling Lua5.1 which has same macro --- src/script/lua_api/l_areastore.cpp | 4 ++-- src/script/lua_api/l_areastore.h | 2 +- src/script/lua_api/l_inventory.cpp | 2 +- src/script/lua_api/l_inventory.h | 2 +- src/script/lua_api/l_item.cpp | 2 +- src/script/lua_api/l_item.h | 2 +- src/script/lua_api/l_itemstackmeta.cpp | 2 +- src/script/lua_api/l_itemstackmeta.h | 2 +- src/script/lua_api/l_minimap.cpp | 2 +- src/script/lua_api/l_minimap.h | 2 +- src/script/lua_api/l_nodemeta.cpp | 4 ++-- src/script/lua_api/l_nodemeta.h | 4 ++-- src/script/lua_api/l_nodetimer.cpp | 2 +- src/script/lua_api/l_nodetimer.h | 2 +- src/script/lua_api/l_noise.cpp | 10 +++++----- src/script/lua_api/l_noise.h | 10 +++++----- src/script/lua_api/l_object.cpp | 2 +- src/script/lua_api/l_object.h | 2 +- src/script/lua_api/l_settings.cpp | 2 +- src/script/lua_api/l_settings.h | 2 +- src/script/lua_api/l_storage.cpp | 2 +- src/script/lua_api/l_storage.h | 2 +- src/script/lua_api/l_vmanip.cpp | 2 +- src/script/lua_api/l_vmanip.h | 2 +- 24 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp index 09a5c78f9..b81985a7f 100644 --- a/src/script/lua_api/l_areastore.cpp +++ b/src/script/lua_api/l_areastore.cpp @@ -74,7 +74,7 @@ static inline void push_areas(lua_State *L, const std::vector &areas, static int deserialization_helper(lua_State *L, AreaStore *as, std::istream &is) { - try { + try { as->deserialize(is); } catch (const SerializationError &e) { lua_pushboolean(L, false); @@ -380,7 +380,7 @@ void LuaAreaStore::Register(lua_State *L) } const char LuaAreaStore::className[] = "AreaStore"; -const luaL_reg LuaAreaStore::methods[] = { +const luaL_Reg LuaAreaStore::methods[] = { luamethod(LuaAreaStore, get_area), luamethod(LuaAreaStore, get_areas_for_pos), luamethod(LuaAreaStore, get_areas_in_area), diff --git a/src/script/lua_api/l_areastore.h b/src/script/lua_api/l_areastore.h index 7dea08df4..8292e7712 100644 --- a/src/script/lua_api/l_areastore.h +++ b/src/script/lua_api/l_areastore.h @@ -28,7 +28,7 @@ class LuaAreaStore : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index 9a4aa845d..f5e76a7b6 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -463,7 +463,7 @@ void InvRef::Register(lua_State *L) } const char InvRef::className[] = "InvRef"; -const luaL_reg InvRef::methods[] = { +const luaL_Reg InvRef::methods[] = { luamethod(InvRef, is_empty), luamethod(InvRef, get_size), luamethod(InvRef, set_size), diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h index cc5333965..91d41c0d0 100644 --- a/src/script/lua_api/l_inventory.h +++ b/src/script/lua_api/l_inventory.h @@ -36,7 +36,7 @@ private: InventoryLocation m_loc; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static InvRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 7e6f457e1..19b5b0955 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -462,7 +462,7 @@ void LuaItemStack::Register(lua_State *L) } const char LuaItemStack::className[] = "ItemStack"; -const luaL_reg LuaItemStack::methods[] = { +const luaL_Reg LuaItemStack::methods[] = { luamethod(LuaItemStack, is_empty), luamethod(LuaItemStack, get_name), luamethod(LuaItemStack, set_name), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 1ba5d79e0..b4efaefc8 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -28,7 +28,7 @@ private: ItemStack m_stack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp index 304a7cdf3..efdd77b51 100644 --- a/src/script/lua_api/l_itemstackmeta.cpp +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -102,7 +102,7 @@ void ItemStackMetaRef::Register(lua_State *L) } const char ItemStackMetaRef::className[] = "ItemStackMetaRef"; -const luaL_reg ItemStackMetaRef::methods[] = { +const luaL_Reg ItemStackMetaRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_itemstackmeta.h b/src/script/lua_api/l_itemstackmeta.h index 6f9b2016c..4ef64a91e 100644 --- a/src/script/lua_api/l_itemstackmeta.h +++ b/src/script/lua_api/l_itemstackmeta.h @@ -31,7 +31,7 @@ private: ItemStack *istack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static ItemStackMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp index 182894f4f..c68602909 100644 --- a/src/script/lua_api/l_minimap.cpp +++ b/src/script/lua_api/l_minimap.cpp @@ -201,7 +201,7 @@ void LuaMinimap::Register(lua_State *L) } const char LuaMinimap::className[] = "Minimap"; -const luaL_reg LuaMinimap::methods[] = { +const luaL_Reg LuaMinimap::methods[] = { luamethod(LuaMinimap, show), luamethod(LuaMinimap, hide), luamethod(LuaMinimap, get_pos), diff --git a/src/script/lua_api/l_minimap.h b/src/script/lua_api/l_minimap.h index 9a299b4fd..8be72b8e7 100644 --- a/src/script/lua_api/l_minimap.h +++ b/src/script/lua_api/l_minimap.h @@ -28,7 +28,7 @@ class LuaMinimap : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 4368a8c50..55d11fc13 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -215,7 +215,7 @@ void NodeMetaRef::Register(lua_State *L) } -const luaL_reg NodeMetaRef::methodsServer[] = { +const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), @@ -237,7 +237,7 @@ void NodeMetaRef::RegisterClient(lua_State *L) } -const luaL_reg NodeMetaRef::methodsClient[] = { +const luaL_Reg NodeMetaRef::methodsClient[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, get_int), luamethod(MetaDataRef, get_float), diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 6d146416b..2ac028079 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -39,8 +39,8 @@ private: bool m_is_local; static const char className[]; - static const luaL_reg methodsServer[]; - static const luaL_reg methodsClient[]; + static const luaL_Reg methodsServer[]; + static const luaL_Reg methodsClient[]; static NodeMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp index ed11cc58e..17b275c46 100644 --- a/src/script/lua_api/l_nodetimer.cpp +++ b/src/script/lua_api/l_nodetimer.cpp @@ -162,7 +162,7 @@ void NodeTimerRef::Register(lua_State *L) } const char NodeTimerRef::className[] = "NodeTimerRef"; -const luaL_reg NodeTimerRef::methods[] = { +const luaL_Reg NodeTimerRef::methods[] = { luamethod(NodeTimerRef, start), luamethod(NodeTimerRef, set), luamethod(NodeTimerRef, stop), diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h index 239112037..ae362d8b3 100644 --- a/src/script/lua_api/l_nodetimer.h +++ b/src/script/lua_api/l_nodetimer.h @@ -32,7 +32,7 @@ private: ServerEnvironment *m_env; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index e0039371f..e3e76191f 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -135,7 +135,7 @@ void LuaPerlinNoise::Register(lua_State *L) const char LuaPerlinNoise::className[] = "PerlinNoise"; -const luaL_reg LuaPerlinNoise::methods[] = { +const luaL_Reg LuaPerlinNoise::methods[] = { luamethod(LuaPerlinNoise, get2d), luamethod(LuaPerlinNoise, get3d), {0,0} @@ -393,7 +393,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L) const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap"; -const luaL_reg LuaPerlinNoiseMap::methods[] = { +const luaL_Reg LuaPerlinNoiseMap::methods[] = { luamethod(LuaPerlinNoiseMap, get2dMap), luamethod(LuaPerlinNoiseMap, get2dMap_flat), luamethod(LuaPerlinNoiseMap, calc2dMap), @@ -498,7 +498,7 @@ void LuaPseudoRandom::Register(lua_State *L) const char LuaPseudoRandom::className[] = "PseudoRandom"; -const luaL_reg LuaPseudoRandom::methods[] = { +const luaL_Reg LuaPseudoRandom::methods[] = { luamethod(LuaPseudoRandom, next), {0,0} }; @@ -597,7 +597,7 @@ void LuaPcgRandom::Register(lua_State *L) const char LuaPcgRandom::className[] = "PcgRandom"; -const luaL_reg LuaPcgRandom::methods[] = { +const luaL_Reg LuaPcgRandom::methods[] = { luamethod(LuaPcgRandom, next), luamethod(LuaPcgRandom, rand_normal_dist), {0,0} @@ -711,7 +711,7 @@ void LuaSecureRandom::Register(lua_State *L) } const char LuaSecureRandom::className[] = "SecureRandom"; -const luaL_reg LuaSecureRandom::methods[] = { +const luaL_Reg LuaSecureRandom::methods[] = { luamethod(LuaSecureRandom, next_bytes), {0,0} }; diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h index 11ec348bf..f252b5ba2 100644 --- a/src/script/lua_api/l_noise.h +++ b/src/script/lua_api/l_noise.h @@ -32,7 +32,7 @@ class LuaPerlinNoise : public ModApiBase private: NoiseParams np; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -64,7 +64,7 @@ class LuaPerlinNoiseMap : public ModApiBase Noise *noise; bool m_is3d; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -103,7 +103,7 @@ private: PseudoRandom m_pseudo; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -134,7 +134,7 @@ private: PcgRandom m_rnd; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -169,7 +169,7 @@ class LuaSecureRandom : public ModApiBase private: static const size_t RAND_BUF_SIZE = 2048; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; u32 m_rand_idx; char m_rand_buf[RAND_BUF_SIZE]; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index d5681b809..f9d2754e7 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1823,7 +1823,7 @@ void ObjectRef::Register(lua_State *L) } const char ObjectRef::className[] = "ObjectRef"; -const luaL_reg ObjectRef::methods[] = { +const luaL_Reg ObjectRef::methods[] = { // ServerActiveObject luamethod(ObjectRef, remove), luamethod_aliased(ObjectRef, get_pos, getpos), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 2c9aa559a..b6fc35bc2 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -37,7 +37,7 @@ private: ServerActiveObject *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; public: static ObjectRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp index d3fe03005..809f7d115 100644 --- a/src/script/lua_api/l_settings.cpp +++ b/src/script/lua_api/l_settings.cpp @@ -214,7 +214,7 @@ LuaSettings* LuaSettings::checkobject(lua_State* L, int narg) } const char LuaSettings::className[] = "Settings"; -const luaL_reg LuaSettings::methods[] = { +const luaL_Reg LuaSettings::methods[] = { luamethod(LuaSettings, get), luamethod(LuaSettings, get_bool), luamethod(LuaSettings, set), diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h index d5edd32ce..b90f0a8f2 100644 --- a/src/script/lua_api/l_settings.h +++ b/src/script/lua_api/l_settings.h @@ -28,7 +28,7 @@ class LuaSettings : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp index 867ab9c8d..59906dda5 100644 --- a/src/script/lua_api/l_storage.cpp +++ b/src/script/lua_api/l_storage.cpp @@ -129,7 +129,7 @@ void StorageRef::clearMeta() } const char StorageRef::className[] = "StorageRef"; -const luaL_reg StorageRef::methods[] = { +const luaL_Reg StorageRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_storage.h b/src/script/lua_api/l_storage.h index e09b8b391..ec6f8d941 100644 --- a/src/script/lua_api/l_storage.h +++ b/src/script/lua_api/l_storage.h @@ -41,7 +41,7 @@ private: ModMetadata *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; virtual Metadata *getmeta(bool auto_create); virtual void clearMeta(); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index 5f129d2af..7316fb200 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -452,7 +452,7 @@ void LuaVoxelManip::Register(lua_State *L) } const char LuaVoxelManip::className[] = "VoxelManip"; -const luaL_reg LuaVoxelManip::methods[] = { +const luaL_Reg LuaVoxelManip::methods[] = { luamethod(LuaVoxelManip, read_from_map), luamethod(LuaVoxelManip, get_data), luamethod(LuaVoxelManip, set_data), diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h index 65fc0d97a..b6a69f36a 100644 --- a/src/script/lua_api/l_vmanip.h +++ b/src/script/lua_api/l_vmanip.h @@ -38,7 +38,7 @@ private: bool is_mapgen_vm; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); -- cgit v1.2.3 From f6da7b3fda5bbb793c7795a228ea6f2602b93fbe Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 5 Apr 2017 12:18:22 +0100 Subject: Sneak: Add option for old move code Temporary option for the old move code for specific old sneak behaviour. Enabled by setting the added 'new move' physics override to false. By default 'new move' is true. --- doc/lua_api.txt | 6 +- src/content_cao.cpp | 2 + src/content_sao.cpp | 6 +- src/content_sao.h | 1 + src/genericobject.cpp | 3 +- src/genericobject.h | 3 +- src/localplayer.cpp | 309 ++++++++++++++++++++++++++++++++++++++++ src/localplayer.h | 8 ++ src/script/lua_api/l_object.cpp | 21 ++- src/script/lua_api/l_object.h | 2 +- 10 files changed, 349 insertions(+), 12 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7b967726d..4427e26d8 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3021,7 +3021,11 @@ This is basically a reference to a C++ `ServerActiveObject` * `jump`: multiplier to default jump value (default: `1`) * `gravity`: multiplier to default gravity value (default: `1`) * `sneak`: whether player can sneak (default: `true`) - * `sneak_glitch`: whether player can use the sneak glitch (default: `true`) + * `sneak_glitch`: whether player can use the new move code replications + of the old sneak side-effects: sneak ladders and 2 node sneak jump + when next to a ledge 2 nodes up (default: `true`) + * `new_move`: use new move/sneak code. When `false` the exact old code + is used for the specific old sneak behaviour (default: `true`) * `get_physics_override()`: returns the table given to set_physics_override * `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID number on success diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 84f198b75..ac283da88 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1652,6 +1652,7 @@ void GenericCAO::processMessage(const std::string &data) // these are sent inverted so we get true when the server sends nothing bool sneak = !readU8(is); bool sneak_glitch = !readU8(is); + bool new_move = !readU8(is); if(m_is_local_player) @@ -1662,6 +1663,7 @@ void GenericCAO::processMessage(const std::string &data) player->physics_override_gravity = override_gravity; player->physics_override_sneak = sneak; player->physics_override_sneak_glitch = sneak_glitch; + player->physics_override_new_move = new_move; } } else if (cmd == GENERIC_CMD_SET_ANIMATION) { // TODO: change frames send as v2s32 value diff --git a/src/content_sao.cpp b/src/content_sao.cpp index bb2387d1a..908365397 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -789,6 +789,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer m_physics_override_gravity(1), m_physics_override_sneak(true), m_physics_override_sneak_glitch(true), + m_physics_override_new_move(true), m_physics_override_sent(false) { assert(m_peer_id != 0); // pre-condition @@ -886,7 +887,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4 msg_os << serializeLongString(gob_cmd_update_physics_override(m_physics_override_speed, m_physics_override_jump, m_physics_override_gravity, m_physics_override_sneak, - m_physics_override_sneak_glitch)); // 5 + m_physics_override_sneak_glitch, m_physics_override_new_move)); // 5 // (GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only. msg_os << serializeLongString(gob_cmd_update_nametag_attributes(m_prop.nametag_color)); // 6 int message_count = 6 + m_bone_position.size(); @@ -1049,7 +1050,8 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_physics_override_sent = true; std::string str = gob_cmd_update_physics_override(m_physics_override_speed, m_physics_override_jump, m_physics_override_gravity, - m_physics_override_sneak, m_physics_override_sneak_glitch); + m_physics_override_sneak, m_physics_override_sneak_glitch, + m_physics_override_new_move); // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); diff --git a/src/content_sao.h b/src/content_sao.h index c1b01b6dd..e53e8ecce 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -397,6 +397,7 @@ public: float m_physics_override_gravity; bool m_physics_override_sneak; bool m_physics_override_sneak_glitch; + bool m_physics_override_new_move; bool m_physics_override_sent; }; diff --git a/src/genericobject.cpp b/src/genericobject.cpp index c4660cf44..07d2445b4 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -118,7 +118,7 @@ std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups) } std::string gob_cmd_update_physics_override(float physics_override_speed, float physics_override_jump, - float physics_override_gravity, bool sneak, bool sneak_glitch) + float physics_override_gravity, bool sneak, bool sneak_glitch, bool new_move) { std::ostringstream os(std::ios::binary); // command @@ -130,6 +130,7 @@ std::string gob_cmd_update_physics_override(float physics_override_speed, float // these are sent inverted so we get true when the server sends nothing writeU8(os, !sneak); writeU8(os, !sneak_glitch); + writeU8(os, !new_move); return os.str(); } diff --git a/src/genericobject.h b/src/genericobject.h index 48e71db75..7d2ec4b14 100644 --- a/src/genericobject.h +++ b/src/genericobject.h @@ -68,7 +68,8 @@ std::string gob_cmd_punched(s16 damage, s16 result_hp); std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups); std::string gob_cmd_update_physics_override(float physics_override_speed, - float physics_override_jump, float physics_override_gravity, bool sneak, bool sneak_glitch); + float physics_override_jump, float physics_override_gravity, + bool sneak, bool sneak_glitch, bool new_move); std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend, bool frame_loop); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 9dc3bf5aa..ea4347207 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -49,6 +49,7 @@ LocalPlayer::LocalPlayer(Client *client, const char *name): physics_override_gravity(1.0f), physics_override_sneak(true), physics_override_sneak_glitch(true), + physics_override_new_move(true), // Temporary option for old move code overridePosition(v3f(0,0,0)), last_position(v3f(0,0,0)), last_speed(v3f(0,0,0)), @@ -66,6 +67,7 @@ LocalPlayer::LocalPlayer(Client *client, const char *name): hurt_tilt_strength(0.0f), m_position(0,0,0), m_sneak_node(32767,32767,32767), + m_sneak_node_bb_ymax(0), // To support temporary option for old move code m_sneak_node_bb_top(0,0,0,0,0,0), m_sneak_node_exists(false), m_need_to_get_new_sneak_node(true), @@ -178,6 +180,12 @@ static bool detectLedge(Map *map, INodeDefManager *nodemgr, v3s16 pos) void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, std::vector *collision_info) { + // Temporary option for old move code + if (!physics_override_new_move) { + old_move(dtime, env, pos_max_d, collision_info); + return; + } + Map *map = &env->getMap(); INodeDefManager *nodemgr = m_client->ndef(); @@ -806,3 +814,304 @@ void LocalPlayer::accelerateVertical(const v3f &target_speed, const f32 max_incr m_speed.Y += d_wanted; } +// Temporary option for old move code +void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector *collision_info) +{ + Map *map = &env->getMap(); + INodeDefManager *nodemgr = m_client->ndef(); + + v3f position = getPosition(); + + // Copy parent position if local player is attached + if (isAttached) { + setPosition(overridePosition); + m_sneak_node_exists = false; + return; + } + + // Skip collision detection if noclip mode is used + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool noclip = m_client->checkLocalPrivilege("noclip") && + g_settings->getBool("noclip"); + bool free_move = noclip && fly_allowed && g_settings->getBool("free_move"); + if (free_move) { + position += m_speed * dtime; + setPosition(position); + m_sneak_node_exists = false; + return; + } + + /* + Collision detection + */ + bool is_valid_position; + MapNode node; + v3s16 pp; + + /* + Check if player is in liquid (the oscillating value) + */ + if (in_liquid) { + // If in liquid, the threshold of coming out is at higher y + pp = floatToInt(position + v3f(0, BS * 0.1, 0), BS); + node = map->getNodeNoEx(pp, &is_valid_position); + if (is_valid_position) { + in_liquid = nodemgr->get(node.getContent()).isLiquid(); + liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity; + } else { + in_liquid = false; + } + } else { + // If not in liquid, the threshold of going in is at lower y + pp = floatToInt(position + v3f(0, BS * 0.5, 0), BS); + node = map->getNodeNoEx(pp, &is_valid_position); + if (is_valid_position) { + in_liquid = nodemgr->get(node.getContent()).isLiquid(); + liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity; + } else { + in_liquid = false; + } + } + + /* + Check if player is in liquid (the stable value) + */ + pp = floatToInt(position + v3f(0, 0, 0), BS); + node = map->getNodeNoEx(pp, &is_valid_position); + if (is_valid_position) + in_liquid_stable = nodemgr->get(node.getContent()).isLiquid(); + else + in_liquid_stable = false; + + /* + Check if player is climbing + */ + pp = floatToInt(position + v3f(0, 0.5 * BS, 0), BS); + v3s16 pp2 = floatToInt(position + v3f(0, -0.2 * BS, 0), BS); + node = map->getNodeNoEx(pp, &is_valid_position); + bool is_valid_position2; + MapNode node2 = map->getNodeNoEx(pp2, &is_valid_position2); + + if (!(is_valid_position && is_valid_position2)) + is_climbing = false; + else + is_climbing = (nodemgr->get(node.getContent()).climbable || + nodemgr->get(node2.getContent()).climbable) && !free_move; + + /* + Collision uncertainty radius + Make it a bit larger than the maximum distance of movement + */ + //f32 d = pos_max_d * 1.1; + // A fairly large value in here makes moving smoother + f32 d = 0.15 * BS; + // This should always apply, otherwise there are glitches + sanity_check(d > pos_max_d); + // Maximum distance over border for sneaking + f32 sneak_max = BS * 0.4; + + /* + If sneaking, keep in range from the last walked node and don't + fall off from it + */ + if (control.sneak && m_sneak_node_exists && + !(fly_allowed && g_settings->getBool("free_move")) && !in_liquid && + physics_override_sneak && !got_teleported) { + f32 maxd = 0.5 * BS + sneak_max; + v3f lwn_f = intToFloat(m_sneak_node, BS); + position.X = rangelim(position.X, lwn_f.X - maxd, lwn_f.X + maxd); + position.Z = rangelim(position.Z, lwn_f.Z - maxd, lwn_f.Z + maxd); + + if (!is_climbing) { + // Move up if necessary + f32 new_y = (lwn_f.Y - 0.5 * BS) + m_sneak_node_bb_ymax; + if (position.Y < new_y) + position.Y = new_y; + /* + Collision seems broken, since player is sinking when + sneaking over the edges of current sneaking_node. + TODO (when fixed): Set Y-speed only to 0 when position.Y < new_y. + */ + if (m_speed.Y < 0) + m_speed.Y = 0; + } + } + + if (got_teleported) + got_teleported = false; + + // this shouldn't be hardcoded but transmitted from server + float player_stepheight = touching_ground ? (BS * 0.6) : (BS * 0.2); + +#ifdef __ANDROID__ + player_stepheight += (0.6 * BS); +#endif + + v3f accel_f = v3f(0, 0, 0); + + collisionMoveResult result = collisionMoveSimple(env, m_client, + pos_max_d, m_collisionbox, player_stepheight, dtime, + &position, &m_speed, accel_f); + + /* + If the player's feet touch the topside of any node, this is + set to true. + + Player is allowed to jump when this is true. + */ + bool touching_ground_was = touching_ground; + touching_ground = result.touching_ground; + + //bool standing_on_unloaded = result.standing_on_unloaded; + + /* + Check the nodes under the player to see from which node the + player is sneaking from, if any. If the node from under + the player has been removed, the player falls. + */ + f32 position_y_mod = 0.05 * BS; + if (m_sneak_node_bb_ymax > 0) + position_y_mod = m_sneak_node_bb_ymax - position_y_mod; + v3s16 current_node = floatToInt(position - v3f(0, position_y_mod, 0), BS); + if (m_sneak_node_exists && + nodemgr->get(map->getNodeNoEx(m_old_node_below)).name == "air" && + m_old_node_below_type != "air") { + // Old node appears to have been removed; that is, + // it wasn't air before but now it is + m_need_to_get_new_sneak_node = false; + m_sneak_node_exists = false; + } else if (nodemgr->get(map->getNodeNoEx(current_node)).name != "air") { + // We are on something, so make sure to recalculate the sneak + // node. + m_need_to_get_new_sneak_node = true; + } + + if (m_need_to_get_new_sneak_node && physics_override_sneak) { + m_sneak_node_bb_ymax = 0; + v3s16 pos_i_bottom = floatToInt(position - v3f(0, position_y_mod, 0), BS); + v2f player_p2df(position.X, position.Z); + f32 min_distance_f = 100000.0 * BS; + // If already seeking from some node, compare to it. + v3s16 new_sneak_node = m_sneak_node; + for (s16 x= -1; x <= 1; x++) + for (s16 z= -1; z <= 1; z++) { + v3s16 p = pos_i_bottom + v3s16(x, 0, z); + v3f pf = intToFloat(p, BS); + v2f node_p2df(pf.X, pf.Z); + f32 distance_f = player_p2df.getDistanceFrom(node_p2df); + f32 max_axis_distance_f = MYMAX( + fabs(player_p2df.X - node_p2df.X), + fabs(player_p2df.Y - node_p2df.Y)); + + if (distance_f > min_distance_f || + max_axis_distance_f > 0.5 * BS + sneak_max + 0.1 * BS) + continue; + + // The node to be sneaked on has to be walkable + node = map->getNodeNoEx(p, &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable == false) + continue; + // And the node above it has to be nonwalkable + node = map->getNodeNoEx(p + v3s16(0, 1, 0), &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable) + continue; + // If not 'sneak_glitch' the node 2 nodes above it has to be nonwalkable + if (!physics_override_sneak_glitch) { + node =map->getNodeNoEx(p + v3s16(0, 2, 0), &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable) + continue; + } + + min_distance_f = distance_f; + new_sneak_node = p; + } + + bool sneak_node_found = (min_distance_f < 100000.0 * BS * 0.9); + + m_sneak_node = new_sneak_node; + m_sneak_node_exists = sneak_node_found; + + if (sneak_node_found) { + f32 cb_max = 0; + MapNode n = map->getNodeNoEx(m_sneak_node); + std::vector nodeboxes; + n.getCollisionBoxes(nodemgr, &nodeboxes); + for (std::vector::iterator it = nodeboxes.begin(); + it != nodeboxes.end(); ++it) { + aabb3f box = *it; + if (box.MaxEdge.Y > cb_max) + cb_max = box.MaxEdge.Y; + } + m_sneak_node_bb_ymax = cb_max; + } + + /* + If sneaking, the player's collision box can be in air, so + this has to be set explicitly + */ + if (sneak_node_found && control.sneak) + touching_ground = true; + } + + /* + Set new position + */ + setPosition(position); + + /* + Report collisions + */ + // Dont report if flying + if (collision_info && !(g_settings->getBool("free_move") && fly_allowed)) { + for (size_t i = 0; i < result.collisions.size(); i++) { + const CollisionInfo &info = result.collisions[i]; + collision_info->push_back(info); + } + } + + if (!result.standing_on_object && !touching_ground_was && touching_ground) { + MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround"); + m_client->event()->put(e); + // Set camera impact value to be used for view bobbing + camera_impact = getSpeed().Y * -1; + } + + { + camera_barely_in_ceiling = false; + v3s16 camera_np = floatToInt(getEyePosition(), BS); + MapNode n = map->getNodeNoEx(camera_np); + if (n.getContent() != CONTENT_IGNORE) { + if (nodemgr->get(n).walkable && nodemgr->get(n).solidness == 2) + camera_barely_in_ceiling = true; + } + } + + /* + Update the node last under the player + */ + m_old_node_below = floatToInt(position - v3f(0, BS / 2, 0), BS); + m_old_node_below_type = nodemgr->get(map->getNodeNoEx(m_old_node_below)).name; + + /* + Check properties of the node on which the player is standing + */ + const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos())); + // Determine if jumping is possible + m_can_jump = touching_ground && !in_liquid; + if (itemgroup_get(f.groups, "disable_jump")) + m_can_jump = false; + // Jump key pressed while jumping off from a bouncy block + if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") && + m_speed.Y >= -0.5 * BS) { + float jumpspeed = movement_speed_jump * physics_override_jump; + if (m_speed.Y > 1) { + // Reduce boost when speed already is high + m_speed.Y += jumpspeed / (1 + (m_speed.Y / 16 )); + } else { + m_speed.Y += jumpspeed; + } + setSpeed(m_speed); + m_can_jump = false; + } +} diff --git a/src/localplayer.h b/src/localplayer.h index ae987b893..01e859bf0 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -58,12 +58,17 @@ public: float physics_override_gravity; bool physics_override_sneak; bool physics_override_sneak_glitch; + // Temporary option for old move code + bool physics_override_new_move; v3f overridePosition; void move(f32 dtime, Environment *env, f32 pos_max_d); void move(f32 dtime, Environment *env, f32 pos_max_d, std::vector *collision_info); + // Temporary option for old move code + void old_move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector *collision_info); void applyControl(float dtime); @@ -137,6 +142,9 @@ private: v3f m_position; v3s16 m_sneak_node; + // Stores the max player uplift by m_sneak_node + // To support temporary option for old move code + f32 m_sneak_node_bb_ymax; // Stores the top bounding box of m_sneak_node aabb3f m_sneak_node_bb_top; // Whether the player is allowed to sneak diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 0699705cb..95e977f9e 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -401,7 +401,7 @@ int ObjectRef::l_get_armor_groups(lua_State *L) } // set_physics_override(self, physics_override_speed, physics_override_jump, -// physics_override_gravity, sneak, sneak_glitch) +// physics_override_gravity, sneak, sneak_glitch, new_move) int ObjectRef::l_set_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -410,11 +410,18 @@ int ObjectRef::l_set_physics_override(lua_State *L) if (co == NULL) return 0; // Do it if (lua_istable(L, 2)) { - co->m_physics_override_speed = getfloatfield_default(L, 2, "speed", co->m_physics_override_speed); - co->m_physics_override_jump = getfloatfield_default(L, 2, "jump", co->m_physics_override_jump); - co->m_physics_override_gravity = getfloatfield_default(L, 2, "gravity", co->m_physics_override_gravity); - co->m_physics_override_sneak = getboolfield_default(L, 2, "sneak", co->m_physics_override_sneak); - co->m_physics_override_sneak_glitch = getboolfield_default(L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch); + co->m_physics_override_speed = getfloatfield_default( + L, 2, "speed", co->m_physics_override_speed); + co->m_physics_override_jump = getfloatfield_default( + L, 2, "jump", co->m_physics_override_jump); + co->m_physics_override_gravity = getfloatfield_default( + L, 2, "gravity", co->m_physics_override_gravity); + co->m_physics_override_sneak = getboolfield_default( + L, 2, "sneak", co->m_physics_override_sneak); + co->m_physics_override_sneak_glitch = getboolfield_default( + L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch); + co->m_physics_override_new_move = getboolfield_default( + L, 2, "new_move", co->m_physics_override_new_move); co->m_physics_override_sent = false; } else { // old, non-table format @@ -454,6 +461,8 @@ int ObjectRef::l_get_physics_override(lua_State *L) lua_setfield(L, -2, "sneak"); lua_pushboolean(L, co->m_physics_override_sneak_glitch); lua_setfield(L, -2, "sneak_glitch"); + lua_pushboolean(L, co->m_physics_override_new_move); + lua_setfield(L, -2, "new_move"); return 1; } diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index b6fc35bc2..98f5c2b11 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -105,7 +105,7 @@ private: static int l_get_armor_groups(lua_State *L); // set_physics_override(self, physics_override_speed, physics_override_jump, - // physics_override_gravity, sneak, sneak_glitch) + // physics_override_gravity, sneak, sneak_glitch, new_move) static int l_set_physics_override(lua_State *L); // get_physics_override(self) -- cgit v1.2.3 From f1d7a26b7c341b468f34325cec5c3d495f175a8f Mon Sep 17 00:00:00 2001 From: Ben Deutsch Date: Fri, 17 Mar 2017 10:39:47 +0100 Subject: Add clouds API --- doc/lua_api.txt | 9 ++++ src/client.h | 11 +++++ src/cloudparams.h | 33 ++++++++++++++ src/clouds.cpp | 90 ++++++++++++++++++++----------------- src/clouds.h | 54 +++++++++++++++++++--- src/game.cpp | 13 ++++++ src/network/clientopcodes.cpp | 2 +- src/network/clientpackethandler.cpp | 28 ++++++++++++ src/network/networkprotocol.h | 10 +++++ src/network/serveropcodes.cpp | 2 +- src/remoteplayer.cpp | 8 ++++ src/remoteplayer.h | 12 +++++ src/script/lua_api/l_object.cpp | 81 +++++++++++++++++++++++++++++++++ src/script/lua_api/l_object.h | 6 +++ src/server.cpp | 30 +++++++++++++ src/server.h | 12 +++++ src/sky.cpp | 6 ++- 17 files changed, 357 insertions(+), 50 deletions(-) create mode 100644 src/cloudparams.h (limited to 'src/script/lua_api/l_object.h') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index eba8a5fef..479e38a2e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3077,6 +3077,15 @@ This is basically a reference to a C++ `ServerActiveObject` * `"skybox"`: Uses 6 textures, `bgcolor` used * `"plain"`: Uses 0 textures, `bgcolor` used * `get_sky()`: returns bgcolor, type and a table with the textures +* `set_clouds(parameters)`: set cloud parameters + * `parameters` is a table with the following optional fields: + * `density`: from `0` (no clouds) to `1` (full clouds) (default `0.4`) + * `color`: basic cloud color, with alpha channel (default `#fff0f0e5`) + * `ambient`: cloud color lower bound, use for a "glow at night" effect (default `#000000`) + * `height`: cloud height, i.e. y of cloud base (default per conf, usually `120`) + * `thickness`: cloud thickness in nodes (default `16`) + * `speed`: 2D cloud speed + direction in nodes per second (default `{x=0, y=-2}`) +* `get_clouds()`: returns a table with the current cloud parameters as in `set_clouds` * `override_day_night_ratio(ratio or nil)` * `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount * `nil`: Disables override, defaulting to sunlight based on day-night cycle diff --git a/src/client.h b/src/client.h index f5b03f19d..7cbfadd50 100644 --- a/src/client.h +++ b/src/client.h @@ -77,6 +77,7 @@ enum ClientEventType CE_HUDCHANGE, CE_SET_SKY, CE_OVERRIDE_DAY_NIGHT_RATIO, + CE_CLOUD_PARAMS, }; struct ClientEvent @@ -178,6 +179,15 @@ struct ClientEvent bool do_override; float ratio_f; } override_day_night_ratio; + struct { + f32 density; + u32 color_bright; + u32 color_ambient; + f32 height; + f32 thickness; + f32 speed_x; + f32 speed_y; + } cloud_params; }; }; @@ -331,6 +341,7 @@ public: void handleCommand_HudSetFlags(NetworkPacket* pkt); void handleCommand_HudSetParam(NetworkPacket* pkt); void handleCommand_HudSetSky(NetworkPacket* pkt); + void handleCommand_CloudParams(NetworkPacket* pkt); void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt); void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt); void handleCommand_EyeOffset(NetworkPacket* pkt); diff --git a/src/cloudparams.h b/src/cloudparams.h new file mode 100644 index 000000000..dafec4b27 --- /dev/null +++ b/src/cloudparams.h @@ -0,0 +1,33 @@ +/* +Minetest +Copyright (C) 2017 bendeutsch, Ben Deutsch + +This program is free software; you can redistribute it and/or modify +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 +(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 +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CLOUDPARAMS_HEADER +#define CLOUDPARAMS_HEADER + +struct CloudParams +{ + float density; + video::SColor color_bright; + video::SColor color_ambient; + float thickness; + float height; + v2f speed; +}; + +#endif diff --git a/src/clouds.cpp b/src/clouds.cpp index 82b63b6b3..627fac47a 100644 --- a/src/clouds.cpp +++ b/src/clouds.cpp @@ -32,6 +32,7 @@ irr::scene::ISceneManager *g_menucloudsmgr = NULL; static void cloud_3d_setting_changed(const std::string &settingname, void *data) { + // TODO: only re-read cloud settings, not height or radius ((Clouds *)data)->readSettings(); } @@ -44,9 +45,10 @@ Clouds::Clouds( ): scene::ISceneNode(parent, mgr, id), m_seed(seed), - m_camera_pos(0,0), - m_time(0), - m_camera_offset(0,0,0) + m_camera_pos(0.0f, 0.0f), + m_origin(0.0f, 0.0f), + m_camera_offset(0.0f, 0.0f, 0.0f), + m_color(1.0f, 1.0f, 1.0f, 1.0f) { m_material.setFlag(video::EMF_LIGHTING, false); //m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); @@ -57,14 +59,18 @@ Clouds::Clouds( //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + m_params.density = 0.4f; + m_params.thickness = 16.0f; + m_params.color_bright = video::SColor(229, 255, 240, 240); + m_params.color_ambient = video::SColor(255, 0, 0, 0); + m_params.speed = v2f(0.0f, -2.0f); + m_passed_cloud_y = cloudheight; readSettings(); g_settings->registerChangedCallback("enable_3d_clouds", &cloud_3d_setting_changed, this); - m_box = aabb3f(-BS*1000000,m_cloud_y-BS,-BS*1000000, - BS*1000000,m_cloud_y+BS,BS*1000000); - + updateBox(); } Clouds::~Clouds() @@ -88,6 +94,10 @@ void Clouds::OnRegisterSceneNode() void Clouds::render() { + + if (m_params.density <= 0.0f) + return; // no need to do anything + video::IVideoDriver* driver = SceneManager->getVideoDriver(); if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) @@ -107,15 +117,12 @@ void Clouds::render() Clouds move from Z+ towards Z- */ - const float cloud_size = BS * 64; - const v2f cloud_speed(0, -BS * 2); + static const float cloud_size = BS * 64.0f; const float cloud_full_radius = cloud_size * m_cloud_radius_i; - // Position of cloud noise origin in world coordinates - v2f world_cloud_origin_pos_f = m_time * cloud_speed; // Position of cloud noise origin from the camera - v2f cloud_origin_from_camera_f = world_cloud_origin_pos_f - m_camera_pos; + v2f cloud_origin_from_camera_f = m_origin - m_camera_pos; // The center point of drawing in the noise v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f; // The integer center point of drawing in the noise @@ -127,7 +134,7 @@ void Clouds::render() v2f world_center_of_drawing_in_noise_f = v2f( center_of_drawing_in_noise_i.X * cloud_size, center_of_drawing_in_noise_i.Y * cloud_size - ) + world_cloud_origin_pos_f; + ) + m_origin; /*video::SColor c_top(128,b*240,b*240,b*255); video::SColor c_side_1(128,b*230,b*230,b*255); @@ -146,10 +153,6 @@ void Clouds::render() c_bottom_f.r *= 0.80; c_bottom_f.g *= 0.80; c_bottom_f.b *= 0.80; - c_top_f.a = 0.9; - c_side_1_f.a = 0.9; - c_side_2_f.a = 0.9; - c_bottom_f.a = 0.9; video::SColor c_top = c_top_f.toSColor(); video::SColor c_side_1 = c_side_1_f.toSColor(); video::SColor c_side_2 = c_side_2_f.toSColor(); @@ -187,11 +190,14 @@ void Clouds::render() zi + center_of_drawing_in_noise_i.Y ); - double noise = noise2d_perlin( + float noise = noise2d_perlin( (float)p_in_noise_i.X * cloud_size_noise, (float)p_in_noise_i.Y * cloud_size_noise, m_seed, 3, 0.5); - grid[i] = (noise >= 0.4); + // normalize to 0..1 (given 3 octaves) + static const float noise_bound = 1.0f + 0.5f + 0.25f; + float density = noise / noise_bound * 0.5f + 0.5f; + grid[i] = (density < m_params.density); } } @@ -236,8 +242,9 @@ void Clouds::render() v[3].Color.setBlue(255); }*/ - f32 rx = cloud_size/2; - f32 ry = 8 * BS; + f32 rx = cloud_size / 2.0f; + // if clouds are flat, the top layer should be at the given height + f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f; f32 rz = cloud_size / 2; for(int i=0; igetU16("cloud_radius"); m_enable_3d = g_settings->getBool("enable_3d_clouds"); } - diff --git a/src/clouds.h b/src/clouds.h index 9c6b41786..a0bda28df 100644 --- a/src/clouds.h +++ b/src/clouds.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include #include "constants.h" +#include "cloudparams.h" // Menu clouds class Clouds; @@ -79,27 +80,68 @@ public: void updateCameraOffset(v3s16 camera_offset) { m_camera_offset = camera_offset; - m_box = aabb3f(-BS * 1000000, m_cloud_y - BS - BS * camera_offset.Y, -BS * 1000000, - BS * 1000000, m_cloud_y + BS - BS * camera_offset.Y, BS * 1000000); + updateBox(); } void readSettings(); + void setDensity(float density) + { + m_params.density = density; + // currently does not need bounding + } + + void setColorBright(const video::SColor &color_bright) + { + m_params.color_bright = color_bright; + } + + void setColorAmbient(const video::SColor &color_ambient) + { + m_params.color_ambient = color_ambient; + } + + void setHeight(float height) + { + m_params.height = height; // add bounding when necessary + updateBox(); + } + + void setSpeed(v2f speed) + { + m_params.speed = speed; + } + + void setThickness(float thickness) + { + m_params.thickness = thickness; + updateBox(); + } + private: + void updateBox() + { + float height_bs = m_params.height * BS; + float thickness_bs = m_params.thickness * BS; + m_box = aabb3f(-BS * 1000000.0f, height_bs - BS * m_camera_offset.Y, -BS * 1000000.0f, + BS * 1000000.0f, height_bs + thickness_bs - BS * m_camera_offset.Y, BS * 1000000.0f); + } + video::SMaterial m_material; aabb3f m_box; s16 m_passed_cloud_y; - float m_cloud_y; u16 m_cloud_radius_i; bool m_enable_3d; - video::SColorf m_color; u32 m_seed; v2f m_camera_pos; - float m_time; + v2f m_origin; + v2f m_speed; v3s16 m_camera_offset; + video::SColorf m_color; + CloudParams m_params; + }; #endif - diff --git a/src/game.cpp b/src/game.cpp index a1cc1ab15..ba6530d80 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3295,6 +3295,19 @@ void Game::processClientEvents(CameraOrientation *cam) event.override_day_night_ratio.ratio_f * 1000); break; + case CE_CLOUD_PARAMS: + if (clouds) { + clouds->setDensity(event.cloud_params.density); + clouds->setColorBright(video::SColor(event.cloud_params.color_bright)); + clouds->setColorAmbient(video::SColor(event.cloud_params.color_ambient)); + clouds->setHeight(event.cloud_params.height); + clouds->setThickness(event.cloud_params.thickness); + clouds->setSpeed(v2f( + event.cloud_params.speed_x, + event.cloud_params.speed_y)); + } + break; + default: // unknown or unhandled type break; diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index 563baf77b..1be6e5522 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -108,7 +108,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_LocalPlayerAnimations }, // 0x51 { "TOCLIENT_EYE_OFFSET", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_EyeOffset }, // 0x52 { "TOCLIENT_DELETE_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner }, // 0x53 - null_command_handler, + { "TOCLIENT_CLOUD_PARAMS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_CloudParams }, // 0x54 null_command_handler, null_command_handler, null_command_handler, diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 772ffe905..defc83f31 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1168,6 +1168,34 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) m_client_event_queue.push(event); } +void Client::handleCommand_CloudParams(NetworkPacket* pkt) +{ + f32 density; + video::SColor color_bright; + video::SColor color_ambient; + f32 height; + f32 thickness; + v2f speed; + + *pkt >> density >> color_bright >> color_ambient + >> height >> thickness >> speed; + + ClientEvent event; + event.type = CE_CLOUD_PARAMS; + event.cloud_params.density = density; + // use the underlying u32 representation, because we can't + // use struct members with constructors here, and this way + // we avoid using new() and delete() for no good reason + event.cloud_params.color_bright = color_bright.color; + event.cloud_params.color_ambient = color_ambient.color; + event.cloud_params.height = height; + event.cloud_params.thickness = thickness; + // same here: deconstruct to skip constructor + event.cloud_params.speed_x = speed.X; + event.cloud_params.speed_y = speed.Y; + m_client_event_queue.push(event); +} + void Client::handleCommand_OverrideDayNightRatio(NetworkPacket* pkt) { bool do_override; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index e7a3469b7..a1a4f5bfa 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -610,6 +610,16 @@ enum ToClientCommand u32 id */ + TOCLIENT_CLOUD_PARAMS = 0x54, + /* + f1000 density + u8[4] color_diffuse (ARGB) + u8[4] color_ambient (ARGB) + f1000 height + f1000 thickness + v2f1000 speed + */ + TOCLIENT_SRP_BYTES_S_B = 0x60, /* Belonging to AUTH_MECHANISM_LEGACY_PASSWORD and AUTH_MECHANISM_SRP. diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index 31b571ff0..450730ca2 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -197,7 +197,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", 0, true }, // 0x51 { "TOCLIENT_EYE_OFFSET", 0, true }, // 0x52 { "TOCLIENT_DELETE_PARTICLESPAWNER", 0, true }, // 0x53 - null_command_factory, + { "TOCLIENT_CLOUD_PARAMS", 0, true }, // 0x54 null_command_factory, null_command_factory, null_command_factory, diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 2dbfe9d9d..2b4db62f5 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -65,6 +65,14 @@ RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef): movement_liquid_fluidity_smooth = g_settings->getFloat("movement_liquid_fluidity_smooth") * BS; movement_liquid_sink = g_settings->getFloat("movement_liquid_sink") * BS; movement_gravity = g_settings->getFloat("movement_gravity") * BS; + + // copy defaults + m_cloud_params.density = 0.4f; + m_cloud_params.color_bright = video::SColor(255, 255, 240, 240); + m_cloud_params.color_ambient = video::SColor(255, 0, 0, 0); + m_cloud_params.height = 120.0f; + m_cloud_params.thickness = 16.0f; + m_cloud_params.speed = v2f(0.0f, -2.0f); } void RemotePlayer::serializeExtraAttributes(std::string &output) diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 4b96835fc..b9d9c74f5 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define REMOTEPLAYER_HEADER #include "player.h" +#include "cloudparams.h" class PlayerSAO; @@ -99,6 +100,16 @@ public: *params = m_sky_params; } + void setCloudParams(const CloudParams &cloud_params) + { + m_cloud_params = cloud_params; + } + + const CloudParams &getCloudParams() const + { + return m_cloud_params; + } + bool checkModified() const { return m_dirty || inventory.checkModified(); } void setModified(const bool x) @@ -154,6 +165,7 @@ private: std::string m_sky_type; video::SColor m_sky_bgcolor; std::vector m_sky_params; + CloudParams m_cloud_params; }; #endif diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index a5b6e3941..6cd852299 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1729,6 +1729,85 @@ int ObjectRef::l_get_sky(lua_State *L) return 3; } +// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) +int ObjectRef::l_set_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + if (!lua_istable(L, 2)) + return 0; + + CloudParams cloud_params = player->getCloudParams(); + + cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density); + + lua_getfield(L, 2, "color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_bright); + lua_pop(L, 1); + lua_getfield(L, 2, "ambient"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_ambient); + lua_pop(L, 1); + + cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height ); + cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness); + + lua_getfield(L, 2, "speed"); + if (lua_istable(L, -1)) { + v2f new_speed; + new_speed.X = getfloatfield_default(L, -1, "x", 0); + new_speed.Y = getfloatfield_default(L, -1, "y", 0); + cloud_params.speed = new_speed; + } + lua_pop(L, 1); + + if (!getServer(L)->setClouds(player, cloud_params.density, + cloud_params.color_bright, cloud_params.color_ambient, + cloud_params.height, cloud_params.thickness, + cloud_params.speed)) + return 0; + + player->setCloudParams(cloud_params); + + lua_pushboolean(L, true); + return 1; +} + +int ObjectRef::l_get_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + const CloudParams &cloud_params = player->getCloudParams(); + + lua_newtable(L); + lua_pushnumber(L, cloud_params.density); + lua_setfield(L, -2, "density"); + push_ARGB8(L, cloud_params.color_bright); + lua_setfield(L, -2, "color"); + push_ARGB8(L, cloud_params.color_ambient); + lua_setfield(L, -2, "ambient"); + lua_pushnumber(L, cloud_params.height); + lua_setfield(L, -2, "height"); + lua_pushnumber(L, cloud_params.thickness); + lua_setfield(L, -2, "thickness"); + lua_newtable(L); + lua_pushnumber(L, cloud_params.speed.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, cloud_params.speed.Y); + lua_setfield(L, -2, "y"); + lua_setfield(L, -2, "speed"); + + return 1; +} + + // override_day_night_ratio(self, brightness=0...1) int ObjectRef::l_override_day_night_ratio(lua_State *L) { @@ -1911,6 +1990,8 @@ const luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, hud_get_hotbar_selected_image), luamethod(ObjectRef, set_sky), luamethod(ObjectRef, get_sky), + luamethod(ObjectRef, set_clouds), + luamethod(ObjectRef, get_clouds), luamethod(ObjectRef, override_day_night_ratio), luamethod(ObjectRef, get_day_night_ratio), luamethod(ObjectRef, set_local_animation), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 98f5c2b11..0912a1c49 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -289,6 +289,12 @@ private: // get_sky(self, type, list) static int l_get_sky(lua_State *L); + // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) + static int l_set_clouds(lua_State *L); + + // get_clouds(self) + static int l_get_clouds(lua_State *L); + // override_day_night_ratio(self, type) static int l_override_day_night_ratio(lua_State *L); diff --git a/src/server.cpp b/src/server.cpp index 2edf83947..9ef69cb37 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1882,6 +1882,20 @@ void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor, Send(&pkt); } +void Server::SendCloudParams(u16 peer_id, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed) +{ + NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id); + pkt << density << color_bright << color_ambient + << height << thickness << speed; + + Send(&pkt); +} + void Server::SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio) { @@ -3196,6 +3210,22 @@ bool Server::setSky(RemotePlayer *player, const video::SColor &bgcolor, return true; } +bool Server::setClouds(RemotePlayer *player, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed) +{ + if (!player) + return false; + + SendCloudParams(player->peer_id, density, + color_bright, color_ambient, height, + thickness, speed); + return true; +} + bool Server::overrideDayNightRatio(RemotePlayer *player, bool do_override, float ratio) { diff --git a/src/server.h b/src/server.h index 948fb8fc2..3a082b9a4 100644 --- a/src/server.h +++ b/src/server.h @@ -332,6 +332,12 @@ public: bool setSky(RemotePlayer *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); + bool setClouds(RemotePlayer *player, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); @@ -401,6 +407,12 @@ private: void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value); void SendSetSky(u16 peer_id, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); + void SendCloudParams(u16 peer_id, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); void SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio); /* diff --git a/src/sky.cpp b/src/sky.cpp index 211a2dcdc..7f999feb0 100644 --- a/src/sky.cpp +++ b/src/sky.cpp @@ -534,8 +534,10 @@ void Sky::update(float time_of_day, float time_brightness, video::SColorf skycolor_bright_dawn_f = video::SColor(255, 180, 186, 250); video::SColorf skycolor_bright_night_f = video::SColor(255, 0, 107, 255); - video::SColorf cloudcolor_bright_normal_f = video::SColor(255, 240, 240, 255); - video::SColorf cloudcolor_bright_dawn_f = video::SColor(255, 255, 223, 191); + // pure white: becomes "diffuse light component" for clouds + video::SColorf cloudcolor_bright_normal_f = video::SColor(255, 255, 255, 255); + // dawn-factoring version of pure white (note: R is above 1.0) + video::SColorf cloudcolor_bright_dawn_f(255.0f/240.0f, 223.0f/240.0f, 191.0f/255.0f); float cloud_color_change_fraction = 0.95; if (sunlight_seen) { -- cgit v1.2.3 From ad9fcf859ec2347325830e09504ae96968b51ea8 Mon Sep 17 00:00:00 2001 From: paramat Date: Fri, 28 Apr 2017 03:06:49 +0100 Subject: Set sky API: Add bool for clouds in front of custom skybox Default true. Add 'm_clouds_enabled' bool to sky.h, set from new bool in 'set sky' API. Make 'getCloudsVisible()' depend on 'm_clouds_enabled' instead of 'm_visible' (whether normal sky is visible). --- doc/lua_api.txt | 8 +++++--- src/client.h | 1 + src/game.cpp | 3 +++ src/network/clientpackethandler.cpp | 6 ++++++ src/network/networkprotocol.h | 1 + src/remoteplayer.h | 8 ++++++-- src/script/lua_api/l_object.cpp | 15 ++++++++++----- src/script/lua_api/l_object.h | 4 ++-- src/server.cpp | 12 ++++++++---- src/server.h | 6 ++++-- src/sky.cpp | 2 ++ src/sky.h | 7 +++++-- 12 files changed, 53 insertions(+), 20 deletions(-) (limited to 'src/script/lua_api/l_object.h') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 77ffb88e2..599e02fcb 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3077,13 +3077,15 @@ This is basically a reference to a C++ `ServerActiveObject` * `hud_set_hotbar_selected_image(texturename)` * sets image for selected item of hotbar * `hud_get_hotbar_selected_image`: returns texturename -* `set_sky(bgcolor, type, {texture names})` +* `set_sky(bgcolor, type, {texture names}, clouds)` * `bgcolor`: ColorSpec, defaults to white - * Available types: + * `type`: Available types: * `"regular"`: Uses 0 textures, `bgcolor` ignored * `"skybox"`: Uses 6 textures, `bgcolor` used * `"plain"`: Uses 0 textures, `bgcolor` used -* `get_sky()`: returns bgcolor, type and a table with the textures + * `clouds`: Boolean for whether clouds appear in front of `"skybox"` or + `"plain"` custom skyboxes (default: `true`) +* `get_sky()`: returns bgcolor, type, table of textures, clouds * `set_clouds(parameters)`: set cloud parameters * `parameters` is a table with the following optional fields: * `density`: from `0` (no clouds) to `1` (full clouds) (default `0.4`) diff --git a/src/client.h b/src/client.h index e8db7de44..0dd519308 100644 --- a/src/client.h +++ b/src/client.h @@ -174,6 +174,7 @@ struct ClientEvent video::SColor *bgcolor; std::string *type; std::vector *params; + bool clouds; } set_sky; struct{ bool do_override; diff --git a/src/game.cpp b/src/game.cpp index ba6530d80..7dd9c942d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3255,6 +3255,8 @@ void Game::processClientEvents(CameraOrientation *cam) case CE_SET_SKY: sky->setVisible(false); + // Whether clouds are visible in front of a custom skybox + sky->setCloudsEnabled(event.set_sky.clouds); if (skybox) { skybox->remove(); @@ -3264,6 +3266,7 @@ void Game::processClientEvents(CameraOrientation *cam) // Handle according to type if (*event.set_sky.type == "regular") { sky->setVisible(true); + sky->setCloudsEnabled(true); } else if (*event.set_sky.type == "skybox" && event.set_sky.params->size() == 6) { sky->setFallbackBgColor(*event.set_sky.bgcolor); diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 4316a77d4..c3626158e 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1192,11 +1192,17 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) for (size_t i = 0; i < count; i++) params->push_back(deSerializeString(is)); + bool clouds = true; + try { + clouds = readU8(is); + } catch (...) {} + ClientEvent event; event.type = CE_SET_SKY; event.set_sky.bgcolor = bgcolor; event.set_sky.type = type; event.set_sky.params = params; + event.set_sky.clouds = clouds; m_client_event_queue.push(event); } diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 70cad85d8..7126c237b 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -584,6 +584,7 @@ enum ToClientCommand foreach count: u8 len u8[len] param + u8 clouds (boolean) */ TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO = 0x50, diff --git a/src/remoteplayer.h b/src/remoteplayer.h index b9d9c74f5..7d46205c5 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -85,19 +85,21 @@ public: } void setSky(const video::SColor &bgcolor, const std::string &type, - const std::vector ¶ms) + const std::vector ¶ms, bool &clouds) { m_sky_bgcolor = bgcolor; m_sky_type = type; m_sky_params = params; + m_sky_clouds = clouds; } void getSky(video::SColor *bgcolor, std::string *type, - std::vector *params) + std::vector *params, bool *clouds) { *bgcolor = m_sky_bgcolor; *type = m_sky_type; *params = m_sky_params; + *clouds = m_sky_clouds; } void setCloudParams(const CloudParams &cloud_params) @@ -165,6 +167,8 @@ private: std::string m_sky_type; video::SColor m_sky_bgcolor; std::vector m_sky_params; + bool m_sky_clouds; + CloudParams m_cloud_params; }; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 6cd852299..6f61ab55c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1662,7 +1662,7 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) return 1; } -// set_sky(self, bgcolor, type, list) +// set_sky(self, bgcolor, type, list, clouds = true) int ObjectRef::l_set_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -1678,9 +1678,8 @@ int ObjectRef::l_set_sky(lua_State *L) std::vector params; if (lua_istable(L, 4)) { - int table = lua_gettop(L); lua_pushnil(L); - while (lua_next(L, table) != 0) { + while (lua_next(L, 4) != 0) { // key at index -2 and value at index -1 if (lua_isstring(L, -1)) params.push_back(lua_tostring(L, -1)); @@ -1694,7 +1693,11 @@ int ObjectRef::l_set_sky(lua_State *L) if (type == "skybox" && params.size() != 6) throw LuaError("skybox expects 6 textures"); - if (!getServer(L)->setSky(player, bgcolor, type, params)) + bool clouds = true; + if (lua_isboolean(L, 5)) + clouds = lua_toboolean(L, 5); + + if (!getServer(L)->setSky(player, bgcolor, type, params, clouds)) return 0; lua_pushboolean(L, true); @@ -1712,8 +1715,9 @@ int ObjectRef::l_get_sky(lua_State *L) video::SColor bgcolor(255, 255, 255, 255); std::string type; std::vector params; + bool clouds; - player->getSky(&bgcolor, &type, ¶ms); + player->getSky(&bgcolor, &type, ¶ms, &clouds); type = type == "" ? "regular" : type; push_ARGB8(L, bgcolor); @@ -1726,6 +1730,7 @@ int ObjectRef::l_get_sky(lua_State *L) lua_rawseti(L, -2, i); i++; } + lua_pushboolean(L, clouds); return 3; } diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 0912a1c49..9801ce02b 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -283,10 +283,10 @@ private: // hud_get_hotbar_selected_image(self) static int l_hud_get_hotbar_selected_image(lua_State *L); - // set_sky(self, type, list) + // set_sky(self, bgcolor, type, list, clouds = true) static int l_set_sky(lua_State *L); - // get_sky(self, type, list) + // get_sky(self) static int l_get_sky(lua_State *L); // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) diff --git a/src/server.cpp b/src/server.cpp index 190a1baf2..bf01fb7eb 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1871,7 +1871,8 @@ void Server::SendHUDSetParam(u16 peer_id, u16 param, const std::string &value) } void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor, - const std::string &type, const std::vector ¶ms) + const std::string &type, const std::vector ¶ms, + bool &clouds) { NetworkPacket pkt(TOCLIENT_SET_SKY, 0, peer_id); pkt << bgcolor << type << (u16) params.size(); @@ -1879,6 +1880,8 @@ void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor, for(size_t i=0; i ¶ms) + const std::string &type, const std::vector ¶ms, + bool &clouds) { if (!player) return false; - player->setSky(bgcolor, type, params); - SendSetSky(player->peer_id, bgcolor, type, params); + player->setSky(bgcolor, type, params, clouds); + SendSetSky(player->peer_id, bgcolor, type, params, clouds); return true; } diff --git a/src/server.h b/src/server.h index 5e6211637..2e735e77c 100644 --- a/src/server.h +++ b/src/server.h @@ -335,7 +335,8 @@ public: bool setPlayerEyeOffset(RemotePlayer *player, v3f first, v3f third); bool setSky(RemotePlayer *player, const video::SColor &bgcolor, - const std::string &type, const std::vector ¶ms); + const std::string &type, const std::vector ¶ms, + bool &clouds); bool setClouds(RemotePlayer *player, float density, const video::SColor &color_bright, const video::SColor &color_ambient, @@ -410,7 +411,8 @@ private: void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask); void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value); void SendSetSky(u16 peer_id, const video::SColor &bgcolor, - const std::string &type, const std::vector ¶ms); + const std::string &type, const std::vector ¶ms, + bool &clouds); void SendCloudParams(u16 peer_id, float density, const video::SColor &color_bright, const video::SColor &color_ambient, diff --git a/src/sky.cpp b/src/sky.cpp index 7f999feb0..5414f74bd 100644 --- a/src/sky.cpp +++ b/src/sky.cpp @@ -85,6 +85,8 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, } m_directional_colored_fog = g_settings->getBool("directional_colored_fog"); + + m_clouds_enabled = true; } diff --git a/src/sky.h b/src/sky.h index 72cb2d581..c9678a80b 100644 --- a/src/sky.h +++ b/src/sky.h @@ -65,10 +65,12 @@ public: return m_visible ? m_skycolor : m_fallback_bg_color; } - bool getCloudsVisible() { return m_clouds_visible && m_visible; } + bool getCloudsVisible() { return m_clouds_visible && m_clouds_enabled; } const video::SColorf &getCloudColor() { return m_cloudcolor_f; } void setVisible(bool visible) { m_visible = visible; } + // Set only from set_sky API + void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; } void setFallbackBgColor(const video::SColor &fallback_bg_color) { m_fallback_bg_color = fallback_bg_color; @@ -123,7 +125,8 @@ private: bool m_sunlight_seen; float m_brightness; float m_cloud_brightness; - bool m_clouds_visible; + bool m_clouds_visible; // Whether clouds are disabled due to player underground + bool m_clouds_enabled; // Initialised to true, reset only by set_sky API bool m_directional_colored_fog; video::SColorf m_bgcolor_bright_f; video::SColorf m_skycolor_bright_f; -- cgit v1.2.3