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,577 @@
----------------------------------------------------------------------------------------------------------------------
--' Ñõåìà êåìïåð. ×óäàê ñ áàëüøîé ïóøêîé õîäèò è îòñòðåëèâàåò æèâíîñòü.
--' àâòîð: Äèäåíêî Ðóñëàí (Stohe)
--' TODO:
----------------------------------------------------------------------------------------------------------------------
--function printf()
--end
----------------------------------------------------------------------------------------------------------------------
-- EVALUATORS
----------------------------------------------------------------------------------------------------------------------
function id(npc)
if npc then
return npc:id()
end
return nil
end
--' Óñëîâèå çàâåðøåíèÿ ñêðèïòà
class "evaluator_end" (property_evaluator)
function evaluator_end:__init(name, storage) super (nil, name)
self.a = storage
end
function evaluator_end:evaluate()
return not xr_logic.is_active(self.object, self.a)
end
--' Îáû÷íûé êîìáàò èëè êåìïåðñêèé
class "evaluator_close_combat" (property_evaluator)
function evaluator_close_combat:__init(name, storage) super (nil, name)
self.a = storage
self.close_combat = false
end
function evaluator_close_combat:evaluate()
if not xr_logic.is_active(self.object, self.a) then
return true
end
if self.mgr == nil then
self.mgr = self.object:motivation_action_manager()
end
if not self.mgr:evaluator(stalker_ids.property_enemy):evaluate() then
return false
end
-- åñëè ìû íå ìîæåì âîåâàòü âîîáùå - âåðíóòü false
if not self.mgr:evaluator(xr_evaluators_id.sidor_wounded_base + 1):evaluate() then
return false
end
-- Åñëè âèäèì ãðàíàòó - àâòîìàòîì îòïóñêàåì â close_combat (âîçâðàùàåì true)
if self.mgr:evaluator(stalker_ids.property_danger):evaluate() then
return true
end
if self.object:best_enemy() == nil then
return self.close_combat -- Òóò âîçìîæíî íóæíî ïðîñòî óñòàíàâëèâàòü FALSE è âîçâðàùàòü FALSE
end
if self.close_combat == false then
self.close_combat = self.object:position():distance_to(self.object:memory_position(self.object:best_enemy())) < self.a.radius
end
if self.close_combat == true then
local a = self.object:memory_time(self.object:best_enemy())
if a then
if time_global() - a > 20000 then
self.close_combat = false
end
else
self.close_combat = false
end
end
return self.close_combat
end
----------------------------------------------------------------------------------------------------------------------
-- ACTIONS
----------------------------------------------------------------------------------------------------------------------
--' Ïàòðóëèðîâàòü òåððèòîðèþ ïî ïàòðóëüíîìó ïóòè
class "action_patrol" (action_base)
function action_patrol:__init (npc,action_name,storage) super (nil,action_name)
self.a = storage
self.move_mgr = db.storage[npc:id()].move_mgr
self.a.scan_table = {}
end
function action_patrol:initialize()
action_base.initialize(self)
self.object:set_desired_position()
self.object:set_desired_direction()
self:reset_scheme()
self.enemy_position = nil
end
function action_patrol:reset_scheme()
--printf("CAMPER %s RESET SCHEME", self.object:name())
state_mgr.set_state(self.object, "patrol")
self.a.signals = {}
self.a.scan_table = {}
if self.a.sniper == true then
self.move_mgr:reset(self.a.path_walk,
utils.path_parse_waypoints(self.a.path_walk),
nil,
nil,
nil,self.a.suggested_state,{obj=self,func=self.process_point})
-- òóò âñòàâèòü ïàðñèíã óãëîâ äëÿ ñêàíà
local path = patrol(self.a.path_look)
if path ~= nil then
for k = 0, path:count() - 1 do
for i = 0, 31 do
if path:flag(k, i) then
if self.a.scan_table[i] == nil then
self.a.scan_table[i] = {}
end
table.insert(self.a.scan_table[i], {key = k, pos = path:point(k)})
end
end
end
end
--' Âêëþ÷àåì áûñòðûé àïäåéò ñíàéïåðà
if self.object:sniper_update_rate() == false then
self.object:sniper_update_rate(true)
end
else
self.move_mgr:reset(self.a.path_walk,
utils.path_parse_waypoints(self.a.path_walk),
self.a.path_look,
utils.path_parse_waypoints(self.a.path_look),
nil,self.a.suggested_state,{obj=self,func=self.process_point})
--' Âêëþ÷àåì îáû÷íûé àïäåéò ñíàéïåðà
if self.object:sniper_update_rate() == true then
self.object:sniper_update_rate(false)
end
end
self.a.last_look_point = nil
self.a.cur_look_point = nil
self.a.scan_begin = nil
end
function action_patrol:activate_scheme()
self:reset_scheme()
end
function action_patrol:can_shoot()
if self.a.shoot == "always" then
return true
end
if self.a.shoot == "none" then
return false
end
if self.a.shoot == "terminal" then
if self.move_mgr:standing_on_terminal_waypoint() then
return true
else
return false
end
end
abort("Camper: unrecognized shoot type [%s] for [%s]", tostring(self.a.shoot), self.object:name())
return true
end
function action_patrol:execute()
action_base.execute (self)
self.enemy = self.object:best_enemy()
if self.enemy ~= nil then
self.a.mem_enemy = self.object:memory_time(self.enemy)
--'Çàáûâàíèå âðàãà ïî âðåìåíè.
if self.a.mem_enemy == nil or
time_global()- self.a.mem_enemy > self.a.idle
then
self.enemy = nil
self.a.mem_enemy = nil
self.move_mgr:continue()
end
else
if self.a.mem_enemy ~= nil then
self.a.mem_enemy = nil
self.move_mgr:continue()
end
end
-- Òðè òèïà äåéñòâèÿ:
-- Åñòü âðàã
if self.enemy ~= nil then
if self.object:see(self.enemy) == true and self:can_shoot() then
-- îòñòðåë âðàãà
--printf("cp: [%s] see [%s]", self.object:name(), self.enemy:name())
if self.a.sniper == true then
if self.a.suggested_state.campering_fire then
state_mgr.set_state(self.object, self.a.suggested_state.campering_fire, nil, nil, {look_object = self.enemy, look_position = self.enemy:position()}, {animation = true})
else
state_mgr.set_state(self.object, "hide_sniper_fire", nil, nil, {look_object = self.enemy, look_position = self.enemy:position()}, {animation = true})
end
else
if self.a.suggested_state.campering_fire then
state_mgr.set_state(self.object, self.a.suggested_state.campering_fire, nil, nil, {look_object = self.enemy, look_position = self.enemy:position()}, {animation = true})
else
state_mgr.set_state(self.object, "hide_fire", nil, nil, {look_object = self.enemy, look_position = self.enemy:position()}, {animation = true})
end
end
--'printf("attack sound [%s]", tostring(self.a.attack_sound))
xr_sound.set_sound_play(self.object:id(), self.a.attack_sound)
else
--' Àíàëèçèðóåì ïîñëåäíþþ èçâåñòíóþ ïîçèöèþ âðàãà.
local memory_position = self.object:memory_position(self.enemy)
if self.enemy_position == nil or
self.enemy_position.x ~= memory_position.x or
self.enemy_position.y ~= memory_position.y or
self.enemy_position.z ~= memory_position.z
then
self.enemy_position = memory_position
--' Çàíåñòè ìåñòî ïîèñêà âðàãà â scan_table
if self.a.sniper == true then
self.position = self.object:position()
self.direction = vector():set(self.enemy_position.x - self.position.x,
0,
self.enemy_position.z - self.position.z)
self.direction:normalize()
local wide_sight = self.position:distance_to(self.enemy_position)*math.tan(self.a.enemy_disp)
self.point_0 = vector():set(self.enemy_position.x + wide_sight*self.direction.z,
self.enemy_position.y,
self.enemy_position.z - wide_sight*self.direction.x)
self.point_2 = vector():set(self.enemy_position.x - wide_sight*self.direction.z,
self.enemy_position.y,
self.enemy_position.z + wide_sight*self.direction.x)
self.a.scan_table[-1] = {}
table.insert(self.a.scan_table[-1], {key = 0, pos =self.point_0})
table.insert(self.a.scan_table[-1], {key = 1, pos =self.enemy_position})
table.insert(self.a.scan_table[-1], {key = 2, pos =self.point_2})
end
end
-- xr_sound.set_sound(self.object, nil)
if self.a.sniper == true then
-- ïîèñê âðàãà (ñêàíèðîâàíèå âðàãà)
--printf("SCAN_ENEMY [%s] of [%s]", utils.to_str(time_global() - self.a.mem_enemy), utils.to_str(self.a.idle))
-- ñêàíèðóåì
if time_global() - self.a.mem_enemy < self.a.post_enemy_wait then
local position
if self.enemy_position then
position = {look_position = self.enemy_position}
end
if self.a.suggested_state.campering then
state_mgr.set_state(self.object, self.a.suggested_state.campering, nil, nil, position)
else
state_mgr.set_state(self.object, "hide_na", nil, nil, position)
end
else
self:scan(-1)
end
else
-- åñëè íîðåòðèò èëè ìû íà ìåñòå - íûêàòüñÿ, èíà÷å èäòè íà òî÷êó
if self:on_place() then
--printf("on place[%s]", self.object:name())
local position
if self.enemy_position then
position = {look_position = self.enemy_position}
end
if self.a.suggested_state.campering then
state_mgr.set_state(self.object, self.a.suggested_state.campering, nil, nil, position)
else
state_mgr.set_state(self.object, "hide", nil, nil, position)
end
else
--printf("not on place[%s]", self.object:name())
-- èäåì äàëüøå
self.move_mgr:continue()
self.move_mgr:update()
end
end
end
return
end
local danger = self:process_danger()
if danger then
-- xr_sound.set_sound(self.object, nil)
self.danger = true
return
end
if self.danger == true then
self.danger = false
self.move_mgr:continue()
end
-- åñëè íåò íè âðàãà íè äåíæåðà.
if self.a.sniper == true then
-- Ñêàíèðîâàíèå ìåñòíîñòè â óçëîâûõ òî÷êàõ
-- åñëè ìû íà òî÷êå - çàïóñòèòü ñ÷åò÷èê ñêàíèðîâàíèÿ è ïîñêàíèðîâàòü îïðåäåëåííîå âðåìÿ.
if self:on_place() then
if self.scantime == nil then
self.scantime = time_global()
end
--printf("SCAN [%s] : [%s] of [%s]", self.object:name(), utils.to_str(time_global() - self.scantime), utils.to_str(self.a.scantime_free))
-- ñêàíèðóåì
self:scan(self.a.wp_flag)
-- åñëè ìû ñòîèì íà ôèíàëüíîé òî÷êå - íå ðåñåòèòü.
if self.move_mgr:standing_on_terminal_waypoint() then
return
end
-- ïðîâåðêà íà çàâåðøåíèå ñêàíèðîâàíèÿ.
if self.scantime ~= nil and time_global() - self.scantime >= self.a.scantime_free then
self.move_mgr:continue()
end
else
self.scantime = nil
self.move_mgr:update()
end
else
-- Ïåðåìåùåíèå ïî move_mgr
--printf("camper [%s] update move mgr", self.object:name())
self.move_mgr:update()
end
end
function action_patrol:process_danger()
if xr_danger.is_danger(self.object) == false then
return false
end
local best_danger = self.object:best_danger()
if best_danger == nil then
return false
end
local best_danger_object = best_danger:object()
local bd_type = best_danger:type()
local passed_time = time_global() - best_danger:time()
local bd_type = best_danger:type()
local position = {look_position = best_danger:position()}
if self.danger ~= true then
self.object:play_sound(stalker_ids.sound_alarm, 1, 0, 1, 0)
end
-- Åñëè äåíæåð îïàñíûé - ñòðåëüíóòü â ïîçèöèþ åãî èíèöèàòîðà, åñëè íåò - ïîâåðíóòüñÿ è ñìîòðåòü òóäà.
-- Îïàñíûé äåíæåð - õèò èëè î÷åíü áëèçêèé ðèêîøåò.
local urgent_danger = (best_danger_object ~= nil) and
(bd_type == danger_object.attacked) and
(time_global() - best_danger:time() < 5000)
if urgent_danger == true then
local danger_object_position = {look_position = best_danger_object:position()}
if self.a.suggested_state.campering_fire then
state_mgr.set_state(self.object, self.a.suggested_state.campering_fire, nil, nil, danger_object_position)
else
state_mgr.set_state(self.object, "hide_fire", nil, nil, danger_object_position)
end
else
if self.a.suggested_state.campering then
state_mgr.set_state(self.object, self.a.suggested_state.campering, nil, nil, position)
else
if self.a.sniper == true then
state_mgr.set_state(self.object, "hide_na", nil, nil, position)
else
state_mgr.set_state(self.object, "hide", nil, nil, position)
end
end
end
return true
end
function action_patrol:scan(flag)
if self.a.scan_table[flag] == nil then
return
end
if self.flag ~= flag then
self.flag = flag
self.a.scan_begin = nil
self.a.cur_look_point = nil
self.a.last_look_point = nil
end
if self.a.scan_begin == nil or
time_global() - self.a.scan_begin > self.a.time_scan_delta then
self.next_point = self:get_next_point(flag)
if self.a.cur_look_point == nil then
self.a.cur_look_point = 1
end
if self.a.last_look_point == nil then
self.a.last_look_point = self.next_point
end
--printf("Look at [%s][%s]", utils.to_str(self.a.last_look_point.key), utils.to_str(self.a.cur_look_point))
self.look_position = self.a.last_look_point.pos
self.dest_position = self.next_point.pos
self.look_point = vector():set(self.look_position.x + self.a.cur_look_point * (self.dest_position.x - self.look_position.x)/self.a.scandelta,
self.look_position.y + self.a.cur_look_point * (self.dest_position.y - self.look_position.y)/self.a.scandelta,
self.look_position.z + self.a.cur_look_point * (self.dest_position.z - self.look_position.z)/self.a.scandelta)
if self.a.suggested_state.campering then
state_mgr.set_state(self.object, self.a.suggested_state.campering, nil, nil, {look_position = self.look_point})
else
state_mgr.set_state(self.object, "hide_na", nil, nil, {look_position = self.look_point})
end
if self.a.cur_look_point >= self.a.scandelta then
self.a.cur_look_point = nil
self.a.last_look_point = self.next_point
else
if self.a.scan_begin ~= nil then
self.a.cur_look_point = self.a.cur_look_point + (time_global() - self.a.scan_begin)/self.a.time_scan_delta
else
self.a.cur_look_point = self.a.cur_look_point + 1
end
end
self.a.scan_begin = time_global()
end
end
function action_patrol:get_next_point(flag)
local next = false
if self.a.last_look_point == nil then
table.sort(self.a.scan_table[flag], function(a,b) return a.key < b.key end)
end
-- print_table(self.a.scan_table[flag])
for k,v in pairs(self.a.scan_table[flag]) do
if self.a.last_look_point == nil then
return v
end
if next == true then
return v
end
if self.a.last_look_point.key == v.key then
next = true
end
end
if next == true then
if self.a.last_look_point.key == 0 then
table.sort(self.a.scan_table[flag], function(a,b) return a.key < b.key end)
else
table.sort(self.a.scan_table[flag], function(a,b) return a.key > b.key end)
end
end
return self.a.last_look_point
end
function action_patrol:process_point(mode, number)
return false
end
function action_patrol:finalize()
self.move_mgr:finalize()
action_base.finalize (self)
end
function action_patrol:on_place()
if self.a.no_retreat == true then return false end
local path = patrol(self.a.path_walk)
if path ~= nil then
for k = 0, path:count() - 1 do
if utils.stalker_at_waypoint(self.object, patrol(self.a.path_walk), k) then
for i = 0, 31 do
if path:flag(k, i) then
self.a.wp_flag = i
return true
end
end
self.a.wp_flag = nil
return false
end
end
self.a.wp_flag = nil
return false
end
end
----------------------------------------------------------------------------------------------------------------------
-- BINDER
----------------------------------------------------------------------------------------------------------------------
function add_to_binder(object, ini, scheme, section, storage)
local operators = {}
local properties = {}
local manager = object:motivation_action_manager()
operators["patrol"] = xr_actions_id.stohe_camper_base + 1
operators["search_corpse"] = xr_actions_id.corpse_exist
operators["help_wounded"] = xr_actions_id.wounded_exist
properties["end"] = xr_evaluators_id.stohe_camper_base + 1
properties["can_fight"] = xr_evaluators_id.sidor_wounded_base + 1
properties["close_combat"] = xr_evaluators_id.stohe_camper_base + 2
properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4
manager:add_evaluator (properties["end"], this.evaluator_end("camper_end", storage))
manager:add_evaluator (properties["close_combat"], this.evaluator_close_combat("camper_close_combat", storage))
local action = this.action_patrol (object,"action_camper_patrol", storage)
action:add_precondition (world_property(stalker_ids.property_alive, true))
action:add_precondition (world_property(properties["end"], false))
action:add_precondition (world_property(properties["close_combat"], false))
action:add_precondition (world_property(properties["can_fight"], true))
action:add_precondition (world_property(stalker_ids.property_danger,false))
action:add_precondition (world_property(stalker_ids.property_anomaly,false))
-- Äóáëÿæ common_precondition áåç ïîäáîðà âåùåé.
action:add_precondition (world_property(xr_evaluators_id.stohe_meet_base + 1,false))
action:add_precondition (world_property(xr_evaluators_id.sidor_wounded_base + 0, false))
action:add_precondition (world_property(xr_evaluators_id.abuse_base, false))
action:add_effect (world_property(properties["end"], true))
action:add_effect (world_property(stalker_ids.property_enemy, false))
action:add_effect (world_property(properties["state_mgr_logic_active"], false))
manager:add_action (operators["patrol"], action)
xr_logic.subscribe_action_for_events(object, storage, action)
action = manager:action (xr_actions_id.alife)
action:add_precondition (world_property(properties["end"], true))
action = manager:action (stalker_ids.action_gather_items)
action:add_precondition (world_property(properties["end"], true))
action = manager:action (operators["search_corpse"])
action:add_precondition (world_property(properties["end"], true))
action = manager:action (operators["help_wounded"])
action:add_precondition (world_property(properties["end"], true))
action = manager:action (stalker_ids.action_combat_planner)
action:add_precondition (world_property(properties["close_combat"], true))
action:add_effect (world_property(properties["close_combat"], false))
action:add_effect (world_property(properties["state_mgr_logic_active"], false))
action:add_effect (world_property(properties["end"], true))
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.path_walk = utils.cfg_get_string(ini, section, "path_walk", npc, true, gulag_name)
st.path_look = utils.cfg_get_string(ini, section, "path_look", npc, true, gulag_name)
if st.path_walk == st.path_look then
abort("You are trying to set 'path_look' equal to 'path_walk' in section [%s] for npc [%s]", section, npc:name())
end
st.sniper = utils.cfg_get_bool(ini, section, "sniper", npc, false)
st.no_retreat = utils.cfg_get_bool(ini, section, "no_retreat", npc, false)
st.shoot = utils.cfg_get_string(ini, section, "shoot", npc, false, "", "always")
st.sniper_anim = utils.cfg_get_string(ini, section, "sniper_anim", npc, false, "hide_na")
if st.sniper == true and st.no_retreat == true then
_G.abort("ERROR: NPC [%s] Section [%s]. No_retreat not available for SNIPER.", npc:name(), section)
end
st.radius = utils.cfg_get_number(ini, section, "radius", npc, false, 20)
st.suggested_state = {}
st.suggested_state.moving = utils.cfg_get_string(ini, section, "def_state_moving", npc, false, "")
st.suggested_state.moving_fire = utils.cfg_get_string(ini, section, "def_state_moving_fire", npc, false, "")
st.suggested_state.campering = utils.cfg_get_string(ini, section, "def_state_campering", npc, false, "")
st.suggested_state.standing = utils.cfg_get_string(ini, section, "def_state_standing", npc, false, "", st.suggested_state.campering)
st.suggested_state.campering_fire = utils.cfg_get_string(ini, section, "def_state_campering_fire", npc, false, "")
st.scantime_free = utils.cfg_get_number(ini, section, "scantime_free", npc, false, 60000)
st.attack_sound = utils.cfg_get_string(ini, section, "attack_sound", npc, false, "", "fight_attack")
if st.attack_sound == "false" then
st.attack_sound = nil
end
-- Âðåìÿ çàáûâàíèÿ âðàãà
st.idle = utils.cfg_get_number(ini, section, "enemy_idle", npc, false, 60000)
st.post_enemy_wait = 5000 -- âðåìÿ, êîòîðîå ìû æäåì âðàãà, ñìîòðÿ â åãî ïîñëåäíþþ ïîçèöèþ.
st.enemy_disp = 7/57.2957 -- Óãîë â ïðåäåëàõ êîòîðîãî ñíàéïåð âåäåò ïîèñê ïîòåðÿííîãî âðàãà.
st.scandelta = 30
st.timedelta = 4000
st.time_scan_delta = st.timedelta/st.scandelta
end