158 lines
No EOL
7.2 KiB
Text
158 lines
No EOL
7.2 KiB
Text
------------------------------------------------------------------------------------
|
|
-- Ñõåìà: ïðÿ÷åìñÿ â êàâåðå
|
|
------------------------------------------------------------------------------------
|
|
class "evaluator_need_cover" (property_evaluator)
|
|
function evaluator_need_cover:__init(storage, name) super(nil, name)
|
|
self.st = storage
|
|
end
|
|
function evaluator_need_cover:evaluate()
|
|
return xr_logic.is_active(self.object, self.st)
|
|
end
|
|
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
class "action_cover" (action_base)
|
|
function action_cover:__init (npc_name, action_name, storage) super(nil, action_name)
|
|
self.st = storage
|
|
end
|
|
function action_cover:initialize()
|
|
action_base.initialize(self)
|
|
self.board = sim_board.get_sim_board()
|
|
end
|
|
function action_cover:activate_scheme()
|
|
self.st.signals = {}
|
|
self.board = sim_board.get_sim_board()
|
|
--' Âûñ÷èòûâàåì êàâåð.
|
|
local base_point = sim_board.get_sim_board():get_smart_by_name(self.st.smart).m_level_vertex_id
|
|
|
|
|
|
local direction_vector = vector():set(math.random(-100,100), 0, math.random(-100,100))
|
|
local base_vertex_id = level.vertex_in_direction(base_point, direction_vector, math.random(self.st.radius_min,self.st.radius_max))
|
|
local self_random_position = level.vertex_position(base_vertex_id)
|
|
|
|
--' Ïîëó÷àåì âðàãà, îòíîñèòåëüíî êîòîðîãî íàäî èñêàòü êàâåð
|
|
self.enemy_random_position = self_random_position --' äåôîëòîâàÿ ïîçèöèÿ
|
|
|
|
local cover = nil
|
|
local tcover = nil
|
|
|
|
local cover_dist = 2
|
|
while cover == nil and cover_dist <= 4 do
|
|
cover = self.object:best_cover(self_random_position, self.enemy_random_position, cover_dist, 1, 150)
|
|
cover_dist = cover_dist + 1
|
|
end
|
|
|
|
if cover == nil then
|
|
--printf("cover is [nil]")
|
|
self.cover_vertex_id = base_vertex_id
|
|
self.cover_position = self_random_position
|
|
--printf("cover doesn't exists -- cover_vertex [%s] cover_position [%s]", tostring(self.cover_vertex_id), vec_to_str(self.cover_position))
|
|
else
|
|
if tcover ~= nil then
|
|
self.cover_vertex_id = tcover.cover_vertex_id
|
|
self.cover_position = tcover.cover_position
|
|
else
|
|
self.cover_vertex_id = cover:level_vertex_id()
|
|
self.cover_position = cover:position()
|
|
end
|
|
--printf("cover exists -- cover_vertex [%s] cover_position [%s]", tostring(self.cover_vertex_id), vec_to_str(self.cover_position))
|
|
end
|
|
|
|
if not self.object:accessible(self.cover_position) then
|
|
local ttp = vector():set(0,0,0)
|
|
self.cover_vertex_id = self.object:accessible_nearest(self.cover_position, ttp)
|
|
self.cover_position = level.vertex_position(self.cover_vertex_id)
|
|
--printf("cover exists but not accesible -- cover_vertex [%s] cover_position [%s]", tostring(self.cover_vertex_id), vec_to_str(self.cover_position))
|
|
end
|
|
|
|
local desired_direction = vector():sub(self.cover_position,self.enemy_random_position)
|
|
printf("desired_direction = %s", vec_to_str(desired_direction))
|
|
if desired_direction ~= nil and not utils.vector_cmp(desired_direction, vector():set(0,0,0)) then
|
|
desired_direction:normalize()
|
|
self.object:set_desired_direction(desired_direction)
|
|
end
|
|
self.object:set_path_type(game_object.level_path)
|
|
|
|
self.object:set_dest_level_vertex_id(self.cover_vertex_id)
|
|
--printf("cover position is %s enemy position is %s", vec_to_str(self.cover_position), vec_to_str(self.enemy_random_position))
|
|
|
|
state_mgr.set_state(self.object, "assault")
|
|
--printf("[%s]Setting cover %s", self.object:name(), self.cover_vertex_id)
|
|
end
|
|
function action_cover:execute()
|
|
--printf("[%s] dist %s to %s", self.object:name(), self.cover_position:distance_to_sqr(self.object:position()), vec_to_str(self.cover_position))
|
|
--' Ïðîâåðÿåì ïðèøëè ëè â òî÷êó.
|
|
if self.cover_position:distance_to_sqr(self.object:position()) <= 0.4 then
|
|
local anim = xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.anim)
|
|
state_mgr.set_state(self.object, anim, nil, nil, {look_position = self.enemy_random_position}, nil, nil)
|
|
else
|
|
self.object:set_dest_level_vertex_id(self.cover_vertex_id)
|
|
state_mgr.set_state(self.object, "assault")
|
|
end
|
|
if self.st.sound_idle ~= nil then
|
|
xr_sound.set_sound_play(self.object:id(), self.st.sound_idle)
|
|
end
|
|
action_base.execute(self)
|
|
end
|
|
function action_cover:finalize()
|
|
action_base.finalize(self)
|
|
end
|
|
--' Âîçâðàùàåò äîñòèã ëè ïåðñîíàæ òî÷êè íà÷àëà ðàáîòû ñõåìû
|
|
function action_cover:position_riched()
|
|
return self.cover_position:distance_to_sqr(self.object:position()) <= 0.4
|
|
end
|
|
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
-- binder
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
function add_to_binder(npc, ini, scheme, section, storage)
|
|
local operators = {}
|
|
local properties = {}
|
|
|
|
local manager = npc:motivation_action_manager()
|
|
|
|
properties["event"] = xr_evaluators_id.reaction
|
|
properties["need_cover"] = xr_evaluators_id.stohe_cover_base + 1
|
|
properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4
|
|
|
|
operators["action_cover"] = xr_actions_id.stohe_cover_base + 1
|
|
|
|
-- evaluators
|
|
manager:add_evaluator(properties["need_cover"], this.evaluator_need_cover(storage, "need_cover"))
|
|
|
|
local new_action = this.action_cover(npc, "action_cover", storage)
|
|
new_action:add_precondition(world_property(stalker_ids.property_alive,true))
|
|
new_action:add_precondition(world_property(stalker_ids.property_danger,false))
|
|
new_action:add_precondition(world_property(stalker_ids.property_enemy,false))
|
|
new_action:add_precondition(world_property(stalker_ids.property_anomaly,false))
|
|
new_action:add_precondition(world_property(xr_evaluators_id.sidor_wounded_base + 0,false))
|
|
new_action:add_precondition(world_property(properties["need_cover"],true))
|
|
new_action:add_effect(world_property(properties["need_cover"],false))
|
|
new_action:add_effect (world_property(properties["state_mgr_logic_active"], false))
|
|
manager:add_action(operators["action_cover"], new_action)
|
|
|
|
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
|
|
xr_logic.subscribe_action_for_events(npc, storage, new_action)
|
|
|
|
new_action = manager:action(xr_actions_id.alife)
|
|
new_action:add_precondition(world_property(properties["need_cover"], false))
|
|
end
|
|
|
|
-- Âêëþ÷åíèå ñõåìû
|
|
function set_scheme(npc, ini, scheme, section, gulag_name)
|
|
local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
|
|
|
|
st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
|
|
|
|
st.smart = utils.cfg_get_string(ini, section, "smart", npc, false, "")
|
|
st.anim = xr_logic.parse_condlist(npc, "anim", "anim", utils.cfg_get_string(ini, section, "anim", npc, false, "", "hide"))
|
|
st.sound_idle= utils.cfg_get_string(ini, section, "sound_idle",npc, false, "")
|
|
|
|
if st.smart == nil then
|
|
abort("There is no path_walk and smart in xr_cover.")
|
|
end
|
|
|
|
st.use_attack_direction = utils.cfg_get_bool(ini, section, "use_attack_direction", npc, false, true)
|
|
|
|
st.radius_min = utils.cfg_get_number(ini, section, "radius_min", npc, false, 3)
|
|
st.radius_max = utils.cfg_get_number(ini, section, "radius_max", npc, false, 5)
|
|
end |