Compare commits

...

5 Commits

Author SHA1 Message Date
TenPlus1 d6ff282917 localised functions, mobs floats on water only, damage_per_sec nodes hurt mobs 2017-05-27 21:29:46 +01:00
TenPlus1 ff4dfe4b4d bugfix 2017-05-27 18:36:30 +01:00
TenPlus1 646020db94 death check added, cooks drops if died in fire/lava/pick_lava 2017-05-27 10:18:21 +01:00
TenPlus1 7de8bc4c24 updated readme and version 2017-05-12 10:11:47 +01:00
TenPlus1 e814a360f6 add owner loyalty so that aggressive tamed mobs will attack player foe's 2017-05-12 10:02:42 +01:00
4 changed files with 136 additions and 78 deletions

192
api.lua
View File

@ -1,8 +1,9 @@
-- Mobs Api (27th April 2017)
-- Mobs Api (27th May 2017)
mobs = {}
mobs.mod = "redo"
mobs.version = "20170527"
-- Intllib
@ -73,7 +74,7 @@ local stuck_path_timeout = 10 -- how long will mob follow path before giving up
-- play sound
mob_sound = function(self, sound)
local mob_sound = function(self, sound)
if sound then
minetest.sound_play(sound, {
@ -86,7 +87,7 @@ end
-- attack player/mob
do_attack = function(self, player)
local do_attack = function(self, player)
if self.state == "attack" then
return
@ -102,7 +103,7 @@ end
-- move mob in facing direction
set_velocity = function(self, v)
local set_velocity = function(self, v)
local yaw = (self.object:getyaw() or 0) + self.rotate
@ -115,7 +116,7 @@ end
-- get overall speed of mob
get_velocity = function(self)
local get_velocity = function(self)
local v = self.object:getvelocity()
@ -124,7 +125,7 @@ end
-- set yaw
set_yaw = function(self, yaw)
local set_yaw = function(self, yaw)
if not yaw or yaw ~= yaw then
yaw = 0
@ -137,7 +138,7 @@ end
-- set defined animation
set_animation = function(self, anim)
local set_animation = function(self, anim)
if not self.animation then return end
@ -159,6 +160,12 @@ set_animation = function(self, anim)
end
-- above function exported for mount.lua
function mobs:set_animation(anim)
set_animation(self, anim)
end
-- this is a faster way to calculate distance
local get_distance = function(a, b)
@ -169,7 +176,7 @@ end
-- check line of sight (BrunoMine)
function line_of_sight(self, pos1, pos2, stepsize)
local line_of_sight = function(self, pos1, pos2, stepsize)
stepsize = stepsize or 1
@ -240,7 +247,7 @@ end
-- are we flying in what we are suppose to? (taikedz)
local function flight_check(self, pos_w)
local flight_check = function(self, pos_w)
local nod = self.standing_in
@ -265,7 +272,7 @@ end
-- particle effects
function effect(pos, amount, texture, min_size, max_size, radius, gravity)
local effect = function(pos, amount, texture, min_size, max_size, radius, gravity)
radius = radius or 2
min_size = min_size or 0.5
@ -291,7 +298,7 @@ end
-- update nametag colour
function update_tag(self)
local update_tag = function(self)
local col = "#00FF00"
local qua = self.hp_max / 4
@ -316,14 +323,55 @@ function update_tag(self)
end
-- check if mob is dead or only hurt
function check_for_death(self)
-- drop items
local item_drop = function(self, cooked)
-- has health actually changed?
if self.health == self.old_health then
return
local obj, item, num
local pos = self.object:getpos()
self.drops = self.drops or {} -- nil check
for n = 1, #self.drops do
if random(1, self.drops[n].chance) == 1 then
num = random(self.drops[n].min, self.drops[n].max)
item = self.drops[n].name
-- cook items when true
if cooked then
local output = minetest.get_craft_result({
method = "cooking", width = 1, items = {item}})
if output and output.item and not output.item:is_empty() then
item = output.item:get_name()
end
end
-- add item if it exists
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
if obj and obj:get_luaentity() then
obj:setvelocity({
x = random(-10, 10) / 9,
y = 6,
z = random(-10, 10) / 9,
})
else
obj:remove() -- item does not exist
end
end
end
self.drops = {}
end
-- check if mob is dead or only hurt
local check_for_death = function(self, cause)
self.old_health = self.health
-- still got some health? play hurt sound
@ -352,32 +400,16 @@ function check_for_death(self)
return false
end
-- drop items when dead
local obj
local pos = self.object:getpos()
self.drops = self.drops or {} -- nil check
for n = 1, #self.drops do
if random(1, self.drops[n].chance) == 1 then
obj = minetest.add_item(pos,
ItemStack(self.drops[n].name .. " "
.. random(self.drops[n].min, self.drops[n].max)))
if obj then
obj:setvelocity({
x = random(-10, 10) / 9,
y = 6,
z = random(-10, 10) / 9,
})
end
end
if cause == "lava" then
item_drop(self, true)
else
item_drop(self, nil)
end
mob_sound(self, self.sounds.death)
local pos = self.object:getpos()
-- execute custom death function
if self.on_die then
@ -415,7 +447,7 @@ end
-- check if within physical map limits (-30911 to 30927)
function within_limits(pos, radius)
local within_limits = function(pos, radius)
if (pos.x - radius) > -30913
and (pos.x + radius) < 30928
@ -431,7 +463,7 @@ end
-- is mob facing a cliff
local function is_at_cliff(self)
local is_at_cliff = function(self)
if self.fear_height == 0 then -- 0 for no falling protection!
return false
@ -456,7 +488,7 @@ end
-- get node but use fallback for nil or unknown
local function node_ok(pos, fallback)
local node_ok = function(pos, fallback)
fallback = fallback or "default:dirt"
@ -475,7 +507,7 @@ end
-- environmental damage (water, lava, fire, light)
do_env_damage = function(self)
local do_env_damage = function(self)
-- feed/tame text timer (so mob 'full' messages dont spam chat)
if self.htimer > 0 then
@ -511,6 +543,8 @@ do_env_damage = function(self)
self.health = self.health - self.light_damage
effect(pos, 5, "tnt_smoke.png")
if check_for_death(self, "light") then return end
end
-- what is mob standing in?
@ -539,6 +573,8 @@ do_env_damage = function(self)
effect(pos, 5, "bubble.png", nil, nil, 1, nil)
if check_for_death(self, "water") then return end
-- lava or fire
elseif self.lava_damage ~= 0
and (nodef.groups.lava
@ -549,23 +585,25 @@ do_env_damage = function(self)
effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
if check_for_death(self, "lava") then return end
-- damage_per_second node check
-- elseif minetest.registered_nodes[self.standing_in].damage_per_second ~= 0 then
elseif minetest.registered_nodes[self.standing_in].damage_per_second ~= 0 then
-- local dps = minetest.registered_nodes[self.standing_in].damage_per_second
local dps = minetest.registered_nodes[self.standing_in].damage_per_second
-- self.health = self.health - dps
self.health = self.health - dps
-- effect(pos, 5, "tnt_smoke.png")
effect(pos, 5, "tnt_smoke.png")
end
end
check_for_death(self)
check_for_death(self, "")
end
-- jump if facing a solid node (not fences or gates)
do_jump = function(self)
local do_jump = function(self)
if not self.jump
or self.jump_height == 0
@ -636,7 +674,7 @@ end
-- blast damage to entities nearby (modified from TNT mod)
function entity_physics(pos, radius)
local entity_physics = function(pos, radius)
radius = radius * 2
@ -663,7 +701,7 @@ end
-- should mob follow what I'm holding ?
function follow_holding(self, clicker)
local follow_holding = function(self, clicker)
if mobs.invis[clicker:get_player_name()] then
return false
@ -693,7 +731,7 @@ end
-- find two animals of same type and breed if nearby and horny
local function breed(self)
local breed = function(self)
-- child takes 240 seconds before growing into adult
if self.child == true then
@ -828,7 +866,7 @@ end
-- find and replace what mob is looking for (grass, wheat etc.)
function replace(self, pos)
local replace = function(self, pos)
if not self.replace_rate
or not self.replace_what
@ -871,7 +909,7 @@ end
-- check if daytime and also if mob is docile during daylight hours
function day_docile(self)
local day_docile = function(self)
if self.docile_by_day == false then
@ -887,7 +925,7 @@ end
-- path finding and smart mob routine by rnd
function smart_mobs(self, s, p, dist, dtime)
local smart_mobs = function(self, s, p, dist, dtime)
local s1 = self.path.lastpos
@ -1164,7 +1202,7 @@ local npc_attack = function(self)
if obj and obj.type == "monster" then
p = obj.object:getpos()
local p = obj.object:getpos()
dist = get_distance(p, s)
@ -1259,7 +1297,6 @@ local follow_flop = function(self)
if p.x > s.x then yaw = yaw + pi end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
-- anyone but standing npc's can move along
@ -1364,7 +1401,6 @@ local do_states = function(self, dtime)
yaw = (random(0, 360) - 180) / 180 * pi
end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
end
@ -1438,7 +1474,6 @@ local do_states = function(self, dtime)
if lp.x > s.x then yaw = yaw + pi end
-- look towards land and jump/move in that direction
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
do_jump(self)
set_velocity(self, self.walk_velocity)
@ -1458,7 +1493,6 @@ local do_states = function(self, dtime)
if lp.x > s.x then yaw = yaw + pi end
end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
-- otherwise randomly turn
@ -1466,7 +1500,6 @@ local do_states = function(self, dtime)
yaw = random() * 2 * pi
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
end
@ -1547,7 +1580,6 @@ local do_states = function(self, dtime)
if p.x > s.x then yaw = yaw + pi end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
if dist > self.reach then
@ -1708,7 +1740,6 @@ local do_states = function(self, dtime)
if p.x > s.x then yaw = yaw + pi end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
-- move towards enemy if beyond mob reach
@ -1808,7 +1839,6 @@ local do_states = function(self, dtime)
if p.x > s.x then yaw = yaw + pi end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
set_velocity(self, 0)
@ -1843,6 +1873,8 @@ local do_states = function(self, dtime)
vec.z = vec.z * (v / amount)
obj:setvelocity(vec)
else
obj:remove() -- arrow entity does not exist
end
end
end
@ -1871,7 +1903,8 @@ local falling = function(self, pos)
end
-- in water then float up
if minetest.registered_nodes[node_ok(pos).name].groups.liquid then
-- if minetest.registered_nodes[node_ok(pos).name].groups.liquid then
if minetest.registered_nodes[node_ok(pos).name].groups.water then
if self.floats == 1 then
@ -1901,7 +1934,7 @@ local falling = function(self, pos)
effect(pos, 5, "tnt_smoke.png", 1, 2, 2, nil)
if check_for_death(self) then
if check_for_death(self, "fall") then
return
end
end
@ -2025,9 +2058,15 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
-- do damage
self.health = self.health - floor(damage)
-- exit here if dead
if check_for_death(self) then
return
-- exit here if dead, special item check
if weapon:get_name() == "mobs:pick_lava" then
if check_for_death(self, "lava") then
return
end
else
if check_for_death(self, "hit") then
return
end
end
--[[ add healthy afterglow when hit (can cause hit lag with larger textures)
@ -2085,19 +2124,20 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
yaw = yaw + pi
end
-- self.object:setyaw(yaw)
yaw = set_yaw(self.object, yaw)
self.state = "runaway"
self.runaway_timer = 0
self.following = nil
end
local name = hitter:get_player_name() or ""
-- attack puncher and call other mobs for help
if self.passive == false
and self.state ~= "flop"
and self.child == false
and hitter:get_player_name() ~= self.owner
and not mobs.invis[ hitter:get_player_name() ] then
and not mobs.invis[ name ] then
-- attack whoever punched mob
self.state = ""
@ -2113,10 +2153,18 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
if obj then
-- only alert members of same mob
if obj.group_attack == true
and obj.state ~= "attack" then
and obj.state ~= "attack"
and obj.owner ~= name
and obj.name == self.name then
do_attack(obj, hitter)
end
-- have owned mobs attack player threat
if obj.owner == name and obj.owner_loyal then
do_attack(obj, self.object)
end
end
end
end
@ -2267,7 +2315,6 @@ local mob_activate = function(self, staticdata, def)
-- set anything changed above
self.object:set_properties(self)
-- self.object:setyaw((random(0, 360) - 180) / 180 * pi)
set_yaw(self.object, (random(0, 360) - 180) / 180 * pi)
update_tag(self)
end
@ -2494,6 +2541,7 @@ minetest.register_entity(name, {
dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5),
attack_animals = def.attack_animals or false,
specific_attack = def.specific_attack,
owner_loyal = def.owner_loyal,
on_blast = def.on_blast or do_tnt,

11
api.txt
View File

@ -1,5 +1,5 @@
MOB API (27th April 2017)
MOB API (12th May 2017)
The mob api is a function that can be called on by other mods to add new animals or monsters into minetest.
@ -25,6 +25,7 @@ This functions registers a new mob as a Minetest entity.
'docile_by_day' when true, mob will not attack during daylight hours unless provoked
'attacks_monsters' usually for npc's to attack monsters in area
'group_attack' true to defend same kind of mobs from attack in area
'owner_loyal' when true owned mobs will attack any monsters you punch
'attack_animals' true for monster to attack animals as well as player and npc's
'specific_attack' has a table of entity names that monsters can attack {"player", "mobs_animal:chicken"}
'hp_min' minimum health
@ -308,6 +309,14 @@ This function allows an attached player to fly the mob around using directional
'stand_animation' string containing movement animation e.g. "stand"
mobs:set_animation(self, name)
This function sets the current animation for mob, defaulting to "stand" if not found.
'self' mob information
'name' name of animation
Certain variables need to be set before using the above functions:
'self.v2' toggle switch

View File

@ -241,7 +241,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then
set_animation(entity, stand_anim)
mobs:set_animation(entity, stand_anim)
end
return
@ -249,7 +249,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- set moving animation
if moving_anim then
set_animation(entity, moving_anim)
mobs:set_animation(entity, moving_anim)
end
-- Stop!
@ -429,9 +429,9 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
-- change animation if stopped
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
set_animation(entity, stand_anim)
mobs:set_animation(entity, stand_anim)
else
-- moving animation
set_animation(entity, moving_anim)
mobs:set_animation(entity, moving_anim)
end
end

View File

@ -22,7 +22,8 @@ Lucky Blocks: 9
Changelog:
- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked
- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack
- 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code)
- 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112
- 1.32- Added new spawn check to count specific mobs AND new minetest.conf setting to chance spawn chance and numbers, added ability to protect tamed mobs