mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2024-12-25 02:00:21 +01:00
split on_step routines into functions
This commit is contained in:
parent
e109fefc11
commit
58c757772f
558
api.lua
558
api.lua
@ -882,258 +882,20 @@ function smart_mobs(self, s, p, dist, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
mobs.spawning_mobs = {}
|
||||
|
||||
-- register mob function
|
||||
function mobs:register_mob(name, def)
|
||||
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
minetest.register_entity(name, {
|
||||
|
||||
stepheight = def.stepheight or 0.6,
|
||||
name = name,
|
||||
type = def.type,
|
||||
attack_type = def.attack_type,
|
||||
fly = def.fly,
|
||||
fly_in = def.fly_in or "air",
|
||||
owner = def.owner or "",
|
||||
order = def.order or "",
|
||||
on_die = def.on_die,
|
||||
do_custom = def.do_custom,
|
||||
jump_height = def.jump_height or 6,
|
||||
jump_chance = def.jump_chance or 0,
|
||||
drawtype = def.drawtype, -- DEPRECATED, use rotate instead
|
||||
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
|
||||
lifetimer = def.lifetimer or 180, -- 3 minutes
|
||||
hp_min = def.hp_min or 5,
|
||||
hp_max = def.hp_max or 10,
|
||||
physical = true,
|
||||
collisionbox = def.collisionbox,
|
||||
visual = def.visual,
|
||||
visual_size = def.visual_size or {x = 1, y = 1},
|
||||
mesh = def.mesh,
|
||||
makes_footstep_sound = def.makes_footstep_sound or false,
|
||||
view_range = def.view_range or 5,
|
||||
walk_velocity = def.walk_velocity or 1,
|
||||
run_velocity = def.run_velocity or 2,
|
||||
damage = def.damage or 0,
|
||||
light_damage = def.light_damage or 0,
|
||||
water_damage = def.water_damage or 0,
|
||||
lava_damage = def.lava_damage or 0,
|
||||
fall_damage = def.fall_damage or 1,
|
||||
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)
|
||||
drops = def.drops or {},
|
||||
armor = def.armor,
|
||||
on_rightclick = def.on_rightclick,
|
||||
arrow = def.arrow,
|
||||
shoot_interval = def.shoot_interval,
|
||||
sounds = def.sounds or {},
|
||||
animation = def.animation,
|
||||
follow = def.follow,
|
||||
jump = def.jump or true,
|
||||
walk_chance = def.walk_chance or 50,
|
||||
attacks_monsters = def.attacks_monsters or false,
|
||||
group_attack = def.group_attack or false,
|
||||
--fov = def.fov or 120,
|
||||
passive = def.passive or false,
|
||||
recovery_time = def.recovery_time or 0.5,
|
||||
knock_back = def.knock_back or 3,
|
||||
blood_amount = def.blood_amount or 5,
|
||||
blood_texture = def.blood_texture or "mobs_blood.png",
|
||||
shoot_offset = def.shoot_offset or 0,
|
||||
floats = def.floats or 1, -- floats in water by default
|
||||
replace_rate = def.replace_rate,
|
||||
replace_what = def.replace_what,
|
||||
replace_with = def.replace_with,
|
||||
replace_offset = def.replace_offset or 0,
|
||||
timer = 0,
|
||||
env_damage_timer = 0, -- only used when state = "attack"
|
||||
tamed = false,
|
||||
pause_timer = 0,
|
||||
horny = false,
|
||||
hornytimer = 0,
|
||||
child = false,
|
||||
gotten = false,
|
||||
health = 0,
|
||||
reach = def.reach or 3,
|
||||
htimer = 0,
|
||||
child_texture = def.child_texture,
|
||||
docile_by_day = def.docile_by_day or false,
|
||||
time_of_day = 0.5,
|
||||
fear_height = def.fear_height or 0,
|
||||
runaway = def.runaway,
|
||||
runaway_timer = 0,
|
||||
pathfinding = def.pathfinding,
|
||||
immune_to = def.immune_to or {},
|
||||
explosion_radius = def.explosion_radius,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
local pos = self.object:getpos()
|
||||
local yaw = self.object:getyaw() or 0
|
||||
|
||||
-- when lifetimer expires remove mob (except npc and tamed)
|
||||
if self.type ~= "npc"
|
||||
and not self.tamed
|
||||
and self.state ~= "attack" then
|
||||
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
|
||||
if self.lifetimer <= 0 then
|
||||
|
||||
-- only despawn away from player
|
||||
local objs = minetest.get_objects_inside_radius(pos, 10)
|
||||
|
||||
for _,oir in pairs(objs) do
|
||||
|
||||
if oir:is_player() then
|
||||
|
||||
self.lifetimer = 20
|
||||
-- monster find someone to attack
|
||||
local monster_attack = function(self)
|
||||
|
||||
if self.type ~= "monster"
|
||||
or not damage_enabled
|
||||
or self.state == "attack"
|
||||
or day_docile(self) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
minetest.log("action",
|
||||
"lifetimer expired, removed " .. self.name)
|
||||
|
||||
effect(pos, 15, "tnt_smoke.png")
|
||||
|
||||
self.object:remove()
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if not self.fly then
|
||||
|
||||
-- floating in water (or falling)
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
-- going up then apply gravity
|
||||
if v.y > 0.1 then
|
||||
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = self.fall_speed,
|
||||
z = 0
|
||||
})
|
||||
end
|
||||
|
||||
-- in water then float up
|
||||
if minetest.registered_nodes[node_ok(pos).name].groups.liquid then -- water then
|
||||
|
||||
if self.floats == 1 then
|
||||
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||
z = 0
|
||||
})
|
||||
end
|
||||
else
|
||||
-- fall downwards
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = self.fall_speed,
|
||||
z = 0
|
||||
})
|
||||
|
||||
-- fall damage
|
||||
if self.fall_damage == 1
|
||||
and self.object:getvelocity().y == 0 then
|
||||
|
||||
local d = self.old_y - self.object:getpos().y
|
||||
|
||||
if d > 5 then
|
||||
|
||||
--self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
||||
self.health = self.health - math.floor(d - 5)
|
||||
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
|
||||
if check_for_death(self) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.old_y = self.object:getpos().y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- knockback timer
|
||||
if self.pause_timer > 0 then
|
||||
|
||||
self.pause_timer = self.pause_timer - dtime
|
||||
|
||||
if self.pause_timer < 1 then
|
||||
self.pause_timer = 0
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- attack timer
|
||||
self.timer = self.timer + dtime
|
||||
|
||||
if self.state ~= "attack" then
|
||||
|
||||
if self.timer < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
self.timer = 0
|
||||
end
|
||||
|
||||
-- never go over 100
|
||||
if self.timer > 100 then
|
||||
self.timer = 1
|
||||
end
|
||||
|
||||
-- node replace check (cow eats grass etc.)
|
||||
replace(self, pos)
|
||||
|
||||
-- mob plays random sound at times
|
||||
if self.sounds.random
|
||||
and math.random(1, 100) == 1 then
|
||||
|
||||
minetest.sound_play(self.sounds.random, {
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
end
|
||||
|
||||
-- environmental damage timer (every 1 second)
|
||||
self.env_damage_timer = self.env_damage_timer + dtime
|
||||
|
||||
if (self.state == "attack" and self.env_damage_timer > 1)
|
||||
or self.state ~= "attack" then
|
||||
|
||||
self.env_damage_timer = 0
|
||||
|
||||
do_env_damage(self)
|
||||
|
||||
-- custom function (defined in mob lua file)
|
||||
if self.do_custom then
|
||||
self.do_custom(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- find someone to attack
|
||||
if self.type == "monster"
|
||||
and damage_enabled
|
||||
and self.state ~= "attack"
|
||||
and not day_docile(self) then
|
||||
|
||||
local s = self.object:getpos()
|
||||
local p, sp, dist
|
||||
local player = nil
|
||||
local type = nil
|
||||
local obj = nil
|
||||
local player, type, obj, min_player = nil, nil, nil, nil
|
||||
local min_dist = self.view_range + 1
|
||||
local min_player = nil
|
||||
|
||||
for _,oir in pairs(minetest.get_objects_inside_radius(s, self.view_range)) do
|
||||
|
||||
@ -1181,18 +943,20 @@ minetest.register_entity(name, {
|
||||
if min_player then
|
||||
do_attack(self, min_player)
|
||||
end
|
||||
end
|
||||
|
||||
-- npc, find closest monster to attack
|
||||
local npc_attack = function(self)
|
||||
|
||||
if self.type ~= "npc"
|
||||
or not self.attacks_monsters
|
||||
or self.state == "attack" then
|
||||
return
|
||||
end
|
||||
|
||||
-- npc, find closest monster to attack
|
||||
local min_dist = self.view_range + 1
|
||||
local min_player = nil
|
||||
|
||||
if self.type == "npc"
|
||||
and self.attacks_monsters
|
||||
and self.state ~= "attack" then
|
||||
|
||||
local s = self.object:getpos()
|
||||
local obj = nil
|
||||
local min_dist = self.view_range + 1
|
||||
local obj, min_player = nil, nil
|
||||
|
||||
for _, oir in pairs(minetest.get_objects_inside_radius(s, self.view_range)) do
|
||||
|
||||
@ -1201,7 +965,6 @@ minetest.register_entity(name, {
|
||||
if obj
|
||||
and obj.type == "monster" then
|
||||
|
||||
-- attack monster
|
||||
p = obj.object:getpos()
|
||||
|
||||
dist = get_distance(p, s)
|
||||
@ -1216,10 +979,10 @@ minetest.register_entity(name, {
|
||||
if min_player then
|
||||
do_attack(self, min_player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- breed and grow children
|
||||
breed(self)
|
||||
-- follow player if owner or holding item, if fish outta water then flop
|
||||
local follow_flop = function(self)
|
||||
|
||||
-- find player to follow
|
||||
if (self.follow ~= ""
|
||||
@ -1345,6 +1108,10 @@ minetest.register_entity(name, {
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- execute current state (stand, walk, run, attacks)
|
||||
local do_states = function(self, dtime)
|
||||
|
||||
if self.state == "stand" then
|
||||
|
||||
@ -1851,11 +1618,72 @@ minetest.register_entity(name, {
|
||||
obj:setvelocity(vec)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end -- END if self.state == "attack"
|
||||
end,
|
||||
-- falling and fall damag
|
||||
local falling = function(self, pos)
|
||||
|
||||
on_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
if self.fly then
|
||||
return
|
||||
end
|
||||
|
||||
-- floating in water (or falling)
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
-- going up then apply gravity
|
||||
if v.y > 0.1 then
|
||||
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = self.fall_speed,
|
||||
z = 0
|
||||
})
|
||||
end
|
||||
|
||||
-- in water then float up
|
||||
if minetest.registered_nodes[node_ok(pos).name].groups.liquid then -- water then
|
||||
|
||||
if self.floats == 1 then
|
||||
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||
z = 0
|
||||
})
|
||||
end
|
||||
else
|
||||
-- fall downwards
|
||||
self.object:setacceleration({
|
||||
x = 0,
|
||||
y = self.fall_speed,
|
||||
z = 0
|
||||
})
|
||||
|
||||
-- fall damage
|
||||
if self.fall_damage == 1
|
||||
and self.object:getvelocity().y == 0 then
|
||||
|
||||
local d = self.old_y - self.object:getpos().y
|
||||
|
||||
if d > 5 then
|
||||
|
||||
--self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
||||
self.health = self.health - math.floor(d - 5)
|
||||
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
|
||||
if check_for_death(self) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.old_y = self.object:getpos().y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
|
||||
-- direction error check
|
||||
dir = dir or {x = 0, y = 0, z = 0}
|
||||
@ -1892,7 +1720,9 @@ minetest.register_entity(name, {
|
||||
for _, no in pairs(self.immune_to) do
|
||||
|
||||
if no[1] == weapon:get_name() then
|
||||
|
||||
damage = no[2] or 0
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
@ -2034,9 +1864,9 @@ minetest.register_entity(name, {
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
end
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
local mob_activate = function(self, staticdata, dtime_s, def)
|
||||
|
||||
-- remove monsters in peaceful mode, or when no data
|
||||
if (self.type == "monster" and peaceful_only)
|
||||
@ -2133,6 +1963,208 @@ minetest.register_entity(name, {
|
||||
-- set anything changed above
|
||||
self.object:set_properties(self)
|
||||
update_tag(self)
|
||||
end
|
||||
|
||||
mobs.spawning_mobs = {}
|
||||
|
||||
-- register mob function
|
||||
function mobs:register_mob(name, def)
|
||||
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
minetest.register_entity(name, {
|
||||
|
||||
stepheight = def.stepheight or 0.6,
|
||||
name = name,
|
||||
type = def.type,
|
||||
attack_type = def.attack_type,
|
||||
fly = def.fly,
|
||||
fly_in = def.fly_in or "air",
|
||||
owner = def.owner or "",
|
||||
order = def.order or "",
|
||||
on_die = def.on_die,
|
||||
do_custom = def.do_custom,
|
||||
jump_height = def.jump_height or 6,
|
||||
jump_chance = def.jump_chance or 0,
|
||||
drawtype = def.drawtype, -- DEPRECATED, use rotate instead
|
||||
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
|
||||
lifetimer = def.lifetimer or 180, -- 3 minutes
|
||||
hp_min = def.hp_min or 5,
|
||||
hp_max = def.hp_max or 10,
|
||||
physical = true,
|
||||
collisionbox = def.collisionbox,
|
||||
visual = def.visual,
|
||||
visual_size = def.visual_size or {x = 1, y = 1},
|
||||
mesh = def.mesh,
|
||||
makes_footstep_sound = def.makes_footstep_sound or false,
|
||||
view_range = def.view_range or 5,
|
||||
walk_velocity = def.walk_velocity or 1,
|
||||
run_velocity = def.run_velocity or 2,
|
||||
damage = def.damage or 0,
|
||||
light_damage = def.light_damage or 0,
|
||||
water_damage = def.water_damage or 0,
|
||||
lava_damage = def.lava_damage or 0,
|
||||
fall_damage = def.fall_damage or 1,
|
||||
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)
|
||||
drops = def.drops or {},
|
||||
armor = def.armor,
|
||||
on_rightclick = def.on_rightclick,
|
||||
arrow = def.arrow,
|
||||
shoot_interval = def.shoot_interval,
|
||||
sounds = def.sounds or {},
|
||||
animation = def.animation,
|
||||
follow = def.follow,
|
||||
jump = def.jump or true,
|
||||
walk_chance = def.walk_chance or 50,
|
||||
attacks_monsters = def.attacks_monsters or false,
|
||||
group_attack = def.group_attack or false,
|
||||
--fov = def.fov or 120,
|
||||
passive = def.passive or false,
|
||||
recovery_time = def.recovery_time or 0.5,
|
||||
knock_back = def.knock_back or 3,
|
||||
blood_amount = def.blood_amount or 5,
|
||||
blood_texture = def.blood_texture or "mobs_blood.png",
|
||||
shoot_offset = def.shoot_offset or 0,
|
||||
floats = def.floats or 1, -- floats in water by default
|
||||
replace_rate = def.replace_rate,
|
||||
replace_what = def.replace_what,
|
||||
replace_with = def.replace_with,
|
||||
replace_offset = def.replace_offset or 0,
|
||||
timer = 0,
|
||||
env_damage_timer = 0, -- only used when state = "attack"
|
||||
tamed = false,
|
||||
pause_timer = 0,
|
||||
horny = false,
|
||||
hornytimer = 0,
|
||||
child = false,
|
||||
gotten = false,
|
||||
health = 0,
|
||||
reach = def.reach or 3,
|
||||
htimer = 0,
|
||||
child_texture = def.child_texture,
|
||||
docile_by_day = def.docile_by_day or false,
|
||||
time_of_day = 0.5,
|
||||
fear_height = def.fear_height or 0,
|
||||
runaway = def.runaway,
|
||||
runaway_timer = 0,
|
||||
pathfinding = def.pathfinding,
|
||||
immune_to = def.immune_to or {},
|
||||
explosion_radius = def.explosion_radius,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
local pos = self.object:getpos()
|
||||
local yaw = self.object:getyaw() or 0
|
||||
|
||||
-- when lifetimer expires remove mob (except npc and tamed)
|
||||
if self.type ~= "npc"
|
||||
and not self.tamed
|
||||
and self.state ~= "attack" then
|
||||
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
|
||||
if self.lifetimer <= 0 then
|
||||
|
||||
-- only despawn away from player
|
||||
local objs = minetest.get_objects_inside_radius(pos, 10)
|
||||
|
||||
for _,oir in pairs(objs) do
|
||||
|
||||
if oir:is_player() then
|
||||
|
||||
self.lifetimer = 20
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
minetest.log("action",
|
||||
"lifetimer expired, removed " .. self.name)
|
||||
|
||||
effect(pos, 15, "tnt_smoke.png")
|
||||
|
||||
self.object:remove()
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
falling(self, pos)
|
||||
|
||||
-- knockback timer
|
||||
if self.pause_timer > 0 then
|
||||
|
||||
self.pause_timer = self.pause_timer - dtime
|
||||
|
||||
if self.pause_timer < 1 then
|
||||
self.pause_timer = 0
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- attack timer
|
||||
self.timer = self.timer + dtime
|
||||
|
||||
if self.state ~= "attack" then
|
||||
|
||||
if self.timer < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
self.timer = 0
|
||||
end
|
||||
|
||||
-- never go over 100
|
||||
if self.timer > 100 then
|
||||
self.timer = 1
|
||||
end
|
||||
|
||||
-- node replace check (cow eats grass etc.)
|
||||
replace(self, pos)
|
||||
|
||||
-- mob plays random sound at times
|
||||
if self.sounds.random
|
||||
and math.random(1, 100) == 1 then
|
||||
|
||||
minetest.sound_play(self.sounds.random, {
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
end
|
||||
|
||||
-- environmental damage timer (every 1 second)
|
||||
self.env_damage_timer = self.env_damage_timer + dtime
|
||||
|
||||
if (self.state == "attack" and self.env_damage_timer > 1)
|
||||
or self.state ~= "attack" then
|
||||
|
||||
self.env_damage_timer = 0
|
||||
|
||||
do_env_damage(self)
|
||||
|
||||
-- custom function (defined in mob lua file)
|
||||
if self.do_custom then
|
||||
self.do_custom(self)
|
||||
end
|
||||
end
|
||||
|
||||
monster_attack(self)
|
||||
|
||||
npc_attack(self)
|
||||
|
||||
breed(self)
|
||||
|
||||
follow_flop(self)
|
||||
|
||||
do_states(self, dtime)
|
||||
|
||||
end,
|
||||
|
||||
on_punch = mob_punch,
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
mob_activate(self, staticdata, dtime_s, def)
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
|
2836
api_old.lua
Normal file
2836
api_old.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,4 +20,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Above license is for Krupnov Pavel's animals inside of mod, the rest is WTFPL.
|
||||
Above license is for Krupnov Pavel's animals, the rest is WTFPL.
|
Loading…
Reference in New Issue
Block a user