1 local S
= minetest
.get_translator("tsm_pyramids")
3 local mummy_walk_limit
= 1
4 local mummy_chillaxin_speed
= 1
5 local mummy_animation_speed
= 10
6 -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
7 local mummy_animation_blend
= 0
9 -- Default player appearance
10 local mummy_mesh
= "tsm_pyramids_mummy.x"
11 local mummy_texture
= {"tsm_pyramids_mummy.png"}
13 local mummy_drop
= "default:papyrus"
15 local sound_normal
= "mummy"
16 local sound_hit
= "mummy_hurt"
17 local sound_dead
= "mummy_death"
19 local spawner_range
= 17
20 local spawner_max_mobs
= 6
22 local function get_animations()
46 local ANIM_WALK_MINE
= 5
49 local function hit(self
)
52 textures
= {"tsm_pyramids_mummy.png^tsm_pyramids_hit.png"},
54 self
.object
:set_properties(prop
)
55 minetest
.after(0.4, function(self
)
56 local prop
= {textures
= mummy_texture
,}
57 if self
.object
~= nil then
58 self
.object
:set_properties(prop
)
63 local function mummy_update_visuals_def(self
)
64 npc_anim
= 0 -- Animation will be set further below immediately
67 textures
= mummy_texture
,
69 self
.object
:set_properties(prop
)
74 collisionbox
= {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
76 visual_size
= {x
=8,y
=8},
78 textures
= mummy_texture
,
79 makes_footstep_sound
= true,
101 visual_size
= {x
=3.3,y
=3.3},
103 textures
= mummy_texture
,
104 makes_footstep_sound
= false,
106 automatic_rotate
= math
.pi
* 2.9,
110 spawner_DEF
.on_activate
= function(self
)
111 mummy_update_visuals_def(self
)
112 self
.object
:set_velocity({x
=0, y
=0, z
=0})
113 self
.object
:set_acceleration({x
=0, y
=0, z
=0})
114 self
.object
:set_armor_groups({immortal
=1})
118 spawner_DEF
.on_step
= function(self
, dtime
)
119 self
.timer
= self
.timer
+ 0.01
120 local n
= minetest
.get_node_or_nil(self
.object
:get_pos())
121 if self
.timer
> 1 then
122 if n
and n
.name
and n
.name
~= "tsm_pyramids:spawner_mummy" then
128 spawner_DEF
.on_punch
= function(self
, hitter
)
132 MUMMY_DEF
.on_activate
= function(self
)
133 mummy_update_visuals_def(self
)
134 self
.anim
= get_animations()
135 self
.object
:set_animation({x
=self
.anim
.stand_START
,y
=self
.anim
.stand_END
}, mummy_animation_speed
, mummy_animation_blend
)
136 self
.npc_anim
= ANIM_STAND
137 self
.object
:set_acceleration({x
=0,y
=-20,z
=0})--20
139 self
.object
:set_hp(mummy_hp
)
140 self
.object
:set_armor_groups({fleshy
=130})
143 MUMMY_DEF
.on_punch
= function(self
, puncher
, time_from_last_punch
, tool_capabilities
, dir
)
145 self
.attacker
= puncher
147 if puncher
~= nil then
148 local sound
= sound_hit
149 if self
.object
:get_hp() == 0 then sound
= sound_dead
end
150 minetest
.sound_play(sound
, {to_player
= puncher
:get_player_name(), loop
= false, gain
= 0.4})
151 if time_from_last_punch
>= 0.45 then
153 self
.direction
= {x
=self
.object
:get_velocity().x
, y
=self
.object
:get_velocity().y
, z
=self
.object
:get_velocity().z
}
155 self
.object
:set_velocity({x
=dir
.x
*mummy_chillaxin_speed
,y
=5,z
=dir
.z
*mummy_chillaxin_speed
})
156 if self
.state
== 1 then
158 elseif self
.state
>= 2 then
164 if self
.object
:get_hp() == 0 then
165 local obj
= minetest
.add_item(self
.object
:get_pos(), mummy_drop
.." "..math
.random(0,3))
172 MUMMY_DEF
.on_step
= function(self
, dtime
)
173 self
.timer
= self
.timer
+ 0.01
174 self
.turn_timer
= self
.turn_timer
+ 0.01
175 self
.jump_timer
= self
.jump_timer
+ 0.01
176 self
.punch_timer
= self
.punch_timer
+ 0.01
177 self
.attacking_timer
= self
.attacking_timer
+ 0.01
178 self
.sound_timer
= self
.sound_timer
+ dtime
+ 0.01
180 local current_pos
= self
.object
:get_pos()
181 local current_node
= minetest
.get_node(current_pos
)
182 if self
.time_passed
== nil then
186 if self
.object
:get_hp() == 0 then
187 minetest
.sound_play(sound_dead
, {pos
= current_pos
, max_hear_distance
= 10 , gain
= 0.3})
190 local def
= minetest
.registered_nodes
[current_node
.name
]
191 local dps
= def
.damage_per_second
193 if dps
~= nil and dps
> 0 then
197 if dmg
< 4 and (minetest
.get_item_group(current_node
.name
, "water") ~= 0 or minetest
.get_item_group(current_node
.name
, "lava") ~= 0) then
200 -- Damage by suffocation
201 if (def
.walkable
== nil or def
.walkable
== true)
202 and (def
.drowning
== nil or def
.drowning
== 0)
203 and (def
.damage_per_second
== nil or def
.damage_per_second
<= 0)
204 and (def
.collision_box
== nil or def
.collision_box
.type == "regular")
205 and (def
.node_box
== nil or def
.node_box
.type == "regular")
206 and (def
.groups
and def
.groups
.disable_suffocation
~= 1) then
209 self
.envdmg_timer
= self
.envdmg_timer
+ dtime
211 if self
.envdmg_timer
>= 1 then
212 self
.envdmg_timer
= 0
213 self
.object
:set_hp(self
.object
:get_hp()-dmg
)
216 minetest
.sound_play(sound_hit
, {pos
= current_pos
, max_hear_distance
= 10, gain
= 0.3})
222 --update moving state every 1 or 2 seconds
223 if self
.state
< 3 then
224 if self
.timer
> math
.random(1,2) then
225 if self
.attacker
== "" then
226 self
.state
= math
.random(1,2)
227 else self
.state
= 1 end
233 if self
.sound_timer
> math
.random(5,35) then
234 minetest
.sound_play(sound_normal
, {pos
= current_pos
, max_hear_distance
= 10, gain
= 0.2})
239 if self
.state
>= 8 then
240 if self
.punch_timer
> 0.15 then
241 if self
.state
== 9 then
242 self
.object
:set_velocity({x
=self
.direction
.x
*mummy_chillaxin_speed
,y
=-20,z
=self
.direction
.z
*mummy_chillaxin_speed
})
244 elseif self
.state
== 8 then
245 self
.object
:set_velocity({x
=0,y
=-20,z
=0})
252 if self
.state
== 1 then
255 for _
,object
in ipairs(minetest
.get_objects_inside_radius(self
.object
:get_pos(), 4)) do
256 if object
:is_player() then
258 local NPC
= self
.object
:get_pos()
259 local PLAYER
= object
:get_pos()
260 self
.vec
= {x
=PLAYER
.x
-NPC
.x
, y
=PLAYER
.y
-NPC
.y
, z
=PLAYER
.z
-NPC
.z
}
261 self
.yaw
= math
.atan(self
.vec
.z
/self
.vec
.x
)+math
.pi^
2
262 if PLAYER
.x
> NPC
.x
then
263 self
.yaw
= self
.yaw
+ math
.pi
265 self
.yaw
= self
.yaw
- 2
266 self
.object
:set_yaw(self
.yaw
)
267 self
.attacker
= object
271 if self
.attacker
== "" and self
.turn_timer
> math
.random(1,4) then
272 self
.yaw
= 360 * math
.random()
273 self
.object
:set_yaw(self
.yaw
)
275 self
.direction
= {x
= math
.sin(self
.yaw
)*-1, y
= -20, z
= math
.cos(self
.yaw
)}
277 self
.object
:set_velocity({x
=0,y
=self
.object
:get_velocity().y
,z
=0})
278 if self
.npc_anim
~= ANIM_STAND
then
279 self
.anim
= get_animations()
280 self
.object
:set_animation({x
=self
.anim
.stand_START
,y
=self
.anim
.stand_END
}, mummy_animation_speed
, mummy_animation_blend
)
281 self
.npc_anim
= ANIM_STAND
283 if self
.attacker
~= "" then
284 self
.direction
= {x
= math
.sin(self
.yaw
)*-1, y
= -20, z
= math
.cos(self
.yaw
)}
289 if self
.state
== 2 then
291 if self
.direction
~= nil then
292 self
.object
:set_velocity({x
=self
.direction
.x
*mummy_chillaxin_speed
,y
=self
.object
:get_velocity().y
,z
=self
.direction
.z
*mummy_chillaxin_speed
})
294 if self
.turn_timer
> math
.random(1,4) and not self
.attacker
then
295 self
.yaw
= 360 * math
.random()
296 self
.object
:set_yaw(self
.yaw
)
298 self
.direction
= {x
= math
.sin(self
.yaw
)*-1, y
= -20, z
= math
.cos(self
.yaw
)}
300 if self
.npc_anim
~= ANIM_WALK
then
301 self
.anim
= get_animations()
302 self
.object
:set_animation({x
=self
.anim
.walk_START
,y
=self
.anim
.walk_END
}, mummy_animation_speed
, mummy_animation_blend
)
303 self
.npc_anim
= ANIM_WALK
306 if self
.attacker
~= "" and minetest
.settings
:get_bool("enable_damage") then
307 local s
= self
.object
:get_pos()
308 local p
= self
.attacker
:get_pos()
309 if (s
~= nil and p
~= nil) then
310 local dist
= ((p
.x
-s
.x
)^
2 + (p
.y
-s
.y
)^
2 + (p
.z
-s
.z
)^
2)^
0.5
312 if dist
< 2 and self
.attacking_timer
> 0.6 then
313 self
.attacker
:punch(self
.object
, 1.0, {
314 full_punch_interval
=1.0,
315 damage_groups
= {fleshy
=1}
317 self
.attacking_timer
= 0
324 minetest
.register_entity("tsm_pyramids:mummy", MUMMY_DEF
)
325 minetest
.register_entity("tsm_pyramids:mummy_spawner", spawner_DEF
)
330 minetest
.register_craftitem("tsm_pyramids:spawn_egg", {
331 description
= S("Mummy Spawn Egg"),
332 _doc_items_longdesc
= S("Can be used to create a hostile mummy."),
333 _doc_items_usagehelp
= S("Place the egg to create a mummy on this spot. Careful, it will probably attack immediately!"),
334 inventory_image
= "tsm_pyramids_mummy_egg.png",
335 liquids_pointable
= false,
337 on_place
= function(itemstack
, placer
, pointed_thing
)
338 if pointed_thing
.type == "node" then
339 minetest
.add_entity(pointed_thing
.above
,"tsm_pyramids:mummy")
340 if not minetest
.settings
:get_bool("creative_mode") then itemstack
:take_item() end
347 function tsm_pyramids
.spawn_mummy (pos
, number)
348 local node
= minetest
.get_node(pos
)
349 if node
.name
~= "air" then
353 minetest
.add_entity(pos
,"tsm_pyramids:mummy")
358 if default
.node_sound_metal_defaults
then
359 spawnersounds
= default
.node_sound_metal_defaults()
361 spawnersounds
= default
.node_sound_stone_defaults()
364 minetest
.register_node("tsm_pyramids:spawner_mummy", {
365 description
= S("Mummy Spawner"),
366 _doc_items_longdesc
= S("A mummy spawner causes hostile mummies to appear in its vicinity as long it exists."),
368 tiles
= {"tsm_pyramids_spawner.png"},
369 is_ground_content
= false,
370 drawtype
= "allfaces",
371 groups
= {cracky
=1,level
=1},
373 on_construct
= function(pos
)
375 minetest
.add_entity(pos
,"tsm_pyramids:mummy_spawner")
377 on_destruct
= function(pos
)
378 for _
,obj
in ipairs(minetest
.get_objects_inside_radius(pos
, 1)) do
379 if not obj
:is_player() then
380 if obj
~= nil and obj
:get_luaentity().m_name
== "dummy" then
386 sounds
= spawnersounds
,
388 if not minetest
.settings
:get_bool("only_peaceful_mobs") then
389 minetest
.register_abm({
390 nodenames
= {"tsm_pyramids:spawner_mummy"},
393 action
= function(pos
, node
, active_object_count
, active_object_count_wider
)
394 local player_near
= false
396 for _
,obj
in ipairs(minetest
.get_objects_inside_radius(pos
, spawner_range
)) do
397 if obj
:is_player() then
400 if obj
:get_luaentity() and obj
:get_luaentity().mob_name
== "mummy" then
406 if mobs
< spawner_max_mobs
then
408 local p
= minetest
.find_node_near(pos
, 5, {"air"})
409 local p2
= {x
=pos
.x
, y
=pos
.y
+1, z
=pos
.z
}
410 local n2
= minetest
.get_node(p2
)
411 if n2
.name
== "air" then
412 tsm_pyramids
.spawn_mummy(p
, 1)
420 if minetest
.get_modpath("awards") then
421 awards
.register_achievement("tsm_pyramids_no_mummy_spawner", {
422 title
= S("No more mummies!"),
423 description
= S("Destroy a mummy spawner by digging."),
425 icon
= "tsm_pyramids_spawner.png",
428 node
= "tsm_pyramids:spawner_mummy",