People are now visible, experimental support for animals
[walkway.git] / init.lua
1 walkway = {}
2 local speed = 0.4
3 minetest.register_entity("walkway:moving_dummy",{
4 initial_properties = {
5 hp_max = 1,
6 physical = false,
7 collisionbox = {0.005, -0.005, 0.005, -0.005, 0.005, -0.025},
8 visual = "cube",
9 visual_size = {x = 1, y = 1},
10 textures = {"blank.png","blank.png", "blank.png","blank.png","blank.png","blank.png"},
11 spritediv = {x = 1, y = 1},
12 initial_sprite_basepos = {x = 0, y = 0},
13 is_visible = true;
14 },
15 player = nil,
16 on_step = function (self, dtime)
17 local name = ""
18 if self.player and self.player:is_player() then
19 name = self.player:get_player_name()
20 elseif not self.player then
21 self.object:remove()
22 end
23 local pos = self.object:getpos()
24 local napos = minetest.get_node(pos)
25 local dir = vector.new(minetest.facedir_to_dir(napos.param2)) -- a copy of the facedir so we don't overwrite the facedir table
26 local vx=0
27 local vz=0
28 if name ~="" then
29 -- based on code from the tower crane mod --
30 local ctrl = self.player:get_player_control()
31 local yaw = self.player:get_look_horizontal()
32 local pos = self.player:getpos()
33 local walk_speed = minetest.settings:get("movement_speed_walk") or 4
34 local speed_forward = 0
35 local speed_right= 0
36
37 if (ctrl.up or ctrl.down or ctrl.left or ctrl.right) then
38 default.player_set_animation(self.player, "walk" , 30)
39 else
40 default.player_set_animation(self.player, "stand" , 30)
41 end
42
43 if ctrl.up then -- forward
44 speed_forward = walk_speed
45 elseif ctrl.down then -- backward
46 speed_forward = -walk_speed
47 end
48
49 if ctrl.right then -- right
50 speed_right = walk_speed
51 elseif ctrl.left then -- left
52 speed_right = -walk_speed
53 end
54
55 -- calculate the direction vector
56 vx = math.cos(yaw+math.pi/2) * speed_forward + math.cos(yaw) * speed_right
57 vz = math.sin(yaw+math.pi/2) * speed_forward + math.sin(yaw) * speed_right
58 if dir.x == 0 then
59 vx = 0
60 elseif dir.z == 0 then
61 vz = 0
62 end
63 end
64
65
66 if napos.name == "walkway:belt_straight" then
67 self.object:setvelocity({x = dir.x / speed, y = 0, z = dir.z / speed})
68 elseif napos.name == "walkway:belt" then
69 if dir.x == 0 then
70 dir.x = (math.floor(pos.x + 0.5) - pos.x) * 2
71 elseif dir.z == 0 then
72 dir.z = (math.floor(pos.z + 0.5) - pos.z) * 2
73 end
74 self.object:setvelocity({x = dir.x / speed + vx, y = 0, z = dir.z / speed+vz})
75 else
76 if self.player then
77 self.player:set_detach()
78 self.object:remove()
79 else
80 self.object:remove()
81 end
82 if name ~="" then
83 default.player_attached[name] = false
84 end
85 end
86 end
87 })
88
89
90 minetest.register_node("walkway:belt", {
91 description = "Moving Walkway",
92 tiles = {{name="factory_belt_top_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.2}}, "factory_belt_bottom.png", "factory_belt_side.png",
93 "factory_belt_side.png", "factory_belt_side.png", "factory_belt_side.png"},
94 groups = {cracky=1},
95 drawtype = "nodebox",
96 paramtype = "light",
97 paramtype2 = "facedir",
98 is_ground_content = true,
99 legacy_facedir_simple = true,
100 node_box = {
101 type = "fixed",
102 fixed = {{-0.5,-0.5,-0.5,0.5,0.0625,0.5},}
103 },
104 })
105
106 -- minetest.register_node("walkway:belt_straight", {
107 -- description = "straight Conveyor Belt",
108 -- tiles = {{name="factory_belt_top_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.4}}, "factory_belt_bottom.png", "factory_belt_side.png",
109 -- "factory_belt_side.png", "factory_belt_side.png", "factory_belt_side.png"},
110 -- groups = {cracky=1},
111 -- drawtype = "nodebox",
112 -- paramtype = "light",
113 -- paramtype2 = "facedir",
114 -- is_ground_content = true,
115 -- legacy_facedir_simple = true,
116 -- node_box = {
117 -- type = "fixed",
118 -- fixed = {{-0.5,-0.5,-0.5,0.5,0.0625,0.5},}
119 -- },
120 -- })
121
122 minetest.register_abm({
123 nodenames = {"walkway:belt", "walkway:belt_straight"},
124 neighbors = nil,
125 interval = 1,
126 chance = 1,
127 action = function(pos, node, active_object_count, active_object_count_wider)
128 local all_objects = minetest.get_objects_inside_radius(pos, 0.75)
129 local _,obj
130 for _,obj in ipairs(all_objects) do
131 if not obj:is_player() and obj:get_luaentity() and obj:get_luaentity().name == "__builtin:item" then
132 walkway.do_moving_item({x = pos.x, y = pos.y + 0.15, z = pos.z}, obj:get_luaentity().itemstring)
133 obj:get_luaentity().itemstring = ""
134 obj:remove()
135 end
136 end
137 end,
138 })
139
140 minetest.register_abm({
141 nodenames = {"walkway:belt", "walkway:belt_straight"},
142 neighbors = nil,
143 interval = 1,
144 chance = 1,
145 action = function(pos, node, active_object_count, active_object_count_wider)
146 local all_objects = minetest.get_objects_inside_radius(pos, 0.75)
147 local _,obj
148 for _,obj in ipairs(all_objects) do
149 if obj:get_luaentity() then
150 minetest.chat_send_all(obj:get_luaentity().name)
151 end
152 if obj:is_player() and not obj:get_attach() then
153 dum = walkway.do_moving_dummy({x = pos.x, y = pos.y + 0.15, z = pos.z}, obj):get_luaentity()
154 dum.player = obj
155 obj:set_attach(dum.object, "", {x=0,y=9,z=0}, {x=0,y=0,z=0})
156 local name = obj:get_player_name()
157 default.player_attached[name] = true
158 elseif obj:get_luaentity() and string.sub(obj:get_luaentity().name,1,string.len("mobs_animal")) == "mobs_animal" then
159 dum = walkway.do_moving_dummy({x = pos.x, y = pos.y + 0.15, z = pos.z}, obj):get_luaentity()
160 dum.player = obj
161 minetest.chat_send_all("Attaching "..obj:get_luaentity().name)
162 obj:set_attach(dum.object, "", {x=0,y=-1,z=0}, {x=0,y=0,z=0})
163 end
164 end
165 end,
166 })
167
168 -- Based off of the pipeworks item code
169
170 function walkway.do_moving_item(pos, item)
171 if item==":" then
172 return
173 end
174 local stack = ItemStack(item)
175 local obj = minetest.add_entity(pos, "walkway:moving_item")
176 obj:get_luaentity():set_item(stack:to_string())
177 return obj
178 end
179
180 function walkway.do_moving_dummy(pos, player)
181 local stack = ItemStack(item)
182 local obj = minetest.add_entity(pos, "walkway:moving_dummy")
183 -- obj:attach(player)
184 return obj
185 end
186
187
188 minetest.register_entity("walkway:moving_item", {
189 initial_properties = {
190 hp_max = 1,
191 physical = false,
192 collisionbox = {0.125, 0.125, 0.125, 0.125, 0.125, 0.125},
193 visual = "wielditem",
194 visual_size = {x = 0.5, y = 0.5},
195 textures = {""},
196 spritediv = {x = 1, y = 1},
197 initial_sprite_basepos = {x = 0, y = 0},
198 is_visible = false,
199 },
200
201 physical_state = true,
202 itemstring = '',
203 set_item = function(self, itemstring)
204 self.itemstring = itemstring
205 local stack = ItemStack(itemstring)
206 local count = stack:get_count()
207 local max_count = stack:get_stack_max()
208 if count > max_count then
209 count = max_count
210 self.itemstring = stack:get_name().." "..max_count
211 end
212 local s = 0.15 + 0.15 * (count / max_count)
213 local c = 0.8 * s
214 local itemtable = stack:to_table()
215 local itemname = nil
216 if itemtable then
217 itemname = stack:to_table().name
218 end
219 local item_texture = nil
220 local item_type = ""
221 if core.registered_items[itemname] then
222 item_texture = core.registered_items[itemname].inventory_image
223 item_type = core.registered_items[itemname].type
224 end
225 prop = {
226 is_visible = true,
227 visual = "wielditem",
228 textures = {itemname},
229 visual_size = {x = s, y = s},
230 collisionbox = {-c, -c, -c, c, c, c},
231 automatic_rotate = math.pi * 0.2,
232 }
233 self.object:set_properties(prop)
234 end,
235
236 get_staticdata = function(self)
237 return core.serialize({
238 itemstring = self.itemstring
239 })
240 end,
241
242 on_activate = function(self, staticdata, dtime_s)
243 if string.sub(staticdata, 1, string.len("return")) == "return" then
244 local data = core.deserialize(staticdata)
245 if data and type(data) == "table" then
246 self.itemstring = data.itemstring
247 end
248 else
249 self.itemstring = staticdata
250 end
251 self.object:set_armor_groups({immortal = 1})
252 self:set_item(self.itemstring)
253 end,
254
255 on_step = function(self, dtime)
256 local pos = self.object:getpos()
257 local napos = minetest.get_node(pos)
258 local dir = vector.new(minetest.facedir_to_dir(napos.param2)) -- a copy of the facedir so we don't overwrite the facedir table
259 if napos.name == "walkway:belt_straight" then
260 self.object:setvelocity({x = dir.x / speed, y = 0, z = dir.z / speed})
261 elseif napos.name == "walkway:belt" then
262 if dir.x == 0 then
263 dir.x = (math.floor(pos.x + 0.5) - pos.x) * 2
264 elseif dir.z == 0 then
265 dir.z = (math.floor(pos.z + 0.5) - pos.z) * 2
266 end
267 self.object:setvelocity({x = dir.x / speed, y = 0, z = dir.z / speed})
268 else
269 local stack = ItemStack(self.itemstring)
270 local veldir = self.object:getvelocity();
271 minetest.item_drop(stack, walkway.no_player, {x = pos.x + veldir.x / 3, y = pos.y, z = pos.z + veldir.z / 3})
272 self.object:remove()
273 end
274 end
275 })
276
277 minetest.register_craft({
278 output = "walkway:belt 12",
279 recipe = {
280 {"", "default:gold_ingot", ""},
281 {"default:stone", "default:mese_crystal", "default:stone"},
282 {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
283 }
284 })