split on_step routines into functions

This commit is contained in:
TenPlus1 2016-04-15 19:56:24 +01:00
parent e109fefc11
commit 58c757772f
3 changed files with 3658 additions and 790 deletions

558
api.lua
View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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.