1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
local container_entities = {}
local function update_container_entity(entity, stack)
entity:set_properties {
physical = false,
pointable = false,
collide_with_objects = false,
visual = "wielditem",
visual_size = {x = 0.4, y = 0.4},
wield_item = stack:get_name(),
static_save = false,
}
end
minetest.register_entity("vzxv_itemstacks:itemstack",{
initial_properties = {
physical = false,
pointable = false,
static_save = false,
},
on_activate = function(self)
local ent = self.object
local pos = vzxv.round_pos(ent:get_pos())
container_entities[minetest.hash_node_position(pos)] = ent
end,
on_deactivate = function(self)
local ent = self.object
local pos = vzxv.round_pos(ent:get_pos())
container_entities[minetest.hash_node_position(pos)] = nil
end,
})
local function get_container_entity(pos)
return container_entities[minetest.hash_node_position(pos)]
end
local function add_container_entity(pos)
pos = {x = pos.x, y = pos.y - 0.20, z = pos.z}
minetest.add_entity(pos, "vzxv_itemstacks:itemstack")
end
local function remove_container_entity(pos)
local h = minetest.hash_node_position(pos)
if container_entities[h] then
container_entities[h]:remove()
end
container_entities[h] = nil
end
function vzxv.is_container(pos)
local item = minetest.get_node(pos).name
return minetest.get_item_group(item, "container")
end
function vzxv.get_container_stack(pos)
local meta = minetest.get_meta(pos)
local stack = meta:get_string("stack")
return ItemStack(stack)
end
function vzxv.set_container_stack(pos, stack)
pos = vzxv.round_pos(pos)
local entity = get_container_entity(pos)
if stack and not entity then
add_container_entity(pos)
entity = get_container_entity(pos)
elseif not stack and entity then
remove_container_entity(pos)
end
local meta = minetest.get_meta(pos)
meta:set_string("stack",stack:to_string())
if entity then
update_container_entity(entity, stack)
end
end
minetest.register_lbm {
name = "vzxv_itemstacks:load_itemstacks",
nodenames = {"group:container"},
run_at_every_load = true,
action = function(pos)
local stack = vzxv.get_container_stack(pos)
local entity = get_container_entity(pos)
if stack and not stack:is_empty() then
if not entity then
add_container_entity(pos)
entity = get_container_entity(pos)
end
update_container_entity(entity, stack)
end
end,
}
-- containers must call this when removed
function vzxv.container_destruct(pos)
remove_container_entity(pos)
end
function vzxv.add_container_items(pos, stack)
local contents = vzxv.get_container_stack(pos)
local free_space = contents:get_free_space()
local amount = math.min(free_space, stack:get_count())
contents:set_count(contents:get_count() + amount)
vzxv.set_container_stack(pos, contents)
stack:set_count(stack:get_count() - amount)
return stack
end
function vzxv.take_container_items(pos, n)
local contents = vzxv.get_container_stack(pos)
local removed = contents:take_item(n)
vzxv.set_container_stack(pos, contents)
return removed
end
function vzxv.player_take_container_items(pos, _, player)
local items = vzxv.take_container_items(pos, 99)
local leftover = vzxv.collect_items(player, items)
vzxv.add_container_items(pos, leftover)
return true
end
function vzxv.player_add_container_items(pos, _, player, stack)
local items = vzxv.remove_items(player, stack)
local leftover = vzxv.add_container_items(pos, items)
vzxv.give_items(player, leftover)
return leftover
end
|