Skip to content

Commit

Permalink
Add clan chest
Browse files Browse the repository at this point in the history
  • Loading branch information
alek13 committed Dec 30, 2023
1 parent 894ce7d commit e6bf1c4
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 14 deletions.
9 changes: 9 additions & 0 deletions mods/lord/Blocks/clan_node/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
local mod_path = minetest.get_modpath(minetest.get_current_modname())
local old_require = require
require = function(name) return dofile(mod_path .. "/src/" .. name:gsub("%.", "/") .. ".lua") end


require("chest").init()


require = old_require
2 changes: 2 additions & 0 deletions mods/lord/Blocks/clan_node/locale/clan_node.ru.tr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# textdomain: clan_node

2 changes: 2 additions & 0 deletions mods/lord/Blocks/clan_node/locale/template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# textdomain: quest_node

3 changes: 3 additions & 0 deletions mods/lord/Blocks/clan_node/mod.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = clan_node
description = Clans specific nodes (chests, ... etc)
depends = default, clans
20 changes: 20 additions & 0 deletions mods/lord/Blocks/clan_node/src/chest.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local node = require("chest.node")


local function register()
minetest.register_node("clan_node:chest", node.definition)
minetest.register_on_player_receive_fields(node.form_handler)
minetest.register_craft({
output = "clan_node:chest",
recipe = {
{"farming:string", "default:chest", "farming:string"}
},
})
end


return {
init = function()
register()
end
}
91 changes: 91 additions & 0 deletions mods/lord/Blocks/clan_node/src/chest/node.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
--- @type clan_node.chest.node.Form
local Form = require("chest.node.Form")


local S = minetest.get_translator('clan_node')

local definition = {
description = S("Clan Chest"),
tiles = {
"default_chest_top.png",
"default_chest_top.png",
"default_chest_side.png",
"default_chest_side.png",
"default_chest_side.png",
"default_chest_front.png"
},
sounds = default.node_sound_wood_defaults(),
sound_open = "default_chest_open",
sound_close = "default_chest_close",
groups = {
choppy = 2,
oddly_breakable_by_hand = 2,
not_in_creative_inventory = 1,
},
is_ground_content = false,
paramtype = "light",
paramtype2 = "facedir",

--- @param itemstack ItemStack
--- @param placer Player
--- @param pointed_thing pointed_thing
on_place = function(itemstack, placer, pointed_thing)
if not clans.get_by_player(placer) then
minetest.chat_send_player(
placer:get_player_name(), S("You can't place this item. This chest is only for clan players.")
)
return itemstack, nil
end
return minetest.item_place(itemstack, placer, pointed_thing)
end,
--- @param pos Position
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Clan Chest"))
meta:set_string("owned_clan", "")
local inventory = meta:get_inventory()
inventory:set_size("main", 8 * 4)
end,
--- @param pos Position
--- @param placer Player
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
local clan = clans.get_by_player(placer)
if not clan then
local node_name = minetest.get_node(pos).name
minetest.remove_node(pos)
minetest.add_item(pos, node_name)
end
meta:set_string("owned_clan", clan.name)
meta:set_string("infotext", S("@1 Clan Chest", clan.title))
end,
--- @param pos Position
--- @param player Player
can_dig = function(pos, player)
return
clans.get_by_player(player) and
minetest.get_meta(pos):get_inventory():is_empty("main")
end,
on_blast = function() end,
--- @param pos Position
--- @param clicker Player
on_rightclick = function(pos, node, clicker)
local chest_clan_name = minetest.get_meta(pos):get_string("owned_clan")
if not chest_clan_name or not clans.clan_is_online(chest_clan_name) then
return
end
local player_clan = clans.get_by_player(clicker)
local player_clan_name = player_clan and player_clan.name or nil
if player_clan_name ~= chest_clan_name then
local chest_clan = clans.get_by_name(chest_clan_name)
minetest.chat_send_all(minetest.colorize("red", S("Clan @1 is under the raid", chest_clan.title)))
end
Form:new(pos, clicker):open()
end,
}


return {
definition = definition,
form_handler = Form.handler
}
106 changes: 106 additions & 0 deletions mods/lord/Blocks/clan_node/src/chest/node/Form.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

---
--- @class clan_node.chest.node.Form
---
local Form = {
--- @const
--- @type string
NAME = "clan_node:chest",
--- @static
--- @type table<string,clan_node.chest.node.Form>
opened_for = {},

--- @private
--- @type Position
node_position = nil,
--- @type string
player_name = nil,
}

--- Constructor
--- @public
--- @param pos Position
--- @param player Player
--- @return clan_node.chest.node.Form
function Form:new(pos, player)
local class = self
self = {}

self.node_position = pos
self.player_name = player:get_player_name()

return setmetatable(self, {__index = class})
end

--- @public
--- @static
--- @param player Player
--- @return clan_node.chest.node.Form
function Form.get_opened_for(player)
return Form.opened_for[player:get_player_name()]
end

--- @public
function Form:open()
local player_name = self.player_name
self.opened_for[player_name] = self;

local node_pos = self.node_position
local sound = minetest.registered_nodes[minetest.get_node(node_pos).name].sound_open
if not sound then return end
minetest.sound_play(sound, { gain = 0.3, pos = node_pos, max_hear_distance = 10}, true)
minetest.show_formspec(player_name, self.NAME, self:get_spec())
end

--- @public
function Form:close()
self.opened_for[self.player_name] = nil

local node_pos = self.node_position
local sound = minetest.registered_nodes[minetest.get_node(node_pos).name].sound_close
if not sound then return end
minetest.sound_play(sound, { gain = 0.3, pos = node_pos, max_hear_distance = 10}, true)
end

--- @private
function Form:get_spec()
local pos = self.node_position

local str_pos = pos.x .. "," .. pos.y .. "," .. pos.z
local formspec = "size[8,9]" ..
"list[nodemeta:" .. str_pos .. ";main;0,0.3;8,4;]" ..
"list[current_player;main;0,4.85;8,1;]" ..
"list[current_player;main;0,6.08;8,3;8]" ..
"listring[nodemeta:" .. str_pos .. ";main]" ..
"listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85)

return formspec
end

--- @static
--- @param player Player
--- @param form_name string
--- @param fields table
function Form.handler(player, form_name, fields)
if form_name ~= Form.NAME then
return
end

local form = Form.get_opened_for(player)
if not form then return end

if fields.quit then
form:close()
end
end

minetest.register_on_leaveplayer(function(player, timed_out)
local form = Form.get_opened_for(player);
if form then
form:close()
end
end)


return Form
85 changes: 71 additions & 14 deletions mods/lord/Player/clans/init.lua
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
--- @class Clan
--- @class clans.Clan
--- @field public name string
--- @field public title string
--- @field public players table<number,string>


-- HACK: this is a quick hardcoded local storage for clans data
-- TODO: save this data somewhere else (mod-storage?)
-- TODO: commands for manage
--- @type table<string,Clan>
local clans = {
--- @type table<string,clans.Clan>
local clans_storage = {
masons = {
title = "Masons",
name = "masons",
title = "Masons",
players = { "Petus_mason", "Swed_mason", "Dormi_mason", "JikiSo_mason", "Alek_mason", "Zhekil_mason" },
},
havit = {
title = "Havit-Nakyar",
players = { "Doloment", "Sdoh", "Aiex" }
},
--havit = {
-- name = "havit",
-- title = "Havit-Nakyar",
-- players = { "Doloment", "Sdoh", "Aiex" }
--},
vassals = {
title = "Vassals",
players = { "Pilsner_vassal", "PePe_vassal", "JakeVovaDimas", "Semi_vassal" },
name = "vassals",
title = "Vassals",
players = { "Pilsner_vassal", "PePe_vassal", "JVD_vassal", "Semi_vassal" },
},
}
--- @type table<string,boolean> local cache for clan is online
local clan_is_online_cache = {}

--- @param player Player
--- @return Clan|table|nil returns clan data ( `{ title = "...", players {...}, ... }` )
local function get_clan(player)
--- @return clans.Clan|nil returns clan data ( `{ title = "...", players {...}, ... }` )
local function get_clan_by_player(player)
local player_name = player:get_player_name()

for _, clan in pairs(clans) do
for _, clan in pairs(clans_storage) do
if table.contains(clan.players, player_name) then
return clan
end
Expand All @@ -36,17 +42,68 @@ local function get_clan(player)
return nil
end

--- @param name string
local function get_clan_by_name(name)
return clans_storage[name]
end

--- @param name string
--- @return boolean|nil
local function check_clan_is_online(name)
local clan = get_clan_by_name(name)
if not clan then return nil end
for _, player in pairs(minetest.get_connected_players()) do
if table.contains(clan.players, player:get_player_name()) then
return true
end
end
return false
end

--- @param name string
--- @return boolean|nil
local function clan_is_online(name)
if not clans_storage[name] then return nil end
if clan_is_online_cache[name] == nil then
clan_is_online_cache[name] = check_clan_is_online(name)
end

return clan_is_online_cache[name]
end

minetest.register_on_joinplayer(function(player, last_login)
if not player or not player:is_player() then
return
end

local clan = get_clan(player)
local clan = get_clan_by_player(player)
if not clan then
return
end

clan_is_online_cache[clan.name] = true

player:set_nametag_attributes({
text = player:get_player_name() .. " " .. minetest.colorize("#3d7", "["..clan.title.."]"),
})
end)

minetest.register_on_leaveplayer(function(player, timed_out)
if not player or not player:is_player() then
return
end
local clan = get_clan_by_player(player)
if not clan then
return
end

clan_is_online_cache[clan.name] = check_clan_is_online(clan.name)
end)

--- API ---

clans = {
get_by_player = get_clan_by_player,
get_by_name = get_clan_by_name,
clan_is_online = clan_is_online,
}

0 comments on commit e6bf1c4

Please sign in to comment.