diff --git a/mods/hudbars/init.lua b/mods/hudbars/init.lua index 65d317e0..ebd2ba1e 100755 --- a/mods/hudbars/init.lua +++ b/mods/hudbars/init.lua @@ -328,6 +328,7 @@ local function update_hud(player) --health hb.change_hudbar(player, "health", player:get_hp()) end + hb.change_hudbar(player, "sprint", sprint.players[player:get_player_name()].stamina, sprint.players[player:get_player_name()].maxStamina) end minetest.register_on_joinplayer(function(player) diff --git a/mods/pclasses/adventurer.lua b/mods/pclasses/adventurer.lua new file mode 100644 index 00000000..e31eefb4 --- /dev/null +++ b/mods/pclasses/adventurer.lua @@ -0,0 +1,11 @@ +----------------------------- +-- Default class assignment +-- + +pclasses.api.register_class("adventurer", { + determination = function() return true end, + on_assigned = function(pname) + minetest.chat_send_player(pname, "You are now an adventurer") + end +}) + diff --git a/mods/pclasses/api.lua b/mods/pclasses/api.lua new file mode 100644 index 00000000..a7ace6c2 --- /dev/null +++ b/mods/pclasses/api.lua @@ -0,0 +1,161 @@ +------------------ +-- PClasses' API +-- + +-- Various utility functions + +-- Register the class (basic registration) +function pclasses.api.register_class(cname, def) + if not cname then + minetest.log("error", "[PClasses] Error registering unamed class") + return + elseif not def then + minetest.log("error", "[PClasses] Error registering class " .. + cname .. ". Reason : no definition table.") + return + elseif not def.determination then + minetest.log("error", "[PClasses] Error registreing class " .. + cname .. ". Reason : no determination function.") + return + end + + pclasses.classes[cname] = def + return true +end + +------------------------ +-- Getters and Setters +-- + +-- Get class specs by name +function pclasses.api.get_class_by_name(cname) + return pclasses.classes[cname] +end + + +-- Get single player +function pclasses.api.get_player_class(pname) + return pclasses.datas.players[pname] +end + +-- Get all players for a class +function pclasses.api.get_class_players(cname) + local pnames = {} + if pclasses.api.get_class_by_name(cname) then + for p,c in ipairs(pclasses.datas.players) do + if c == cname then + table.insert(pnames, table.getn(pnames)+1) + end + end + end +end + +-- Set single player +function pclasses.api.set_player_class(pname, cname) + if pclasses.api.get_class_by_name(cname) then + pclasses.datas.players[pname] = cname + return true + end + return false +end + +-- Util function(s) + +pclasses.api.util.does_wear_full_armor = function(pname, material, noshield) + local inv = minetest.get_inventory({type = "detached", name = pname .. "_armor"}) + if not inv or inv:is_empty("armor") then + return false + end + local full_armor = true + for _, piece in pairs({"chestplate", "leggings", "boots", "helmet"}) do + full_armor = full_armor and inv:contains_item("armor", "3d_armor:" .. piece .. "_" .. material) + end + return full_armor and (inv:contains_item("armor", "shields:shield_" .. material) or noshield) +end + +---------------------------- +-- Determination callback -- +---------------------------- + +function pclasses.api.assign_class(player) + -- Look for every sign needed to deduct a player's class + -- Starting from the most important class to the less one + + local pname = player:get_player_name() + if pclasses.classes["hunter"].determination(player) then + if pclasses.api.get_player_class(pname) ~= "hunter" then + if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then + pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) + end + pclasses.api.set_player_class(pname, "hunter") + pclasses.api.get_class_by_name("hunter").on_assigned(pname) + end + + elseif pclasses.api.get_class_by_name("warrior").determination(player) then + if pclasses.api.get_player_class(pname) ~= "warrior" then + if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then + pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) + end + pclasses.api.set_player_class(pname, "warrior") + pclasses.api.get_class_by_name("warrior").on_assigned(pname) + end + elseif pclasses.conf.default_class then + if pclasses.api.get_player_class(pname) ~= pclasses.conf.default_class then + if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then + pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) + end + pclasses.api.set_player_class(pname, pclasses.conf.default_class) + pclasses.api.get_class_by_name(pclasses.conf.default_class).on_assigned(pname) + end + end +end + +minetest.register_on_respawnplayer(pclasses.api.assign_class) +minetest.register_on_joinplayer(function(player) minetest.after(1, pclasses.api.assign_class, player) end) +minetest.register_on_leaveplayer(pclasses.api.assign_class) + +------------------- +-- Reserved items +-- +function pclasses.api.reserve_item(cname, itemstring) + pclasses.datas.reserved_items[itemstring] = pclasses.datas.reserved_items or {} + table.insert(pclasses.datas.reserved_items[itemstring], 1, cname) +end + +pclasses.api.reserve_item("warrior", "moreores:sword_mithril") +pclasses.api.reserve_item("warrior", "default:dungeon_master_s_blood_sword") + +pclasses.api.reserve_item("hunter", "throwing:bow_minotaur_horn") +pclasses.api.reserve_item("hunter", "throwing:bow_minotaur_born_improved") + + +minetest.register_globalstep(function(dtime) + for id, ref in ipairs(minetest.get_connected_players()) do + local name = ref:get_player_name() + local inv = minetest.get_inventory({type="player", name = name}) + for i = 1, inv:get_size("main") do + local stack = inv:get_stack("main", i) + if pclasses.datas.reserved_items[stack:get_name()] then + local drop_stack = true + for class in pairs(pclasses.datas.reserved_items) do + if pclasses.api.get_player_class(name) == class then + drop_stack = false + end + end + if drop_stack then + inv:set_stack("main", i, "") + local pos = ref:getpos() + pos.y = pos.y+2 + pos.x = pos.x + math.random(-10,10) + pos.z = pos.z + math.random(-10,10) + minetest.after(1, function() + local item = minetest.add_item(pos, stack) + if item then + item:setvelocity({x = math.random(-10,10), y = math.random(1,7), z = math.random(-10,10)}) + end + end) + end + end + end + end +end) diff --git a/mods/pclasses/hunter.lua b/mods/pclasses/hunter.lua new file mode 100644 index 00000000..425e9015 --- /dev/null +++ b/mods/pclasses/hunter.lua @@ -0,0 +1,28 @@ +------------------ +-- Hunter class -- +------------------ + +-- +-- See https://github.com/Ombridride/minetest-minetestforfun-server/issues/114 +-- + +pclasses.api.register_class("hunter", { + determination = function(player) + return pclasses.api.util.does_wear_full_armor(player:get_player_name(), "reinforcedleather", true) + or pclasses.api.util.does_wear_full_armor(player:get_player_name(), "hardenedleather", true) + end, + on_assigned = function(pname) + minetest.chat_send_player(pname, "You are now a hunter") + minetest.sound_play("pclasses_full_hunter") + local reinforced = pclasses.api.util.does_wear_full_armor(pname, "reinforcedleather", true) + if reinforced then + sprint.increase_maxstamina(pname, 20) + else + sprint.increase_maxstamina(pname, 10) + end + minetest.log("action", "[PClasses] Player " .. pname .. " become a hunter") + end, + on_unassigned = function(pname) + sprint.set_default_maxstamina(pname) + end, +}) diff --git a/mods/pclasses/init.lua b/mods/pclasses/init.lua index f05a1401..40c09ffe 100755 --- a/mods/pclasses/init.lua +++ b/mods/pclasses/init.lua @@ -27,63 +27,9 @@ pclasses.datas.players = {} pclasses.datas.reserved_items = {} pclasses.datas.hud_ids = {} -- HUD maybe? - --- Various utility functions - --- Register the class (basic registration) -function pclasses.api.register_class(cname, def) - if not cname then - minetest.log("error", "[PClasses] Error registering unamed class") - return - elseif not def then - minetest.log("error", "[PClasses] Error registering class " .. - cname .. ". Reason : no definition table.") - return - elseif not def.determination then - minetest.log("error", "[PClasses] Error registreing class " .. - cname .. ". Reason : no determination function.") - return - end - - pclasses.classes[cname] = def - return true -end - ------------------------- --- Getters and Setters --- - --- Get class specs by name -function pclasses.api.get_class_by_name(cname) - return pclasses.classes[cname] -end +dofile(minetest.get_modpath("pclasses") .. "/api.lua") --- Get single player -function pclasses.api.get_player_class(pname) - return pclasses.datas.players[pname] -end - --- Get all players for a class -function pclasses.api.get_class_players(cname) - local pnames = {} - if pclasses.api.get_class_by_name(cname) then - for p,c in ipairs(pclasses.datas.players) do - if c == cname then - table.insert(pnames, table.getn(pnames)+1) - end - end - end -end - --- Set single player -function pclasses.api.set_player_class(pname, cname) - if pclasses.api.get_class_by_name(cname) then - pclasses.datas.players[pname] = cname - return true - end - return false -end --------------------------- -- Backup and load system @@ -117,17 +63,15 @@ minetest.register_globalstep(function(dtime) end) minetest.register_on_shutdown(save_datas) ------------------------------ --- Default class assignment + + +------------------ +-- Default class -- + if pclasses.conf.default_class then - local res = pclasses.api.register_class(pclasses.conf.default_class, { - determination = function() return true end, - on_assigned = function(pname) - minetest.chat_send_player(pname, "You are now an adventurer") - end - }) - if res then + dofile(minetest.get_modpath("pclasses") .. "/" .. pclasses.conf.default_class .. ".lua") + if pclasses.api.get_class_by_name(pclasses.conf.default_class) then minetest.register_on_joinplayer(function(player) if not pclasses.api.get_player_class(player:get_player_name()) then pclasses.api.set_player_class(player:get_player_name(), @@ -137,146 +81,12 @@ if pclasses.conf.default_class then end end -pclasses.api.util.does_wear_full_armor = function(pname, material, noshield) - local inv = minetest.get_inventory({type = "detached", name = pname .. "_armor"}) - if not inv or inv:is_empty("armor") then - return false - end - local full_armor = true - for _, piece in pairs({"chestplate", "leggings", "boots", "helmet"}) do - full_armor = full_armor and inv:contains_item("armor", "3d_armor:" .. piece .. "_" .. material) - end - return full_armor and (inv:contains_item("armor", "shields:shield_" .. material) or noshield) -end + ------------ -- Classes -- -pclasses.api.register_class("warrior", { - determination = function(player) - return pclasses.api.util.does_wear_full_armor(player:get_player_name(), "harnededleather", true) - or pclasses.api.util.does_wear_full_armor(player:get_player_name(), "reinforcedleather", true) - end, - on_assigned = function(pname) - minetest.sound_play("pclasses_full_warrior") - minetest.chat_send_player(pname, "You are now a warrior") - sprint.set_max_stamina(pname, 20) - end, - on_unassigned = function(pname) - sprint.set_default_maxstamina(pname) - end, -}) +dofile(minetest.get_modpath("pclasses") .. "/warrior.lua") +dofile(minetest.get_modpath("pclasses") .. "/hunter.lua") - -pclasses.api.register_class("hunter", { - determination = function(player) - local inv = minetest.get_inventory({type = "detached", name = player:get_player_name() .. "_armor"}) - local shift_class = false - if not inv or inv:is_empty("armor") then - return shift_class - end - shift_class = true - for _,piece in pairs({"chestplate", "leggings", "boots", "helmet"}) do - shift_class = shift_class and (inv:contains_item("armor", "3d_armor:" .. piece .. "_reinforcedleather") - or inv:contains_item("armor", "3d_armor:" .. piece .. "_hardenedleather")) - end - return shift_class - end, - on_assigned = function(pname) - minetest.chat_send_player(pname, "You are now a hunter") - minetest.sound_play("pclasses_full_hunter") - local reinforced = pclasses.api.util.does_wear_full_armor(pname, "reinforcedleather", true) - if reinforced then - sprint.increase_maxstamina(pname, 20) - else - sprint.increase_maxstamina(pname, 10) - end - end, - on_unassigned = function(pname) - sprint.set_default_maxstamina(pname) - end, -}) - -function pclasses.api.assign_class(player) - -- Look for every sign needed to deduct a player's class - -- Starting from the most important class to the less one - - local pname = player:get_player_name() - if pclasses.api.get_class_by_name("hunter").determination(player) then - if pclasses.api.get_player_class(pname) ~= "hunter" then - if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then - pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) - end - pclasses.api.set_player_class(pname, "hunter") - pclasses.api.get_class_by_name("hunter").on_assigned(pname) - end - - elseif pclasses.api.get_class_by_name("warrior").determination(player) then - if pclasses.api.get_player_class(pname) ~= "warrior" then - if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then - pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) - end - pclasses.api.set_player_class(pname, "warrior") - pclasses.api.get_class_by_name("warrior").on_assigned(pname) - end - elseif pclasses.conf.default_class then - if pclasses.api.get_player_class(pname) ~= pclasses.conf.default_class then - if pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned then - pclasses.api.get_class_by_name(pclasses.api.get_player_class(pname)).on_unassigned(pname) - end - pclasses.api.set_player_class(pname, pclasses.conf.default_class) - pclasses.api.get_class_by_name(pclasses.conf.default_class).on_assigned(pname) - end - end -end - -minetest.register_on_respawnplayer(pclasses.api.assign_class) -minetest.register_on_joinplayer(function(player) minetest.after(1, pclasses.api.assign_class, player) end) -minetest.register_on_leaveplayer(pclasses.api.assign_class) - -------------------- --- Reserved items --- -function pclasses.api.reserve_item(cname, itemstring) - pclasses.datas.reserved_items[itemstring] = pclasses.datas.reserved_items or {} - table.insert(pclasses.datas.reserved_items[itemstring], 1, cname) -end - -pclasses.api.reserve_item("warrior", "moreores:sword_mithril") -pclasses.api.reserve_item("warrior", "default:dungeon_master_s_blood_sword") - -pclasses.api.reserve_item("hunter", "throwing:bow_minotaur_horn") -pclasses.api.reserve_item("hunter", "throwing:bow_minotaur_born_improved") - - -minetest.register_globalstep(function(dtime) - for id, ref in ipairs(minetest.get_connected_players()) do - local name = ref:get_player_name() - local inv = minetest.get_inventory({type="player", name = name}) - for i = 1, inv:get_size("main") do - local stack = inv:get_stack("main", i) - if pclasses.datas.reserved_items[stack:get_name()] then - local drop_stack = true - for class in pairs(pclasses.datas.reserved_items) do - if pclasses.api.get_player_class(name) == class then - drop_stack = false - end - end - if drop_stack then - inv:set_stack("main", i, "") - local pos = ref:getpos() - pos.y = pos.y+2 - pos.x = pos.x + math.random(-10,10) - pos.z = pos.z + math.random(-10,10) - minetest.after(1, function() - local item = minetest.add_item(pos, stack) - if item then - item:setvelocity({x = math.random(-10,10), y = math.random(1,7), z = math.random(-10,10)}) - end - end) - end - end - end - end -end) diff --git a/mods/pclasses/warrior.lua b/mods/pclasses/warrior.lua new file mode 100644 index 00000000..227d322e --- /dev/null +++ b/mods/pclasses/warrior.lua @@ -0,0 +1,22 @@ +------------------- +-- Warrior class -- +------------------- + +-- +-- See https://github.com/Ombridride/minetest-minetestforfun-server/issues/113 +-- + +pclasses.api.register_class("warrior", { + determination = function(player) + return pclasses.api.util.does_wear_full_armor(player:get_player_name(), "blackmithril", true) + end, + on_assigned = function(pname) + minetest.sound_play("pclasses_full_warrior") + minetest.chat_send_player(pname, "You are now a warrior") + sprint.set_maxstamina(pname, 20) + minetest.log("action", "[PClasses] Player " .. pname .. " become a warrior") + end, + on_unassigned = function(pname) + sprint.set_default_maxstamina(pname) + end, +}) diff --git a/mods/sprint/esprint.lua b/mods/sprint/esprint.lua index ef5a7e6e..30289949 100755 --- a/mods/sprint/esprint.lua +++ b/mods/sprint/esprint.lua @@ -7,19 +7,19 @@ to this software to the public domain worldwide. This software is distributed without any warranty. ]] -local players = {} +sprint.players = {} local staminaHud = {} -- Lil' helping functions sprint.set_maxstamina = function(pname, mstamina) - if players[pname] and mstamina > 0 then - players[pname].maxStamina = mstamina + if sprint.players[pname] and mstamina > 0 then + sprint.players[pname].maxStamina = mstamina end end sprint.get_maxstamina = function(pname) - if players[pname] then - return players[pname].maxStamina + if sprint.players[pname] then + return sprint.players[pname].maxStamina end end @@ -37,11 +37,18 @@ sprint.dicrease_maxstamina = function(pname, sdicrease) end end +sprint.set_default_maxstamina = function(pname) + if sprint.players[pname] then + sprint.players[pname].maxStamina = SPRINT_STAMINA + end +end + + minetest.register_on_joinplayer(function(player) local playerName = player:get_player_name() - players[playerName] = { + sprint.players[playerName] = { sprinting = false, timeOut = 0, stamina = SPRINT_STAMINA, @@ -51,7 +58,7 @@ minetest.register_on_joinplayer(function(player) if SPRINT_HUDBARS_USED then hb.init_hudbar(player, "sprint") else - players[playerName].hud = player:hud_add({ + sprint.players[playerName].hud = player:hud_add({ hud_elem_type = "statbar", position = {x=0.5,y=1}, size = {x=24, y=24}, @@ -65,22 +72,22 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_leaveplayer(function(player) local playerName = player:get_player_name() - players[playerName] = nil + sprint.players[playerName] = nil end) local gameTime = 0 minetest.register_globalstep(function(dtime) --Get the gametime gameTime = gameTime + dtime - --Loop through all connected players - for playerName,playerInfo in pairs(players) do + --Loop through all connected sprint.players + for playerName,playerInfo in pairs(sprint.players) do local player = minetest.get_player_by_name(playerName) if player ~= nil then --Check if the player should be sprinting if player:get_player_control()["aux1"] and player:get_player_control()["up"] then - players[playerName]["shouldSprint"] = true + sprint.players[playerName]["shouldSprint"] = true else - players[playerName]["shouldSprint"] = false + sprint.players[playerName]["shouldSprint"] = false end --Stop sprinting if the player is pressing the LMB or RMB if player:get_player_control()["LMB"] or player:get_player_control()["RMB"] then @@ -119,9 +126,9 @@ minetest.register_globalstep(function(dtime) end end --Adjust player states - if players[playerName]["shouldSprint"] == true and playerInfo["timeOut"] == 0 then --Stopped + if sprint.players[playerName]["shouldSprint"] == true and playerInfo["timeOut"] == 0 then --Stopped setSprinting(playerName, true) - elseif players[playerName]["shouldSprint"] == false then + elseif sprint.players[playerName]["shouldSprint"] == false then setSprinting(playerName, false) end @@ -152,7 +159,7 @@ minetest.register_globalstep(function(dtime) playerInfo["stamina"] = playerInfo["maxStamina"] end - --Update the players's hud sprint stamina bar + --Update the sprint.players's hud sprint stamina bar if SPRINT_HUDBARS_USED then hb.change_hudbar(player, "sprint", playerInfo["stamina"]) @@ -169,8 +176,8 @@ end) function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) local player = minetest.get_player_by_name(playerName) - if players[playerName] then - players[playerName]["sprinting"] = sprinting + if sprint.players[playerName] then + sprint.players[playerName]["sprinting"] = sprinting if sprinting == true then player:set_physics_override({speed=SPRINT_SPEED,jump=SPRINT_JUMP}) elseif sprinting == false then