they use the ai obstacle detection so there's not much we can do about that from our end, you can try adding
forcesimpleobstacle = 3
to any major obstacles but if there's a lot of obstacles they will still get confused (default ai will do the same)
script for the random sound (at slot 1)
*should be the same as yours except the sound code but might be worth renaming it anyway as any new downloads from the store will overwrite this script i guess*
--animations
-- 0 = walk
-- 1 = run
-- 2 = graze
-- 3 = look
-- 4 = die
--how close player can get before spooking the elk (halved if player is visible)
local alert_range = 500
--adjusts how likely entity is to graze / look (higher = less likely)
local anim_chance = 2
--how far from starting location elk can wander/move
local wander_range = 2500
--maximum movement between updates
local move_dist = 800
--how fast walking animations are
local walk_speed = 1
--how fast running animations are
local run_speed = 1.3
--how long dead body will stay on the ground for
local remove_delay = 5000
--delay between call sound playing (50% random so they wont all play at the same time)
local sound_delay = 10000
local delay = {}
local dead = {}
local state = {}
local startx = {}
local startz = {}
local destx = {}
local destz = {}
local dist_from_start = {}
local health = {}
local returned = {}
local new_alert_range = {}
local sound_timer = {}
function elk1_init(e)
state[e] = "walk"
returned[e] = 1
end
function elk1_main(e)
--set HP higher so we can check for death and animate correctly when killed
if health[e] == nil then
health[e] = 5000+g_Entity[e]['health']
SetEntityHealth(e,5000+g_Entity[e]['health'])
startx[e] = g_Entity[e]['x']
startz[e] = g_Entity[e]['z']
destx[e] = g_Entity[e]['x'] + math.random(-move_dist,move_dist)
destz[e] = g_Entity[e]['z'] + math.random(-move_dist,move_dist)
sound_timer[e] = GetTimer(e) + math.random(sound_delay * 0.75,sound_delay * 1.25)
--if alive
else
if g_Entity[e]['health'] > 5000 then
EntObjNum = g_Entity[e]['obj']
--check if player detected or elk is hurt
if (GetPlayerDistance(e) <= alert_range or g_Entity[e]['health'] < health[e]) and state[e] ~= "alert" then
state[e] = "alert"
StopAnimation(e)
SetCharacterToRun(e)
end
--if idle (grazing or looking)
if state[e] == "idle" then
ModulateSpeed(e,walk_speed)
--do idle animations
CharacterControlLimbo(e)
if g_Entity[e]['animating'] == 0 then
SetAnimation(math.random(2,3))
PlayAnimation(e)
g_Entity[e]['animating'] = 1
end
--if idle animations are finished then move to
if (GetAnimationFrame(e) >= 220 and GetAnimationFrame(e) <= 221) or (GetAnimationFrame(e) >= 448 and GetAnimationFrame(e) <= 450) or GetAnimationFrame(e) >= 3000 then
state[e] = "walk"
sound_timer[e] = GetTimer(e) + math.random(sound_delay * 0.75,sound_delay * 1.25)
SetCharacterToWalk(e)
destx[e] = g_Entity[e]['x'] + math.random(-move_dist/2,move_dist/2)
destz[e] = g_Entity[e]['z'] + math.random(-move_dist/2,move_dist/2)
end
elseif state[e] == "walk" then
if GetTimer(e) > sound_timer[e] then
sound_timer[e] = GetTimer(e) + math.random(sound_delay * 0.75,sound_delay * 1.25)
PlaySoundIfSilent(e,1)
end
CharacterControlUnarmed(e)
ModulateSpeed(e,walk_speed)
--check we aren't at our current destination
if g_Entity[e]['x'] < destx[e] + 75 and g_Entity[e]['x'] > destx[e] - 75 and g_Entity[e]['z'] < destz[e] + 75 and g_Entity[e]['z'] > destz[e] - 75 then
--check for look / graze
if math.random(0,anim_chance) == anim_chance then
state[e] = "idle"
CharacterControlLimbo(e)
StopAnimation(e)
else
--check distance from start position
local disx = g_Entity[e]['x'] - startx[e]
local disz = g_Entity[e]['z'] - startz[e]
dist_from_start[e] = math.sqrt(disx^2 + disz^2)
--move back to start location if we have wandered too far
if dist_from_start[e] > wander_range and returned[e] == 0 then
destx[e] = startx[e]
destz[e] = startz[e]
else
--if not grazing/looking or too far from start then update to new destination
destx[e] = g_Entity[e]['x'] + math.random(-move_dist,move_dist)
destz[e] = g_Entity[e]['z'] + math.random(-move_dist,move_dist)
end
end
else
--move to our new/current destination
AIEntityGoToPosition(EntObjNum,destx[e],destz[e])
end
--check if we are near our start position
if g_Entity[e]['x'] < startx[e] + 80 and g_Entity[e]['x'] > startx[e] - 80 and g_Entity[e]['z'] < startz[e] + 80 and g_Entity[e]['z'] > startz[e] - 80 then
returned[e] = 1
else
returned[e] = 0
end
if state[e] == "idle" then
AIEntityStop(e)
end
elseif state[e] == "alert" then
CharacterControlUnarmed(e)
ModulateSpeed(e,run_speed)
--if player still nearby then update destination to run away from him
if GetPlayerDistance(e) < alert_range * 3.75 then
if g_Entity[e]['x'] < g_PlayerPosX then
destx[e] = g_Entity[e]['x'] - move_dist
else
destx[e] = g_Entity[e]['x'] + move_dist
end
if g_Entity[e]['z'] < g_PlayerPosZ then
destz[e] = g_Entity[e]['z'] - move_dist
else
destz[e] = g_Entity[e]['z'] + move_dist
end
--move to our new/current destination
AIEntityGoToPosition(EntObjNum,destx[e],destz[e])
else
--check if we outran the player
StopAnimation(e)
health[e] = g_Entity[e]['health']
--choose new state (idle or walk)
state[e] = "walk"
SetCharacterToWalk(e)
end
end --state
--Prompt("state = "..state[e].. " , animation frame = "..GetAnimationFrame(e).. " , at starting location = "..returned[e].. " , HP = "..g_Entity[e]['health'].. " , last health = " ..health[e])
else
EntObjNum = g_Entity[e]['obj']
if dead[e] == nil then
ModulateSpeed(e,walk_speed)
if delay[e] == nil then
delay[e] = GetTimer(e) + remove_delay
end
StopAnimation(e)
dead[e] = 1
elseif dead[e] == 1 then
CharacterControlLimbo(e)
SetAnimation(4)
PlayAnimation(e)
dead[e] = 2
elseif dead[e] == 2 then
if GetTimer(e) >= delay[e] then
Destroy(e)
end
end
end --hp
end
end --main
function elk1_exit(e)
ModulateSpeed(e,walk_speed)
SetAnimation(4)
PlayAnimation(e)
end
life\'s one big game
windows vista ultimate
i5 @3.3ghz, 4gb ram, geforce gtx460, directx 11