Cleaned up animation parts.

This commit is contained in:
Auke Kok 2016-04-30 20:05:18 -07:00
parent e44317b153
commit 4a16c98b63
2 changed files with 116 additions and 141 deletions

157
init.lua
View File

@ -82,19 +82,14 @@ local factors = {}
-- Animation functions -- Animation functions
-- --
local function animation_select(self, phase, segment) local function animation_select(self, animation, segment)
local state = self.entity_ai_state local state = self.entity_ai_state
state.phase = phase state.animation = animation
local animname = self.script[state.driver].animations[phase] print("animation: " .. self.name .. ", animation = " .. animation .. ", segment = " .. (segment or 0))
if not animname then
print(self.name .. ": no animations for " .. phase .. "-" .. segment .. "(" .. animname ..")")
return
end
print("animation: " .. self.name .. ", phase = " .. phase .. ", anim = " .. animname .. ", " .. (segment or 0))
if not segment then if not segment then
local animations = self.script.animations[animname] local animations = self.script.animations[animation]
if not animations then if not animations then
print(self.name .. ": no animations for " .. phase .. "-" .. segment .. "(" .. animname ..")") print(self.name .. ": no animations for " .. animation .. ", segment = " .. (segment or 0))
return return
end end
for i = 1, 3 do for i = 1, 3 do
@ -113,14 +108,14 @@ local function animation_select(self, phase, segment)
end end
end end
else else
local animdef = self.script.animations[animname][segment] local animdef = self.script.animations[animation][segment]
if animdef then if animdef then
state.segment = segment state.segment = segment
self.object:set_animation(animdef[1], animdef.frame_speed, animdef.frame_loop) self.object:set_animation(animdef[1], animdef.frame_speed, animdef.frame_loop)
return return
end end
end end
print("animation_select: can't find animation " .. state.phase .. " for driver " .. state.driver .. " for entity " .. self.name) print("animation_select: can't find animation " .. state.animation .. " for driver " .. state.driver .. " for entity " .. self.name)
end end
local function animation_loop(self, dtime) local function animation_loop(self, dtime)
@ -132,7 +127,7 @@ local function animation_loop(self, dtime)
state.animttl = nil state.animttl = nil
state.factors.anim_end = true state.factors.anim_end = true
print("trigger anim_end") print("trigger anim_end")
animation_select(self, state.phase, state.segment + 1) animation_select(self, state.animation, state.segment + 1)
end end
end end
end end
@ -156,44 +151,11 @@ end
drivers.roam = { drivers.roam = {
start = function(self) start = function(self)
-- start with moving animation -- start with idle animation unless we get a path
animation_select(self, "idle") animation_select(self, "idle")
local state = self.entity_ai_state local state = self.entity_ai_state
state.roam_idle = true
state.roam_ttl = math.random(3, 9) state.roam_ttl = math.random(3, 9)
end,
step = function(self, dtime)
animation_loop(self, dtime)
consider_factors(self, dtime)
-- handle movement stuff
local state = self.entity_ai_state
if state.roam_ttl and state.roam_ttl > 0 then
state.roam_ttl = state.roam_ttl - dtime
if state.roam_idle then
-- we should already be stopped
return
elseif state.roam_move then
-- do path movement
if not self.path then
state.roam_ttl = 0
return
end
if self.path:distance() < 1.0 then
state.roam_ttl = 0
return
end
if not self.path:step(dtime) then
-- pathing failed
state.roam_ttl = 0
end
else
print("unknown roam state!")
end
else
-- reset ttl
state.roam_ttl = math.random(3, 9)
-- flip state
if state.roam_idle then
-- get a target -- get a target
local pos = self.object:getpos() local pos = self.object:getpos()
local minp, maxp = vector.sort({ local minp, maxp = vector.sort({
@ -209,8 +171,10 @@ drivers.roam = {
local nodes = minetest.find_nodes_in_area_under_air(minp, maxp, local nodes = minetest.find_nodes_in_area_under_air(minp, maxp,
{"group:flora", "group:snappy", "group:dirt", "group:soil", "group:crumbly", "default:dirt_with_dry_grass", "default:sand"}) {"group:flora", "group:snappy", "group:dirt", "group:soil", "group:crumbly", "default:dirt_with_dry_grass", "default:sand"})
if #nodes == 0 then if #nodes == 0 then
-- failed to get a target, just stand still -- failed to get a target
print("No target found, stopped") print("No target found, stopped")
state.driver = "idle"
drivers.idle.start(self)
return return
end end
@ -229,6 +193,8 @@ drivers.roam = {
-- move to the top surface of pick -- move to the top surface of pick
if not pick then if not pick then
print("no path found!") print("no path found!")
state.driver = "idle"
drivers.idle.start(self)
return return
end end
@ -247,20 +213,32 @@ drivers.roam = {
self.path = Path(self, pick) self.path = Path(self, pick)
if not self.path:find() then if not self.path:find() then
print("Unable to calculate path") print("Unable to calculate path")
state.driver = "idle"
drivers.idle.start(self)
return return
end end
-- done, roaming mode good! -- done, roaming mode good!
animation_select(self, "move") animation_select(self, "move")
state.roam_idle = nil end,
state.roam_move = true step = function(self, dtime)
else animation_loop(self, dtime)
animation_select(self, "idle") consider_factors(self, dtime)
state.roam_idle = true -- handle movement stuff
state.roam_move = nil local state = self.entity_ai_state
-- stop if state.roam_ttl > 0 then
self.object:setvelocity(vector.new()) state.roam_ttl = state.roam_ttl - dtime
-- do path movement
if not self.path or
self.path:distance() < 0.7 or
not self.path:step(dtime) then
state.driver = "idle"
drivers.idle.start(self)
return
end end
else
state.driver = "idle"
drivers.idle.start(self)
end end
end, end,
stop = function(self) stop = function(self)
@ -268,6 +246,27 @@ drivers.roam = {
end, end,
} }
drivers.idle = {
start = function(self)
animation_select(self, "idle")
self.object:setvelocity(vector.new())
local state = self.entity_ai_state
state.idle_ttl = math.random(2, 20)
end,
step = function(self, dtime)
animation_loop(self, dtime)
consider_factors(self, dtime)
local state = self.entity_ai_state
state.idle_ttl = state.idle_ttl - dtime
if state.idle_ttl <= 0 then
state.driver = "roam"
drivers.roam.start(self)
end
end,
stop = function(self)
end,
}
drivers.startle = { drivers.startle = {
start = function(self) start = function(self)
-- startle animation -- startle animation
@ -292,7 +291,6 @@ drivers.startle = {
drivers.eat = { drivers.eat = {
start = function(self) start = function(self)
-- startle animation
animation_select(self, "eat") animation_select(self, "eat")
self.object:setvelocity(vector.new()) self.object:setvelocity(vector.new())
-- collect info we want to use in this driver -- collect info we want to use in this driver
@ -347,7 +345,7 @@ drivers.flee = {
consider_factors(self, dtime) consider_factors(self, dtime)
-- are we fleeing yet? -- are we fleeing yet?
if self.path.distance then if self.path and self.path.distance then
-- stop fleeing if we're at a safe distance -- stop fleeing if we're at a safe distance
-- execute flee path -- execute flee path
if self.path:distance() < 2.0 then if self.path:distance() < 2.0 then
@ -431,8 +429,6 @@ drivers.flee = {
-- done, roaming mode good! -- done, roaming mode good!
animation_select(self, "move") animation_select(self, "move")
state.roam_idle = nil
state.roam_move = true
end end
end, end,
stop = function(self) stop = function(self)
@ -609,6 +605,14 @@ local sheep_script = {
-- mob script states: -- mob script states:
roam = { roam = {
driver = "roaming", driver = "roaming",
factors = {
got_hit = "startle",
became_fertile = "fertile",
attractor_nearby = "attracted",
},
},
idle = {
driver = "idle",
factors = { factors = {
got_hit = "startle", got_hit = "startle",
became_fertile = "fertile", became_fertile = "fertile",
@ -616,10 +620,6 @@ local sheep_script = {
too_far_from_home = "homing", too_far_from_home = "homing",
near_grass = "eat", near_grass = "eat",
}, },
animations = {
move = "move",
idle = "idle",
},
}, },
eat = { eat = {
driver = "eat", driver = "eat",
@ -628,19 +628,12 @@ local sheep_script = {
became_fertile = "fertile", became_fertile = "fertile",
attractor_nearby = "attracted", attractor_nearby = "attracted",
}, },
animations = {
eat = "eat",
idle = "idle",
},
}, },
startle = { startle = {
driver = "startle", driver = "startle",
factors = { factors = {
anim_end = "flee", anim_end = "flee",
}, },
animations = {
idle = "startle",
},
}, },
flee = { flee = {
driver = "flee", driver = "flee",
@ -648,9 +641,6 @@ local sheep_script = {
got_hit = "startle", got_hit = "startle",
fleed_too_long = "roam", fleed_too_long = "roam",
}, },
animations = {
move = "run",
},
}, },
attracted = { attracted = {
driver = "approach", driver = "approach",
@ -658,20 +648,12 @@ local sheep_script = {
became_fertile = "fertile", became_fertile = "fertile",
approached_too_long = "roam", approached_too_long = "roam",
}, },
animations = {
move = "move",
idle = "idle",
},
}, },
fertile = { fertile = {
driver = "mate", driver = "mate",
factors = { factors = {
got_hit = "startle", got_hit = "startle",
}, },
animations = {
move = "move",
idle = "idle",
},
}, },
homing = { homing = {
driver = "homing", driver = "homing",
@ -679,16 +661,9 @@ local sheep_script = {
near_home = "roam", near_home = "roam",
got_hit = "startle", got_hit = "startle",
}, },
animations = {
move = "move",
idle = "idle",
},
}, },
death = { death = {
driver = "death", driver = "death",
animations = {
idle = "death",
},
}, },
} }
@ -700,7 +675,7 @@ minetest.register_entity("entity_ai:sheep", {
mesh = "sheep.b3d", mesh = "sheep.b3d",
textures = {"sheep_fur.png"}, textures = {"sheep_fur.png"},
-- standard stuff -- standard stuff
collisionbox = {-7/16, -1/2, -7/16, 7/16, 6/16, 7/16}, collisionbox = {-5/16, -1/2, -5/16, 5/16, 4/16, 5/16},
-- entity_ai stuff -- entity_ai stuff
script = sheep_script, script = sheep_script,
-- standard callbacks -- standard callbacks

View File

@ -88,7 +88,7 @@ function Path:step(dtime)
local curspd = self.object:getvelocity() local curspd = self.object:getvelocity()
local pos = self.object:getpos() local pos = self.object:getpos()
-- if jumping, let jump finish before making more adjustments -- if jumping, let jump finish before making more adjustments
if curspd.y <= 0.2 and curspd.y >= 0 then if curspd.y >= 0 and curspd.y <= 2 then
local i, v = next(self.path, nil) local i, v = next(self.path, nil)
if not i then if not i then
return false return false
@ -131,7 +131,7 @@ function Path:step(dtime)
-- don't jump from too far away -- don't jump from too far away
if vdif > 0.1 and len < 1.5 then if vdif > 0.1 and len < 1.5 then
-- jump -- jump
spd = {x = spd.x/10, y = 5, z = spd.z/10} spd = {x = spd.x/4, y = 5, z = spd.z/4}
self.object:setvelocity(spd) self.object:setvelocity(spd)
elseif vdif < 0 and len <= 1.1 then elseif vdif < 0 and len <= 1.1 then
-- drop one path node just to be sure -- drop one path node just to be sure