mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2024-11-15 23:10:31 +01:00
[mobs] Update (tidy code)
- Put back calc_velocity - Update mobs mod - Change the way chicken drop eggs (use throwing-like entities)
This commit is contained in:
parent
61bfb3ae55
commit
933543529b
|
@ -28,6 +28,7 @@ This mod contains the following additions:
|
|||
|
||||
Changelog:
|
||||
|
||||
1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick
|
||||
1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first
|
||||
1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added
|
||||
1.16- Mobs follow multiple items now, Npc's can breed
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- Mobs Api (27th October 2015)
|
||||
-- Mobs Api (4th November 2015)
|
||||
mobs = {}
|
||||
mobs.mod = "redo"
|
||||
|
||||
|
@ -146,7 +146,9 @@ function check_for_death(self)
|
|||
|
||||
-- still got some health? play hurt sound
|
||||
if hp > 0 then
|
||||
|
||||
self.health = hp
|
||||
|
||||
if self.sounds.damage then
|
||||
minetest.sound_play(self.sounds.damage,{
|
||||
pos = pos,
|
||||
|
@ -160,10 +162,12 @@ function check_for_death(self)
|
|||
-- drop items when dead
|
||||
local obj
|
||||
for _,drop in ipairs(self.drops) do
|
||||
|
||||
if math.random(1, drop.chance) == 1 then
|
||||
obj = minetest.add_item(pos,
|
||||
ItemStack(drop.name .. " "
|
||||
.. math.random(drop.min, drop.max)))
|
||||
|
||||
if obj then
|
||||
obj:setvelocity({
|
||||
x = math.random(-1, 1),
|
||||
|
@ -216,6 +220,7 @@ do_env_damage = function(self)
|
|||
end
|
||||
|
||||
local pos = self.object:getpos()
|
||||
|
||||
self.time_of_day = minetest.get_timeofday()
|
||||
|
||||
-- remove mob if beyond map limits
|
||||
|
@ -230,14 +235,18 @@ do_env_damage = function(self)
|
|||
and self.time_of_day > 0.2
|
||||
and self.time_of_day < 0.8
|
||||
and (minetest.get_node_light(pos) or 0) > 12 then
|
||||
|
||||
self.object:set_hp(self.object:get_hp() - self.light_damage)
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
end
|
||||
|
||||
if self.water_damage ~= 0 or self.lava_damage ~= 0 then
|
||||
|
||||
pos.y = (pos.y + self.collisionbox[2]) + 0.1 -- foot level
|
||||
|
||||
local nod = node_ok(pos, "air") ; -- print ("standing in "..nod.name)
|
||||
local nodef = minetest.registered_nodes[nod.name]
|
||||
|
||||
if not nodef then return end --MFF fix crash
|
||||
pos.y = pos.y + 1
|
||||
|
||||
|
@ -252,7 +261,8 @@ do_env_damage = function(self)
|
|||
if self.lava_damage ~= 0
|
||||
and (nodef.groups.lava
|
||||
or nod.name == "fire:basic_flame"
|
||||
or nod.name == "fire:eternal_flame") then
|
||||
or nod.name == "fire:eternal_flame"
|
||||
or nod.name == "fire:permanent_flame") then
|
||||
self.object:set_hp(self.object:get_hp() - self.lava_damage)
|
||||
effect(pos, 5, "fire_basic_flame.png")
|
||||
end
|
||||
|
@ -264,7 +274,8 @@ end
|
|||
-- jump if facing a solid node (not fences)
|
||||
do_jump = function(self)
|
||||
|
||||
if self.fly then
|
||||
if self.fly
|
||||
or self.child then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -329,6 +340,17 @@ in_fov = function(self, pos)
|
|||
return true
|
||||
end
|
||||
|
||||
function calc_velocity(pos1, pos2, old_vel, power)
|
||||
local vel = vector.direction(pos1, pos2)
|
||||
vel = vector.normalize(vel)
|
||||
vel = vector.multiply(vel, power)
|
||||
local dist = vector.distance(pos1, pos2)
|
||||
dist = math.max(dist, 1)
|
||||
vel = vector.divide(vel, dist)
|
||||
vel = vector.add(vel, old_vel)
|
||||
return vel
|
||||
end
|
||||
|
||||
-- blast damage to entities nearby (modified from TNT mod)
|
||||
function entity_physics(pos, radius, self) --/MFF (Crabman|06/23/2015)add self to use punch function
|
||||
|
||||
|
@ -360,11 +382,13 @@ function node_ok(pos, fallback)
|
|||
fallback = fallback or "default:dirt"
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
|
||||
if not node then
|
||||
return minetest.registered_nodes[fallback]
|
||||
end
|
||||
|
||||
local nodef = minetest.registered_nodes[node.name]
|
||||
|
||||
if nodef then
|
||||
return node
|
||||
end
|
||||
|
@ -402,7 +426,9 @@ local function breed(self)
|
|||
if self.horny == true
|
||||
and self.hornytimer < 240
|
||||
and self.child == false then
|
||||
|
||||
self.hornytimer = self.hornytimer + 1
|
||||
|
||||
if self.hornytimer >= 240 then
|
||||
self.hornytimer = 0
|
||||
self.horny = false
|
||||
|
@ -411,18 +437,22 @@ local function breed(self)
|
|||
|
||||
-- child take 240 seconds before growing into adult
|
||||
if self.child == true then
|
||||
|
||||
self.hornytimer = self.hornytimer + 1
|
||||
|
||||
if self.hornytimer > 240 then
|
||||
|
||||
self.child = false
|
||||
self.hornytimer = 0
|
||||
|
||||
self.object:set_properties({
|
||||
textures = self.base_texture,
|
||||
mesh = self.base_mesh,
|
||||
visual_size = self.base_size,
|
||||
collisionbox = self.base_colbox,
|
||||
})
|
||||
-- jump when grown so not to fall into ground
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
-- jump when fully grown so not to fall into ground
|
||||
self.object:setvelocity({
|
||||
x = 0,
|
||||
y = self.jump_height,
|
||||
|
@ -434,25 +464,33 @@ local function breed(self)
|
|||
-- find another same animal who is also horny and mate if close enough
|
||||
if self.horny == true
|
||||
and self.hornytimer <= 40 then
|
||||
|
||||
local pos = self.object:getpos()
|
||||
effect({x = pos.x, y = pos.y + 1, z = pos.z}, 4, "heart.png")
|
||||
|
||||
local ents = minetest.get_objects_inside_radius(pos, 3)
|
||||
local num = 0
|
||||
local ent = nil
|
||||
|
||||
for i, obj in ipairs(ents) do
|
||||
|
||||
ent = obj:get_luaentity()
|
||||
|
||||
-- check for same animal with different colour
|
||||
local canmate = false
|
||||
|
||||
if ent then
|
||||
|
||||
if ent.name == self.name then
|
||||
canmate = true
|
||||
else
|
||||
local entname = string.split(ent.name,":")
|
||||
local selfname = string.split(self.name,":")
|
||||
|
||||
if entname[1] == selfname[1] then
|
||||
entname = string.split(entname[2],"_")
|
||||
selfname = string.split(selfname[2],"_")
|
||||
|
||||
if entname[1] == selfname[1] then
|
||||
canmate = true
|
||||
end
|
||||
|
@ -469,16 +507,21 @@ local function breed(self)
|
|||
|
||||
-- found your mate? then have a baby
|
||||
if num > 1 then
|
||||
|
||||
self.hornytimer = 41
|
||||
ent.hornytimer = 41
|
||||
|
||||
-- spawn baby
|
||||
minetest.after(7, function(dtime)
|
||||
|
||||
local mob = minetest.add_entity(pos, self.name)
|
||||
local ent2 = mob:get_luaentity()
|
||||
local textures = self.base_texture
|
||||
|
||||
if self.child_texture then
|
||||
textures = self.child_texture[1]
|
||||
end
|
||||
|
||||
mob:set_properties({
|
||||
textures = textures,
|
||||
visual_size = {
|
||||
|
@ -625,7 +668,9 @@ minetest.register_entity(name, {
|
|||
if self.type ~= "npc"
|
||||
and not self.tamed
|
||||
and self.state ~= "attack" then
|
||||
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
|
||||
if self.lifetimer <= 0 then
|
||||
minetest.log("action",
|
||||
"lifetimer expired, removed " .. self.name)
|
||||
|
@ -671,7 +716,9 @@ minetest.register_entity(name, {
|
|||
-- 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))
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
|
@ -717,6 +764,7 @@ minetest.register_entity(name, {
|
|||
|
||||
-- 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 then
|
||||
self.env_damage_timer = 0
|
||||
|
@ -725,6 +773,7 @@ minetest.register_entity(name, {
|
|||
if self.do_custom then
|
||||
self.do_custom(self)
|
||||
end
|
||||
|
||||
elseif self.state ~= "attack" then
|
||||
self.env_damage_timer = 0
|
||||
do_env_damage(self)
|
||||
|
@ -769,6 +818,7 @@ minetest.register_entity(name, {
|
|||
p.y = p.y + 1
|
||||
sp.y = sp.y + 1 -- aim higher to make looking up hills more realistic
|
||||
dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
|
||||
|
||||
if dist < self.view_range then
|
||||
-- and self.in_fov(self,p) then
|
||||
-- choose closest player to attack
|
||||
|
@ -793,11 +843,15 @@ minetest.register_entity(name, {
|
|||
if self.type == "npc"
|
||||
and self.attacks_monsters
|
||||
and self.state ~= "attack" then
|
||||
|
||||
local s = self.object:getpos()
|
||||
local p, dist --MFF
|
||||
local obj = nil
|
||||
|
||||
for _, oir in pairs(minetest.get_objects_inside_radius(s,self.view_range)) do
|
||||
|
||||
obj = oir:get_luaentity()
|
||||
|
||||
if obj
|
||||
and obj.type == "monster" then
|
||||
-- attack monster
|
||||
|
@ -809,6 +863,7 @@ minetest.register_entity(name, {
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
if min_player then
|
||||
do_attack(self, min_player)
|
||||
end
|
||||
|
@ -865,6 +920,7 @@ minetest.register_entity(name, {
|
|||
end
|
||||
|
||||
if p then
|
||||
|
||||
local dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
|
||||
|
||||
-- dont follow if out of range
|
||||
|
@ -909,6 +965,7 @@ minetest.register_entity(name, {
|
|||
if self.state == "stand" then
|
||||
|
||||
if math.random(1, 4) == 1 then
|
||||
|
||||
local lp = nil
|
||||
local s = self.object:getpos()
|
||||
|
||||
|
@ -954,6 +1011,7 @@ minetest.register_entity(name, {
|
|||
end
|
||||
|
||||
elseif self.state == "walk" then
|
||||
|
||||
local s = self.object:getpos()
|
||||
local lp = minetest.find_node_near(s, 1, {"group:water"})
|
||||
|
||||
|
@ -995,6 +1053,7 @@ minetest.register_entity(name, {
|
|||
|
||||
set_velocity(self, self.walk_velocity)
|
||||
set_animation(self, "walk")
|
||||
|
||||
if math.random(1, 100) <= 30 then
|
||||
set_velocity(self, 0)
|
||||
self.state = "stand"
|
||||
|
@ -1102,8 +1161,9 @@ minetest.register_entity(name, {
|
|||
local p2 = p
|
||||
local p_y = math.floor(p2.y + 1)
|
||||
local v = self.object:getvelocity()
|
||||
if nod
|
||||
and nod.name == self.fly_in then
|
||||
|
||||
if nod.name == self.fly_in then
|
||||
|
||||
if me_y < p_y then
|
||||
self.object:setvelocity({
|
||||
x = v.x,
|
||||
|
@ -1243,7 +1303,9 @@ minetest.register_entity(name, {
|
|||
|
||||
-- load entity variables
|
||||
if staticdata then
|
||||
|
||||
local tmp = minetest.deserialize(staticdata)
|
||||
|
||||
if tmp then
|
||||
for _,stat in pairs(tmp) do
|
||||
self[_] = stat
|
||||
|
@ -1281,13 +1343,16 @@ minetest.register_entity(name, {
|
|||
|
||||
-- set child objects to half size
|
||||
if self.child == true then
|
||||
|
||||
vis_size = {
|
||||
x = self.base_size.x / 2,
|
||||
y = self.base_size.y / 2
|
||||
}
|
||||
|
||||
if def.child_texture then
|
||||
textures = def.child_texture[1]
|
||||
end
|
||||
|
||||
colbox = {
|
||||
self.base_colbox[1] / 2,
|
||||
self.base_colbox[2] / 2,
|
||||
|
@ -1330,6 +1395,7 @@ minetest.register_entity(name, {
|
|||
self.state = "stand"
|
||||
|
||||
local tmp = {}
|
||||
|
||||
for _,stat in pairs(self) do
|
||||
local t = type(stat)
|
||||
if t ~= 'function'
|
||||
|
@ -1343,10 +1409,12 @@ minetest.register_entity(name, {
|
|||
end,
|
||||
|
||||
on_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
|
||||
-- weapon wear
|
||||
hitter:set_detach() --MFF (crabman|27/7/2015) anti usebug, immortal if attached
|
||||
local weapon = hitter:get_wielded_item()
|
||||
local punch_interval = tool_capabilities.full_punch_interval or 1.4
|
||||
|
||||
if weapon:get_definition().tool_capabilities ~= nil then
|
||||
local wear = math.floor((punch_interval / 75) * 9000)
|
||||
weapon:add_wear(wear)
|
||||
|
@ -1355,7 +1423,9 @@ minetest.register_entity(name, {
|
|||
|
||||
-- weapon sounds
|
||||
if weapon:get_definition().sounds ~= nil then
|
||||
|
||||
local s = math.random(0, #weapon:get_definition().sounds)
|
||||
|
||||
minetest.sound_play(weapon:get_definition().sounds[s], {
|
||||
object = hitter,
|
||||
max_hear_distance = 8
|
||||
|
@ -1382,34 +1452,46 @@ minetest.register_entity(name, {
|
|||
|
||||
-- knock back effect
|
||||
if self.knock_back > 0 then
|
||||
|
||||
local kb = self.knock_back
|
||||
local r = self.recovery_time
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
if tflp < punch_interval then
|
||||
|
||||
if kb > 0 then
|
||||
kb = kb * (tflp / punch_interval)
|
||||
end
|
||||
|
||||
r = r * (tflp / punch_interval)
|
||||
end
|
||||
|
||||
self.object:setvelocity({
|
||||
x = dir.x * kb,
|
||||
y = 0,
|
||||
z = dir.z * kb
|
||||
})
|
||||
|
||||
self.pause_timer = r
|
||||
end
|
||||
|
||||
-- attack puncher and call other mobs for help
|
||||
if self.passive == false
|
||||
and not self.tamed then
|
||||
|
||||
if self.state ~= "attack" then
|
||||
do_attack(self, hitter)
|
||||
end
|
||||
|
||||
-- alert others to the attack
|
||||
local obj = nil
|
||||
|
||||
for _, oir in pairs(minetest.get_objects_inside_radius(hitter:getpos(), 5)) do
|
||||
|
||||
obj = oir:get_luaentity()
|
||||
|
||||
if obj then
|
||||
|
||||
if obj.group_attack == true
|
||||
and not obj.tamed --MFF(crabman) group tamed don't attack
|
||||
and obj.state ~= "attack" then
|
||||
|
@ -1427,7 +1509,8 @@ end -- END mobs:register_mob function
|
|||
|
||||
mobs.spawning_mobs = {}
|
||||
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, spawn_in_area) --MFF crabman
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
interval, chance, active_object_count, min_height, max_height, spawn_in_area) --MFF crabman
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
-- chance override in minetest.conf for registered mob
|
||||
|
@ -1442,7 +1525,9 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||
neighbors = neighbors,
|
||||
interval = interval,
|
||||
chance = chance,
|
||||
|
||||
action = function(pos, node, _, active_object_count_wider)
|
||||
|
||||
-- do not spawn if too many active entities in area
|
||||
if active_object_count_wider > active_object_count
|
||||
or not mobs.spawning_mobs[name]
|
||||
|
@ -1453,7 +1538,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||
-- spawn above node
|
||||
pos.y = pos.y + 1
|
||||
|
||||
-- mobs cannot spawn inside protected areas if enabled
|
||||
-- mobs cannot spawn in protected areas when enabled
|
||||
if mobs.protected == 1
|
||||
and minetest.is_protected(pos, "")
|
||||
and not spawn_in_area then --MFF crabman
|
||||
|
@ -1470,20 +1555,18 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||
return
|
||||
end
|
||||
|
||||
-- are we spawning inside a solid node?
|
||||
-- are we spawning inside solid nodes?
|
||||
if minetest.registered_nodes[node_ok(pos).name].walkable == true then
|
||||
return
|
||||
end
|
||||
|
||||
pos.y = pos.y + 1
|
||||
|
||||
if minetest.registered_nodes[node_ok(pos).name].walkable == true then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.setting_getbool("display_mob_spawn") then
|
||||
minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
-- spawn mob half block higher
|
||||
-- spawn mob half block higher then ground
|
||||
pos.y = pos.y - 0.5
|
||||
minetest.add_entity(pos, name)
|
||||
--print ("Spawned "..name.." at "..minetest.pos_to_string(pos).." on "..node.name.." near "..neighbors[1])
|
||||
|
@ -1494,14 +1577,17 @@ end
|
|||
|
||||
-- compatibility with older mob registration
|
||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height)
|
||||
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height)
|
||||
|
||||
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
|
||||
chance, active_object_count, -31000, max_height)
|
||||
end
|
||||
|
||||
-- explosion
|
||||
-- explosion (cannot break protected or unbreakable nodes)
|
||||
function mobs:explosion(pos, radius, fire, smoke, sound)
|
||||
-- node hit, bursts into flame (cannot blast through unbreakable/specific nodes)
|
||||
if not fire then fire = 0 end
|
||||
if not smoke then smoke = 0 end
|
||||
|
||||
fire = fire or 0
|
||||
smoke = smoke or 0
|
||||
|
||||
local pos = vector.round(pos)
|
||||
local vm = VoxelManip()
|
||||
local minp, maxp = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius))
|
||||
|
@ -1513,6 +1599,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
local c_obsidian = minetest.get_content_id("default:obsidian")
|
||||
local c_brick = minetest.get_content_id("default:obsidianbrick")
|
||||
local c_chest = minetest.get_content_id("default:chest_locked")
|
||||
|
||||
-- explosion sound
|
||||
if sound
|
||||
and sound ~= "" then
|
||||
minetest.sound_play(sound, {
|
||||
|
@ -1521,15 +1609,18 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
max_hear_distance = 16
|
||||
})
|
||||
end
|
||||
-- if area protected or at map limits then no blast damage
|
||||
|
||||
-- if area protected or near map limits then no blast damage
|
||||
if minetest.is_protected(pos, "")
|
||||
or not within_limits(pos, radius) then
|
||||
return
|
||||
end
|
||||
|
||||
for z = -radius, radius do
|
||||
for y = -radius, radius do
|
||||
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
|
||||
for x = -radius, radius do
|
||||
|
||||
p.x = pos.x + x
|
||||
p.y = pos.y + y
|
||||
p.z = pos.z + z
|
||||
|
@ -1539,6 +1630,7 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
and data[vi] ~= c_obsidian
|
||||
and data[vi] ~= c_brick
|
||||
and data[vi] ~= c_chest then
|
||||
|
||||
local n = node_ok(p).name
|
||||
if not minetest.is_protected(p, "") --/MFF (Crabman|06/23/2015) re-added node protected in areas
|
||||
and minetest.get_item_group(n, "unbreakable") ~= 1
|
||||
|
@ -1546,11 +1638,15 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
-- if chest then drop items inside
|
||||
if n == "default:chest"
|
||||
or n == "3dchest:chest" then
|
||||
|
||||
local meta = minetest.get_meta(p)
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1,32 do
|
||||
|
||||
for i = 1, 32 do
|
||||
|
||||
local m_stack = inv:get_stack("main", i)
|
||||
local obj = minetest.add_item(p, m_stack)
|
||||
|
||||
if obj then
|
||||
obj:setvelocity({
|
||||
x = math.random(-2, 2),
|
||||
|
@ -1560,6 +1656,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- after effects
|
||||
if fire > 0
|
||||
and (minetest.registered_nodes[n].groups.flammable
|
||||
or math.random(1, 100) <= 30) then
|
||||
|
@ -1567,6 +1665,7 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||
else
|
||||
minetest.remove_node(p)
|
||||
end
|
||||
|
||||
if smoke > 0 then
|
||||
effect(p, 2, "tnt_smoke.png", 5)
|
||||
end
|
||||
|
@ -1580,7 +1679,9 @@ end
|
|||
|
||||
-- register arrow for shoot attack
|
||||
function mobs:register_arrow(name, def)
|
||||
|
||||
if not name or not def then return end -- errorcheck
|
||||
|
||||
minetest.register_entity(name, {
|
||||
physical = false,
|
||||
visual = def.visual,
|
||||
|
@ -1595,8 +1696,11 @@ function mobs:register_arrow(name, def)
|
|||
timer = 0,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
self.timer = self.timer + 1
|
||||
|
||||
local pos = self.object:getpos()
|
||||
|
||||
if self.timer > 150
|
||||
or not within_limits(pos, 0) then
|
||||
self.object:remove() ; -- print ("removed arrow")
|
||||
|
@ -1604,15 +1708,21 @@ function mobs:register_arrow(name, def)
|
|||
end
|
||||
|
||||
if self.hit_node then
|
||||
|
||||
local node = node_ok(pos).name
|
||||
|
||||
if minetest.registered_nodes[node].walkable then
|
||||
|
||||
self.hit_node(self, pos, node)
|
||||
|
||||
if self.drop == true then
|
||||
pos.y = pos.y + 1
|
||||
self.lastpos = (self.lastpos or pos)
|
||||
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
||||
end
|
||||
|
||||
self.object:remove() ; -- print ("hit node")
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -1620,19 +1730,24 @@ function mobs:register_arrow(name, def)
|
|||
if (self.hit_player or self.hit_mob)
|
||||
-- clear mob entity before arrow becomes active
|
||||
and self.timer > (10 - (self.velocity / 2)) then
|
||||
|
||||
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do
|
||||
|
||||
if self.hit_player
|
||||
and player:is_player() then
|
||||
|
||||
self.hit_player(self, player)
|
||||
self.object:remove() ; -- print ("hit player")
|
||||
return
|
||||
end
|
||||
|
||||
if self.hit_mob
|
||||
and player:get_luaentity()
|
||||
and player:get_luaentity().name ~= self.object:get_luaentity().name
|
||||
and player:get_luaentity().name ~= "__builtin:item"
|
||||
and player:get_luaentity().name ~= "gauges:hp_bar"
|
||||
and player:get_luaentity().name ~= "signs:text" then
|
||||
|
||||
self.hit_mob(self, player)
|
||||
self.object:remove() ; -- print ("hit mob")
|
||||
return
|
||||
|
@ -1646,30 +1761,42 @@ end
|
|||
|
||||
-- Spawn Egg
|
||||
function mobs:register_egg(mob, desc, background, addegg)
|
||||
|
||||
local invimg = background
|
||||
|
||||
if addegg == 1 then
|
||||
invimg = invimg.."^mobs_chicken_egg.png"
|
||||
invimg = invimg .. "^mobs_chicken_egg.png"
|
||||
end
|
||||
|
||||
minetest.register_craftitem(mob, {
|
||||
description = desc,
|
||||
inventory_image = invimg,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
|
||||
local pos = pointed_thing.above
|
||||
if pos and within_limits(pos, 0)
|
||||
|
||||
if pos
|
||||
and within_limits(pos, 0)
|
||||
and not minetest.is_protected(pos, placer:get_player_name()) then
|
||||
|
||||
pos.y = pos.y + 1
|
||||
|
||||
local mob = minetest.add_entity(pos, mob)
|
||||
local ent = mob:get_luaentity()
|
||||
|
||||
if ent.type ~= "monster" then
|
||||
-- set owner and tame
|
||||
-- set owner and tame if not monster
|
||||
ent.owner = placer:get_player_name()
|
||||
ent.tamed = true
|
||||
end
|
||||
|
||||
-- if not in creative then take item
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
@ -1677,22 +1804,28 @@ end
|
|||
|
||||
-- capture critter (thanks to blert2112 for idea)
|
||||
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
||||
if clicker:is_player()
|
||||
and clicker:get_inventory()
|
||||
and not self.child then
|
||||
|
||||
if not self.child
|
||||
and clicker:is_player()
|
||||
and clicker:get_inventory() then
|
||||
|
||||
-- get name of clicked mob
|
||||
local mobname = self.name
|
||||
|
||||
-- if not nil change what will be added to inventory
|
||||
if replacewith then
|
||||
mobname = replacewith
|
||||
end
|
||||
|
||||
local name = clicker:get_player_name()
|
||||
|
||||
-- is mob tamed?
|
||||
if self.tamed == false
|
||||
and force_take == false then
|
||||
minetest.chat_send_player(name, "Not tamed!")
|
||||
return
|
||||
end
|
||||
|
||||
-- cannot pick up if not owner
|
||||
if self.owner ~= name
|
||||
and force_take == false then
|
||||
|
@ -1701,26 +1834,30 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
|||
end
|
||||
|
||||
if clicker:get_inventory():room_for_item("main", mobname) then
|
||||
|
||||
-- was mob clicked with hand, net, or lasso?
|
||||
local tool = clicker:get_wielded_item()
|
||||
local chance = 0
|
||||
|
||||
if tool:is_empty() then
|
||||
chance = chance_hand
|
||||
|
||||
elseif tool:get_name() == "mobs:net" then
|
||||
chance = chance_net
|
||||
tool:add_wear(4000) -- 17 uses
|
||||
clicker:set_wielded_item(tool)
|
||||
|
||||
elseif tool:get_name() == "mobs:magic_lasso" then
|
||||
-- pick up if owner
|
||||
chance = chance_lasso
|
||||
tool:add_wear(650) -- 100 uses
|
||||
clicker:set_wielded_item(tool)
|
||||
end
|
||||
|
||||
-- return if no chance
|
||||
if chance == 0 then return end
|
||||
-- calculate chance.. was capture successful?
|
||||
if math.random(100) <= chance then
|
||||
-- successful capture.. add to inventory
|
||||
|
||||
-- calculate chance.. add to inventory if successful?
|
||||
if math.random(1, 100) <= chance then
|
||||
clicker:get_inventory():add_item("main", mobname)
|
||||
self.object:remove()
|
||||
else
|
||||
|
|
|
@ -54,18 +54,122 @@ mobs:register_mob("mobs:chicken", {
|
|||
-- follows wheat
|
||||
follow = {"farming:seed_wheat", "farming:seed_cotton"},
|
||||
view_range = 8,
|
||||
replace_rate = 2500,
|
||||
replace_what = {"air"},
|
||||
replace_with = "mobs:egg",
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
mobs:feed_tame(self, clicker, 8, true, true)
|
||||
mobs:capture_mob(self, clicker, 30, 50, 80, false, nil)
|
||||
end,
|
||||
|
||||
do_custom = function(self)
|
||||
if not self.child
|
||||
and math.random(1, 500) == 1 then
|
||||
local pos = self.object:getpos()
|
||||
minetest.add_item(pos, "mobs:egg")
|
||||
minetest.sound_play("default_place_node_hard", {
|
||||
pos = pos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 5,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
-- spawn on default or bamboo grass between 8 and 20 light, 1 in 10000 change, 1 chicken in area up to 31000 in height
|
||||
mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
||||
-- register spawn egg
|
||||
mobs:register_egg("mobs:chicken", "Chicken", "mobs_chicken_inv.png", 1)
|
||||
-- egg entity
|
||||
|
||||
mobs:register_arrow("mobs:egg_entity", {
|
||||
visual = "sprite",
|
||||
visual_size = {x=.5, y=.5},
|
||||
textures = {"mobs_chicken_egg.png"},
|
||||
velocity = 6,
|
||||
|
||||
hit_player = function(self, player)
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 1},
|
||||
}, nil)
|
||||
end,
|
||||
|
||||
hit_mob = function(self, player)
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 1},
|
||||
}, nil)
|
||||
end,
|
||||
|
||||
hit_node = function(self, pos, node)
|
||||
|
||||
local num = math.random(1, 10)
|
||||
if num == 1 then
|
||||
pos.y = pos.y + 1
|
||||
local nod = minetest.get_node_or_nil(pos)
|
||||
if not nod
|
||||
or not minetest.registered_nodes[nod.name]
|
||||
or minetest.registered_nodes[nod.name].walkable == true then
|
||||
return
|
||||
end
|
||||
local mob = minetest.add_entity(pos, "mobs:chicken")
|
||||
local ent2 = mob:get_luaentity()
|
||||
mob:set_properties({
|
||||
textures = ent2.child_texture[1],
|
||||
visual_size = {
|
||||
x = ent2.base_size.x / 2,
|
||||
y = ent2.base_size.y / 2
|
||||
},
|
||||
collisionbox = {
|
||||
ent2.base_colbox[1] / 2,
|
||||
ent2.base_colbox[2] / 2,
|
||||
ent2.base_colbox[3] / 2,
|
||||
ent2.base_colbox[4] / 2,
|
||||
ent2.base_colbox[5] / 2,
|
||||
ent2.base_colbox[6] / 2
|
||||
},
|
||||
})
|
||||
ent2.child = true
|
||||
ent2.tamed = true
|
||||
ent2.owner = self.playername
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- snowball throwing item
|
||||
|
||||
local egg_GRAVITY = 9
|
||||
local egg_VELOCITY = 19
|
||||
|
||||
-- shoot snowball
|
||||
local mobs_shoot_egg = function (item, player, pointed_thing)
|
||||
local playerpos = player:getpos()
|
||||
minetest.sound_play("default_place_node_hard", {
|
||||
pos = playerpos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 5,
|
||||
})
|
||||
local obj = minetest.add_entity({
|
||||
x = playerpos.x,
|
||||
y = playerpos.y +1.5,
|
||||
z = playerpos.z
|
||||
}, "mobs:egg_entity")
|
||||
local dir = player:get_look_dir()
|
||||
obj:get_luaentity().velocity = egg_VELOCITY -- needed for api internal timing
|
||||
obj:setvelocity({
|
||||
x = dir.x * egg_VELOCITY,
|
||||
y = dir.y * egg_VELOCITY,
|
||||
z = dir.z * egg_VELOCITY
|
||||
})
|
||||
obj:setacceleration({
|
||||
x = dir.x * -3,
|
||||
y = -egg_GRAVITY,
|
||||
z = dir.z * -3
|
||||
})
|
||||
-- pass player name to egg for chick ownership
|
||||
local ent2 = obj:get_luaentity()
|
||||
ent2.playername = player:get_player_name()
|
||||
item:take_item()
|
||||
return item
|
||||
end
|
||||
|
||||
-- egg
|
||||
minetest.register_node("mobs:egg", {
|
||||
|
@ -83,12 +187,13 @@ minetest.register_node("mobs:egg", {
|
|||
type = "fixed",
|
||||
fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
|
||||
},
|
||||
groups = {snappy=2, dig_immediate=3},
|
||||
groups = {snappy = 2, dig_immediate = 3},
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
if placer:is_player() then
|
||||
minetest.set_node(pos, {name = "mobs:egg", param2 = 1})
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_use = mobs_shoot_egg
|
||||
})
|
||||
|
||||
-- fried egg
|
||||
|
@ -104,7 +209,7 @@ minetest.register_craft({
|
|||
output = "mobs:chicken_egg_fried",
|
||||
})
|
||||
|
||||
-- chicken (raw and cooked)
|
||||
-- raw chicken
|
||||
minetest.register_craftitem("mobs:chicken_raw", {
|
||||
description = "Raw Chicken",
|
||||
inventory_image = "mobs_chicken_raw.png",
|
||||
|
|
|
@ -168,6 +168,7 @@ minetest.register_entity("mobs:sheep", {
|
|||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer >= 1 then
|
||||
self.timer = 0
|
||||
|
@ -180,17 +181,3 @@ minetest.register_entity("mobs:sheep", {
|
|||
end,
|
||||
|
||||
})
|
||||
|
||||
-- -- shears (right click sheep to shear wool)
|
||||
-- minetest.register_tool("mobs:shears", {
|
||||
-- description = "Steel Shears (right-click sheep to shear)",
|
||||
-- inventory_image = "mobs_shears.png",
|
||||
-- tool_capabilities = { -- Modif MFF /DEBUT
|
||||
-- full_punch_interval = 1,
|
||||
-- max_drop_level=1,
|
||||
-- groupcaps={
|
||||
-- snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2},
|
||||
-- },
|
||||
-- damage_groups = {fleshy=0},
|
||||
-- }
|
||||
-- }) -- Modif MFF /FIN
|
||||
|
|
Loading…
Reference in New Issue
Block a user