Allow modifying movement speed, jump height and gravity per-player via the Lua API.
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Fri, 5 Apr 2013 11:03:28 +0000 (01:03 -1000)
committerPilzAdam <pilzadam@minetest.net>
Fri, 5 Apr 2013 00:00:59 +0000 (02:00 +0200)
14 files changed:
doc/lua_api.txt
src/clientserver.h
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h
src/environment.cpp
src/genericobject.cpp
src/genericobject.h
src/localplayer.cpp
src/player.cpp
src/player.h
src/scriptapi_object.cpp
src/scriptapi_object.h
src/serverobject.h

index 029c84d030b8282169dee418442b73fdc79cfd05..a61ffce648d7a9f7c4701e96e28178e2174a2427 100644 (file)
@@ -1348,6 +1348,10 @@ Player-only: (no-op for other objects)
     {jump=bool,right=bool,left=bool,LMB=bool,RMB=bool,sneak=bool,aux1=bool,down=bool,up=bool}
 - get_player_control_bits(): returns integer with bit packed player pressed keys
     bit nr/meaning: 0/up ,1/down ,2/left ,3/right ,4/jump ,5/aux1 ,6/sneak ,7/LMB ,8/RMB
+- set_physics_override(speed, jump, gravity)
+    modifies per-player walking speed, jump height, and gravity.
+    Values default to 1 and act as offsets to the physics settings 
+    in minetest.conf. nil will keep the current setting.
     
 InvRef: Reference to an inventory
 methods:
index 28b57997195a1e79093478fcaf66f189a020f698..8b1e0a7e48483a062571303043d97fbc04f2dd0b 100644 (file)
@@ -88,9 +88,11 @@ SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
        PROTOCOL_VERSION 18:
                damageGroups added to ToolCapabilities
                sound_place added to ItemDefinition
+       PROTOCOL_VERSION 19:
+               GENERIC_CMD_SET_PHYSICS_OVERRIDE
 */
 
-#define LATEST_PROTOCOL_VERSION 18
+#define LATEST_PROTOCOL_VERSION 19
 
 // Server's supported network protocol range
 #define SERVER_PROTOCOL_VERSION_MIN 13
index 84fc0bf79bf2defbcc604d8bf10fea3fe5c2cc06..0a1a92271e721fb41b9b96a30cedab84f15b3c3d 100644 (file)
@@ -1679,6 +1679,19 @@ public:
 
                        updateTexturePos();
                }
+               else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE)
+               {
+                       float override_speed = readF1000(is);
+                       float override_jump = readF1000(is);
+                       float override_gravity = readF1000(is);
+                       if(m_is_local_player)
+                       {
+                               LocalPlayer *player = m_env->getLocalPlayer();
+                               player->physics_override_speed = override_speed;
+                               player->physics_override_jump = override_jump;
+                               player->physics_override_gravity = override_gravity;
+                       }
+               }
                else if(cmd == GENERIC_CMD_SET_ANIMATION)
                {
                        m_animation_range = readV2F1000(is);
index ae08b4260385fb9b4f253b7ff81fc2dd9482094f..e6c8c725c25ff82cd74ef514301ea1917d43d201 100644 (file)
@@ -935,7 +935,11 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
        m_moved(false),
        m_inventory_not_sent(false),
        m_hp_not_sent(false),
-       m_wielded_item_not_sent(false)
+       m_wielded_item_not_sent(false),
+       m_physics_override_speed(1),
+       m_physics_override_jump(1),
+       m_physics_override_gravity(1),
+       m_physics_override_sent(false)
 {
        assert(m_player);
        assert(m_peer_id != 0);
@@ -1019,7 +1023,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
                writeF1000(os, m_player->getYaw());
                writeS16(os, getHP());
 
-               writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
+               writeU8(os, 5 + m_bone_position.size()); // number of messages stuffed in here
                os<<serializeLongString(getPropertyPacket()); // message 1
                os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
                os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
@@ -1027,6 +1031,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
                        os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
                }
                os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
+               os<<serializeLongString(gob_cmd_update_physics_override(m_physics_override_speed, m_physics_override_jump, m_physics_override_gravity)); // 5
        }
        else
        {
@@ -1196,6 +1201,14 @@ void PlayerSAO::step(float dtime, bool send_recommended)
                m_messages_out.push_back(aom);
        }
 
+       if(m_physics_override_sent == false){
+               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);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push_back(aom);
+       }
+
        if(m_animation_sent == false){
                m_animation_sent = true;
                std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
index 60ca8f319fd88abf852be59a21a3d6e8c58a93d3..dca02bb00ba5e2e6cbb55b56072fe182f0a8e87f 100644 (file)
@@ -101,7 +101,7 @@ private:
        float m_last_sent_position_timer;
        float m_last_sent_move_precision;
        bool m_armor_groups_sent;
-       
+
        v2f m_animation_range;
        float m_animation_speed;
        float m_animation_blend;
@@ -257,8 +257,6 @@ private:
        ItemGroupList m_armor_groups;
        bool m_armor_groups_sent;
 
-
-
        bool m_properties_sent;
        struct ObjectProperties m_prop;
        // Cached privileges for enforcement
@@ -285,6 +283,11 @@ public:
        bool m_inventory_not_sent;
        bool m_hp_not_sent;
        bool m_wielded_item_not_sent;
+
+       float m_physics_override_speed;
+       float m_physics_override_jump;
+       float m_physics_override_gravity;
+       bool m_physics_override_sent;
 };
 
 #endif
index 07cdb24d10ec887b378e087702868328e0427108..385e5b955d50b0bd2926473968835ba21423457a 100644 (file)
@@ -2057,7 +2057,7 @@ void ClientEnvironment::step(float dtime)
                                // Gravity
                                v3f speed = lplayer->getSpeed();
                                if(lplayer->in_liquid == false)
-                                       speed.Y -= lplayer->movement_gravity * dtime_part * 2;
+                                       speed.Y -= lplayer->movement_gravity * lplayer->physics_override_gravity * dtime_part * 2;
 
                                // Liquid floating / sinking
                                if(lplayer->in_liquid && !lplayer->swimming_vertical)
index f7b272b00d283a85abf7438649fc8e77527bcee2..e2fbde8387095bfa9e402f49dae83bdedf730275 100644 (file)
@@ -117,6 +117,18 @@ std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
        return os.str();
 }
 
+std::string gob_cmd_update_physics_override(float physics_override_speed, float physics_override_jump, float physics_override_gravity)
+{
+       std::ostringstream os(std::ios::binary);
+       // command 
+       writeU8(os, GENERIC_CMD_SET_PHYSICS_OVERRIDE);
+       // parameters
+       writeF1000(os, physics_override_speed);
+       writeF1000(os, physics_override_jump);
+       writeF1000(os, physics_override_gravity);
+       return os.str();
+}
+
 std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend)
 {
        std::ostringstream os(std::ios::binary);
index 9a21baa6723fbdd156c07b326feae34fdfe029f3..276865ab972250df9844311550eaf395df0b2751 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GENERIC_CMD_SET_ANIMATION 6
 #define GENERIC_CMD_SET_BONE_POSITION 7
 #define GENERIC_CMD_SET_ATTACHMENT 8
+#define GENERIC_CMD_SET_PHYSICS_OVERRIDE 9
 
 #include "object_properties.h"
 std::string gob_cmd_set_properties(const ObjectProperties &prop);
@@ -62,6 +63,8 @@ std::string gob_cmd_punched(s16 damage, s16 result_hp);
 #include "itemgroup.h"
 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);
+
 std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend);
 
 std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation);
index a90ae69671ce70583b353cedb1fca72da18aee92..b69bdb24f69148a51ed266c2c2243124ce8274e7 100644 (file)
@@ -529,7 +529,7 @@ void LocalPlayer::applyControl(float dtime)
                        v3f speedJ = getSpeed();
                        if(speedJ.Y >= -0.5 * BS)
                        {
-                               speedJ.Y = movement_speed_jump;
+                               speedJ.Y = movement_speed_jump * physics_override_jump;
                                setSpeed(speedJ);
                                
                                MtEvent *e = new SimpleTriggerEvent("PlayerJump");
@@ -584,8 +584,8 @@ void LocalPlayer::applyControl(float dtime)
                incH = incV = movement_acceleration_default * BS * dtime;
 
        // Accelerate to target speed with maximum increment
-       accelerateHorizontal(speedH, incH);
-       accelerateVertical(speedV, incV);
+       accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed);
+       accelerateVertical(speedV * physics_override_speed, incV * physics_override_speed);
 }
 
 v3s16 LocalPlayer::getStandingNodePos()
index 4c81887bedeaab151adb7ad9ca1743829cb05594..1ca9423b0e9528583cbb2ce0d4664ef89087a9f8 100644 (file)
@@ -71,6 +71,11 @@ Player::Player(IGameDef *gamedef):
        movement_liquid_fluidity_smooth = 0.5 * BS;
        movement_liquid_sink = 10 * BS;
        movement_gravity = 9.81 * BS;
+
+       // Movement overrides are multipliers and must be 1 by default
+       physics_override_speed = 1;
+       physics_override_jump = 1;
+       physics_override_gravity = 1;
 }
 
 Player::~Player()
index 496c99532d8fe4bfca2f7b1e53c248ad2add675f..d95e535ffda63d91c5cf67cab8571d9c08f464f8 100644 (file)
@@ -222,6 +222,10 @@ public:
        f32 movement_liquid_sink;
        f32 movement_gravity;
 
+       float physics_override_speed;
+       float physics_override_jump;
+       float physics_override_gravity;
+
        u16 hp;
 
        float hurt_tilt_timer;
index a0f93cbbad33ec0ce5eafe6eb3792c5a668c9926..05433a598fae6433773dfc2c525f2f6389c97e20 100644 (file)
@@ -297,6 +297,28 @@ int ObjectRef::l_set_armor_groups(lua_State *L)
        return 0;
 }
 
+// set_physics_override(self, physics_override_speed, physics_override_jump, physics_override_gravity)
+int ObjectRef::l_set_physics_override(lua_State *L)
+{
+       ObjectRef *ref = checkobject(L, 1);
+       PlayerSAO *co = (PlayerSAO *) getobject(ref);
+       if(co == NULL) return 0;
+       // Do it
+       if(!lua_isnil(L, 2)){
+               co->m_physics_override_speed = lua_tonumber(L, 2);
+               co->m_physics_override_sent = false;
+       }
+       if(!lua_isnil(L, 3)){
+               co->m_physics_override_jump = lua_tonumber(L, 3);
+               co->m_physics_override_sent = false;
+       }
+       if(!lua_isnil(L, 4)){
+               co->m_physics_override_gravity = lua_tonumber(L, 4);
+               co->m_physics_override_sent = false;
+       }
+       return 0;
+}
+
 // set_animation(self, frame_range, frame_speed, frame_blend)
 int ObjectRef::l_set_animation(lua_State *L)
 {
@@ -756,6 +778,7 @@ const luaL_reg ObjectRef::methods[] = {
        luamethod(ObjectRef, get_wielded_item),
        luamethod(ObjectRef, set_wielded_item),
        luamethod(ObjectRef, set_armor_groups),
+       luamethod(ObjectRef, set_physics_override),
        luamethod(ObjectRef, set_animation),
        luamethod(ObjectRef, set_bone_position),
        luamethod(ObjectRef, set_attach),
index a37abbb781f0545cd1ae95c88d159b8a159fbe2f..a44016933517c8d3f71a2d0042bec8cb52fe980e 100644 (file)
@@ -103,6 +103,9 @@ private:
        // set_armor_groups(self, groups)
        static int l_set_armor_groups(lua_State *L);
 
+       // set_physics_override(self, physics_override_speed, physics_override_jump, physics_override_gravity)
+       static int l_set_physics_override(lua_State *L);
+
        // set_animation(self, frame_range, frame_speed, frame_blend)
        static int l_set_animation(lua_State *L);
 
index 7a5b47bd16f671ecf95e43d38c75ee789f482c4a..13a075a2575b52dd59ce3f99ca9caace8d8c6de8 100644 (file)
@@ -152,6 +152,8 @@ public:
 
        virtual void setArmorGroups(const ItemGroupList &armor_groups)
        {}
+       virtual void setPhysicsOverride(float physics_override_speed, float physics_override_jump, float physics_override_gravity)
+       {}
        virtual void setAnimation(v2f frames, float frame_speed, float frame_blend)
        {}
        virtual void setBonePosition(std::string bone, v3f position, v3f rotation)