add game&rawdata

This commit is contained in:
Vasily Petrov 2026-06-17 23:06:51 +03:00
parent 0133cd976c
commit 49b34b5546
45731 changed files with 709831 additions and 0 deletions

View file

@ -0,0 +1,501 @@
--[[----------------------------------------------------------------------------------------------------------
Ñõåìà, âåäóùÿÿ ñòàëêåðà ê ìåñòó åãî ðàáîòû ïîä smart terrain.
Ïðèâîäèò ñòàëêåðà ê ìåñòó ðàáîòû åäèíîæäû. Äàëüøå ñòàëêåð õîäèò ïîä îáû÷íûìè ñõåìàìè.
×óãàé Àëåêñàíäð (chugai)
------------------------------------------------------------------------------------------------------------]]
--local function printf()
--end
----------------------------------------------------------------------------------------------------------------------
-- Ñõåìà ïàòðóëü äëÿ reach_task_location.
----------------------------------------------------------------------------------------------------------------------
local key = nil
local data = nil
--'patrol states
local patrol_move = 0 -- ïðîñòî äâèæåíèå
local patrol_hide = 1 -- ðàêîõîä
local patrol_sprint = 2 -- î÷åíü áûñòðî áåæèì
local patrol_run = 3 -- ïðîñòî íåñåìñÿ, àêè ëîñè â êóêóðóçó
local patrol_stop = 4 -- ñòîèì
local patrols = {}
local formations = {}
formations["back"] = {
{ dir = vector ():set (0.3, 0, -1), dist = 1.2 },
{ dir = vector ():set (-0.3, 0, -1), dist = 1.2 },
{ dir = vector ():set (0.3, 0, -1), dist = 2.4 },
{ dir = vector ():set (-0.3, 0, -1), dist = 2.4 },
{ dir = vector ():set (0.3, 0, -1), dist = 3.6 },
{ dir = vector ():set (-0.3, 0, -1), dist = 3.6 },
{ dir = vector ():set (0.3, 0, -1), dist = 4.8 },
{ dir = vector ():set (-0.3, 0, -1), dist = 4.8 },
{ dir = vector ():set (0.3, 0, -1), dist = 6 },
{ dir = vector ():set (-0.3, 0, -1), dist = 6 },
{ dir = vector ():set (0.3, 0, -1), dist = 7.2 },
{ dir = vector ():set (-0.3, 0, -1), dist = 7.2 },
{ dir = vector ():set (0.3, 0, -1), dist = 8.4 },
{ dir = vector ():set (-0.3, 0, -1), dist = 8.4}
}
local accel_by_curtype = {
walk = "run",
patrol = "rush",
raid = "assault",
sneak = "sneak_run",
sneak_run = "assault"
}
class "PatrolManager"
function PatrolManager:__init(target_id)
self.target_name = target_id
self.npc_list = {}
self.current_state = "patrol"
self.commander_id = -1
self.formation = "back"
self.commander_lid = -1
self.commander_dir = vector ():set (0, 0, 1)
self.npc_count = 0
end
--' Äîáàâëåíèå íîâîãî ïåðñîíàæà
function PatrolManager:add_npc(npc)
--'validate npc
if npc == nil or npc:alive() == false or self.npc_list[npc:id()] ~= nil then
return
end
--' Ïðîâåðêà íà òî ÷òî â ïàòðóëå íå áîëüøå 7 ñòàëêåðîâ (èíà÷å áóäåò âûëåòàòü äàëüøå)
-- if self.npc_count == 7 then
-- abort("[XR_REACH_TASK] attempt to add more then 7 npc. [%s]", npc:name())
-- return
-- end
--' if this npc first in command then set him as commander
self.npc_list[npc:id ()] = {soldier = npc:id(), dir = vector ():set (1, 0, 0), dist = 0}
self.npc_count = self.npc_count + 1
--' åñëè ìóæèê ïåðâûé èëè ñ÷èòàåòñÿ ëèäåðîì, òî óñòàíîâèì, êàê ëèäåðà
if npc:id() == get_object_squad(npc):commander_id() then
self.commander_id = npc:id ()
printf ("[XR_REACH_TASK] ASSIGNED NPC %s AS PATROL COMMANDER", npc:name ())
end
--printf ("[XR_REACH_TASK] NPC %s added to patrol manager %s", npc:name (), self.target_name)
self:reset_positions ()
end
--' Óäàëåíèå ïåðñîíàæà
function PatrolManager:remove_npc(npc)
if npc == nil then return end
if self.npc_list[npc:id()] == nil then
return
end
--printf ("[XR_REACH_TASK] NPC %s removed from patrol manager %s", npc:name(), self.target_name)
self.npc_list[npc:id ()] = nil
self.npc_count = self.npc_count - 1
if npc:id () == self.commander_id then
self.commander_id = -1
self:reset_positions ()
end
end
--' Ïåðåñ÷åò çàíèìàåìûõ ïîçèöèé
function PatrolManager:reset_positions()
local form_ = formations[self.formation]
local index = 1
for key, data in pairs(self.npc_list) do
--óñòàíîâèì êîìàíäîðà, åñëè ýòî åùå íå ñäåëàíî
local se_npc = alife():object(data.soldier)
local squad = se_npc and get_object_squad(se_npc)
if squad == nil then
return
end
if self.commander_id == -1 then
self.commander_id = squad:commander_id()
end
-- ïåðåñ÷èòàåì ïîçèöèè
if self.commander_id ~= self.npc_list[key].soldier then
--printf("key[%s] index[%s]", tostring(key), tostring(index))
self.npc_list[key].dir = form_[index].dir
self.npc_list[key].dist = form_[index].dist
self.npc_list[key].vertex_id = -1
self.npc_list[key].accepted = true
index = index + 1
end
end
end
--' Óñòàíîâëåíèå ôîðìàöèè
function PatrolManager:set_formation(formation)
if formation == nil then
abort ("Invalid formation (nil) for PatrolManager[%s]", self.target_name)
end
if formation ~= "around" and formation ~= "back" and formation ~= "line" then
abort ("Invalid formation (%s) for PatrolManager[%s]", formation, self.target_name)
end
self.formation = formation
self:reset_positions ()
end
--' Ïîëó÷èòü êîìàíäèðà ïàòðóëÿ
function PatrolManager:get_commander(npc)
if npc == nil then
abort ("Invalid NPC on call PatrolManager:get_npc_command in PatrolManager[%s]", self.target_name)
end
--çàêåøèðóåì àéäèøíèê íåïèñÿ
local npc_id = npc:id ()
--ïðîâåðêà íåïèñÿ íà ïðèñóòñâèå â ñïèñêå
if self.npc_list[npc:id ()] == nil then
abort ("NPC with name %s can't present in PatrolManager[%s]", npc:name (), self.target_name)
end
--ïðîâåðêà, ÷òîáû êîìàíäèð íå âçäóìàë çàäàâàòü ãëóïûõ âîïðîñîâ
if npc:id () == self.commander_id then
abort ("Patrol commander called function PatrolManager:get_npc_command in PatrolManager[%s]", self.target_name)
end
--ïîëó÷èì äàííûå êîìàíäèðà
local commander = self.npc_list[self.commander_id].soldier
if commander == nil then
abort ("Patrol commander not present in PatrolManager[%s]", self.target_name)
end
return level.object_by_id(commander)
end
--' Ïîëó÷èòü ïàðàìåòðû äåéñòâèÿ NPC
function PatrolManager:get_npc_command(npc)
if npc == nil then
abort("Invalid NPC on call PatrolManager:get_npc_command in PatrolManager[%s]", self.target_name)
end
--'çàêåøèðóåì àéäèøíèê íåïèñÿ
local npc_id = npc:id ()
if self.npc_list[self.commander_id] == nil then
return npc:level_vertex_id(), npc:direction(), self.current_state
end
--'ïðîâåðêà íåïèñÿ íà ïðèñóòñâèå â ñïèñêå
if self.npc_list[npc:id ()] == nil then
abort("NPC with name %s can't present in PatrolManager[%s]", npc:name (), self.target_name)
end
--'ïðîâåðêà, ÷òîáû êîìàíäèð íå âçäóìàë çàäàâàòü ãëóïûõ âîïðîñîâ
if npc:id() == self.commander_id then
abort("Patrol commander called function PatrolManager:get_npc_command in PatrolManager[%s]", self.target_name)
end
--'ïîëó÷èì äàííûå êîìàíäèðà
local commander = level.object_by_id(self.npc_list[self.commander_id].soldier)
if commander == nil then
abort("commander is nil!!!")
end
local dir = commander:direction()
local pos = vector():set(0, 0, 0)
local vertex_id = commander:location_on_path(5, pos)
--' Åñëè êîìàíäèð ñàì åùå íå äîøåë äî ïóòè (ðàññòîÿíèå äî âåðòåêñà áîëüøå ÷åì 5 ìåòðîâ)
--' òî çà îñíîâíóþ òî÷êó áåðåì âåðòåêñ êîìàíäèðà
if level.vertex_position(vertex_id):distance_to(level.object_by_id(self.npc_list[npc_id].soldier):position()) > 5 then
vertex_id = commander:level_vertex_id()
end
--'óáåðåì âëèÿíèå âåðòèêàëüíîé ñîñòàâëÿþùåé
dir.y = 0
dir:normalize()
--'ïîëó÷èì äàííûå ñàëàãè
local dir_s = self.npc_list[npc_id].dir
local dist_s = self.npc_list[npc_id].dist
--'ðàñ÷åò ïîçèöèè äëÿ ñàëàãè
--'ñíà÷àëà ïîëó÷èì íàïðàâëåíèå
local angle = yaw_degree(dir_s, vector():set(0, 0, 1))
local vvv = vector_cross(dir_s, vector():set(0, 0, 1))
if vvv.y < 0 then
angle = -angle
end
dir_s = vector_rotate_y(dir, angle)
local d = 2
--'òåïåðü àè íîäó îòíîñèòåëüíî êîìàíäîðà îðäåíà ðûöàðåé õðàìà
local vertex = level.vertex_in_direction(level.vertex_in_direction(vertex_id, dir_s, dist_s), dir, d)
self.npc_list[npc_id].vertex_id = vertex
--' ïðîâåðèì, à íå èìååò ëè ñìûñëà íåïèñþ ñêîððåêòèðîâàòü ñâîþ ïîçèöèþ
--local distance = level.vertex_position(vertex):distance_to(self.npc_list[npc_id].soldier:position())
-- íóæíî ñ÷èòàòü îòñòàâàíèå îò êîìàíäèðà, à íå îò ðàñ÷åòíîé òî÷êè.
local distance = commander:position():distance_to(level.object_by_id(self.npc_list[npc_id].soldier):position())
if distance > dist_s + 2 then
--' Èãðîê ñèëüíî îòñòàë. Íåîáõîäèìî èçìåíèòü òèï ïåðåìåùåíèÿ.
--' Òèï ïåðåìåùåíèÿ çàäàåì â çàâèñèìîñòè îò áàçîâîãî òèïà.
local new_state = accel_by_curtype[self.current_state]
if new_state ~= nil then
return vertex, dir, new_state
end
end
return vertex, dir, self.current_state
end
--' Óñòàíîâèòü äåéñòâèå ÍÏÑ
function PatrolManager:set_command(npc, command, formation)
if npc == nil or npc:alive () == false then
abort ("NPC commander possible dead in PatrolManager[%s]", self.target_name)
end
if npc:id () ~= self.commander_id then
return --abort ("NPC %s is not commander in PatrolManager[%s]", npc:name (), self.target_name)
end
self.current_state = command
if self.formation ~= formation then
self.formation = formation
self:set_formation (formation)
end
self.commander_lid = npc:level_vertex_id ()
self.commander_dir = npc:direction ()
self:update ()
end
--' ßâëÿåòñÿ ëè óêàçàííûé ÍÏÑ êîìàíäèðîì.
function PatrolManager:is_commander(npc_id)
return npc_id == self.commander_id
end
--' Íàõîäèòñÿ ëè êîìàíäèð ïàòðóëÿ â ñõåìå XR_MEET
function PatrolManager:is_commander_in_meet()
if self.commander_id == -1 then return false end
local npc = level.object_by_id(self.npc_list[self.commander_id].soldier)
if npc ~= nil and npc:alive () == true then
return xr_meet.is_meet (npc)
end
return false
end
--' Àïäåéò
function PatrolManager:update ()
if tm_enabled == true then
self.tm:update ()
end
end
local function squad_current_action (object)
local squad = get_object_squad(object)
return squad and squad.current_action
end
-- âêëþ÷åíèå ïàòðóëÿ
local function add_to_patrol(npc, target_id)
local squad_id = get_object_squad(npc).id
if patrols[target_id.."_to_"..squad_id] == nil then
patrols[target_id.."_to_"..squad_id] = PatrolManager(target_id)
end
patrols[target_id.."_to_"..squad_id]:add_npc(npc)
end
class "evaluator_reached_task_location" ( property_evaluator )
function evaluator_reached_task_location:__init( name, storage ) super ( nil, name )
self.st = storage
end
function evaluator_reached_task_location:evaluate()
local squad = get_object_squad(self.object)
if squad and squad.current_action and squad.current_action.name == "reach_target" then
local squad_target = alife():object(squad.assigned_target_id)
if squad_target == nil then
return false
end
return not squad_target:am_i_reached(squad)
end
return false
end
--------------------------------------------------------------------------------------------------------------
-- äåéñòâèå "äîâåñòè ñòàëêåðà ê ìåñòó ðàáîòû"
class "action_reach_task_location" ( action_base )
function action_reach_task_location:__init( name, storage ) super ( nil, name )
self.st = storage
end
function action_reach_task_location:initialize()
action_base.initialize( self )
self.target_id = get_object_squad(self.object).assigned_target_id
self.squad_id = get_object_squad(self.object).id
self.cur_state = "patrol"
self.formation = "back"
self.l_vid = -1
self.dist = 0
self.dir = vector():set(0, 0, 1)
self.on_point = false
self.was_reset = false
self.time_to_update = time_global () + 1000
self.object:set_desired_direction ()
self.object:set_movement_selection_type (game_object.alifeMovementTypeMask)
self.object:set_item (object.idle, self.object:best_weapon())
self.object:set_body_state (move.standing)
self.object:set_detail_path_type ( move.line )
self.object:set_mental_state (anim.free)
self.object:set_movement_type (move.walk)
local squad_target = alife():object(self.target_id)
self.object:set_dest_game_vertex_id (squad_target.m_game_vertex_id)
self.object:set_path_type ( game_object.game_path )
self.object:inactualize_patrol_path ()
self.object:set_sight (look.path_dir,nil,0)
add_to_patrol (self.object, self.target_id)
end
function action_reach_task_location:execute()
if self.object:id() == get_object_squad(self.object):commander_id() then
self:commander_execute()
else
self:soldier_execute()
end
action_base.execute (self)
end
function action_reach_task_location:finalize()
self.object:set_movement_selection_type(game_object.alifeMovementTypeRandom)
action_base.finalize( self )
end
function action_reach_task_location:commander_execute()
local squad = get_object_squad(self.object)
local squad_target = simulation_objects.get_sim_obj_registry().objects[squad.assigned_target_id]
if squad_target == nil and squad:get_script_target() ~= nil then
squad_target = alife():object(squad.assigned_target_id)
end
local function update_movement (target, object)
if target ~= nil and not object:is_talking() then
if xr_conditions.surge_started() then
object:set_movement_type(move.run)
object:set_mental_state (anim.free)
return
end
if target:clsid() == clsid.online_offline_group_s then
object:set_movement_type(move.run)
if target.position:distance_to_sqr(object:position()) <= 10000 then
object:set_mental_state (anim.danger)
else
object:set_mental_state (anim.free)
end
else
object:set_movement_type(move.walk)
object:set_mental_state (anim.free)
end
else
object:set_movement_type(move.stand)
end
end
if squad_target ~= nil and not self.object:is_talking() then
local pos, lv_id, gv_id = squad_target:get_location()
if self.object:game_vertex_id() ~= gv_id then
self.object:set_path_type (game_object.game_path)
self.object:set_dest_game_vertex_id (gv_id)
self.object:set_sight (look.path_dir,nil,0)
update_movement (squad_target, self.object)
patrols[self.target_id.."_to_"..self.squad_id]:set_command(self.object, self.cur_state, self.formation)
return
end
self.object:set_path_type ( game_object.level_path )
if not self.object:accessible(pos) then
local ttp = vector():set(0,0,0)
lv_id = self.object:accessible_nearest(pos, ttp)
pos = level.vertex_position(lv_id)
end
self.object:set_sight (look.path_dir,nil,0)
self.object:set_dest_level_vertex_id(lv_id)
self.object:set_desired_position(pos)
end
update_movement (squad_target, self.object)
patrols[self.target_id.."_to_"..self.squad_id]:set_command(self.object, self.cur_state, self.formation)
end
function action_reach_task_location:soldier_execute()
if self.time_to_update - time_global() > 0 then
return
end
local squad = get_object_squad(self.object)
local squad_target = simulation_objects.get_sim_obj_registry().objects[squad.assigned_target_id]
if squad_target == nil and squad:get_script_target() ~= nil then
squad_target = alife():object(squad.assigned_target_id)
end
self.time_to_update = time_global() + 1000
self.l_vid, self.dir, self.cur_state = patrols[self.target_id.."_to_"..self.squad_id]:get_npc_command(self.object)
self.l_vid = utils.send_to_nearest_accessible_vertex(self.object, self.l_vid)
local desired_direction = self.dir
--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)
if squad_target == nil or squad_target:clsid() == clsid.online_offline_group_s or xr_conditions.surge_started() then
self.object:set_movement_type(level.object_by_id(squad:commander_id()):movement_type())
self.object:set_mental_state (level.object_by_id(squad:commander_id()):mental_state())
return
end
if level.object_by_id(get_object_squad(self.object):commander_id()):movement_type() == move.stand then
self.object:set_movement_type(move.stand)
return
end
if level.vertex_position(self.l_vid):distance_to(self.object:position()) > 5 then
self.object:set_movement_type(move.run)
else
self.object:set_movement_type(move.walk)
end
end
function action_reach_task_location:death_callback(npc)
if self.target_id ~= nil then
patrols[self.target_id.."_to_"..self.squad_id]:remove_npc(npc)
end
end
function action_reach_task_location:net_destroy(npc)
if self.target_id ~= nil then
patrols[self.target_id.."_to_"..self.squad_id]:remove_npc(npc)
end
end
--------------------------------------------------------------------------------------------------------------
function set_reach_task( npc, ini, scheme)
local st = xr_logic.assign_storage_and_bind( npc, ini, scheme )
end
function add_to_binder(npc, ini, scheme, section, storage)
local manager = npc:motivation_action_manager()
local alife_action = manager:action(stalker_ids.action_alife_planner)
local alife_action_planner = cast_planner(alife_action)
local new_action = alife_action_planner:action(stalker_ids.action_smart_terrain_task)
xr_logic.subscribe_action_for_events(npc, storage, new_action)
end
function add_reach_task_action(npc)
local manager = npc:motivation_action_manager()
local alife_action = manager:action(stalker_ids.action_alife_planner)
local alife_action_planner = cast_planner(alife_action)
alife_action_planner:remove_evaluator(stalker_ids.property_smart_terrain_task)
alife_action_planner:add_evaluator(stalker_ids.property_smart_terrain_task, evaluator_reached_task_location( "reached_task_location", st))
alife_action_planner:remove_action(stalker_ids.action_smart_terrain_task)
local new_action = action_reach_task_location("reach_task_location", st)
new_action:add_precondition (world_property(stalker_ids.property_alife, true))
new_action:add_precondition (world_property(stalker_ids.property_smart_terrain_task, true))
new_action:add_effect (world_property(stalker_ids.property_smart_terrain_task, false))
alife_action_planner:add_action(stalker_ids.action_smart_terrain_task, new_action)
end