This repository has been archived by the owner on Dec 14, 2019. It is now read-only.
/
init.lua
204 lines (185 loc) · 5.61 KB
/
init.lua
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
creatures = {}
creatures.ANIM_STAND = 1
creatures.ANIM_SIT = 2
creatures.ANIM_LAY = 3
creatures.ANIM_WALK = 4
creatures.ANIM_EAT = 5
creatures.ANIM_RUN = 6
-- Drop items (when not killed by player) only if items get removed
creatures.drop_on_death = false
local remove_items = minetest.setting_get("remove_items")
if minetest.get_modpath("builtin_item") ~= nil and remove_items ~= nil and tonumber(remove_items) > 0 then
creatures.drop_on_death = true
end
-- spawning controls (experimental)
creatures.spawned = {}
local spawn_day = 600
local tod = 0
local absolute_mob_max = 50
local function timer(tick)
tod = tod + 1
if tod > spawn_day then
tod = 0
creatures.spawned = nil
creatures.spawned = {}
end
minetest.after(tick, timer, tick)
end
timer(1)
local tool_uses = {0, 30, 110, 150, 280, 300, 500, 1000}
-- helping functions
function creatures.spawn(pos, number, mob, limit, range, abs_max)
if not pos or not number or not mob then return end
if number < 1 then return end
if limit == nil then limit = 1 end
if range == nil then range = 10 end
if abs_max == nil then abs_max = absolute_mob_max end
local m_name = string.sub(mob,11)
local spawned = creatures.spawned[m_name]
if not spawned then spawned = 0 end
local res,mobs,player_near = creatures.find_mates(pos, m_name, range)
for i=1,number do
local x = 1/math.random(1,3)
local z = 1/math.random(1,3)
local p = {x=pos.x+x,y=pos.y,z=pos.z+z}
if mobs+i <= limit and spawned+i < abs_max then
minetest.after(i/5,function()
local obj = minetest.env:add_entity(p, mob)
if obj then
creatures.spawned[m_name] = spawned + 1
minetest.log("action", "Spawned "..mob.." at ("..pos.x..","..pos.y..","..pos.z..")")
end
end)
end
end
end
function creatures.add_wear(player, def)
if not minetest.setting_getbool("creative_mode") then
local item = player:get_wielded_item()
if def and def.damage_groups and def.damage_groups.fleshy then
local uses = tool_uses[def.damage_groups.fleshy] or 0
if uses > 0 then
local wear = 65535/uses
item:add_wear(wear)
player:set_wielded_item(item)
end
end
end
end
function creatures.drop(pos, items, dir)
if dir == nil then
dir = {x=1,y=1,z=1}
end
for _,item in ipairs(items) do
for i=1,item.count do
local x = 1/math.random(1,5)*dir.x--math.random(0, 6)/3 - 0.5*dir.x
local z = 1/math.random(1,5)*dir.z--math.random(0, 6)/3 - 0.5*dir.z
local p = {x=pos.x+x,y=pos.y,z=pos.z+z}
local node = minetest.get_node_or_nil(p)
if node == nil or not node.name or node.name ~= "air" then
p = pos
end
local obj = minetest.env:add_item(p, {name=item.name})
end
end
end
function creatures.find_mates(pos, name, radius)
local player_near = false
local mobs = 0
for _,obj in ipairs(minetest.env:get_objects_inside_radius(pos, radius)) do
if obj:is_player() then
player_near = true
else
local entity = obj:get_luaentity()
if entity and entity.mob_name and entity.mob_name == name then
mobs = mobs + 1
end
end
end
if mobs > 1 then
return true,mobs,player_near
end
return false,mobs,player_near
end
function creatures.compare_pos(pos1,pos2)
if pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z then
return true
end
return false
end
function creatures.attack(self, pos1, pos2, dist, range)
if not self then return end
if not pos1 or not pos2 then return end
if minetest.line_of_sight(pos1,pos2) ~= true then
return
end
if dist < range and self.attacking_timer > 0.6 then
self.attacker:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups = {fleshy=1}
})
self.attacking_timer = 0
end
end
function creatures.jump(self, pos, jump_y, timer)
if not self or not pos then return end
if self.direction ~= nil then
if self.jump_timer > timer then
self.jump_timer = 0
local p = {x=pos.x + self.direction.x,y=pos.y,z=pos.z + self.direction.z}-- pos
local n = minetest.get_node_or_nil(p)
p.y = p.y+1
local n2 = minetest.get_node_or_nil(p)
local def = nil
local def2 = nil
if n and n.name then
def = minetest.registered_items[n.name]
end
if n2 and n2.name then
def2 = minetest.registered_items[n2.name]
end
if def and def.walkable and def2 and not def2.walkable and not def.groups.fences and n.name ~= "default:fence_wood" then--
self.object:setvelocity({x=self.object:getvelocity().x,y=jump_y,z=self.object:getvelocity().z})
end
end
end
end
function creatures.follow(self, items, radius)
local current_pos = self.object:getpos()
-- seach for players
for _,object in ipairs(minetest.env:get_objects_inside_radius(current_pos, radius)) do
if object:is_player() then
local item = object:get_wielded_item()
local item_name = item:get_name()
if item and item_name and item_name ~= "" then
local quit = true
for _,food in ipairs(items) do
if food.name == item_name then
quit = false
end
end
if quit then return end
NPC = current_pos
PLAYER = object:getpos()
self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z}
self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
if PLAYER.x > NPC.x then
self.yaw = self.yaw + math.pi
end
self.yaw = self.yaw - 2
self.object:setyaw(self.yaw)
self.feeder = object
end
end
end
end
-- hostile mobs
dofile(minetest.get_modpath("creatures").."/ghost.lua")
dofile(minetest.get_modpath("creatures").."/zombie.lua")
-- friendly mobs
dofile(minetest.get_modpath("creatures").."/sheep.lua")
-- spawning
dofile(minetest.get_modpath("creatures").."/spawn.lua")
dofile(minetest.get_modpath("creatures").."/spawners.lua")
-- other stuff
dofile(minetest.get_modpath("creatures").."/items.lua")