diff --git a/mods/PLAYER/mcl_playerinfo/README.md b/mods/PLAYER/mcl_playerinfo/README.md new file mode 100644 index 0000000000..fe5ac0a42d --- /dev/null +++ b/mods/PLAYER/mcl_playerinfo/README.md @@ -0,0 +1,15 @@ +# PlayerInfo mod for MineClone 2 + +This is a helper mod for other mod to query the nodes around the player. + +Every half 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: + +- `mcl_playerinfo[name].node_stand` +- `mcl_playerinfo[name].node_stand_below` +- `mcl_playerinfo[name].node_foot` +- `mcl_playerinfo[name].node_head` + +## License +MIT License + diff --git a/mods/PLAYER/mcl_playerinfo/depends.txt b/mods/PLAYER/mcl_playerinfo/depends.txt new file mode 100644 index 0000000000..e5b017ff7b --- /dev/null +++ b/mods/PLAYER/mcl_playerinfo/depends.txt @@ -0,0 +1,7 @@ +mcl_init +mcl_util +mcl_core +mcl_particles +mcl_hunger +mcl_death_messages +3d_armor? diff --git a/mods/PLAYER/mcl_playerinfo/init.lua b/mods/PLAYER/mcl_playerinfo/init.lua new file mode 100644 index 0000000000..8fa615da11 --- /dev/null +++ b/mods/PLAYER/mcl_playerinfo/init.lua @@ -0,0 +1,91 @@ +-- Player state for public API +mcl_playerinfo = {} + +-- Get node but use fallback for nil or unknown +local function node_ok(pos, fallback) + + fallback = fallback or "air" + + local node = minetest.get_node_or_nil(pos) + + if not node then + return fallback + end + + if minetest.registered_nodes[node.name] then + return node.name + end + + return fallback +end + +local time = 0 + +local get_player_nodes = function(player_pos) + local work_pos = table.copy(player_pos) + + -- what is around me? + work_pos.y = work_pos.y - 0.1 -- standing on + local node_stand = node_ok(work_pos) + local node_stand_below = node_ok({x=work_pos.x, y=work_pos.y-1, z=work_pos.z}) + + work_pos.y = work_pos.y + 1.5 -- head level + local node_head = node_ok(work_pos) + + work_pos.y = work_pos.y - 1.2 -- feet level + local node_feet = node_ok(work_pos) + + return node_stand, node_stand_below, node_head, node_feet +end + +minetest.register_globalstep(function(dtime) + + time = time + dtime + + -- Run the rest of the code every 0.5 seconds + if time < 0.5 then + return + end + + -- reset time for next check + -- FIXME: Make sure a regular check interval applies + time = 0 + + -- check players + for _,player in pairs(minetest.get_connected_players()) do + -- who am I? + local name = player:get_player_name() + + -- where am I? + local pos = player:getpos() + + -- what is around me? + local node_stand, node_stand_below, node_head, node_feet = get_player_nodes(pos) + mcl_playerinfo[name].node_stand = node_stand + mcl_playerinfo[name].node_stand_below = node_stand_below + mcl_playerinfo[name].node_head = node_head + mcl_playerinfo[name].node_feet = node_feet + + end + +end) + +-- set to blank on join (for 3rd party mods) +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + + mcl_playerinfo[name] = { + node_head = "", + node_feet = "", + node_stand = "", + node_stand_below = "", + } + +end) + +-- clear when player leaves +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + + mcl_playerinfo[name] = nil +end) diff --git a/mods/PLAYER/mcl_playerinfo/license.txt b/mods/PLAYER/mcl_playerinfo/license.txt new file mode 100644 index 0000000000..fec6f6aa51 --- /dev/null +++ b/mods/PLAYER/mcl_playerinfo/license.txt @@ -0,0 +1,21 @@ +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/mods/PLAYER/mcl_playerinfo/mod.conf b/mods/PLAYER/mcl_playerinfo/mod.conf new file mode 100644 index 0000000000..ee2b80e7e1 --- /dev/null +++ b/mods/PLAYER/mcl_playerinfo/mod.conf @@ -0,0 +1 @@ +name = mcl_playerinfo diff --git a/mods/PLAYER/mcl_playerplus/README.md b/mods/PLAYER/mcl_playerplus/README.md index 853bd44210..e51d086fb6 100644 --- a/mods/PLAYER/mcl_playerplus/README.md +++ b/mods/PLAYER/mcl_playerplus/README.md @@ -12,20 +12,13 @@ Suffocation *not* dealt to player with the `noclip` privilege. ## Notes This mod is based on PlayerPlus [`playerplus`] by TenPlus1. It is now very different than the original, no compability is intended. +See also `mcl_playerinfo` for the player node info. ## API -Every half 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: - -- `mcl_playerplus[name].node_stand` -- `mcl_playerplus[name].node_stand_below` -- `mcl_playerplus[name].node_foot` -- `mcl_playerplus[name].node_head` - Setting the group `disable_suffocation=1` disables suffocation for nodes which would otherwise deal suffocation damage. ## License -WTFPL. +MIT License diff --git a/mods/PLAYER/mcl_playerplus/depends.txt b/mods/PLAYER/mcl_playerplus/depends.txt index e5b017ff7b..45b93f966b 100644 --- a/mods/PLAYER/mcl_playerplus/depends.txt +++ b/mods/PLAYER/mcl_playerplus/depends.txt @@ -4,4 +4,5 @@ mcl_core mcl_particles mcl_hunger mcl_death_messages +mcl_playerinfo 3d_armor? diff --git a/mods/PLAYER/mcl_playerplus/description.txt b/mods/PLAYER/mcl_playerplus/description.txt index c1c9097f3f..4664d5f8c4 100644 --- a/mods/PLAYER/mcl_playerplus/description.txt +++ b/mods/PLAYER/mcl_playerplus/description.txt @@ -1 +1 @@ -Hurts players touching a cactus and when with the head inside solid blocks. +Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 4f03d2b0f6..97a3ec9e57 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,48 +1,10 @@ --- Player state for public API -mcl_playerplus = {} - -- Internal player state local mcl_playerplus_internal = {} --- get node but use fallback for nil or unknown -local function node_ok(pos, fallback) - - fallback = fallback or "air" - - local node = minetest.get_node_or_nil(pos) - - if not node then - return fallback - end - - if minetest.registered_nodes[node.name] then - return node.name - end - - return fallback -end - local armor_mod = minetest.get_modpath("3d_armor") local def = {} local time = 0 -local get_player_nodes = function(player_pos) - local work_pos = table.copy(player_pos) - - -- what is around me? - work_pos.y = work_pos.y - 0.1 -- standing on - local node_stand = node_ok(work_pos) - local node_stand_below = node_ok({x=work_pos.x, y=work_pos.y-1, z=work_pos.z}) - - work_pos.y = work_pos.y + 1.5 -- head level - local node_head = node_ok(work_pos) - - work_pos.y = work_pos.y - 1.2 -- feet level - local node_feet = node_ok(work_pos) - - return node_stand, node_stand_below, node_head, node_feet -end - minetest.register_globalstep(function(dtime) time = time + dtime @@ -58,7 +20,13 @@ minetest.register_globalstep(function(dtime) local pos = player:getpos() - local node_stand, node_stand_below, node_head, node_feet = get_player_nodes(pos) + local node_stand = mcl_playerinfo[name].node_stand + local node_stand_below = mcl_playerinfo[name].node_stand_below + local node_head = mcl_playerinfo[name].node_head + local node_feet = mcl_playerinfo[name].node_feet + if not node_stand or not node_stand_below or not node_head or not node_feet then + return + end -- Cause buggy exhaustion for jumping @@ -107,11 +75,13 @@ minetest.register_globalstep(function(dtime) local pos = player:getpos() -- what is around me? - local node_stand, node_stand_below, node_head, node_feet = get_player_nodes(pos) - mcl_playerplus[name].node_stand = node_stand - mcl_playerplus[name].node_stand_below = node_stand_below - mcl_playerplus[name].node_head = node_head - mcl_playerplus[name].node_feet = node_feet + local node_stand = mcl_playerinfo[name].node_stand + local node_stand_below = mcl_playerinfo[name].node_stand_below + local node_head = mcl_playerinfo[name].node_head + local node_feet = mcl_playerinfo[name].node_feet + if not node_stand or not node_stand_below or not node_head or not node_feet then + return + end -- set defaults def.speed = 1 @@ -127,12 +97,11 @@ minetest.register_globalstep(function(dtime) end -- standing on soul sand? if so walk slower - if mcl_playerplus[name].node_stand == "mcl_nether:soul_sand" then + if node_stand == "mcl_nether:soul_sand" then -- TODO: Tweak walk speed -- TODO: Also slow down mobs -- FIXME: This whole speed thing is a giant hack. We need a proper framefork for cleanly handling player speeds - local below = mcl_playerplus[name].node_stand_below - if below == "mcl_core:ice" or below == "mcl_core:packed_ice" or below == "mcl_core:slimeblock" then + if node_stand_below == "mcl_core:ice" or node_stand_below == "mcl_core:packed_ice" or node_stand_below == "mcl_core:slimeblock" then def.speed = def.speed - 0.9 else def.speed = def.speed - 0.6 @@ -146,7 +115,7 @@ minetest.register_globalstep(function(dtime) -- Is player suffocating inside node? (Only for solid full opaque cube type nodes -- without group disable_suffocation=1) - local ndef = minetest.registered_nodes[mcl_playerplus[name].node_head] + local ndef = minetest.registered_nodes[node_head] if (ndef.walkable == nil or ndef.walkable == true) and (ndef.collision_box == nil or ndef.collision_box.type == "regular") @@ -198,8 +167,8 @@ minetest.register_globalstep(function(dtime) --[[ Swimming: Cause exhaustion. NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid! Head alone does not count. We respect that for now. ]] - if minetest.get_item_group(mcl_playerplus[name].node_feet, "liquid") ~= 0 or - minetest.get_item_group(mcl_playerplus[name].node_stand, "liquid") ~= 0 then + if minetest.get_item_group(node_feet, "liquid") ~= 0 or + minetest.get_item_group(node_stand, "liquid") ~= 0 then local lastPos = mcl_playerplus_internal[name].lastPos if lastPos then local dist = vector.distance(lastPos, pos) @@ -214,7 +183,7 @@ minetest.register_globalstep(function(dtime) end -- Underwater: Spawn bubble particles - if minetest.get_item_group(mcl_playerplus[name].node_head, "water") ~= 0 then + if minetest.get_item_group(node_head, "water") ~= 0 then minetest.add_particlespawner({ amount = 10, @@ -275,13 +244,6 @@ end) minetest.register_on_joinplayer(function(player) local name = player:get_player_name() - mcl_playerplus[name] = { - node_head = "", - node_feet = "", - node_stand = "", - node_stand_below = "", - } - mcl_playerplus_internal[name] = { lastPos = nil, swimDistance = 0, @@ -293,6 +255,5 @@ end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() - mcl_playerplus[name] = nil mcl_playerplus_internal[name] = nil end) diff --git a/mods/PLAYER/mcl_sprint/depends.txt b/mods/PLAYER/mcl_sprint/depends.txt index 2f74428476..2fd97244ab 100644 --- a/mods/PLAYER/mcl_sprint/depends.txt +++ b/mods/PLAYER/mcl_sprint/depends.txt @@ -1,2 +1,2 @@ -mcl_playerplus +mcl_playerinfo mcl_hunger diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 931f853109..c4fe3a0ac3 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -14,6 +14,16 @@ mcl_sprint.SPEED = 1.3 local players = {} +-- Returns true if the player with the given name is sprinting, false if not. +-- Returns nil if player does not exist. +mcl_sprint.is_sprinting = function(playername) + if players[playername] then + return players[playername].sprinting + else + return nil + end +end + minetest.register_on_joinplayer(function(player) local playerName = player:get_player_name() @@ -82,7 +92,7 @@ minetest.register_globalstep(function(dtime) if players[playerName]["shouldSprint"] == true then --Stopped local sprinting -- Prevent sprinting if standing on soul sand or hungry - if mcl_playerplus[playerName].node_stand == "mcl_nether:soul_sand" or (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) then + if mcl_playerinfo[playerName].node_stand == "mcl_nether:soul_sand" or (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) then sprinting = false else sprinting = true @@ -101,7 +111,7 @@ function setSprinting(playerName, sprinting) --Sets the state of a player (0=sto if players[playerName] then players[playerName]["sprinting"] = sprinting -- Don't overwrite physics when standing on soul sand or sleeping - if mcl_playerplus[playerName].node_stand ~= "mcl_nether:soul_sand" and player:get_attribute("mcl_beds:sleeping") ~= "true" then + if mcl_playerinfo[playerName].node_stand ~= "mcl_nether:soul_sand" and player:get_attribute("mcl_beds:sleeping") ~= "true" then if sprinting == true then player:set_physics_override({speed=mcl_sprint.SPEED}) elseif sprinting == false then