Compare commits
5 Commits
feb26ed940
...
d6ff282917
Author | SHA1 | Date |
---|---|---|
TenPlus1 | d6ff282917 | |
TenPlus1 | ff4dfe4b4d | |
TenPlus1 | 646020db94 | |
TenPlus1 | 7de8bc4c24 | |
TenPlus1 | e814a360f6 |
192
api.lua
192
api.lua
|
@ -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
11
api.txt
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue