688 lines
24 KiB
Text
688 lines
24 KiB
Text
----------------------------------------------------------------------------------------------------------------------
|
|
-- Ìåíåäæåð èçìåíåíèÿ ñîñòîÿíèÿ òåëà
|
|
-- àâòîð: Äèäåíêî Ðóñëàí (Stohe)
|
|
-- TODO:
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
--function printf()
|
|
--end
|
|
|
|
aim_ratio = 1000/50
|
|
min_ratio = 1500
|
|
|
|
--' Ýâàëóàòîð, êîòîðûé ñèíõðîíèçèðóåò ìåíåäæåð.
|
|
--' Ìû óæå â áåçðàëè÷íîì ñîñòîÿíèè idle èëè íåò
|
|
class "evaluator_state_mgr_idle" (property_evaluator)
|
|
function evaluator_state_mgr_idle:__init(name, state_manager) super (nil, name)
|
|
self.st = state_manager
|
|
self.mgr = nil
|
|
end
|
|
function evaluator_state_mgr_idle:evaluate()
|
|
local t = self.st.target_state == "idle" and
|
|
--not self.st.planner:evaluator(self.st.properties["locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animstate_locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animation_locked"]):evaluate() and
|
|
|
|
self.st.planner:evaluator(self.st.properties["movement"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animstate"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animation"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["smartcover"]):evaluate()
|
|
|
|
if self.mgr == nil then
|
|
self.mgr = self.object:motivation_action_manager()
|
|
end
|
|
|
|
if not self.mgr:initialized() then
|
|
return false
|
|
end
|
|
|
|
if t == true then
|
|
if self.mgr:current_action_id() == xr_actions_id.state_mgr + 1 then
|
|
self.st.combat = true
|
|
end
|
|
end
|
|
|
|
if self.st.combat == true then return true end
|
|
|
|
--' Åñëè ó íàñ ïîñò êîìáàò âåéò - âåðíóòü ÒÐÓ. Äåëàëîñü, ÷òîáû êîãäà ÷óâàê âûïîëíÿåò ïîñò êîìáàò, îí ñ÷èòàë ÷òî ñòåéò ìåíåäæåð íàõîäèòñÿ â áåçðàçëè÷íîì ñîñòîÿíèè.
|
|
|
|
-- Çàðåìëåííî, ïîòîìó ÷òî áûë áàã, êîãäà ÷óâàê óæå âûïîëíÿåò ïëàííåð êîìáàòà, à åùå íå âûøåë èç àíèìàöèè ïîñòêîìáàòà
|
|
-- UPD: Îòðåìëåíî, ïîòîìó ÷òî ñòåéò ìåíåäæåð íå èìååò ïðàâà ðàáîòàòü âî âðåìÿ ïîñò êîìáàòà.
|
|
if self.combat_planner == nil then
|
|
self.combat_planner = cast_planner(self.mgr:action(stalker_ids.action_combat_planner))
|
|
end
|
|
if not self.combat_planner:initialized() then
|
|
return false
|
|
end
|
|
--if self.combat_planner:current_action_id() == stalker_ids.action_post_combat_wait then
|
|
-- return true
|
|
--end
|
|
|
|
|
|
|
|
return false
|
|
end
|
|
|
|
--' Ìû óæå â áåçðàëè÷íîì ñîñòîÿíèè idle èëè íåò ()ó÷åò ñ ïðîâåðêîé alife
|
|
class "evaluator_state_mgr_idle_alife" (property_evaluator)
|
|
function evaluator_state_mgr_idle_alife:__init(name, state_manager) super (nil, name)
|
|
self.st = state_manager
|
|
self.t = nil
|
|
end
|
|
function evaluator_state_mgr_idle_alife:evaluate()
|
|
if not self.object:alive() then
|
|
return true
|
|
end
|
|
-- àïäåéò ìåíåäæåðà àíèìàöèé
|
|
-- ðàíüøå îí áûë òóò, ñåé÷àñ îí âûíåñåí èç ýâàëóàòîðà
|
|
|
|
-- printf("SECTION %s", utils.to_str(db.storage[self.st.npc:id()].active_section))
|
|
mgr = self.object:motivation_action_manager()
|
|
self.t = nil
|
|
if mgr:initialized() then
|
|
self.t = mgr:current_action_id()
|
|
--printf("ACTION %s", utils.to_str(self.t))
|
|
if self.t ~= xr_actions_id.alife then
|
|
self.st.alife = false
|
|
end
|
|
end
|
|
|
|
-- if db.storage[self.st.npc:id()].active_section == nil then --Çàðåìèë, ïîòîìó ÷òî ÷óâàêè ïîêà ó íèõ åñòü àêòèâíàÿ ñåêöèÿ ñðûâàëèñü â àëàéô áåç êîððåêòíîãî çàâåðøåíèÿ àíèìàöèé
|
|
if xr_meet.is_meet(self.object) == false then
|
|
local t = self.st.target_state == "idle" and
|
|
--not self.st.planner:evaluator(self.st.properties["locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["weapon_locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animstate_locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animation_locked"]):evaluate() and
|
|
|
|
self.st.planner:evaluator(self.st.properties["movement"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animstate"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animation"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["smartcover"]):evaluate()
|
|
|
|
-- printf("[%s] %s", self.object:name(), utils.to_str(self.st.target_state))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["locked"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["movement"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["animstate"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["animation"]):evaluate()))
|
|
|
|
if t == true then self.st.alife = true end
|
|
if self.st.alife == true then
|
|
return true
|
|
end
|
|
return t
|
|
else
|
|
return false
|
|
end
|
|
-- end
|
|
-- return true
|
|
end
|
|
|
|
--' Ìû óæå â áåçðàëè÷íîì ñîñòîÿíèè idle èëè íåò ()ó÷åò ñ ïðîâåðêîé alife
|
|
class "evaluator_state_mgr_idle_items" (property_evaluator)
|
|
function evaluator_state_mgr_idle_items:__init(name, state_manager) super (nil, name)
|
|
self.st = state_manager
|
|
self.t = nil
|
|
end
|
|
function evaluator_state_mgr_idle_items:evaluate()
|
|
if not self.object:alive() then
|
|
return true
|
|
end
|
|
-- àïäåéò ìåíåäæåðà àíèìàöèé
|
|
-- ðàíüøå îí áûë òóò, ñåé÷àñ îí âûíåñåí èç ýâàëóàòîðà
|
|
|
|
-- printf("SECTION %s", utils.to_str(db.storage[self.st.npc:id()].active_section))
|
|
-- mgr = self.object:motivation_action_manager()
|
|
-- self.t = nil
|
|
-- if mgr:initialized() then
|
|
-- self.t = mgr:current_action_id()
|
|
-- --printf("ACTION %s", utils.to_str(self.t))
|
|
-- if self.t ~= xr_actions_id.alife then
|
|
-- self.st.alife = false
|
|
-- end
|
|
-- end
|
|
|
|
-- if db.storage[self.st.npc:id()].active_section == nil then --Çàðåìèë, ïîòîìó ÷òî ÷óâàêè ïîêà ó íèõ åñòü àêòèâíàÿ ñåêöèÿ ñðûâàëèñü â àëàéô áåç êîððåêòíîãî çàâåðøåíèÿ àíèìàöèé
|
|
if xr_meet.is_meet(self.object) == false then
|
|
local t = self.st.target_state == "idle" and
|
|
-- not self.st.planner:evaluator(self.st.properties["locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animstate_locked"]):evaluate() and
|
|
not self.st.planner:evaluator(self.st.properties["animation_locked"]):evaluate() and
|
|
|
|
self.st.planner:evaluator(self.st.properties["movement"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animstate"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["animation"]):evaluate() and
|
|
self.st.planner:evaluator(self.st.properties["smartcover"]):evaluate()
|
|
|
|
-- printf("[%s] %s", self.object:name(), utils.to_str(self.st.target_state))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["locked"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["movement"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["animstate"]):evaluate()))
|
|
-- printf("%s", utils.to_str(self.st.planner:evaluator(self.st.properties["animation"]):evaluate()))
|
|
|
|
-- if t == true then self.st.alife = true end
|
|
-- if self.st.alife == true then
|
|
-- return true
|
|
-- end
|
|
return t
|
|
else
|
|
return false
|
|
end
|
|
-- end
|
|
-- return true
|
|
end
|
|
|
|
|
|
class "evaluator_state_mgr_logic_active" (property_evaluator)
|
|
function evaluator_state_mgr_logic_active:__init(name, state_manager) super (nil, name)
|
|
self.st = state_manager
|
|
self.t = nil
|
|
end
|
|
function evaluator_state_mgr_logic_active:evaluate()
|
|
--printf("evaluator_state_mgr_logic_active [%s] active_section[%s]", self.object:name(), tostring(db.storage[self.object:id()].active_section))
|
|
if db.storage[self.object:id()].active_section == nil then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
--' Ïåðåõîä â idle
|
|
class "act_state_mgr_to_idle" (action_base)
|
|
function act_state_mgr_to_idle:__init(name,state_manager) super (nil, name)
|
|
self.st = state_manager
|
|
end
|
|
function act_state_mgr_to_idle:initialize()
|
|
action_base.initialize(self)
|
|
--' self.object:movement_enabled(true)
|
|
|
|
self.object:inactualize_patrol_path ()
|
|
|
|
if self.object:best_enemy() then
|
|
self.st:set_state("idle", nil, nil, nil, {fast_set = true})
|
|
return
|
|
end
|
|
if self.object:best_danger() then
|
|
self.st:set_state("idle", nil, nil, nil, {fast_set = true})
|
|
return
|
|
end
|
|
self.st:set_state("idle")
|
|
utils.send_to_nearest_accessible_vertex( self.object, self.object:level_vertex_id() )
|
|
self.object:set_path_type ( game_object.level_path )
|
|
end
|
|
function act_state_mgr_to_idle:execute()
|
|
utils.send_to_nearest_accessible_vertex( self.object, self.object:level_vertex_id() )
|
|
self.object:set_path_type ( game_object.level_path )
|
|
if self.object:best_enemy() then
|
|
self.st:set_state("idle", nil, nil, nil, {fast_set = true})
|
|
action_base.execute(self)
|
|
return
|
|
end
|
|
if self.object:best_danger() then
|
|
self.st:set_state("idle", nil, nil, nil, {fast_set = true})
|
|
action_base.execute(self)
|
|
return
|
|
end
|
|
self.st:set_state("idle")
|
|
action_base.execute(self)
|
|
end
|
|
function act_state_mgr_to_idle:finalize()
|
|
-- Ïî çàâåðøåíèþ ïåðåõîäà íóæíî çàïèñàòü -1 â óêàçàòåëü "íà êîãî ñìîòðåòü",
|
|
-- ÷òîáû ïðè âîçâðàòå áûëî ïîíÿòíî ÷òî åãî íóæíî ïåðåèíèöèàëèçèðîâàòü.
|
|
|
|
self.st.current_object = -1
|
|
|
|
action_base.finalize(self)
|
|
end
|
|
|
|
|
|
--'-------------------------------------------------------------------------------------
|
|
--' Ýâàëóàòîðû è ýêøåíû ìåíåäæåðà
|
|
--'-------------------------------------------------------------------------------------
|
|
--' Çàêîí÷èë ëè ìåíåäæåð ñâîþ ðàáîòó
|
|
class "eva_state_mgr_end" (property_evaluator)
|
|
function eva_state_mgr_end:__init(name, st) super (nil, name)
|
|
self.st = st
|
|
self.mgr = nil
|
|
end
|
|
function eva_state_mgr_end:evaluate()
|
|
if self.mgr == nil then
|
|
self.mgr = self.object:motivation_action_manager()
|
|
end
|
|
if self.combat_planner == nil then
|
|
self.combat_planner = cast_planner(self.mgr:action(stalker_ids.action_combat_planner))
|
|
end
|
|
|
|
if not self.mgr:initialized() then
|
|
return false
|
|
end
|
|
|
|
local current_action_id = self.mgr:current_action_id()
|
|
|
|
if current_action_id == stalker_ids.action_combat_planner then
|
|
if not self.combat_planner:initialized() then
|
|
return false
|
|
end
|
|
--if self.combat_planner:current_action_id() == stalker_ids.action_post_combat_wait then
|
|
-- self.st.combat = false
|
|
--end
|
|
else
|
|
if current_action_id ~= stalker_ids.action_danger_planner and
|
|
current_action_id ~= stalker_ids.action_anomaly_planner
|
|
then
|
|
self.st.combat = false
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
--' Çàëî÷åí ëè ìåíåäæåð
|
|
class "eva_state_mgr_locked" (property_evaluator)
|
|
function eva_state_mgr_locked:__init(name, st) super (nil, name)
|
|
self.st = st
|
|
end
|
|
function eva_state_mgr_locked:evaluate()
|
|
--printf("%s weapon locked %s", self.object:name(), tostring(self.st.planner:evaluator(self.st.properties["weapon_locked"]):evaluate()))
|
|
--printf("%s turning %s", self.object:name(), tostring(self.object:is_body_turning()))
|
|
|
|
return self.st.planner:initialized() and (
|
|
self.st.planner:evaluator(self.st.properties["weapon_locked"]):evaluate() or
|
|
self.object:is_body_turning() )
|
|
|
|
|
|
end
|
|
|
|
class "eva_state_mgr_locked_external" (property_evaluator)
|
|
function eva_state_mgr_locked_external:__init(name, st) super (nil, name)
|
|
self.st = st
|
|
end
|
|
function eva_state_mgr_locked_external:evaluate()
|
|
--printf("npc %s", self.object:name())
|
|
--printf("combat[%s] alife[%s]", tostring(self.st.combat), tostring(self.st.alife))
|
|
if self.st.combat or self.st.alife then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
|
|
|
|
--' Èäëîâûé ýêøí ìåíåäæåðà
|
|
class "act_state_mgr_end" (action_base)
|
|
function act_state_mgr_end:__init(name, st) super (nil, name)
|
|
self.st = st
|
|
end
|
|
function act_state_mgr_end:initialize()
|
|
action_base.initialize(self)
|
|
end
|
|
function act_state_mgr_end:execute()
|
|
action_base.execute(self)
|
|
|
|
self:weapon_update()
|
|
end
|
|
function act_state_mgr_end:weapon_update()
|
|
-- Êîëëáåê íà çàâåðøåíèå ñîñòîÿíèÿ
|
|
if self.st.callback ~= nil then
|
|
if self.st.callback.begin == nil then
|
|
self.st.callback.begin = time_global()
|
|
end
|
|
|
|
if time_global() - self.st.callback.begin >= self.st.callback.timeout then
|
|
if self.st.callback.func ~= nil then
|
|
self.st.callback.func(self.st.callback.obj)
|
|
end
|
|
self.st.callback = nil
|
|
end
|
|
end
|
|
|
|
|
|
|
|
local t = state_lib.states[self.st.target_state].weapon
|
|
local w = isWeapon(self.object:best_weapon())
|
|
|
|
if not w then
|
|
return
|
|
end
|
|
if t == "fire" or t == "sniper_fire" then
|
|
-- printf("[%s] shooting", self.object:name())
|
|
local sniper_aim = 3000
|
|
if self.st.look_object ~= nil then
|
|
local look_object = level.object_by_id(self.st.look_object)
|
|
if look_object == nil then
|
|
self.st.look_object = nil
|
|
return
|
|
end
|
|
if self.object:see(look_object) ~= nil and
|
|
(not IsStalker(look_object) or
|
|
self.object:relation(look_object) == game_object.enemy) and
|
|
look_object:alive() == true
|
|
then
|
|
if t == "sniper_fire" then
|
|
sniper_aim = self.object:position():distance_to(look_object:position())*aim_ratio
|
|
if sniper_aim <= min_ratio then
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), 1, min_ratio)
|
|
return
|
|
end
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), 1, sniper_aim)
|
|
else
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), state_mgr_weapon.get_queue_params(self.object, look_object, state_lib.states[self.st.target_state]))
|
|
end
|
|
return
|
|
else
|
|
self.object:set_item(object.idle, self.object:best_weapon())
|
|
return
|
|
end
|
|
end
|
|
|
|
if self.st.look_position ~= nil and
|
|
self.st.look_object == nil
|
|
then
|
|
if t == "sniper_fire" then
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), 1, sniper_aim)
|
|
else
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), state_mgr_weapon.get_queue_params(self.object, nil, state_lib.states[self.st.target_state]))
|
|
end
|
|
return
|
|
end
|
|
self.object:set_item(object.fire1, self.object:best_weapon(), state_mgr_weapon.get_queue_params(self.object, nil, state_lib.states[self.st.target_state]))
|
|
return
|
|
elseif t == "unstrapped" then
|
|
--printf("[%s] not shooting", self.object:name())
|
|
self.object:set_item(state_mgr_weapon.get_idle_state(self.st.target_state), self.object:best_weapon())
|
|
end
|
|
end
|
|
function act_state_mgr_end:finalize()
|
|
action_base.finalize(self)
|
|
end
|
|
|
|
--' Ëîê ìåíåäæåðà
|
|
class "act_state_mgr_locked" (action_base)
|
|
function act_state_mgr_locked:__init(name, st) super (nil, name)
|
|
self.st = st
|
|
end
|
|
function act_state_mgr_locked:initialize()
|
|
action_base.initialize(self)
|
|
end
|
|
function act_state_mgr_locked:execute()
|
|
action_base.execute(self)
|
|
end
|
|
function act_state_mgr_locked:finalize()
|
|
action_base.finalize(self)
|
|
end
|
|
|
|
|
|
--' Ñàì ìåíåäæåð
|
|
class "state_manager"
|
|
function state_manager:__init(npc)
|
|
state_mgr_goap.goap_graph(self, npc)
|
|
|
|
self.target_state = "idle"
|
|
self.current_direction = nil
|
|
self.target_position = nil
|
|
self.current_object = nil
|
|
self.combat = false
|
|
self.alife = true
|
|
self.need_reweapon = false
|
|
|
|
self.animation_position = nil
|
|
self.animation_direction = nil
|
|
self.pos_direction_applied = false
|
|
end
|
|
function state_manager:set_state(state_name, callback, timeout, target, extra)
|
|
--printf("Set State called: for %s State: %s", self.npc:name(), state_name)
|
|
--callstack()
|
|
|
|
if state_lib.states[state_name] == nil then
|
|
abort("ERROR: ILLEGAL SET STATE CALLED!!! %s fo %s", tostring(state_name), self.npc:name())
|
|
end
|
|
if target then
|
|
if target.look_position then
|
|
--printf("look position: %s %s %s", target.look_position.x,
|
|
-- target.look_position.y,
|
|
-- target.look_position.z)
|
|
else
|
|
--printf("look position: NIL")
|
|
end
|
|
if target.look_object then
|
|
--printf("look object: %s", target.look_object:name())
|
|
else
|
|
--printf("look object: NIL")
|
|
end
|
|
else
|
|
--printf("look target NIL")
|
|
end
|
|
|
|
--ñïåðâà óñòàíàâëèâàåì öåëè
|
|
if target ~= nil then
|
|
self.look_position = target.look_position
|
|
if target.look_object ~= nil then
|
|
self.look_object = target.look_object:id()
|
|
else
|
|
self.look_object = nil
|
|
end
|
|
else
|
|
self.look_position = nil
|
|
self.look_object = nil
|
|
end
|
|
|
|
local switched = false
|
|
local last_state = self.target_state
|
|
if self.target_state ~= state_name then
|
|
--printf("Set State called: for %s State: %s [%s]", self.npc:name(), state_name, device():time_global())
|
|
--callstack()
|
|
--log(string.format("Set State called: for %s State: %s [%s]", self.npc:name(), state_name, device():time_global()))
|
|
--' Åñëè ìû ïåðåêëþ÷àåìñÿ èç ñòðåëÿþùåãî ñîñòîÿíèÿ â íåñòðåëÿþùåå - íåîáõîäèìî ñðàçó æå ïðåêðàòèòü ñòðåëüáó
|
|
|
|
if (state_lib.states[self.target_state].weapon == "fire" or
|
|
state_lib.states[self.target_state].weapon == "sniper_fire") and -- or self.target_state == "idle" Çàðåìèë, ïîòîìó ÷òî çàëèïàëè â àíèìïîèíòàõ, êîãäà ïðè àêòèâíîé àíèìàöèè àíñòðàïàëîñü îðóæèå.
|
|
(state_lib.states[state_name].weapon ~= "fire" and
|
|
state_lib.states[state_name].weapon ~= "sniper_fire")
|
|
then
|
|
--self.npc:set_item(state_mgr_weapon.get_idle_state(state_name), state_mgr_weapon.get_weapon(self.npc, state_name))
|
|
if self.npc:weapon_unstrapped() then
|
|
self.npc:set_item(object.idle, state_mgr_weapon.get_weapon(self.npc, state_name))
|
|
--printf("[%s] stop shooting", self.npc:name())
|
|
end
|
|
end
|
|
|
|
|
|
--' Ïðîâåðêà íà íåîáõîäèìîñòü special_danger_move
|
|
if state_lib.states[state_name].special_danger_move == true then
|
|
--printf("SPECIAL DANGER MOVE %s for stalker [%s]", tostring(self.npc:special_danger_move()), self.npc:name())
|
|
if self.npc:special_danger_move() ~= true then
|
|
self.npc:special_danger_move(true)
|
|
end
|
|
else
|
|
--printf("SPECIAL DANGER MOVE %s for stalker [%s]", tostring(self.npc:special_danger_move()), self.npc:name())
|
|
if self.npc:special_danger_move() == true then
|
|
self.npc:special_danger_move(false)
|
|
end
|
|
end
|
|
|
|
self.target_state = state_name
|
|
self.current_object = nil
|
|
switched = true
|
|
|
|
if extra ~= nil then
|
|
self.fast_set = extra.fast_set
|
|
|
|
-- Çàíîâî çàñòàâëÿåì ïðèìåíèòü ïîçèöèþ è íàïðàâëåíèå â ñëó÷àå åñëè îíî íå áûëî ïðèìåíåíî ëèáî ïîçèöèÿ è íàïðàâëåíèå èçìåíèëèñü.
|
|
if self.pos_direction_applied == false or
|
|
(self.animation_position ~= nil and extra.animation_position ~= nil and (not utils.vector_cmp(self.animation_position, extra.animation_position)) or
|
|
self.animation_direction ~= nil and extra.animation_direction ~= nil and (not utils.vector_cmp(self.animation_direction, extra.animation_direction)) )
|
|
|
|
then
|
|
self.animation_position = extra.animation_position
|
|
self.animation_direction = extra.animation_direction
|
|
self.pos_direction_applied = false
|
|
end
|
|
else
|
|
self.animation_position = nil
|
|
self.animation_direction = nil
|
|
self.pos_direction_applied = false
|
|
self.fast_set = nil
|
|
|
|
end
|
|
|
|
self.callback = callback
|
|
if timeout ~= nil and
|
|
timeout >= 0
|
|
then
|
|
self.callback.timeout = timeout
|
|
self.callback.begin = nil
|
|
else
|
|
if self.callback then
|
|
self.callback.func = nil
|
|
self.callback.timeout = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function state_manager:get_state()
|
|
return self.target_state
|
|
end
|
|
function state_manager:update()
|
|
--printf("Update called for stalker [%s]", self.npc:name())
|
|
-- Îáðàáàòûâàåì êîëëáåê
|
|
if self.animation.states.current_state == state_lib.states[self.target_state].animation then
|
|
if self.callback ~= nil and
|
|
self.callback.func ~= nil
|
|
then
|
|
if self.callback.begin == nil then
|
|
-- Èíèöèàëèçèðóåì êîëëáåê
|
|
self.callback.begin = time_global()
|
|
--printf(" Callback initialized %s", time_global())
|
|
else
|
|
-- Ïðîâåðÿåì, íå ïðèøëî ëè âðåìÿ âûçâàòü êîëëáåê
|
|
if time_global() - self.callback.begin >= self.callback.timeout then
|
|
--printf(" Callback called %s", time_global())
|
|
|
|
local a = self.callback.func
|
|
local b = self.callback.obj
|
|
self.callback.begin = nil
|
|
self.callback.func = nil
|
|
a(b)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local last_pl_id = nil
|
|
self.planner:update()
|
|
if not self.planner:initialized() then return end
|
|
local pl_id = self.planner:current_action_id()
|
|
while pl_id ~= last_pl_id and
|
|
pl_id ~= self.operators["end"] and
|
|
pl_id ~= self.operators["locked"]
|
|
do
|
|
last_pl_id = pl_id
|
|
self.planner:update()
|
|
pl_id = self.planner:current_action_id()
|
|
end
|
|
|
|
--self.planner:show("")
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function set_state(npc, state_name, callback, timeout, target, extra)
|
|
if db.storage[npc:id()].state_mgr then
|
|
db.storage[npc:id()].state_mgr:set_state(state_name, callback, timeout, target, extra)
|
|
end
|
|
end
|
|
function get_state(npc)
|
|
if db.storage[npc:id()].state_mgr then
|
|
return db.storage[npc:id()].state_mgr:get_state()
|
|
end
|
|
return nil
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function bind_manager(object)
|
|
local manager = object:motivation_action_manager()
|
|
|
|
|
|
local properties = {}
|
|
properties["state_mgr_idle_combat"] = xr_evaluators_id.state_mgr + 1
|
|
properties["state_mgr_idle_alife"] = xr_evaluators_id.state_mgr + 2
|
|
properties["state_mgr_idle_smartcover"] = xr_evaluators_id.state_mgr + 3
|
|
properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4
|
|
properties["state_mgr_idle_items"] = xr_evaluators_id.state_mgr + 5
|
|
|
|
local operators = {}
|
|
operators["state_mgr_to_idle_combat"] = xr_actions_id.state_mgr + 1
|
|
operators["state_mgr_to_idle_alife"] = xr_actions_id.state_mgr + 2
|
|
operators["state_mgr_to_idle_items"] = xr_actions_id.state_mgr + 3
|
|
|
|
local state_manager = state_mgr.state_manager(object)
|
|
|
|
manager:add_evaluator(properties["state_mgr_idle_combat"], evaluator_state_mgr_idle("state_mgr_idle_combat", state_manager))
|
|
manager:add_evaluator(properties["state_mgr_idle_alife"], evaluator_state_mgr_idle_alife("state_mgr_idle_alife", state_manager))
|
|
manager:add_evaluator(properties["state_mgr_idle_items"], evaluator_state_mgr_idle_items("state_mgr_idle_items", state_manager))
|
|
manager:add_evaluator(properties["state_mgr_logic_active"], evaluator_state_mgr_logic_active("state_mgr_logic_active", state_manager))
|
|
|
|
local action = this.act_state_mgr_to_idle("state_mgr_to_idle_combat", state_manager)
|
|
action:add_precondition (world_property(properties["state_mgr_idle_combat"], false))
|
|
action:add_effect (world_property(properties["state_mgr_idle_combat"], true))
|
|
manager:add_action(operators["state_mgr_to_idle_combat"], action)
|
|
|
|
|
|
action = this.act_state_mgr_to_idle("state_mgr_to_idle_items", state_manager)
|
|
action:add_precondition (world_property(properties["state_mgr_idle_items"], false))
|
|
action:add_precondition (world_property(stalker_ids.property_items, true))
|
|
action:add_precondition (world_property(stalker_ids.property_enemy, false))
|
|
action:add_effect (world_property(properties["state_mgr_idle_items"], true))
|
|
manager:add_action(operators["state_mgr_to_idle_items"], action)
|
|
|
|
|
|
action = this.act_state_mgr_to_idle("state_mgr_to_idle_alife", state_manager)
|
|
action:add_precondition (world_property(stalker_ids.property_enemy, false))
|
|
action:add_precondition (world_property(stalker_ids.property_danger,false))
|
|
|
|
action:add_precondition (world_property(properties["state_mgr_logic_active"], false))
|
|
|
|
action:add_precondition (world_property(properties["state_mgr_idle_alife"], false))
|
|
action:add_effect (world_property(properties["state_mgr_idle_alife"], true))
|
|
manager:add_action(operators["state_mgr_to_idle_alife"], action)
|
|
|
|
|
|
action = manager:action(xr_actions_id.alife)
|
|
action:add_precondition(world_property(properties["state_mgr_idle_alife"],true))
|
|
|
|
action = manager:action(stalker_ids.action_gather_items)
|
|
action:add_precondition(world_property(properties["state_mgr_idle_items"],true))
|
|
|
|
action = manager:action(stalker_ids.action_combat_planner)
|
|
action:add_precondition(world_property(properties["state_mgr_idle_combat"],true))
|
|
|
|
action = manager:action(stalker_ids.action_anomaly_planner)
|
|
action:add_precondition(world_property(properties["state_mgr_idle_combat"],true))
|
|
|
|
action = manager:action(stalker_ids.action_danger_planner)
|
|
action:add_precondition(world_property(properties["state_mgr_idle_combat"],true))
|
|
|
|
|
|
return state_manager
|
|
end
|
|
|
|
|
|
function is_npc_in_combat(npc)
|
|
local mgr = npc:motivation_action_manager()
|
|
|
|
if not mgr:initialized() then
|
|
return false
|
|
end
|
|
|
|
local current_action_id = mgr:current_action_id()
|
|
return current_action_id == stalker_ids.action_combat_planner or
|
|
current_action_id == stalker_ids.action_post_combat_wait
|
|
end
|