]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/spawning.lua
Make hostile mobs only spawn if area is really dark
[Crafter.git] / mods / mob / spawning.lua
1 local minetest,vector,math,table = minetest,vector,math,table
2
3 --this is where mob spawning is defined
4
5 --spawn mob in a square doughnut shaped radius
6 local timer = 6
7 --the amount of mobs that the game will try to spawn per player
8 local spawn_goal_per_player = 5
9 --the amount of mobs that the spawner will cap out at
10 local mob_limit = 100
11
12 --the height in which the game will search the x and z chosen (NUMBER up, NUMBER down)
13 local find_node_height = 32
14
15 --for debug testing to isolate mobs
16 local spawn = true
17
18 local spawn_table = {"pig","chicken","sheep"}
19 local snow_dark_spawn_table = {"snoider","sneeper",}
20 local snow_light_spawn_table = {"snowman"}
21 local dark_spawn_table = {"creeper","creeper","creeper","spider","spider","spider","big_slime","medium_slime","small_slime"}
22 local nether_spawn_table = {"nitro_creeper"}
23 local aether_spawn_table = {"phyg"}
24
25
26 local axis
27 --inner and outer part of square donut radius
28 local inner = 18
29 local outer = 50
30 local int = {-1,1}
31 local position_calculation = function(pos)                              
32         --this is used to determine the axis buffer from the player
33         axis = math.random(0,1)
34
35         --cast towards the direction
36         if axis == 0 then --x
37                 pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)]
38                 pos.z = pos.z + math.random(-outer,outer)
39         else --z
40                 pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)]
41                 pos.x = pos.x + math.random(-outer,outer)
42         end
43         return(pos)
44 end
45
46
47 local object_list
48 local entity
49 local counter
50 local get_mobs_in_radius = function(pos)
51         counter = 0
52         object_list = minetest.get_objects_inside_radius(pos, outer)
53         for _,object in ipairs(object_list) do
54                 if not object:is_player() then
55                         entity = object:get_luaentity()
56
57                         if entity.is_mob then
58                                 counter = counter + 1
59                         end
60                 end
61         end
62         return(counter)
63 end
64
65
66 local pos
67 local mobs
68 local spawner
69 local mob_spawning
70 local light_level
71 local mob_pos
72 local function spawn_mobs(player)
73         pos = player:get_pos()
74
75         mobs = get_mobs_in_radius(pos)
76
77         if mobs > spawn_goal_per_player then
78                 return
79         end
80
81         pos = position_calculation(pos)
82
83         spawner = {}
84         if pos.y >= 21000 then
85                 spawner = minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"aether:grass"})
86         elseif pos.y <= -10033 and pos.y >= -20112 then
87                 spawner = minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"nether:netherrack"})
88         else
89                 spawner = minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"main:grass","main:sand","main:water"})
90         end
91         
92         --print(dump(spawner))
93         if table.getn(spawner) > 0 then
94                 mob_pos = spawner[1]
95                 mob_pos.y = mob_pos.y + 1
96                 --aether spawning
97                 if mob_pos.y >= 21000 then
98                         mob_spawning = aether_spawn_table[math.random(1,table.getn(aether_spawn_table))]
99                         --print("Aether Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
100                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
101                 elseif mob_pos.y <= -10033 and mob_pos.y >= -20112 then
102                         mob_spawning = nether_spawn_table[math.random(1,table.getn(nether_spawn_table))]
103                         --print("Nether Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
104                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
105                 else
106                         light_level = minetest.get_node_light(spawner[1])
107
108                         if weather_type == 1 then
109                                 if light_level < 7 then
110                                         mob_spawning = snow_dark_spawn_table[math.random(1,table.getn(snow_dark_spawn_table))]
111                                         --print("Snow Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
112                                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
113                                 else
114                                         local mob_spawning = snow_light_spawn_table[math.random(1,table.getn(snow_light_spawn_table))]
115                                         --print("Snow Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
116                                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
117                                 end
118                         else
119                                 if light_level < 7 then
120                                         mob_spawning = dark_spawn_table[math.random(1,table.getn(dark_spawn_table))]
121                                         --print("Dark Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
122                                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
123                                 else
124                                         mob_spawning = spawn_table[math.random(1,table.getn(spawn_table))]
125                                         --print("Light Spawning "..mob_spawning.." at: "..minetest.pos_to_string(mob_pos))
126                                         minetest.add_entity(mob_pos,"mob:"..mob_spawning)
127                                 end
128                         end
129                 end
130         end
131 end
132
133 local function per_player_handling()
134         if global_mob_amount < mob_limit then
135                 --check through players
136                 for _,player in ipairs(minetest.get_connected_players()) do
137                         spawn_mobs(player)
138                 end
139         end
140
141         minetest.after(10, function()
142                 per_player_handling()
143         end)
144 end
145
146 if spawn then
147         minetest.register_on_mods_loaded(function()
148                 minetest.after(0,function()
149                         per_player_handling()
150                 end)
151         end)
152 end
153
154