Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On move support aka jumpdrive compat #9

Merged
merged 41 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c8012c7
whitespace and minetest. -> core.
SwissalpS Nov 27, 2024
51ec2a8
Update Readme: Minetest -> Luanti
SwissalpS Nov 27, 2024
3b3ea24
add luacheck
SwissalpS Nov 27, 2024
8d6b2f2
update optional depends
SwissalpS Nov 27, 2024
ae679a1
luacheck cleanups
SwissalpS Nov 27, 2024
7ff3dd0
clean close of file after reading
SwissalpS Nov 27, 2024
c8af7c7
avoid duplicate code
SwissalpS Nov 27, 2024
aa514d1
avoid error: "unknown global"
SwissalpS Nov 27, 2024
deb750a
stray whitespace fixups
SwissalpS Nov 27, 2024
c8a4801
whitespace: switch all files to same indent character
SwissalpS Nov 27, 2024
9c688d4
refactor weird declaration
SwissalpS Nov 28, 2024
2175d77
whitespace: two stray spaces
SwissalpS Nov 28, 2024
5cf1946
fix shaddowing global table
SwissalpS Nov 28, 2024
b1d63fd
reduce amount of times transformation string is calculated
SwissalpS Nov 28, 2024
b1ff0eb
use ipairs feature
SwissalpS Nov 28, 2024
78be161
cap max amount of layers
SwissalpS Nov 28, 2024
3d22f9b
fix #5 make transform history non-global
SwissalpS Nov 28, 2024
7e3a84e
minimize metadata size
SwissalpS Nov 28, 2024
dc9867f
add versioning
SwissalpS Nov 28, 2024
b99d10c
add recoverable per player history with saved colour
SwissalpS Nov 28, 2024
f2147ce
rename update_all -> update_preview_inv
SwissalpS Nov 28, 2024
38bf923
dynamically update masks
SwissalpS Nov 28, 2024
9b5962a
banner always exists
SwissalpS Nov 29, 2024
d86c93b
use same function declaration style throughout
SwissalpS Nov 29, 2024
3d5805c
remove set_banner_texture()
SwissalpS Nov 29, 2024
2fea87d
preserve player undo-history over joins
SwissalpS Nov 29, 2024
1c5b116
refactor: reusable transformation string creation
SwissalpS Nov 29, 2024
e3c216e
add transform_string_to_table
SwissalpS Nov 29, 2024
88d628d
cleanup old banners when their entities are generated
SwissalpS Nov 29, 2024
578bd70
read item meta allowing players to edit existing banners
SwissalpS Nov 29, 2024
4178bd1
version bump
SwissalpS Nov 29, 2024
143e549
oopsie fixes
SwissalpS Nov 29, 2024
767a49a
remove stray debug point
SwissalpS Nov 29, 2024
e9cbd37
Merge branch 'master' into readExistingBanner
SwissalpS Nov 29, 2024
fe72fc2
add chatcommand banners_fix
SwissalpS Nov 29, 2024
85ac3b0
Merge branch 'readExistingBanner' of github.com:pandorabox-io/banners…
SwissalpS Nov 29, 2024
088f94b
sensitive github luacheck syntax
SwissalpS Nov 29, 2024
80aff0d
version bump
SwissalpS Nov 29, 2024
cb6bfaf
cleanup: compact node definitions
SwissalpS Nov 30, 2024
f448d73
adds [jumpdrive] compat
SwissalpS Nov 30, 2024
d0989cb
also make factions banners jump-able
SwissalpS Nov 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ read_globals = {
"dump",
"factions",
"inventory_plus",
["table"] = { fields = { "insert_all" } },
"unified_inventory",
"vector",
}
53 changes: 53 additions & 0 deletions chatcommands.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
-- Due to some engine troubles there are sometimes stray
-- banner entities and more rarely there are banner nodes without entities.
-- Calling this command fixes both situations.
core.register_chatcommand("banners_fix", {
description = "recreates the banner-visuals in your area",
func = function(name)
local player = core.get_player_by_name(name)
if not player then
return
end

local pos = player:get_pos()
local t1 = core.get_us_time()

local radius = 10
local entity_count = 0
local objects = core.get_objects_inside_radius(pos, radius)
for _, v in ipairs(objects) do
local e = v:get_luaentity()
if e and e.name == "banners:banner_ent" then
entity_count = entity_count + 1
v:remove()
end
end

local pos1 = vector.subtract(pos, radius)
local pos2 = vector.add(pos, radius)
local nodes = {
"banners:wooden_banner",
"banners:steel_banner",
}
if core.get_modpath("factions") then
table.insert_all(nodes, {
"banners:power_banner",
"banners:death_banner",

})
end
local pos_list = core.find_nodes_in_area(pos1, pos2, nodes)

for _, node_pos in ipairs(pos_list) do
core.add_entity(node_pos, "banners:banner_ent")
end

local t2 = core.get_us_time()
local diff = t2 - t1
local millis = diff / 1000

return true, "Removed " .. entity_count .. " banner entities and restored "
.. #pos_list .. " banners in " .. millis .. " ms"
end
})

18 changes: 6 additions & 12 deletions factions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,8 @@ core.register_node("banners:power_banner", {
stack_max = 1,
paramtype = "light",
paramtype2 = "facedir",
after_place_node = function (pos, player, itemstack, pointed_thing)
banners.after_powerbanner_placed(pos, player, itemstack, pointed_thing)
end,
on_destruct = function(pos)
banners.banner_on_destruct(pos)
end,
after_place_node = banners.after_powerbanner_placed,
on_destruct = banners.banner_on_destruct,
on_dig = function(pos, n, p)
if core.is_protected(pos, p:get_player_name()) then
return
Expand All @@ -163,6 +159,7 @@ core.register_node("banners:power_banner", {
end
banners.banner_on_dig(pos, n, p)
end,
on_movenode = banners.banner_on_movenode,
})

core.register_node("banners:death_banner", {
Expand All @@ -176,12 +173,8 @@ core.register_node("banners:death_banner", {
stack_max = 1,
paramtype = "light",
paramtype2 = "facedir",
after_place_node = function (pos, player, itemstack, pointed_thing)
banners.after_deathbanner_placed(pos, player, itemstack, pointed_thing)
end,
on_destruct = function(pos)
banners.banner_on_destruct(pos)
end,
after_place_node = banners.after_deathbanner_placed,
on_destruct = banners.banner_on_destruct,
-- (pos, node, player)
on_dig = function(pos, _, player)
if core.is_protected(pos, player:get_player_name()) then
Expand All @@ -198,6 +191,7 @@ core.register_node("banners:death_banner", {
end
core.remove_node(pos)
end,
on_movenode = banners.banner_on_movenode,
})

-- (pos, player, itemstack, pointed_thing)
Expand Down
164 changes: 118 additions & 46 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local MP = core.get_modpath("banners") .. "/"
dofile(MP .. "smartfs.lua")

banners = {
version = 20241128.1533
version = 20241130.1920
}

banners.masks = {
Expand Down Expand Up @@ -47,24 +47,43 @@ banners.colors = {
"brown", "darkbrown"
}

local valid_masks = {}
local valid_colors = {}
do
local i, s
i = #banners.masks
repeat
s = banners.masks[i]
valid_masks[s .. ".png"] = true
i = i - 1
until i == 0

i = #banners.colors
repeat
s = banners.colors[i]
valid_colors["bg_" .. s .. ".png"] = true
i = i - 1
until i == 0
end

banners.base_transform = {
texture = "bg_white.png",
mask = "mask_background.png"
}

banners.creation_form_func = function(state)
function banners.creation_form_func(state)
-- helper functions
state.update_player_inv = function(self, transform_string)
function state:update_player_inv(transform_string)
local player = core.get_player_by_name(self.player)
local newbanner = player:get_wielded_item()
newbanner:get_meta():set_string("", transform_string)
player:set_wielded_item(newbanner)
end
state.update_preview = function(self, transform_string)
function state:update_preview(transform_string)
self:get("banner_preview"):setImage(transform_string)
self:get("color_indicator"):setImage(self.current_color)
end
state.update_preview_inv = function(self)
function state:update_preview_inv()
local transform_string = self.banner:get_transform_string()
self:update_preview(transform_string)
self:update_player_inv(transform_string)
Expand All @@ -78,6 +97,7 @@ banners.creation_form_func = function(state)
state.banner:push_transform(banners.base_transform)
histories[state.player] = state.banner
end
state.banner:read_item(state.player)
state.current_color = state.banner.color
state:size(20, 10)
state:image(3, 0.4, 4, 2, "banner_preview", nil)
Expand Down Expand Up @@ -144,34 +164,36 @@ end
banners.creation_form = smartfs.create("banners:banner_creation",
banners.creation_form_func)


-- banner definition
banners.Banner = {}

function banners.Banner:new(banner)
banner = banner or { color = "bg_black.png", transforms = {} }
setmetatable(banner, self)
self.__index = self
return banner
end
function banners.Banner.push_transform(self, transform)
table.insert(self.transforms, transform)
if #self.transforms > banners.max_undo_levels then
table.remove(self.transforms, 1)
function banners.transform_string_to_table(transform_string)
local mask, parts, texture
local transforms = {}
for part in transform_string:gmatch("%(([^%)]+)%)") do
parts = part:split("^[")
if 3 == #parts then
texture = parts[1]
mask = parts[2]:sub(6)
if valid_masks[mask] and valid_colors[texture] then
table.insert(transforms, {
texture = texture,
mask = mask
})
end
end
end
return transforms
end
function banners.Banner.pop_transform(self)
table.remove(self.transforms)
end
function banners.Banner.get_transform_string(self)

function banners.transform_table_to_string(transforms)
local i = #transforms
if 0 == i then return "" end

local final = {}
local used = {}
local transform
-- work backwards to keep resulting data small
local i = #self.transforms
repeat
transform = self.transforms[i]
-- same mask can be trimmed out only using most recent
transform = transforms[i]
-- duplicate mask can be trimmed out only use most recent
if not used[transform.mask] then
used[transform.mask] = true
table.insert(final, 1, "(" .. transform.texture
Expand All @@ -183,13 +205,54 @@ function banners.Banner.get_transform_string(self)
end
i = i - 1
until i == 0
local ret = table.concat(final, "^")
return ret
return table.concat(final, "^")
end

-- banner definition
banners.Banner = {}

function banners.Banner:new(banner)
banner = banner or { color = "bg_black.png", transforms = {} }
setmetatable(banner, self)
self.__index = self
return banner
end

function banners.Banner:push_transform(transform)
table.insert(self.transforms, transform)
if #self.transforms > banners.max_undo_levels then
table.remove(self.transforms, 1)
end
end

function banners.Banner:pop_transform()
table.remove(self.transforms)
end

function banners.Banner:get_transform_string()
return banners.transform_table_to_string(self.transforms)
end

function banners.Banner:read_item(player_name)
local player = core.get_player_by_name(player_name)
local item = player:get_wielded_item()
if "banners:" ~= item:get_name():sub(1, 8) then return end

local transforms = banners.transform_string_to_table(
item:get_meta():get_string(""))
local total = #transforms
if 0 == total then return end

local i = 1
repeat
self:push_transform(transforms[i])
i = i + 1
until i > total
end

-- helper function for determining the flag's direction
-- (pos, pointed_thing)
banners.determine_flag_direction = function(_, pointed_thing)
function banners.determine_flag_direction(_, pointed_thing)
local above = pointed_thing.above
local under = pointed_thing.under
local dir = {
Expand All @@ -201,13 +264,13 @@ banners.determine_flag_direction = function(_, pointed_thing)
end

-- (itemstack, player, pointed_thing)
banners.banner_on_use = function(_, player)
function banners.banner_on_use(_, player)
if player.is_player then
banners.creation_form:show(player:get_player_name())
end
end

banners.banner_on_dig = function(pos, node, player)
function banners.banner_on_dig(pos, node, player)
if not player or core.is_protected(pos, player:get_player_name()) then
return
end
Expand All @@ -223,7 +286,7 @@ banners.banner_on_dig = function(pos, node, player)
end

-- (pos, node, player)
banners.banner_on_destruct = function(pos)
function banners.banner_on_destruct(pos)
local objects = core.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
local e = v:get_luaentity()
Expand All @@ -234,21 +297,33 @@ banners.banner_on_destruct = function(pos)
end

-- (pos, player, itemstack, pointed_thing)
banners.banner_after_place = function(pos, _, itemstack, pointed_thing)
function banners.banner_after_place(pos, _, itemstack, pointed_thing)
core.get_node(pos).param2 = banners.determine_flag_direction(pos, pointed_thing)
core.get_meta(pos):set_string("banner", itemstack:get_meta():get_string(""))
local meta = core.get_meta(pos)
meta:set_string("banner", itemstack:get_meta():get_string(""))
meta:set_float("version", banners.version)
core.add_entity(pos, "banners:banner_ent")
end

-- banner entity
local set_banner_texture = function(obj, texture)
obj:set_properties({ textures = { "banner_uv_text.png^" .. texture } })
-- [jumpdrive] compat
-- (from_pos, to_pos, additional_info)
function banners.banner_on_movenode(_, to_pos)
core.add_entity(to_pos, "banners:banner_ent")
end

-- banner entity

banners.banner_on_activate = function(self)
function banners:banner_on_activate()
local pos = self.object:get_pos()
local banner = core.get_meta(pos):get_string("banner")
local meta = core.get_meta(pos)
local banner = meta:get_string("banner")
-- cleanup meta of old banners
if meta:get_float("version") < 20241122 then
meta:set_float("version", banners.version)
banner = banners.transform_table_to_string(
banners.transform_string_to_table(banner))
meta:set_string("banner", banner)
end
local banner_face = core.get_node(pos).param2
local yaw = 0.
if banner_face == 2 then
Expand All @@ -261,9 +336,9 @@ banners.banner_on_activate = function(self)
yaw = 4.71238898038469 -- 3 * pi / 2
end
self.object:set_yaw(yaw)
if banner then
set_banner_texture(self.object, banner)
end
self.object:set_properties({
textures = { "banner_uv_text.png^" .. banner }
})
end

core.register_entity("banners:banner_ent", {
Expand All @@ -276,15 +351,12 @@ core.register_entity("banners:banner_ent", {
on_activate = banners.banner_on_activate,
})

core.register_on_leaveplayer(function(player)
histories[player:get_player_name()] = nil
end)

if core.get_modpath("factions") then
dofile(MP .. "factions.lua")
end

dofile(MP .. "items.lua")
dofile(MP .. "nodes.lua")
dofile(MP .. "crafts.lua")
dofile(MP .. "chatcommands.lua")

Loading