Remove intllib-related code
[minetest_hades/hades_revisited.git] / mods / mobs / spawner.lua
blobe10773cb9ebee307b3e066aea2e222266dea34e6
2 local MP = minetest.get_modpath(minetest.get_current_modname())
3 local S = minetest.get_translator("mobs")
5 -- mob spawner
7 local spawner_default = "mobs_animal:pumba 10 15 0 0"
9 minetest.register_node("mobs:spawner", {
10 tiles = {"mob_spawner.png"},
11 drawtype = "glasslike",
12 paramtype = "light",
13 walkable = true,
14 description = S("Mob Spawner"),
15 groups = {cracky = 1},
17 on_construct = function(pos)
19 local meta = minetest.get_meta(pos)
21 -- text entry formspec
22 meta:set_string("formspec",
23 "field[text;" .. minetest.formspec_escape(S("Mob MinLight MaxLight Amount PlayerDist")) .. ";${command}]")
24 meta:set_string("infotext", S("Spawner Not Active (enter settings)"))
25 meta:set_string("command", spawner_default)
26 end,
28 on_right_click = function(pos, placer)
30 if minetest.is_protected(pos, placer:get_player_name()) then
31 return
32 end
33 end,
35 on_receive_fields = function(pos, formname, fields, sender)
37 if not fields.text or fields.text == "" then
38 return
39 end
41 local meta = minetest.get_meta(pos)
42 local comm = fields.text:split(" ")
43 local name = sender:get_player_name()
45 if minetest.is_protected(pos, name) then
46 minetest.record_protection_violation(pos, name)
47 return
48 end
50 local mob = comm[1] -- mob to spawn
51 local mlig = tonumber(comm[2]) -- min light
52 local xlig = tonumber(comm[3]) -- max light
53 local num = tonumber(comm[4]) -- total mobs in area
54 local pla = tonumber(comm[5]) -- player distance (0 to disable)
55 local yof = tonumber(comm[6]) or 0 -- Y offset to spawn mob
57 if mob and mob ~= "" and mobs.spawning_mobs[mob] == true
58 and num and num >= 0 and num <= 10
59 and mlig and mlig >= 0 and mlig <= 15
60 and xlig and xlig >= 0 and xlig <= 15
61 and pla and pla >=0 and pla <= 20
62 and yof and yof > -10 and yof < 10 then
64 meta:set_string("command", fields.text)
65 meta:set_string("infotext", S("Spawner Active (@1)", mob))
67 else
68 minetest.chat_send_player(name, S("Mob Spawner settings failed!"))
69 minetest.chat_send_player(name,
70 S("Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10]”"))
71 end
72 end,
76 local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 99)
78 -- spawner abm
79 minetest.register_abm({
80 label = "Mob spawner node",
81 nodenames = {"mobs:spawner"},
82 interval = 10,
83 chance = 4,
84 catch_up = false,
86 action = function(pos, node, active_object_count, active_object_count_wider)
88 -- return if too many entities already
89 if active_object_count_wider >= max_per_block then
90 return
91 end
93 -- get meta and command
94 local meta = minetest.get_meta(pos)
95 local comm = meta:get_string("command"):split(" ")
97 -- get settings from command
98 local mob = comm[1]
99 local mlig = tonumber(comm[2])
100 local xlig = tonumber(comm[3])
101 local num = tonumber(comm[4])
102 local pla = tonumber(comm[5]) or 0
103 local yof = tonumber(comm[6]) or 0
105 -- if amount is 0 then do nothing
106 if num == 0 then
107 return
110 -- are we spawning a registered mob?
111 if not mobs.spawning_mobs[mob] then
112 --print ("--- mob doesn't exist", mob)
113 return
116 -- check objects inside 9x9 area around spawner
117 local objs = minetest.get_objects_inside_radius(pos, 9)
118 local count = 0
119 local ent = nil
121 -- count mob objects of same type in area
122 for k, obj in ipairs(objs) do
124 ent = obj:get_luaentity()
126 if ent and ent.name and ent.name == mob then
127 count = count + 1
131 -- is there too many of same type?
132 if count >= num then
133 return
136 -- spawn mob if player detected and in range
137 if pla > 0 then
139 local in_range = 0
140 local objs = minetest.get_objects_inside_radius(pos, pla)
142 for _,oir in pairs(objs) do
144 if oir:is_player() then
146 in_range = 1
148 break
152 -- player not found
153 if in_range == 0 then
154 return
158 -- find air blocks within 5 nodes of spawner
159 local air = minetest.find_nodes_in_area(
160 {x = pos.x - 5, y = pos.y + yof, z = pos.z - 5},
161 {x = pos.x + 5, y = pos.y + yof, z = pos.z + 5},
162 {"air"})
164 -- spawn in random air block
165 if air and #air > 0 then
167 local pos2 = air[math.random(#air)]
168 local lig = minetest.get_node_light(pos2) or 0
170 pos2.y = pos2.y + 0.5
172 -- only if light levels are within range
173 if lig >= mlig and lig <= xlig
174 and minetest.registered_entities[mob] then
175 minetest.add_entity(pos2, mob)