648 lines
18 KiB
Plaintext
648 lines
18 KiB
Plaintext
---- Ai Additions ----
|
||
---- Rulix aka Bak ---
|
||
--evaspy = rx_utils.prof_spy()
|
||
rx_utils.init()
|
||
rx_ini = ini_file([[misc\ai_additions\misc.ltx]])
|
||
|
||
ids_to_remove = {}
|
||
|
||
local death_sound_prob = rx_utils.read_from_ini(rx_ini,"sound","death_probability",50)/100
|
||
local ff_sound_prob = rx_utils.read_from_ini(rx_ini,"sound","friendlyfire_probability",50)/100
|
||
local grenade_sound_prob = rx_utils.read_from_ini(rx_ini,"sound","grenade_probability",50)/100
|
||
|
||
function printf(str,...)
|
||
rx_utils.printf(str,...)
|
||
end
|
||
|
||
-----------------------------------storage-------------------------------------
|
||
function get_storage(id,name)
|
||
local st = db.storage[id]
|
||
if not st then
|
||
local obj = level.object_by_id(id)
|
||
local objname = obj and obj:character_name() or "<nil>"
|
||
printf("get_storage[%s|%s]:not npc storage!!! (%s)",id,name,objname)
|
||
return {}
|
||
end
|
||
if not st.rx_ai then
|
||
st.rx_ai = {}
|
||
end
|
||
if not name then
|
||
return st.rx_ai
|
||
end
|
||
if not st.rx_ai[name] then
|
||
st.rx_ai[name] = {}
|
||
end
|
||
return st.rx_ai[name]
|
||
end
|
||
|
||
function get_var(npc,name,def)
|
||
local st = npc and db.storage[npc:id()]
|
||
if st.pstor and st.pstor[name] then
|
||
return st.pstor[name]
|
||
end
|
||
return def
|
||
end
|
||
|
||
function save_var(npc,name,val)
|
||
local st = db.storage[npc:id()]
|
||
if not st.pstor then
|
||
st.pstor = {}
|
||
end
|
||
st.pstor[name] = val
|
||
return val
|
||
end
|
||
|
||
------------------------------------callbacks----------------------------------
|
||
|
||
function actor_update()
|
||
if #ids_to_remove > 0 then
|
||
for i=1,#ids_to_remove do
|
||
local sobj = alife():object(ids_to_remove[i])
|
||
if sobj then
|
||
alife():release(sobj,true)
|
||
end
|
||
end
|
||
ids_to_remove = {}
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.global_update()
|
||
end
|
||
end
|
||
|
||
function actor_net_spawn()
|
||
if rx_gl then
|
||
rx_gl.net_spawn()
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.init()
|
||
end
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.actor_net_spawn()
|
||
end
|
||
rx_sound.load_sounds()
|
||
end
|
||
|
||
function actor_item_take(item)
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.actor_item_take(item)
|
||
end
|
||
end
|
||
|
||
function actor_save()
|
||
if rx_wmgr then
|
||
rx_wmgr.return_all()
|
||
end
|
||
if rx_addons then
|
||
rx_addons.actor_save()
|
||
end
|
||
end
|
||
|
||
function npc_update(npc,st) -- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
st = st.rx_ai --get_storage(npc:id())
|
||
if not st then
|
||
printf("npc_update[%s]:not st!!!",npc:name())
|
||
return
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.npc_update(npc,st)
|
||
end
|
||
if rx_addons then
|
||
rx_addons.npc_update(npc,st)
|
||
end
|
||
eat_medkit(npc)
|
||
look_into_optical_sight(npc)
|
||
-- planner
|
||
local action_id = st.planner:current_action_id()
|
||
if action_id ~= st.planner_action_id then
|
||
issue_event(npc,"action_switch",action_id,st.planner_action_id)
|
||
if st.planner_action_id == stalker_ids.action_combat_planner then
|
||
st.combat_planner_fix_timer = nil
|
||
end
|
||
st.planner_action_id = action_id
|
||
end
|
||
if action_id == stalker_ids.action_combat_planner and rx_combat then
|
||
rx_combat.combat_planner_update(npc,st)
|
||
end
|
||
end
|
||
|
||
function squad_switch_online(squad)
|
||
end
|
||
|
||
function squad_switch_offline(squad)
|
||
end
|
||
|
||
function npc_net_spawn(npc)
|
||
local st = get_storage(npc:id())
|
||
st.planner = npc:motivation_action_manager()
|
||
if rx_kill_wounded then
|
||
rx_kill_wounded.add_kill_wounded(npc)
|
||
end
|
||
if rx_combat then
|
||
rx_combat.add_combat(npc,st)
|
||
end
|
||
common_planner_pair(npc)
|
||
rx_sound.init_npc_sound(npc)
|
||
end
|
||
|
||
function corpse_net_spawn(npc,loaded)
|
||
if xr_corpse_detection and loaded then
|
||
xr_corpse_detection.corpse_net_spawn(npc)
|
||
end
|
||
end
|
||
|
||
function npc_switch_online(id)
|
||
end
|
||
|
||
function npc_switch_offline(id) -- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
if rx_addons then
|
||
rx_addons.npc_switch_offline(id)
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.kill_wm(id,nil,true)
|
||
end
|
||
unsubscribe_from_events(id)
|
||
end
|
||
|
||
function npc_net_destroy(npc)
|
||
if not npc:alive() then
|
||
return
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.clear_wm(npc)
|
||
end
|
||
end
|
||
|
||
local hit_bone_id = -1
|
||
function npc_death(npc,who)
|
||
if npc then
|
||
local npc_id = npc:id()
|
||
if rx_wmgr then
|
||
rx_wmgr.kill_wm(npc_id,true)
|
||
end
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.npc_death(npc,who)
|
||
end
|
||
issue_event(npc,"death_callback",who)
|
||
unsubscribe_from_events(npc_id)
|
||
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (hit_bone_id >= 15 and hit_bone_id <= 19) or math.random() > death_sound_prob then
|
||
npc:set_sound_mask(-1)
|
||
end
|
||
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
local st = db.storage[npc_id]
|
||
if not (st and st.rx_ai and st.pstor) then
|
||
return
|
||
end
|
||
local pstor = st.pstor
|
||
for i,val in ipairs({'fa_target','gl_charged','kw_type','courage','kn_spawn','wounded_fight','wounded_state','wounded_sound','wounded_victim','wounded_time'}) do
|
||
pstor[val] = nil
|
||
end
|
||
-- fixing possible afterlife evaluators activity
|
||
local planner = st.rx_ai.planner or npc:motivation_action_manager()
|
||
for id,ret in pairs(death_disable_evas) do
|
||
planner:remove_evaluator(id)
|
||
planner:add_evaluator(id,property_evaluator_const(ret))
|
||
end
|
||
end
|
||
end
|
||
|
||
function npc_hit(npc,amount,dir,who,bone_id)
|
||
if npc and amount > 0 then
|
||
hit_bone_id = bone_id
|
||
issue_event(npc,"hit_callback",amount,dir,who,bone_id)
|
||
get_storage(npc:id()).hit_by_anomaly = rx_utils.is_anomaly(who) or nil
|
||
-- sound part
|
||
local snd
|
||
if math.random() < ff_sound_prob and who and who:alive() and not xr_wounded.is_wounded(npc) and who:id() ~= npc:id() then
|
||
if npc:relation(who) ~= game_object.enemy and who:relation(npc) ~= game_object.enemy then
|
||
if npc:position():distance_to_sqr(who:position()) < 1000 then
|
||
if bone_id == 0 then
|
||
snd = "friendly_grenade"
|
||
else
|
||
snd = "friendly_fire"
|
||
end
|
||
end
|
||
else
|
||
local actid = npc:motivation_action_manager():current_action_id()
|
||
if actid >= base_id and actid < base_id+100 then
|
||
snd = "npc_hit"
|
||
end
|
||
end
|
||
end
|
||
if snd then
|
||
rx_sound.set_sound_play(npc:id(),snd)
|
||
end
|
||
end
|
||
end
|
||
|
||
function npc_hear(npc,who_id,sound_type,sound_position,sound_power)
|
||
-- issue_event(npc,"hear_callback",who_id,sound_type,sound_position,sound_power)
|
||
end
|
||
|
||
function npc_item_take(npc,item)
|
||
if npc then
|
||
if rx_addons then
|
||
rx_addons.npc_item_take(npc,item)
|
||
end
|
||
issue_event(npc,"on_item_take",item)
|
||
end
|
||
end
|
||
|
||
function npc_item_drop(npc,item)
|
||
if npc then
|
||
issue_event(npc,"on_item_drop",item)
|
||
end
|
||
end
|
||
|
||
function monster_death(npc,who)
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.npc_death(npc,who)
|
||
end
|
||
end
|
||
|
||
------------------------------------events-------------------------------------
|
||
function issue_event(npc,name,...)
|
||
local st = get_storage(npc:id(),"events")
|
||
for k,v in pairs(st) do
|
||
if v and k[name] then
|
||
k[name](k,...)
|
||
end
|
||
end
|
||
end
|
||
|
||
function broadcast_event(name,...)
|
||
for id,st in pairs(db.storage) do
|
||
if st.rx_ai then
|
||
st = st.rx_ai.events
|
||
if st then
|
||
for k,v in pairs(st) do
|
||
if v and k[name] then
|
||
k[name](k,...)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function subscribe_for_events(npc,obj)
|
||
get_storage(npc:id(),"events")[obj] = true
|
||
end
|
||
|
||
function unsubscribe_from_events(npc_id,obj)
|
||
if obj then
|
||
get_storage(npc_id,"events")[obj] = nil
|
||
else
|
||
get_storage(npc_id)["events"] = nil
|
||
end
|
||
end
|
||
|
||
------------------------------------planner------------------------------------
|
||
base_id = 18800
|
||
reset_protected_actions = {}
|
||
no_talk_actions = {}
|
||
death_disable_evas = {
|
||
--[xr_evaluators_id.state_mgr + 1] = true,
|
||
--[xr_evaluators_id.state_mgr + 2] = true,
|
||
}
|
||
|
||
function is_active_action(npc,actid)
|
||
if not actid then
|
||
local mgr = npc:motivation_action_manager()
|
||
actid = mgr and mgr:initialized() and mgr:current_action_id() or 0
|
||
end
|
||
return actid > base_id and actid < base_id+100
|
||
end
|
||
|
||
function cant_talk(npc,actid)
|
||
if not actid then
|
||
local mgr = npc:motivation_action_manager()
|
||
actid = mgr:initialized() and mgr:current_action_id() or 0
|
||
end
|
||
return no_talk_actions[actid] == true
|
||
end
|
||
|
||
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
-- <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>:
|
||
-- rx_ai.reset_protected_actions[action_id] = true
|
||
-- <20><><EFBFBD><EFBFBD><EFBFBD> rx_ai.process_postponed_setup(npc:id()) <20><> action:finalize()
|
||
function process_postponed_setup(id)
|
||
local stor = db.storage[id]
|
||
if stor and stor.active_scheme then
|
||
local mm = stor.move_mgr
|
||
if mm.path_walk and mm.setup_movement_postponed then
|
||
mm.setup_movement_postponed = nil
|
||
mm:setup_movement_by_patrol_path()
|
||
end
|
||
end
|
||
end
|
||
|
||
function is_reset_protected_action(npc,actid)
|
||
if not actid then
|
||
local mgr = npc:motivation_action_manager()
|
||
actid = mgr:initialized() and mgr:current_action_id() or 0
|
||
end
|
||
return reset_protected_actions[actid] == true
|
||
end
|
||
|
||
function load_schemes()
|
||
if rx_reload then
|
||
load_scheme("rx_reload","reload",modules.stype_stalker)
|
||
end
|
||
if rx_gl then
|
||
load_scheme("rx_gl","launch_grenade",modules.stype_stalker)
|
||
end
|
||
if rx_facer then
|
||
load_scheme("rx_facer","facer",modules.stype_stalker)
|
||
end
|
||
if rx_bandage then
|
||
load_scheme("rx_bandage","bandage",modules.stype_stalker)
|
||
end
|
||
if rx_ff then
|
||
load_scheme("rx_ff","rx_ff",modules.stype_stalker)
|
||
end
|
||
if rx_knife then
|
||
load_scheme("rx_knife","rx_knife",modules.stype_stalker)
|
||
end
|
||
if xr_help_wounded then
|
||
load_scheme("xr_help_wounded","help_wounded",modules.stype_stalker)
|
||
end
|
||
if xr_corpse_detection then
|
||
load_scheme("xr_corpse_detection","corpse_detection",modules.stype_stalker)
|
||
end
|
||
end
|
||
|
||
function disable_schemes(npc)
|
||
--[[if rx_reload then
|
||
rx_reload.disable_scheme(npc,"reload")
|
||
end
|
||
if rx_gl then
|
||
rx_gl.disable_scheme(npc,"launch_grenade")
|
||
end
|
||
if rx_facer then
|
||
rx_facer.disable_scheme(npc,"facer")
|
||
end
|
||
if rx_knife then
|
||
rx_knife.disable_scheme(npc,"knife")
|
||
end]]
|
||
end
|
||
|
||
function enable_schemes(ini,npc,section_logic)
|
||
if rx_reload then
|
||
rx_reload.set_scheme(npc,ini,"reload","reload")
|
||
end
|
||
if rx_gl then
|
||
rx_gl.set_scheme(npc,ini,"launch_grenade","launch_grenade")
|
||
end
|
||
if rx_facer then
|
||
rx_facer.set_scheme(npc,ini,"facer","facer")
|
||
end
|
||
if rx_bandage then
|
||
rx_bandage.set_scheme(npc,ini,"bandage","bandage")
|
||
end
|
||
if rx_ff then
|
||
rx_ff.set_scheme(npc,ini,"rx_ff","rx_ff")
|
||
end
|
||
if rx_knife then
|
||
rx_knife.set_scheme(npc,ini,"rx_knife",section_logic)
|
||
end
|
||
if xr_help_wounded then
|
||
xr_help_wounded.set_help_wounded(npc,ini,"help_wounded","help_wounded")
|
||
end
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.set_corpse_detection(npc,ini,"corpse_detection","corpse_detection")
|
||
end
|
||
end
|
||
|
||
function reset_schemes(npc, scheme, st, section)
|
||
if xr_help_wounded then
|
||
xr_help_wounded.reset_help_wounded(npc, scheme, st, section)
|
||
end
|
||
if xr_corpse_detection then
|
||
xr_corpse_detection.reset_corpse_detection(npc, scheme, st, section)
|
||
end
|
||
if rx_bandage then
|
||
rx_bandage.reset_scheme(npc, scheme, st, section)
|
||
end
|
||
if rx_knife then
|
||
rx_knife.reset_scheme(npc, scheme, st, section)
|
||
end
|
||
if rx_wmgr then
|
||
rx_wmgr.reset_scheme(npc, scheme, st, section)
|
||
end
|
||
end
|
||
|
||
function addCommonPrecondition(action)
|
||
if rx_reload then
|
||
action:add_precondition(world_property(rx_reload.evid_reload,false))
|
||
end
|
||
if rx_gl then
|
||
action:add_precondition(world_property(rx_gl.evid_gl_fire,false))
|
||
action:add_precondition(world_property(rx_gl.evid_gl_reload,false))
|
||
end
|
||
if rx_facer then
|
||
action:add_precondition(world_property(rx_facer.evid_facer,false))
|
||
end
|
||
if rx_bandage then
|
||
action:add_precondition(world_property(rx_bandage.evid_bandage,false))
|
||
end
|
||
if rx_knife then
|
||
action:add_precondition(world_property(rx_knife.evid_knife_attack,false))
|
||
end
|
||
if xr_help_wounded then
|
||
action:add_precondition(world_property(xr_help_wounded.evid_wounded_exist,false))
|
||
end
|
||
if xr_corpse_detection then
|
||
action:add_precondition(world_property(xr_corpse_detection.evid_corpse_exist,false))
|
||
end
|
||
end
|
||
|
||
------------------------------------eating----------------------------------------
|
||
local eating = {enabled = rx_ini:section_exist("npc_eating") and rx_ini:r_bool("npc_eating","enabled")}
|
||
function eat_init()
|
||
local sect = "npc_eating"
|
||
eating.exc_comms = rx_utils.parse_list(rx_ini,sect,"excluded_communities",true)
|
||
eating.exc_npcs = rx_utils.parse_list(rx_ini,sect,"excluded_npcs",true)
|
||
eating.ic = rx_utils.read_from_ini(rx_ini,sect,"in_combat",false,0)
|
||
eating.oc = rx_utils.read_from_ini(rx_ini,sect,"out_combat",true,0)
|
||
eating.max_h = rx_utils.read_from_ini(rx_ini,sect,"medkit_health",50)/100
|
||
eating.min_b = rx_utils.read_from_ini(rx_ini,sect,"bandage_bleeding",0.2)
|
||
eating.medkits = rx_utils.parse_list(rx_ini,sect,"medkits")
|
||
eating.bandages = rx_utils.parse_list(rx_ini,sect,"bandages")
|
||
eating.delay = rx_utils.parse_list(rx_ini,sect,"delay")
|
||
end
|
||
function eat_medkit(npc)
|
||
if not eating.enabled then
|
||
return
|
||
end
|
||
if not eating.max_h then
|
||
eat_init()
|
||
end
|
||
local st = get_storage(npc:id(),"eating")
|
||
if st.disabled then
|
||
return
|
||
elseif st.disabled == nil then
|
||
st.disabled = false
|
||
if eating.exc_comms[npc:character_community()] or eating.exc_npcs[npc:name()] then
|
||
st.disabled = true
|
||
-- printf("[%s]eating disabled",npc:character_name())
|
||
end
|
||
return
|
||
end
|
||
local enemy = npc:best_enemy()
|
||
if xr_wounded.is_wounded(npc) or (not eating.ic and enemy) or (not eating.oc and not enemy) then
|
||
st.item = nil
|
||
st.time = nil
|
||
return
|
||
end
|
||
if st.item and st.time then
|
||
if st.time < time_global() then
|
||
-- printf("[%s]eat[%s] enemy %s",npc:character_name(),st.item,tostring(enemy ~= nil))
|
||
local med = npc:object(st.item)
|
||
if med then
|
||
rx_utils.eat_medkit(npc,med)
|
||
end
|
||
st.item = nil
|
||
end
|
||
return
|
||
end
|
||
if npc.health < eating.max_h and not xr_wounded.is_wounded(npc) then
|
||
for k,v in ipairs(eating.medkits) do
|
||
local medkit = npc:object(v)
|
||
if medkit then
|
||
-- printf("health[%s]=%s:set[%s]",npc:character_name(),npc.health,v)
|
||
st.time = time_global()+math.random(eating.delay[1],eating.delay[2])
|
||
st.item = v
|
||
return
|
||
end
|
||
end
|
||
end
|
||
if npc:get_bleeding() > eating.min_b then
|
||
for k,v in ipairs(eating.bandages) do
|
||
local bandage = npc:object(v)
|
||
if bandage then
|
||
-- printf("bleeding[%s]=%s:set[%s]",npc:character_name(),npc:get_bleeding(),v)
|
||
st.time = time_global()+math.random(eating.delay[1],eating.delay[2])
|
||
st.item = v
|
||
return
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
------------------------------------lios-----------------------------------------
|
||
local lios = {enabled = rx_ini:section_exist("look_into_os") and rx_ini:r_bool("look_into_os","enabled")}
|
||
function lios_init()
|
||
local sect = "look_into_os"
|
||
lios.exc_comms = rx_utils.parse_list(rx_ini,sect,"excluded_communities",true)
|
||
lios.exc_npcs = rx_utils.parse_list(rx_ini,sect,"excluded_npcs",true)
|
||
lios.range_add = rx_utils.read_from_ini(rx_ini,sect,"range_add",0.5)/100
|
||
lios.fov_add = rx_utils.read_from_ini(rx_ini,sect,"fov_add",-0.3)/100
|
||
lios.zoom_factor = {}
|
||
lios.fire_dist = {}
|
||
end
|
||
function look_into_optical_sight(npc)
|
||
if not lios.enabled then
|
||
return
|
||
elseif not lios.range_add then
|
||
lios_init()
|
||
end
|
||
local storage = get_storage(npc:id(),"lios")
|
||
if storage.disabled then
|
||
return
|
||
end
|
||
if not storage.range then
|
||
if lios.exc_comms[npc:character_community()] or lios.exc_npcs[npc:name()] then
|
||
storage.disabled = true
|
||
-- printf("[%s]lios disabled",npc:character_name())
|
||
else
|
||
storage.range = npc:range()
|
||
storage.fov = npc:fov()
|
||
storage.ch = false
|
||
end
|
||
return
|
||
end
|
||
local act = false
|
||
local weapon = npc:active_item()
|
||
if rx_utils.item_is_fa(weapon) and rx_utils.addon_attached(weapon,"sc") then
|
||
-- printf("[%s]have os",npc:character_name())
|
||
local move_type,mental_state = npc:movement_type(),npc:mental_state()
|
||
if (move_type == move.stand or move_type == move.walk) and mental_state == anim.danger then
|
||
-- printf("[%s]set lios",npc:character_name())
|
||
act = true
|
||
end
|
||
end
|
||
if storage.ch ~= act then
|
||
local range,fov = storage.range,storage.fov
|
||
if act == true then
|
||
local function get_zoom_factor(sect)
|
||
if lios.zoom_factor[sect] == nil then
|
||
local scope = rx_utils.read_from_ini(nil,sect,"scope_status",nil) == 2 and rx_utils.read_from_ini(nil,sect,"scopes_sect",nil,1)
|
||
if not scope then
|
||
scope = sect
|
||
end
|
||
lios.zoom_factor[sect] = rx_utils.read_from_ini(nil,scope,"scope_zoom_factor",30)
|
||
lios.fire_dist[sect] = rx_utils.read_from_ini(nil,sect,"fire_distance",150)
|
||
-- printf("lios:%s zf = %s, fd = %s",sect,lios.zoom_factor[sect],lios.fire_dist[sect])
|
||
end
|
||
return lios.zoom_factor[sect],lios.fire_dist[sect]
|
||
end
|
||
local factor,max_range = get_zoom_factor(weapon:section())
|
||
if factor < 80 and max_range > storage.range then
|
||
factor = 30/factor
|
||
range = range+range*lios.range_add*factor
|
||
if range > max_range then
|
||
range = max_range
|
||
end
|
||
fov = fov+fov*lios.fov_add*factor
|
||
if fov < 40 then
|
||
fov = 40
|
||
end
|
||
end
|
||
end
|
||
npc:set_range(range)
|
||
npc:set_fov(fov)
|
||
storage.ch = act
|
||
-- printf("[%s]change to %s,set[%s][%s]",npc:character_name(),tostring(storage.ch),range,fov)
|
||
end
|
||
end
|
||
|
||
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>
|
||
class "evaluator_danger_grenade" (property_evaluator)
|
||
function evaluator_danger_grenade:__init(npc,name) super (nil,name)
|
||
-- rx_ai.subscribe_for_events(npc,self)
|
||
end
|
||
function evaluator_danger_grenade:evaluate()
|
||
if not self.ceva then
|
||
self.ceva = cast_planner(self.object:motivation_action_manager():action(stalker_ids.action_combat_planner)):evaluator(stalker_ids.property_danger_grenade)
|
||
self.storage:set_property(stalker_ids.property_danger_grenade,false)
|
||
return false
|
||
end
|
||
if self.ceva:evaluate() then
|
||
local best_danger = self.object:best_danger()
|
||
local grenade = best_danger:dependent_object()
|
||
if grenade then
|
||
if grenade:clsid() ~= clsid.obj_explosive and grenade:id() ~= self.react_id then -- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
self.react_id = grenade:id()
|
||
local initiator = best_danger:object()
|
||
if not (initiator and self.object:team() == initiator:team()) and math.random() < grenade_sound_prob then
|
||
self.object:play_sound(stalker_ids.sound_grenade_alarm,2.5,1.0)
|
||
end
|
||
end
|
||
self.storage:set_property(stalker_ids.property_danger_grenade,true)
|
||
return true
|
||
else -- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
self.react_id = nil
|
||
end
|
||
end
|
||
self.storage:set_property(stalker_ids.property_danger_grenade,false)
|
||
return false
|
||
end
|
||
|
||
function common_planner_pair(npc)
|
||
local manager = npc:motivation_action_manager()
|
||
manager:add_evaluator(stalker_ids.property_danger_grenade,evaluator_danger_grenade(npc,"eva_danger_grenade"))
|
||
local action = manager:action(stalker_ids.action_danger_planner)
|
||
action:add_effect(world_property(stalker_ids.property_danger_grenade,false))
|
||
end
|