1
0
mirror of https://codeberg.org/tenplus1/mobs_redo.git synced 2024-12-25 18:20:20 +01:00

Tweaked code

This commit is contained in:
TenPlus1 2017-01-05 19:20:37 +00:00
parent 3fb24110bc
commit 093285bec9

306
api.lua
View File

@ -1,9 +1,10 @@
-- Mobs Api (29th December 2016) -- Mobs Api (5th January 2017)
mobs = {} mobs = {}
mobs.mod = "redo" mobs.mod = "redo"
-- Intllib -- Intllib
local S local S
if minetest.get_modpath("intllib") then if minetest.get_modpath("intllib") then
@ -26,12 +27,14 @@ else
end end
mobs.intllib = S mobs.intllib = S
-- Invisibility mod check -- Invisibility mod check
mobs.invis = {} mobs.invis = {}
if rawget(_G, "invisibility") then if rawget(_G, "invisibility") then
mobs.invis = invisibility mobs.invis = invisibility
end end
-- Load settings -- Load settings
local damage_enabled = minetest.setting_getbool("enable_damage") local damage_enabled = minetest.setting_getbool("enable_damage")
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs") local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
@ -75,24 +78,34 @@ local atan = function(x)
end end
local atan2 = math.atan2 local atan2 = math.atan2
do_attack = function(self, player)
if self.state ~= "attack" then mob_sound = function(self, sound)
if random(0,100) < 90 if sound then
and self.sounds.war_cry then minetest.sound_play(sound, {
minetest.sound_play(self.sounds.war_cry, {
object = self.object, object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance max_hear_distance = self.sounds.distance
}) })
end end
end
do_attack = function(self, player)
if self.state == "attack" then
return
end
self.state = "attack"
self.attack = player self.attack = player
self.state = "attack"
if random(0, 100) < 90 then
mob_sound(self, self.sounds.war_cry)
end end
end end
set_velocity = function(self, v) set_velocity = function(self, v)
local yaw = self.object:getyaw() + self.rotate or 0 local yaw = self.object:getyaw() + self.rotate or 0
@ -104,6 +117,7 @@ set_velocity = function(self, v)
}) })
end end
get_velocity = function(self) get_velocity = function(self)
local v = self.object:getvelocity() local v = self.object:getvelocity()
@ -111,6 +125,21 @@ get_velocity = function(self)
return (v.x * v.x + v.z * v.z) ^ 0.5 return (v.x * v.x + v.z * v.z) ^ 0.5
end end
set_anim = function(self, anim_start, anim_end, anim_speed, anim_name)
if not anim_start or not anim_end then
return
end
self.object:set_animation(
{x = anim_start, y = anim_end},
anim_speed or 15, 0)
self.animation.current = anim_name
end
set_animation = function(self, type) set_animation = function(self, type)
if not self.animation then if not self.animation then
@ -119,105 +148,58 @@ set_animation = function(self, type)
self.animation.current = self.animation.current or "" self.animation.current = self.animation.current or ""
self.animation.speed_normal = self.animation.speed_normal or 15 if type == "stand" and self.animation.current ~= "stand" then
if type == "stand" set_anim(self,
and self.animation.current ~= "stand" then self.animation.stand_start,
self.animation.stand_end,
self.animation.speed_stand, "stand")
if self.animation.stand_start elseif type == "walk" and self.animation.current ~= "walk" then
and self.animation.stand_end then
self.object:set_animation({ set_anim(self,
x = self.animation.stand_start, self.animation.walk_start,
y = self.animation.stand_end}, self.animation.walk_end,
(self.animation.speed_stand or self.animation.speed_normal), 0) self.animation.speed_walk, "walk")
self.animation.current = "stand" elseif type == "run" and self.animation.current ~= "run" then
end
elseif type == "walk" set_anim(self,
and self.animation.current ~= "walk" then self.animation.run_start,
self.animation.run_end,
self.animation.speed_run, "run")
if self.animation.walk_start elseif type == "punch" and self.animation.current ~= "punch" then
and self.animation.walk_end then
self.object:set_animation({ set_anim(self,
x = self.animation.walk_start, self.animation.punch_start,
y = self.animation.walk_end}, self.animation.punch_end,
(self.animation.speed_walk or self.animation.speed_normal), 0) self.animation.speed_punch, "punch")
self.animation.current = "walk" elseif type == "punch2" and self.animation.current ~= "punch2" then
end
elseif type == "run" set_anim(self,
and self.animation.current ~= "run" then self.animation.punch2_start,
self.animation.punch2_end,
self.animation.speed_punch2, "punch2")
if self.animation.run_start elseif type == "shoot" and self.animation.current ~= "shoot" then
and self.animation.run_end then
self.object:set_animation({ set_anim(self,
x = self.animation.run_start, self.animation.shoot_start,
y = self.animation.run_end}, self.animation.shoot_end,
(self.animation.speed_run or self.animation.speed_normal), 0) self.animation.speed_shoot, "shoot")
self.animation.current = "run" elseif type == "die" and self.animation.current ~= "die" then
end
elseif type == "punch" set_anim(self,
and self.animation.current ~= "punch" then self.animation.die_start,
self.animation.die_end,
if self.animation.punch_start self.animation.speed_die, "die")
and self.animation.punch_end then
self.object:set_animation({
x = self.animation.punch_start,
y = self.animation.punch_end},
(self.animation.speed_punch or self.animation.speed_normal), 0)
self.animation.current = "punch"
end
elseif type == "punch2"
and self.animation.current ~= "punch2" then
if self.animation.punch2_start
and self.animation.punch2_end then
self.object:set_animation({
x = self.animation.punch2_start,
y = self.animation.punch2_end},
(self.animation.speed_punch2 or self.animation.speed_normal), 0)
self.animation.current = "punch2"
end
elseif type == "shoot"
and self.animation.current ~= "shoot" then
if self.animation.shoot_start
and self.animation.shoot_end then
self.object:set_animation({
x = self.animation.shoot_start,
y = self.animation.shoot_end},
(self.animation.speed_shoot or self.animation.speed_normal), 0)
self.animation.current = "shoot"
end
elseif type == "die"
and self.animation.current ~= "die" then
if self.animation.die_start
and self.animation.die_end then
self.object:set_animation({
x = self.animation.die_start,
y = self.animation.die_end},
(self.animation.speed_die or self.animation.speed_normal), 0)
self.animation.current = "die"
end
end end
end end
-- check line of sight for walkers and swimmers alike -- check line of sight for walkers and swimmers alike
function line_of_sight_water(self, pos1, pos2, stepsize) function line_of_sight_water(self, pos1, pos2, stepsize)
@ -257,6 +239,7 @@ function line_of_sight_water(self, pos1, pos2, stepsize)
end end
-- particle effects -- particle effects
function effect(pos, amount, texture, min_size, max_size, radius, gravity) function effect(pos, amount, texture, min_size, max_size, radius, gravity)
@ -282,6 +265,7 @@ function effect(pos, amount, texture, min_size, max_size, radius, gravity)
}) })
end end
-- update nametag colour -- update nametag colour
function update_tag(self) function update_tag(self)
@ -307,6 +291,7 @@ function update_tag(self)
end end
-- check if mob is dead or only hurt -- check if mob is dead or only hurt
function check_for_death(self) function check_for_death(self)
@ -320,14 +305,7 @@ function check_for_death(self)
-- still got some health? play hurt sound -- still got some health? play hurt sound
if self.health > 0 then if self.health > 0 then
if self.sounds.damage then mob_sound(self, self.sounds.damage)
minetest.sound_play(self.sounds.damage, {
object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance
})
end
-- make sure health isn't higher than max -- make sure health isn't higher than max
if self.health > self.hp_max then if self.health > self.hp_max then
@ -338,13 +316,15 @@ function check_for_death(self)
if not self.nametag2 then if not self.nametag2 then
self.nametag2 = self.nametag or "" self.nametag2 = self.nametag or ""
end end
if show_health then
self.htimer = 2
if show_health then
self.htimer = 2
self.nametag = "health: " .. self.health .. " of " .. self.hp_max self.nametag = "health: " .. self.health .. " of " .. self.hp_max
update_tag(self) update_tag(self)
end end
return false return false
end end
@ -371,15 +351,7 @@ end
end end
end end
-- play death sound mob_sound(self, self.sounds.death)
if self.sounds.death then
minetest.sound_play(self.sounds.death, {
object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance
})
end
-- execute custom death function -- execute custom death function
if self.on_die then if self.on_die then
@ -416,6 +388,7 @@ end
return true return true
end end
-- check if within physical map limits (-30911 to 30927) -- check if within physical map limits (-30911 to 30927)
function within_limits(pos, radius) function within_limits(pos, radius)
@ -431,6 +404,7 @@ function within_limits(pos, radius)
return false -- beyond limits return false -- beyond limits
end end
-- is mob facing a cliff -- is mob facing a cliff
local function is_at_cliff(self) local function is_at_cliff(self)
@ -455,6 +429,7 @@ local function is_at_cliff(self)
return false return false
end end
-- get node but use fallback for nil or unknown -- get node but use fallback for nil or unknown
local function node_ok(pos, fallback) local function node_ok(pos, fallback)
@ -473,6 +448,7 @@ local function node_ok(pos, fallback)
return minetest.registered_nodes[fallback] return minetest.registered_nodes[fallback]
end end
-- environmental damage (water, lava, fire, light) -- environmental damage (water, lava, fire, light)
do_env_damage = function(self) do_env_damage = function(self)
@ -554,6 +530,7 @@ do_env_damage = function(self)
check_for_death(self) check_for_death(self)
end end
-- jump if facing a solid node (not fences or gates) -- jump if facing a solid node (not fences or gates)
do_jump = function(self) do_jump = function(self)
@ -605,17 +582,11 @@ do_jump = function(self)
self.object:setvelocity(v) self.object:setvelocity(v)
if self.sounds.jump then mob_sound(self, self.sounds.jump)
minetest.sound_play(self.sounds.jump, {
object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance
})
end
end end
end end
-- this is a faster way to calculate distance -- this is a faster way to calculate distance
local get_distance = function(a, b) local get_distance = function(a, b)
@ -624,6 +595,7 @@ local get_distance = function(a, b)
return square(x * x + y * y + z * z) return square(x * x + y * y + z * z)
end end
-- blast damage to entities nearby (modified from TNT mod) -- blast damage to entities nearby (modified from TNT mod)
function entity_physics(pos, radius) function entity_physics(pos, radius)
@ -656,6 +628,7 @@ function entity_physics(pos, radius)
end end
end end
-- should mob follow what I'm holding ? -- should mob follow what I'm holding ?
function follow_holding(self, clicker) function follow_holding(self, clicker)
@ -685,6 +658,7 @@ function follow_holding(self, clicker)
return false return false
end end
-- find two animals of same type and breed if nearby and horny -- find two animals of same type and breed if nearby and horny
local function breed(self) local function breed(self)
@ -819,6 +793,7 @@ local function breed(self)
end end
end end
-- find and replace what mob is looking for (grass, wheat etc.) -- find and replace what mob is looking for (grass, wheat etc.)
function replace(self, pos) function replace(self, pos)
@ -848,6 +823,7 @@ function replace(self, pos)
end end
end end
-- check if daytime and also if mob is docile during daylight hours -- check if daytime and also if mob is docile during daylight hours
function day_docile(self) function day_docile(self)
@ -863,6 +839,7 @@ function day_docile(self)
end end
end end
-- path finding and smart mob routine by rnd -- path finding and smart mob routine by rnd
function smart_mobs(self, s, p, dist, dtime) function smart_mobs(self, s, p, dist, dtime)
@ -992,33 +969,20 @@ function smart_mobs(self, s, p, dist, dtime)
self.path.stuck_timer = stuck_timeout - 2 self.path.stuck_timer = stuck_timeout - 2
-- frustration! cant find the damn path :( -- frustration! cant find the damn path :(
if self.sounds.random then mob_sound(self, self.sounds.random)
minetest.sound_play(self.sounds.random, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
else else
-- yay i found path -- yay i found path
if self.sounds.attack then mob_sound(self, self.sounds.attack)
set_velocity(self, self.walk_velocity) set_velocity(self, self.walk_velocity)
minetest.sound_play(self.sounds.attack, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
-- follow path now that it has it -- follow path now that it has it
self.path.following = true self.path.following = true
end end
end end
end end
-- specific attacks -- specific attacks
local specific_attack = function(list, what) local specific_attack = function(list, what)
@ -1038,6 +1002,7 @@ local specific_attack = function(list, what)
return false return false
end end
-- monster find someone to attack -- monster find someone to attack
local monster_attack = function(self) local monster_attack = function(self)
@ -1111,6 +1076,7 @@ local monster_attack = function(self)
end end
end end
-- npc, find closest monster to attack -- npc, find closest monster to attack
local npc_attack = function(self) local npc_attack = function(self)
@ -1148,6 +1114,7 @@ local npc_attack = function(self)
end end
end end
-- follow player if owner or holding item, if fish outta water then flop -- follow player if owner or holding item, if fish outta water then flop
local follow_flop = function(self) local follow_flop = function(self)
@ -1267,6 +1234,7 @@ local follow_flop = function(self)
end end
end end
-- dogshoot attack switch and counter function -- dogshoot attack switch and counter function
local dogswitch = function(self, dtime) local dogswitch = function(self, dtime)
@ -1292,6 +1260,7 @@ local dogswitch = function(self, dtime)
return self.dogshoot_switch return self.dogshoot_switch
end end
-- execute current state (stand, walk, run, attacks) -- execute current state (stand, walk, run, attacks)
local do_states = function(self, dtime) local do_states = function(self, dtime)
@ -1552,14 +1521,7 @@ local do_states = function(self, dtime)
if minetest.find_node_near(pos, 1, {"group:water"}) if minetest.find_node_near(pos, 1, {"group:water"})
or minetest.is_protected(pos, "") then or minetest.is_protected(pos, "") then
if self.sounds.explode then mob_sound(self, self.sounds.explode)
minetest.sound_play(self.sounds.explode, {
object = self.object,
gain = 1.0,
max_hear_distance = 16
})
end
self.object:remove() self.object:remove()
@ -1733,13 +1695,7 @@ local do_states = function(self, dtime)
if line_of_sight_water(self, p2, s2) == true then if line_of_sight_water(self, p2, s2) == true then
-- play attack sound -- play attack sound
if self.sounds.attack then mob_sound(self, self.sounds.attack)
minetest.sound_play(self.sounds.attack, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
-- punch player (or what player is attached to) -- punch player (or what player is attached to)
local attached = self.attack:get_attach() local attached = self.attack:get_attach()
@ -1791,13 +1747,7 @@ local do_states = function(self, dtime)
set_animation(self, "shoot") set_animation(self, "shoot")
-- play shoot attack sound -- play shoot attack sound
if self.sounds.shoot_attack then mob_sound(self, self.sounds.shoot_attack)
minetest.sound_play(self.sounds.shoot_attack, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
local p = self.object:getpos() local p = self.object:getpos()
@ -1822,6 +1772,7 @@ local do_states = function(self, dtime)
end end
end end
-- falling and fall damage -- falling and fall damage
local falling = function(self, pos) local falling = function(self, pos)
@ -1883,6 +1834,7 @@ local falling = function(self, pos)
end end
end end
local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
-- error checking when mod profiling is enabled -- error checking when mod profiling is enabled
@ -1957,8 +1909,8 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
hitter:set_wielded_item(weapon) hitter:set_wielded_item(weapon)
end end
-- only play hit sound and show blood effects if damage is 1 or over -- only play hit sound and show blood effects if damage is 1 or over
if damage >= 1 then if damage >= 1 then
-- weapon sounds -- weapon sounds
if weapon:get_definition().sounds ~= nil then if weapon:get_definition().sounds ~= nil then
@ -2030,8 +1982,7 @@ if damage >= 1 then
self.pause_timer = r self.pause_timer = r
end end
end -- END if damage
end -- END if damage
-- if skittish then run away -- if skittish then run away
if self.runaway == true then if self.runaway == true then
@ -2087,6 +2038,7 @@ end -- END if damage
end end
end end
local mob_activate = function(self, staticdata, dtime_s, def) local mob_activate = function(self, staticdata, dtime_s, def)
-- remove monsters in peaceful mode, or when no data -- remove monsters in peaceful mode, or when no data
@ -2186,6 +2138,7 @@ local mob_activate = function(self, staticdata, dtime_s, def)
update_tag(self) update_tag(self)
end end
local mob_step = function(self, dtime) local mob_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
@ -2270,13 +2223,8 @@ local mob_step = function(self, dtime)
replace(self, pos) replace(self, pos)
-- mob plays random sound at times -- mob plays random sound at times
if self.sounds.random if random(1, 100) == 1 then
and random(1, 100) == 1 then mob_sound(self, self.sounds.random)
minetest.sound_play(self.sounds.random, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end end
-- environmental damage timer (every 1 second) -- environmental damage timer (every 1 second)
@ -2302,6 +2250,7 @@ local mob_step = function(self, dtime)
end end
-- default function when mobs are blown up with TNT -- default function when mobs are blown up with TNT
local do_tnt = function(obj, damage) local do_tnt = function(obj, damage)
@ -2315,6 +2264,7 @@ local do_tnt = function(obj, damage)
return false, true, {} return false, true, {}
end end
mobs.spawning_mobs = {} mobs.spawning_mobs = {}
-- register mob function -- register mob function
@ -2466,6 +2416,7 @@ minetest.register_entity(name, {
end -- END mobs:register_mob function end -- END mobs:register_mob function
-- count how many mobs of one type are inside an area -- count how many mobs of one type are inside an area
local count_mobs = function(pos, type) local count_mobs = function(pos, type)
@ -2488,6 +2439,7 @@ local count_mobs = function(pos, type)
return num return num
end end
-- global functions -- global functions
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
@ -2626,6 +2578,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
}) })
end end
-- compatibility with older mob registration -- compatibility with older mob registration
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
@ -2633,6 +2586,7 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_o
chance, active_object_count, -31000, max_height, day_toggle) chance, active_object_count, -31000, max_height, day_toggle)
end end
-- MarkBu's spawn function -- MarkBu's spawn function
function mobs:spawn(def) function mobs:spawn(def)
@ -2653,6 +2607,7 @@ function mobs:spawn(def)
chance, active_object_count, min_height, max_height, day_toggle, on_spawn) chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
end end
-- set content id's -- set content id's
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore") local c_ignore = minetest.get_content_id("ignore")
@ -2746,6 +2701,7 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
end end
end end
-- register arrow for shoot attack -- register arrow for shoot attack
function mobs:register_arrow(name, def) function mobs:register_arrow(name, def)
@ -2871,6 +2827,7 @@ function mobs:register_arrow(name, def)
}) })
end end
-- Spawn Egg -- Spawn Egg
function mobs:register_egg(mob, desc, background, addegg, no_creative) function mobs:register_egg(mob, desc, background, addegg, no_creative)
@ -2929,6 +2886,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
}) })
end end
-- capture critter (thanks to blert2112 for idea) -- capture critter (thanks to blert2112 for idea)
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
@ -3006,6 +2964,7 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
end end
end end
-- protect tamed mob with rune iten -- protect tamed mob with rune iten
function mobs:protect(self, clicker) function mobs:protect(self, clicker)
@ -3032,6 +2991,7 @@ function mobs:protect(self, clicker)
return false return false
end end
local mob_obj = {} local mob_obj = {}
local mob_sta = {} local mob_sta = {}
@ -3112,13 +3072,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
end end
-- make sound when fed so many times -- make sound when fed so many times
if self.sounds.random then mob_sound(self, self.sounds.random)
minetest.sound_play(self.sounds.random, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
end end
return true return true
@ -3150,6 +3104,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
end end
-- inspired by blockmen's nametag mod -- inspired by blockmen's nametag mod
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
@ -3185,6 +3140,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end) end)
-- compatibility function for old entities to new modpack entities -- compatibility function for old entities to new modpack entities
function mobs:alias_mob(old_name, new_name) function mobs:alias_mob(old_name, new_name)