mirror of
https://github.com/Poikilos/mobs.git
synced 2023-10-03 07:28:50 -07:00
Add support for animation, add 3D sheep model by Pavel_S, fix instant env death when attacking player, upgrade to new damage system, dont rotate that often when standing
This commit is contained in:
parent
4a14524af0
commit
b6eac3aedc
@ -22,6 +22,7 @@ The API documentation is moved to https://github.com/PilzAdam/mobs/wiki/API
|
|||||||
License:
|
License:
|
||||||
Sourcecode: WTFPL (see below)
|
Sourcecode: WTFPL (see below)
|
||||||
Grahpics: WTFPL (see below)
|
Grahpics: WTFPL (see below)
|
||||||
|
Models: WTFPL (by Pavel_S, see below)
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
http://minetest.net/
|
http://minetest.net/
|
||||||
|
119
api.lua
119
api.lua
@ -6,6 +6,7 @@ function mobs:register_mob(name, def)
|
|||||||
collisionbox = def.collisionbox,
|
collisionbox = def.collisionbox,
|
||||||
visual = def.visual,
|
visual = def.visual,
|
||||||
visual_size = def.visual_size,
|
visual_size = def.visual_size,
|
||||||
|
mesh = def.mesh,
|
||||||
textures = def.textures,
|
textures = def.textures,
|
||||||
makes_footstep_sound = def.makes_footstep_sound,
|
makes_footstep_sound = def.makes_footstep_sound,
|
||||||
view_range = def.view_range,
|
view_range = def.view_range,
|
||||||
@ -24,8 +25,10 @@ function mobs:register_mob(name, def)
|
|||||||
arrow = def.arrow,
|
arrow = def.arrow,
|
||||||
shoot_interval = def.shoot_interval,
|
shoot_interval = def.shoot_interval,
|
||||||
sounds = def.sounds,
|
sounds = def.sounds,
|
||||||
|
animation = def.animation,
|
||||||
|
|
||||||
timer = 0,
|
timer = 0,
|
||||||
|
env_damage_timer = 0, -- only if state = "attack"
|
||||||
attack = {player=nil, dist=nil},
|
attack = {player=nil, dist=nil},
|
||||||
state = "stand",
|
state = "stand",
|
||||||
v_start = false,
|
v_start = false,
|
||||||
@ -47,6 +50,64 @@ function mobs:register_mob(name, def)
|
|||||||
return (v.x^2 + v.z^2)^(0.5)
|
return (v.x^2 + v.z^2)^(0.5)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
set_animation = function(self, type)
|
||||||
|
if not self.animation then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not self.animation.current then
|
||||||
|
self.animation.current = ""
|
||||||
|
end
|
||||||
|
if type == "stand" and self.animation.current ~= "stand" then
|
||||||
|
if
|
||||||
|
self.animation.stand_start
|
||||||
|
and self.animation.stand_end
|
||||||
|
and self.animation.speed_normal
|
||||||
|
then
|
||||||
|
self.object:set_animation(
|
||||||
|
{x=self.animation.stand_start,y=self.animation.stand_end},
|
||||||
|
self.animation.speed_normal, 0
|
||||||
|
)
|
||||||
|
self.animation.current = "stand"
|
||||||
|
end
|
||||||
|
elseif type == "walk" and self.animation.current ~= "walk" then
|
||||||
|
if
|
||||||
|
self.animation.walk_start
|
||||||
|
and self.animation.walk_end
|
||||||
|
and self.animation.speed_normal
|
||||||
|
then
|
||||||
|
self.object:set_animation(
|
||||||
|
{x=self.animation.walk_start,y=self.animation.walk_end},
|
||||||
|
self.animation.speed_normal, 0
|
||||||
|
)
|
||||||
|
self.animation.current = "walk"
|
||||||
|
end
|
||||||
|
elseif type == "run" and self.animation.current ~= "run" then
|
||||||
|
if
|
||||||
|
self.animation.run_start
|
||||||
|
and self.animation.run_end
|
||||||
|
and self.animation.speed_run
|
||||||
|
then
|
||||||
|
self.object:set_animation(
|
||||||
|
{x=self.animation.run_start,y=self.animation.run_end},
|
||||||
|
self.animation.speed_run, 0
|
||||||
|
)
|
||||||
|
self.animation.current = "run"
|
||||||
|
end
|
||||||
|
elseif type == "punch" and self.animation.current ~= "punch" then
|
||||||
|
if
|
||||||
|
self.animation.punch_start
|
||||||
|
and self.animation.punch_end
|
||||||
|
and self.animation.speed_normal
|
||||||
|
then
|
||||||
|
self.object:set_animation(
|
||||||
|
{x=self.animation.punch_start,y=self.animation.punch_end},
|
||||||
|
self.animation.speed_normal, 0
|
||||||
|
)
|
||||||
|
self.animation.current = "punch"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime)
|
||||||
if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
|
if self.type == "monster" and minetest.setting_getbool("only_peaceful_mobs") then
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
@ -73,9 +134,7 @@ function mobs:register_mob(name, def)
|
|||||||
local damage = d-5
|
local damage = d-5
|
||||||
self.object:punch(self.object, 1.0, {
|
self.object:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
groupcaps={
|
damage_groups = {fleshy=damage/(self.armor/100)}
|
||||||
fleshy={times={[self.armor]=1/damage}},
|
|
||||||
}
|
|
||||||
}, nil)
|
}, nil)
|
||||||
end
|
end
|
||||||
self.old_y = self.object:getpos().y
|
self.old_y = self.object:getpos().y
|
||||||
@ -98,32 +157,32 @@ function mobs:register_mob(name, def)
|
|||||||
if self.light_damage and self.light_damage ~= 0 and self.object:getpos().y>0 and minetest.env:get_node_light(self.object:getpos()) and minetest.env:get_node_light(self.object:getpos()) > 3 and minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.8 then
|
if self.light_damage and self.light_damage ~= 0 and self.object:getpos().y>0 and minetest.env:get_node_light(self.object:getpos()) and minetest.env:get_node_light(self.object:getpos()) > 3 and minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.8 then
|
||||||
self.object:punch(self.object, 1.0, {
|
self.object:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
groupcaps={
|
damage_groups = {fleshy=self.light_damage/(self.armor/100)}
|
||||||
fleshy={times={[self.armor]=1/self.light_damage}},
|
|
||||||
}
|
|
||||||
}, nil)
|
}, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.water_damage and self.water_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:water") then
|
if self.water_damage and self.water_damage ~= 0 and
|
||||||
|
minetest.get_item_group(minetest.env:get_node(self.object:getpos()).name, "water") ~= 0
|
||||||
|
then
|
||||||
self.object:punch(self.object, 1.0, {
|
self.object:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
groupcaps={
|
damage_groups = {fleshy=self.water_damage/(self.armor/100)}
|
||||||
fleshy={times={[self.armor]=1/self.water_damage}},
|
|
||||||
}
|
|
||||||
}, nil)
|
}, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.lava_damage and self.lava_damage ~= 0 and string.find(minetest.env:get_node(self.object:getpos()).name, "default:lava") then
|
if self.lava_damage and self.lava_damage ~= 0 and
|
||||||
|
minetest.get_item_group(minetest.env:get_node(self.object:getpos()).name, "lava") ~= 0
|
||||||
|
then
|
||||||
self.object:punch(self.object, 1.0, {
|
self.object:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
groupcaps={
|
damage_groups = {fleshy=self.lava_damage/(self.armor/100)}
|
||||||
fleshy={times={[self.armor]=1/self.lava_damage}},
|
|
||||||
}
|
|
||||||
}, nil)
|
}, nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.state == "attack" and self.timer > 1 then
|
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
|
||||||
do_env_damage(self)
|
do_env_damage(self)
|
||||||
elseif self.state ~= "attack" then
|
elseif self.state ~= "attack" then
|
||||||
do_env_damage(self)
|
do_env_damage(self)
|
||||||
@ -151,21 +210,25 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.state == "stand" then
|
if self.state == "stand" then
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 4) == 1 then
|
||||||
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
|
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
|
||||||
end
|
end
|
||||||
|
self.set_animation(self, "stand")
|
||||||
if math.random(1, 100) <= 50 then
|
if math.random(1, 100) <= 50 then
|
||||||
self.set_velocity(self, self.walk_velocity)
|
self.set_velocity(self, self.walk_velocity)
|
||||||
self.state = "walk"
|
self.state = "walk"
|
||||||
|
self.set_animation(self, "walk")
|
||||||
end
|
end
|
||||||
elseif self.state == "walk" then
|
elseif self.state == "walk" then
|
||||||
if math.random(1, 100) <= 30 then
|
if math.random(1, 100) <= 30 then
|
||||||
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
|
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
|
||||||
self.set_velocity(self, self.get_velocity(self))
|
self.set_velocity(self, self.get_velocity(self))
|
||||||
end
|
end
|
||||||
|
self:set_animation("walk")
|
||||||
if math.random(1, 100) <= 10 then
|
if math.random(1, 100) <= 10 then
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
|
self:set_animation("stand")
|
||||||
end
|
end
|
||||||
if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
|
if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
|
||||||
local v = self.object:getvelocity()
|
local v = self.object:getvelocity()
|
||||||
@ -175,6 +238,7 @@ function mobs:register_mob(name, def)
|
|||||||
elseif self.state == "attack" and self.attack_type == "dogfight" then
|
elseif self.state == "attack" and self.attack_type == "dogfight" then
|
||||||
if not self.attack.player or not self.attack.player:is_player() then
|
if not self.attack.player or not self.attack.player:is_player() then
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
|
self:set_animation("stand")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local s = self.object:getpos()
|
local s = self.object:getpos()
|
||||||
@ -185,6 +249,7 @@ function mobs:register_mob(name, def)
|
|||||||
self.v_start = false
|
self.v_start = false
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self.attack = {player=nil, dist=nil}
|
self.attack = {player=nil, dist=nil}
|
||||||
|
self:set_animation("stand")
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.attack.dist = dist
|
self.attack.dist = dist
|
||||||
@ -211,37 +276,26 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
self.set_velocity(self, self.run_velocity)
|
self.set_velocity(self, self.run_velocity)
|
||||||
end
|
end
|
||||||
|
self:set_animation("run")
|
||||||
else
|
else
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
|
self:set_animation("punch")
|
||||||
self.v_start = false
|
self.v_start = false
|
||||||
if self.timer > 1 then
|
if self.timer > 1 then
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
local d1 = 10
|
|
||||||
local d2 = 10
|
|
||||||
local d3 = 10
|
|
||||||
if self.damage > 0 then
|
|
||||||
d3 = 1/self.damage
|
|
||||||
end
|
|
||||||
if self.damage > 1 then
|
|
||||||
d2 = 1/(self.damage-1)
|
|
||||||
end
|
|
||||||
if self.damage > 2 then
|
|
||||||
d1 = 1/(self.damage-2)
|
|
||||||
end
|
|
||||||
if self.sounds and self.sounds.attack then
|
if self.sounds and self.sounds.attack then
|
||||||
minetest.sound_play(self.sounds.attack, {object = self.object})
|
minetest.sound_play(self.sounds.attack, {object = self.object})
|
||||||
end
|
end
|
||||||
self.attack.player:punch(self.object, 1.0, {
|
self.attack.player:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
groupcaps={
|
damage_groups = {fleshy=self.damage}
|
||||||
fleshy={times={[1]=d1, [2]=d2, [3]=d3}},
|
|
||||||
}
|
|
||||||
}, vec)
|
}, vec)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif self.state == "attack" and self.attack_type == "shoot" then
|
elseif self.state == "attack" and self.attack_type == "shoot" then
|
||||||
if not self.attack.player or not self.attack.player:is_player() then
|
if not self.attack.player or not self.attack.player:is_player() then
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
|
self:set_animation("stand")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local s = self.object:getpos()
|
local s = self.object:getpos()
|
||||||
@ -252,6 +306,7 @@ function mobs:register_mob(name, def)
|
|||||||
self.v_start = false
|
self.v_start = false
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self.attack = {player=nil, dist=nil}
|
self.attack = {player=nil, dist=nil}
|
||||||
|
self:set_animation("stand")
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.attack.dist = dist
|
self.attack.dist = dist
|
||||||
@ -271,6 +326,8 @@ function mobs:register_mob(name, def)
|
|||||||
if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
|
if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
|
|
||||||
|
self:set_animation("punch")
|
||||||
|
|
||||||
if self.sounds and self.sounds.attack then
|
if self.sounds and self.sounds.attack then
|
||||||
minetest.sound_play(self.sounds.attack, {object = self.object})
|
minetest.sound_play(self.sounds.attack, {object = self.object})
|
||||||
end
|
end
|
||||||
|
38
init.lua
38
init.lua
@ -18,7 +18,7 @@ mobs:register_mob("mobs:dirt_monster", {
|
|||||||
min = 3,
|
min = 3,
|
||||||
max = 5,},
|
max = 5,},
|
||||||
},
|
},
|
||||||
armor = 3,
|
armor = 100,
|
||||||
drawtype = "front",
|
drawtype = "front",
|
||||||
water_damage = 1,
|
water_damage = 1,
|
||||||
lava_damage = 5,
|
lava_damage = 5,
|
||||||
@ -47,7 +47,7 @@ mobs:register_mob("mobs:stone_monster", {
|
|||||||
max = 5,},
|
max = 5,},
|
||||||
},
|
},
|
||||||
light_resistant = true,
|
light_resistant = true,
|
||||||
armor = 2,
|
armor = 80,
|
||||||
drawtype = "front",
|
drawtype = "front",
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 0,
|
lava_damage = 0,
|
||||||
@ -76,7 +76,7 @@ mobs:register_mob("mobs:sand_monster", {
|
|||||||
max = 5,},
|
max = 5,},
|
||||||
},
|
},
|
||||||
light_resistant = true,
|
light_resistant = true,
|
||||||
armor = 3,
|
armor = 100,
|
||||||
drawtype = "front",
|
drawtype = "front",
|
||||||
water_damage = 3,
|
water_damage = 3,
|
||||||
lava_damage = 1,
|
lava_damage = 1,
|
||||||
@ -88,26 +88,36 @@ mobs:register_spawn("mobs:sand_monster", {"default:desert_sand"}, 20, -1, 7000,
|
|||||||
mobs:register_mob("mobs:sheep", {
|
mobs:register_mob("mobs:sheep", {
|
||||||
type = "animal",
|
type = "animal",
|
||||||
hp_max = 5,
|
hp_max = 5,
|
||||||
collisionbox = {-0.6, -0.625, -0.6, 0.6, 0.625, 0.6},
|
collisionbox = {-0.4, 0, -0.4, 0.4, 1, 0.4},
|
||||||
visual = "upright_sprite",
|
--visual = "upright_sprite",
|
||||||
visual_size = {x=2, y=1.25},
|
--visual_size = {x=2, y=1.25},
|
||||||
textures = {"mobs_sheep.png", "mobs_sheep.png"},
|
--textures = {"mobs_sheep.png", "mobs_sheep.png"},
|
||||||
|
textures = {"mobs_sheep.png"},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "mobs_sheep.x",
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
armor = 3,
|
armor = 200,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs:meat_raw",
|
{name = "mobs:meat_raw",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 2,
|
min = 2,
|
||||||
max = 3,},
|
max = 3,},
|
||||||
},
|
},
|
||||||
drawtype = "side",
|
drawtype = "front",
|
||||||
water_damage = 1,
|
water_damage = 1,
|
||||||
lava_damage = 5,
|
lava_damage = 5,
|
||||||
light_damage = 0,
|
light_damage = 0,
|
||||||
sounds = {
|
sounds = {
|
||||||
random = "mobs_sheep",
|
random = "mobs_sheep",
|
||||||
},
|
},
|
||||||
|
animation = {
|
||||||
|
speed_normal = 10,
|
||||||
|
stand_start = 0,
|
||||||
|
stand_end = 59,
|
||||||
|
walk_start = 81,
|
||||||
|
walk_end = 100,
|
||||||
|
},
|
||||||
|
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
if self.naked then
|
if self.naked then
|
||||||
@ -117,7 +127,9 @@ mobs:register_mob("mobs:sheep", {
|
|||||||
self.naked = true,
|
self.naked = true,
|
||||||
clicker:get_inventory():add_item("main", ItemStack("wool:white "..math.random(1,3)))
|
clicker:get_inventory():add_item("main", ItemStack("wool:white "..math.random(1,3)))
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
textures = {"mobs_sheep_naked.png", "mobs_sheep_naked.png"},
|
--textures = {"mobs_sheep_naked.png", "mobs_sheep_naked.png"},
|
||||||
|
textures = {"mobs_sheep_shaved.png"},
|
||||||
|
mesh = "mobs_sheep_shaved.x",
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -151,7 +163,7 @@ mobs:register_mob("mobs:rat", {
|
|||||||
textures = {"mobs_rat.png", "mobs_rat.png"},
|
textures = {"mobs_rat.png", "mobs_rat.png"},
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
armor = 3,
|
armor = 200,
|
||||||
drops = {},
|
drops = {},
|
||||||
drawtype = "side",
|
drawtype = "side",
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
@ -207,7 +219,7 @@ mobs:register_mob("mobs:oerkki", {
|
|||||||
run_velocity = 3,
|
run_velocity = 3,
|
||||||
damage = 4,
|
damage = 4,
|
||||||
drops = {},
|
drops = {},
|
||||||
armor = 3,
|
armor = 100,
|
||||||
drawtype = "front",
|
drawtype = "front",
|
||||||
light_resistant = true,
|
light_resistant = true,
|
||||||
water_damage = 1,
|
water_damage = 1,
|
||||||
@ -235,7 +247,7 @@ mobs:register_mob("mobs:dungeon_master", {
|
|||||||
min = 1,
|
min = 1,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
},
|
},
|
||||||
armor = 2,
|
armor = 60,
|
||||||
drawtype = "front",
|
drawtype = "front",
|
||||||
water_damage = 1,
|
water_damage = 1,
|
||||||
lava_damage = 1,
|
lava_damage = 1,
|
||||||
|
BIN
models/mobs_sheep.png
Executable file
BIN
models/mobs_sheep.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
7170
models/mobs_sheep.x
Executable file
7170
models/mobs_sheep.x
Executable file
File diff suppressed because it is too large
Load Diff
BIN
models/mobs_sheep_shaved.png
Executable file
BIN
models/mobs_sheep_shaved.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
4592
models/mobs_sheep_shaved.x
Executable file
4592
models/mobs_sheep_shaved.x
Executable file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
Loading…
x
Reference in New Issue
Block a user