diff --git a/doc/lua_api.txt b/doc/lua_api.txt index d65010bb9..d333e4934 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1517,6 +1517,9 @@ Another example: Make red wool from white wool and red dye: connect to each other * `slippery`: Players and items will slide on the node. Only use `slippery = 3` for now to ensure forwards compatibility. + * `speed`: Changes movement speed for players and items will moving on the node in percents. + * `speed = -10`: to slow down the movement (min. -99%) + * `speed = 10`: to speed up the movement (max. 1000%) ### Known damage and digging time defining groups * `crumbly`: dirt, sand diff --git a/games/default/files/default/nodes.lua b/games/default/files/default/nodes.lua index 4b092b3b4..df20cf262 100644 --- a/games/default/files/default/nodes.lua +++ b/games/default/files/default/nodes.lua @@ -105,7 +105,7 @@ minetest.register_node("default:obsidian", { minetest.register_node("default:bedrock", { description = "Bedrock", tiles = {"default_bedrock.png"}, - groups = {oddly_breakable_by_hand = 5, not_in_creative_inventory = 1}, + groups = {oddly_breakable_by_hand = 5, speed = -30, not_in_creative_inventory = 1}, sounds = default.node_sound_stone_defaults(), }) @@ -230,7 +230,7 @@ minetest.register_node("default:snow", { {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5}, }, }, - groups = {crumbly = 3, falling_node = 1, snowy = 1, puts_out_fire = 1, misc = 1}, + groups = {crumbly = 3, falling_node = 1, snowy = 1, puts_out_fire = 1, misc = 1, speed = -30}, sounds = default.node_sound_snow_defaults(), on_use = snow_shoot_snowball, on_construct = function(pos) @@ -244,7 +244,7 @@ minetest.register_node("default:snow", { minetest.register_node("default:snowblock", { description = "Snow Block", tiles = {"default_snow.png"}, - groups = {crumbly = 3, cools_lava = 1, snowy = 1}, + groups = {crumbly = 3, cools_lava = 1, snowy = 1, speed = -30}, sounds = default.node_sound_snow_defaults(), drop = "default:snow 4", on_construct = function(pos) @@ -1491,7 +1491,7 @@ minetest.register_node("default:slimeblock", { }, use_texture_alpha = true, sunlight_propagates = true, - groups = {oddly_breakable_by_hand = 3, disable_jump = 1, fall_damage_add_percent=-100}, + groups = {oddly_breakable_by_hand = 3, disable_jump = 1, fall_damage_add_percent = -100, speed = -30}, }) diff --git a/games/default/files/default/textures/default_pine_needles.png b/games/default/files/default/textures/default_pine_needles.png index e8316737e..3f84da260 100644 Binary files a/games/default/files/default/textures/default_pine_needles.png and b/games/default/files/default/textures/default_pine_needles.png differ diff --git a/games/default/files/experience/textures/expbar_empty.png b/games/default/files/experience/textures/expbar_empty.png index b06867d65..a7d6cc9c8 100644 Binary files a/games/default/files/experience/textures/expbar_empty.png and b/games/default/files/experience/textures/expbar_empty.png differ diff --git a/games/default/files/experience/textures/expbar_full.png b/games/default/files/experience/textures/expbar_full.png index 373f4d0fe..10afe87c0 100644 Binary files a/games/default/files/experience/textures/expbar_full.png and b/games/default/files/experience/textures/expbar_full.png differ diff --git a/games/default/files/experience/textures/orb.png b/games/default/files/experience/textures/orb.png index f4945a478..3df97a29f 100644 Binary files a/games/default/files/experience/textures/orb.png and b/games/default/files/experience/textures/orb.png differ diff --git a/games/default/files/mobs_monster/spider.lua b/games/default/files/mobs_monster/spider.lua index 27bc36b10..bea5af941 100644 --- a/games/default/files/mobs_monster/spider.lua +++ b/games/default/files/mobs_monster/spider.lua @@ -164,7 +164,7 @@ minetest.register_node(":mobs:cobweb", { liquid_renewable = false, liquid_range = 0, walkable = false, - groups = {snappy = 1, disable_jump = 1}, + groups = {snappy = 1, disable_jump = 1, speed = -30}, sounds = default.node_sound_leaves_defaults(), }) diff --git a/games/default/files/player/playerplus/README.md b/games/default/files/player/playerplus/README.md deleted file mode 100644 index 626de21f2..000000000 --- a/games/default/files/player/playerplus/README.md +++ /dev/null @@ -1,20 +0,0 @@ -MultiCraft Game mod: PlayerPlus - -This mod lets the player move faster when walking on ice, slows down the player -when walking on snow, makes touching a cactus hurt and suffocates player when -their head is inside a solid node... enjoy! - -https://forum.minetest.net/viewtopic.php?t=10090&p=153667 - - -The mod has been rewritten and optimized to work with Player Physics API: -https://forum.minetest.net/viewtopic.php?f=9&t=22172 -Removed POVA, monoids support, knock-back, glitch. - -API: -Every second the mod checks which node the player is standing on, which node is -at foot and head level and stores inside a global table to be used by mods: - -- playerplus[name].nod_stand -- playerplus[name].nod_foot -- playerplus[name].nod_head diff --git a/games/default/files/player/playerplus/depends.txt b/games/default/files/player/playerplus/depends.txt deleted file mode 100644 index e32aa361d..000000000 --- a/games/default/files/player/playerplus/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -default -playerphysics diff --git a/games/default/files/player/playerplus/init.lua b/games/default/files/player/playerplus/init.lua deleted file mode 100644 index 961447de1..000000000 --- a/games/default/files/player/playerplus/init.lua +++ /dev/null @@ -1,89 +0,0 @@ -playerplus = {} - --- get node but use fallback for nil or unknown -local node_ok = function(pos, fallback) - fallback = fallback or "air" - local node = minetest.get_node_or_nil(pos) - if node and minetest.registered_nodes[node.name] then - return node.name - end - return fallback -end - -local time = 0 --- check interval -local check = 0.5 -if not minetest.is_singleplayer() then - local check = 1 -end - -minetest.register_globalstep(function(dtime) - time = time + dtime - if time < check then - return - end - -- reset time for next check - time = 0 - -- define locals outside loop - local name, pos, ndef, nslow - - -- loop through players - for _,player in ipairs(minetest.get_connected_players()) do - - name = player:get_player_name() - pos = player:get_pos() - pos.y = pos.y - 0.1 -- standing on - playerplus[name].nod_stand = node_ok(pos) - - -- Does the node below me have an on_walk_over function set? - ndef = minetest.registered_nodes[playerplus[name].nod_stand] - if ndef and ndef.on_walk_over then - ndef.on_walk_over(pos, ndef, player) - end - - pos.y = pos.y + 1.5 -- head level - playerplus[name].nod_head = node_ok(pos) - - pos.y = pos.y - 1.2 -- feet level - playerplus[name].nod_feet = node_ok(pos) - - pos.y = pos.y - 0.2 -- reset pos - - -- are we standing on any nodes that slow player down? - nslow = nil - if playerplus[name].nod_stand == "default:snow" - or playerplus[name].nod_stand == "default:snowblock" - or playerplus[name].nod_stand == "default:bedrock" - or playerplus[name].nod_stand == "default:slimeblock" - or playerplus[name].nod_stand == "mobs:cobweb" - or playerplus[name].nod_feet == "mobs:cobweb" - or playerplus[name].nod_head == "mobs:cobweb" then - nslow = true - end - - -- apply slowdown changes - if nslow and not playerplus[name].nslow then - playerphysics.add_physics_factor(player, "speed", "playerplusslow", 0.7) - playerplus[name].nslow = true - - elseif not nslow and playerplus[name].nslow then - playerphysics.remove_physics_factor(player, "speed", "playerplusslow") - playerplus[name].nslow = nil - end - end -end) - --- set to blank on join (for 3rd party mods) -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - - playerplus[name] = {} - playerplus[name].nod_head = "" - playerplus[name].nod_feet = "" - playerplus[name].nod_stand = "" -end) - --- clear when player leaves -minetest.register_on_leaveplayer(function(player) - playerplus[ player:get_player_name() ] = nil -end) diff --git a/games/default/files/player/playerplus/license.txt b/games/default/files/player/playerplus/license.txt deleted file mode 100644 index fec6f6aa5..000000000 --- a/games/default/files/player/playerplus/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 TenPlus1 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/content_sao.cpp b/src/content_sao.cpp index d82d7946b..dba2c376f 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -922,7 +922,8 @@ void PlayerSAO::step(float dtime, bool send_recommended) const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); // If node generates drown bool noclip = m_privs.count("noclip") && g_settings->getBool("noclip"); - if (c.drowning > 0 && m_hp > 0 &&!noclip) { + int drowning = c.walkable ? 1 : c.drowning; + if (drowning > 0 && m_hp > 0 && !noclip) { if (m_breath > 0) setBreath(m_breath - 1); @@ -940,7 +941,8 @@ void PlayerSAO::step(float dtime, bool send_recommended) MapNode n = m_env->getMap().getNodeNoEx(p); const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); // If player is alive & no drowning, breath - if (m_hp > 0 && m_breath < PLAYER_MAX_BREATH && c.drowning == 0) + int drowning = c.walkable ? 1 : c.drowning; + if (m_hp > 0 && m_breath < PLAYER_MAX_BREATH && drowning == 0) setBreath(m_breath + 1); } diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 48eff0bf8..f406f2c81 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -735,8 +735,15 @@ void LocalPlayer::applyControl(float dtime, ClientEnvironment *env) incH = incV = movement_acceleration_default * BS * dtime; float slip_factor = 1.0f; - if (!free_move && !in_liquid && !in_liquid_stable) + float speed_factor = 1.0f; + if (!free_move && !in_liquid && !in_liquid_stable) { slip_factor = getSlipFactor(env, speedH); + speed_factor = getSpeedFactor(env); + } + + // Apply speed factor + speedH *= speed_factor; + speedV *= speed_factor; // Accelerate to target speed with maximum increment accelerateHorizontal(speedH * physics_override_speed, @@ -1111,7 +1118,6 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d, float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH) { - // Slip on slippery nodes const INodeDefManager *nodemgr = env->getGameDef()->ndef(); Map *map = &env->getMap(); @@ -1129,3 +1135,19 @@ float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH) } return 1.0f; } + +float LocalPlayer::getSpeedFactor(Environment *env) +{ + const INodeDefManager *nodemgr = env->getGameDef()->ndef(); + Map *map = &env->getMap(); + const ContentFeatures &f = nodemgr->get(map->getNodeNoEx( + getStandingNodePos())); + int speed = 0; + if (f.walkable) + speed = itemgroup_get(f.groups, "speed"); + + if (speed != 0) { + return core::clamp(1.0f + (float)speed/100, 0.01f, 10.0f); + } + return 1.0f; +} diff --git a/src/localplayer.h b/src/localplayer.h index 101fdec18..79bbf429a 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -146,6 +146,7 @@ private: void accelerateVertical(const v3f &target_speed, const f32 max_increase); bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max); float getSlipFactor(Environment *env, const v3f &speedH); + float getSpeedFactor(Environment *env); v3f m_position; v3s16 m_standing_node;