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

22
gamedata/scripts/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
// Используйте IntelliSense, чтобы узнать о возможных атрибутах.
// Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
// Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lua",
"request": "launch",
"name": "LuaPanda",
"description": "IX-Ray Lua Debug",
"cwd": "${workspaceFolder}",
"luaFileExtension": "script",
"connectionPort": 8818,
"stopOnEntry": true,
"useCHook": true,
"autoPathMode": true,
"updateTips": true
}
]
}

View file

@ -0,0 +1,5 @@
{
"Lua.diagnostics.disable": [
"undefined-global"
]
}

869
gamedata/scripts/_g.script Normal file
View file

@ -0,0 +1,869 @@
if (jit == nil) then
profiler.setup_hook ()
end
function empty (container)
if (type(container) == "function") then
for i in container do
return (false)
end
return (true)
end
assert (type(container) == "table")
if (container[1] ~= nil) then
return (false)
end
for i,j in pairs(container) do
return (false)
end
return (true)
end
schemes = {} -- ñîîòâåòñòâèå ñõåì ìîäóëÿì
stypes = {} -- òèïv ñõåì
-- ³àãðóæàåò ñõåìó èç ôàéëà íà äèñêå è àêòèâèðóåò â ìîòèâàòîðå.
-- ³äåñü:
-- filename - èìÿ ôàéëà, â êîòîðîì ðåàëèçîâàíà ñõåìà, áåç ðàñøèðåíèÿ
-- scheme - èìÿ ñõåì
function load_scheme(filename, scheme, stype)
schemes[scheme] = filename
stypes[scheme] = stype
end
----------------------------------------------------------------------
dev_debug = false
sim_debug = false
mus_vol = 0
amb_vol = 0
b_discard_settings_shown = false
----------------------------------------------------------------------
local scripts_to_print = {
["stalker_generic"] = true,
["xr_smartcover"] = true,
["xr_logic"] = true,
["xr_conditions"] = true,
["xr_cover"] = true,
["xr_motivator"] = true,
["xr_walker"] = true,
["xr_camper"] = true,
["xr_kamp"] = true,
["restrictor_manager"] = true,
["sim_board"] = true,
["sim_faction"] = true,
["post_combat_idle"] = true,
["xr_death"] = true,
["xr_sound"] = true,
["utils"] = true,
["treasure_manager"] = true,
["object_collection"] = true,
["se_actor"] = true,
["smart_terrain"] = true,
["bind_physic_object"] = true,
["bind_heli"] = true,
["bind_anomaly_zone"] = true,
["bind_stalker"] = true,
["state_mgr_animation"] = true,
["se_stalker"] = true,
["db"] = true,
["sim_squad_generic"] = true,
["sim_squad_scripted"] = true,
["se_smart_cover"] = true,
["se_monster"] = true,
["dialog_manager"] = true,
["xr_combat_ignore"] = true,
["xr_remark"] = true,
["cover_manager"] = true,
["xr_danger"] = true,
["task_manager"] = true,
["task_objects"] = true
}
function printf(fmt,...)
local is_g = 0
local result = fmt
if debug == nil then
log(string.format(fmt,...))
return
end
local info_table = debug.getinfo(2)
local script_name = string.gsub(info_table.short_src, "%.script", "")
script_name = string.gsub(script_name, "gamedata\\scripts\\", "")
if scripts_to_print[script_name] == false then return end
script_name,is_g = string.gsub(script_name, "_g", "")
if is_g == 0 then
result = script_name..":("..info_table.currentline.."):"..fmt
else
result = fmt
end
log(string.format(result,...))
end
----------------------------------------------------------------------
if nil == time_global then
time_global = function () return device():time_global() end
end
function wait_game(time_to_wait)
verify_if_thread_is_running()
if (time_to_wait == nil) then
coroutine.yield()
else
local time_to_stop = game.time() + time_to_wait
while game.time() <= time_to_stop do
coroutine.yield()
end
end
end
function wait(time_to_wait)
verify_if_thread_is_running()
if (time_to_wait == nil) then
coroutine.yield()
else
local time_to_stop = time_global() + time_to_wait
while time_global() <= time_to_stop do
coroutine.yield()
end
end
end
function action(obj,...)
local arg = {...}
local act = entity_action()
local i = 1
while true do
if (arg[i] ~= nil) then
act:set_action(arg[i])
else
break
end
i = i + 1
end
if (obj ~= nil) then
obj:command(act,false)
end
return entity_action(act)
end
function action_first(obj,...)
local arg = {...}
local act = entity_action()
local i = 1
while true do
if (arg[i] ~= nil) then
act:set_action(arg[i])
else
break
end
i = i + 1
end
if (obj ~= nil) then
obj:command(act,true)
end
return entity_action(act)
end
function round (value)
local min = math.floor (value)
local max = min + 1
if value - min > max - value then return max end
return min
end
function distance_between(obj1, obj2)
return obj1:position():distance_to(obj2:position())
end
-- +ñëè îäèí îáúåêò nil, íàïðèìåð íåò àêòåðà, òî ñ÷èòàåì, ÷òî îí äàëåêî
function distance_between_safe(obj1, obj2)
if(obj1 == nil or obj2 == nil) then return 100000 end
return obj1:position():distance_to(obj2:position())
end
local aa = nil
--' ³ðîâåðêà íà èíôîïîðøív, äàæå åñëè èãðîêà íå ñó åñòâóåò
function has_alife_info(info_id)
if aa == nil then
return false
end
return aa:has_info(0, info_id)
end
function reset_action (npc, script_name)
if npc:get_script () then
npc:script (false, script_name)
end
npc:script (true, script_name)
end
--------------------------------------------------
-- Functions and variables added by Zmey
--------------------------------------------------
-- ³îíñòàíòà, êîòîðó³ èñïîëüçîâàòü â ìåñòàõ, ãäå íóæíî çàäàòü íåîãðàíè÷åííîå âðåìÿ äåéñòâèÿ
time_infinite = 100000000
-- +ñëè â äàíívé ìîìåíò âvïîëíÿåòñÿ êàêîå-òî äåéñòâèå, ïðåðvâàåò åãî è îòêë³÷àåò ñêðèïòîâvé ðåæèì
function interrupt_action(who, script_name)
if who:get_script() then
who:script(false, script_name)
end
end
function random_choice(...)
local arg = {...}
local r = math.random(1, #arg)
return arg[r]
end
function if_then_else(cond, if_true, if_false)
if cond then
return if_true
end
return if_false
end
function set_current_time (hour, min, sec)
local current_time_factor = level.get_time_factor ()
printf ("Need time : %d:%d:%d", hour, min, sec)
local current_time = game.time ()
local c_day = math.floor (current_time / 86400000)
local c_time = current_time - c_day * 86400000
local n_time = (sec + min * 60 + hour * 3600) * 1000
if c_time > n_time then c_day = c_day + 1 end
n_time = n_time + c_day * 86400000
level.set_time_factor (10000)
while game.time () < n_time do wait () end
level.set_time_factor (current_time_factor)
end
function random_number (min_value, max_value)
math.randomseed (device ():time_global ())
if min_value == nil and max_value == nil then
return math.random ()
else
return math.random (min_value, max_value)
end
end
function parse_names( s )
local t = {}
for name in string.gfind( s, "([%w_\\]+)%p*" ) do
--for name in string.gfind( s, "%s*([^%,]+)%s*" ) do
table.insert( t, name )
end
return t
end
function parse_key_value( s )
local t = {}
if s == nil then
return nil
end
local key, nam = nil, nil
for name in string.gfind( s, "([%w_\\]+)%p*" ) do
if key == nil then
key = name
else
t[key] = name
key = nil
end
end
return t
end
function parse_nums( s )
local t = {}
for entry in string.gfind( s, "([%-%d%.]+)%,*" ) do
table.insert( t, tonumber( entry ) )
end
return t
end
-- Íàõîäèòñÿ ëè îáüåêò â îíëàéíå.
function is_object_online(obj_id)
return level.object_by_id(obj_id) ~= nil
end
function get_clsid(npc)
if npc == nil then return nil end
return npc:clsid()
end
--Tv÷èñëÿåò yaw â ðàäèàíàõ
function yaw( v1, v2 )
return math.acos( ( (v1.x*v2.x) + (v1.z*v2.z ) ) / ( math.sqrt(v1.x*v1.x + v1.z*v1.z ) * math.sqrt(v2.x*v2.x + v2.z*v2.z ) ) )
end
function yaw_degree( v1, v2 )
return (math.acos( ( (v1.x*v2.x) + (v1.z*v2.z ) ) / ( math.sqrt(v1.x*v1.x + v1.z*v1.z ) * math.sqrt(v2.x*v2.x + v2.z*v2.z ) ) ) * 57.2957)
end
function yaw_degree3d( v1, v2 )
return (math.acos((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/(math.sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z )*math.sqrt(v2.x*v2.x + v2.y*v2.y + v2.z*v2.z)))*57.2957)
end
function vector_cross(v1, v2)
return vector():set(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x)
end
--Ïîâîðà÷èâàåò âåêòîð âîêðóã îñè y ïðîòèâ ÷àñîâîé ñòðåëêè.
function vector_rotate_y(v, angle)
angle = angle * 0.017453292519943295769236907684886
local c = math.cos (angle)
local s = math.sin (angle)
return vector ():set (v.x * c - v.z * s, v.y, v.x * s + v.z * c)
end
-- î÷èñòêà òàáëèöû.
function clear_table (t)
while #t > 0 do
table.remove (t, #t)
end
end
function stop_play_sound(obj)
if obj:alive() == true then
obj:set_sound_mask(-1)
obj:set_sound_mask(0)
end
end
-- Ïå÷àòàåò òàáëèöó êàê äåðåâî.
function print_table(table, subs)
local sub
if subs ~= nil then
sub = subs
else
sub = ""
end
for k,v in pairs(table) do
if type(v) == "table" then
printf(sub.."%s:", tostring(k))
print_table(v, sub.." ")
elseif type(v) == "function" then
printf(sub.."%s:function", tostring(k))
elseif type(v) == "userdata" then
printf(sub.."%s:userdata", tostring(k))
elseif type(v) == "boolean" then
if v == true then
if(type(k)~="userdata") then
printf(sub.."%s:true", tostring(k))
else
printf(sub.."userdata:true")
end
else
if(type(k)~="userdata") then
printf(sub.."%s:false", tostring(k))
else
printf(sub.."userdata:false")
end
end
else
if v ~= nil then
printf(sub.."%s:%s", tostring(k),v)
else
printf(sub.."%s:nil", tostring(k),v)
end
end
end
end
function store_table(table, subs)
local sub
if subs ~= nil then
sub = subs
else
sub = ""
end
printf(sub.."{")
for k,v in pairs(table) do
if type(v) == "table" then
printf(sub.."%s = ", tostring(k))
store_table(v, sub.." ")
elseif type(v) == "function" then
printf(sub.."%s = \"func\",", tostring(k))
elseif type(v) == "userdata" then
printf(sub.."%s = \"userdata\",", tostring(k))
elseif type(v) == "string" then
printf(sub.."%s = \"%s\",", tostring(k), tostring(v))
else
printf(sub.."%s = %s,", tostring(k), tostring(v))
end
end
printf(sub.."},")
end
-------------------------------------------------------------------------------------------
local monster_classes = {}
local stalker_classes = {}
local weapon_classes = {}
local artefact_classes = {}
function IsMonster (object, class_id)
local id = class_id or get_clsid(object)
return monster_classes[id] == true
end
function IsStalker (object, class_id)
local id = class_id or get_clsid(object)
return stalker_classes[id] == true
end
function isWeapon(object, class_id)
local id = class_id or get_clsid(object)
return weapon_classes[id] == true
end
function isArtefact(object, class_id)
local id = class_id or get_clsid(object)
return artefact_classes[id] == true
end
-------------------------------------------------------------------------------------------
function get_object_community(obj)
if type(obj.id) == "function" then
return character_community(obj)
else
return alife_character_community(obj)
end
end
function character_community (obj)
if IsStalker(obj) then
return obj:character_community()
end
return "monster"
end
function alife_character_community (obj)
if IsStalker(obj, obj:clsid()) then
return obj:community()
end
return "monster"
end
-- ïîëó÷èòü ãåéìîáæåêò ïî ñòîðè_àéäè.
function level_object_by_sid( sid )
local sim = alife()
if sim then
local se_obj = sim:story_object( sid )
if se_obj then
return level.object_by_id( se_obj.id )
end
end
return nil
end
-- Ïîëó÷èòü àéäèøíèê îáüåêòà ïî ñòîðè àéäè.
function id_by_sid( sid )
local sim = alife()
if sim then
local se_obj = sim:story_object( sid )
if se_obj then
return se_obj.id
end
end
return nil
end
-- Êðåøíóòü èãðó (ïîñëå âûâîäà ñîîáùåíèÿ îá îøèáêå â ëîã)
function abort(fmt, ...)
local reason = string.format(fmt, ...)
--error_log(reason)
end
function set_inactivate_input_time(delta)
db.storage[db.actor:id()].disable_input_time = game.get_game_time()
db.storage[db.actor:id()].disable_input_idle = delta
level.disable_input()
end
-- ³ðèíèìàåò: ïîçèöè³ ïîëîæåíèÿ, ïîçèöè³ êóäà ñìîòðåòü, âðåìÿ ñíà â ìèíóòàõ.
--[[
function set_sleep_relocate(point, look, timeout)
db.storage[db.actor:id()].sleep_relocate_time = game.get_game_time()
db.storage[db.actor:id()].sleep_relocate_idle = timeout*60
db.storage[db.actor:id()].sleep_relocate_point = point
db.storage[db.actor:id()].sleep_relocate_look = look
end
]]--
-- ïðîâåðÿåò öåëóþ ÷àñòü ÷èñëà íà íå÷åòíîñòü
function odd( x )
return math.floor( x * 0.5 ) * 2 == math.floor( x )
end
--' íàõîäèòñÿ ëè NPC âî ôðóñòðóìå èãðîêà
function npc_in_actor_frustrum(npc)
local actor_dir = device().cam_dir
--local actor_dir = db.actor:direction()
local npc_dir = npc:position():sub(db.actor:position())
local yaw = yaw_degree3d(actor_dir, npc_dir)
--printf("YAW %s", tostring(yaw))
return yaw < 35
end
function start_game_callback()
aa = alife()
squad_community_by_behaviour = {
["stalker"] = "stalker",
["bandit"] = "bandit",
["dolg"] = "dolg",
["freedom"] = "freedom",
["army"] = "army",
["ecolog"] = "ecolog",
["killer"] = "killer",
["zombied"] = "zombied",
["monolith"] = "monolith",
["monster"] = "monster",
["monster_predatory_day"] = "monster",
["monster_predatory_night"] = "monster",
["monster_vegetarian"] = "monster",
["monster_zombied_day"] = "monster",
["monster_zombied_night"] = "monster",
["monster_special"] = "monster"
}
monster_classes = {
[clsid.bloodsucker_s] = true,
[clsid.boar_s] = true,
[clsid.dog_s] = true,
[clsid.flesh_s] = true,
[clsid.pseudodog_s] = true,
[clsid.burer_s] = true,
-- [clsid.cat_s] = true,
[clsid.chimera_s] = true,
[clsid.controller_s] = true,
-- [clsid.fracture_s] = true,
[clsid.poltergeist_s] = true,
[clsid.gigant_s] = true,
-- [clsid.zombie_s] = true,
[clsid.snork_s] = true,
[clsid.tushkano_s] = true,
[clsid.psy_dog_s] = true,
[clsid.psy_dog_phantom_s] = true}
stalker_classes = {
[clsid.script_actor] = true,
[clsid.script_stalker] = true}
weapon_classes = {
[clsid.wpn_vintorez_s] = true,
[clsid.wpn_ak74_s] = true,
[clsid.wpn_lr300_s] = true,
[clsid.wpn_hpsa_s] = true,
[clsid.wpn_pm_s] = true,
[clsid.wpn_shotgun_s] = true,
[clsid.wpn_auto_shotgun_s] = true,
[clsid.wpn_bm16_s] = true,
[clsid.wpn_svd_s] = true,
[clsid.wpn_svu_s] = true,
[clsid.wpn_rg6_s] = true,
[clsid.wpn_rpg7_s] = true,
[clsid.wpn_val_s] = true,
[clsid.wpn_walther_s] = true,
[clsid.wpn_usp45_s] = true,
[clsid.wpn_groza_s] = true,
[clsid.wpn_knife_s] = true,
[clsid.wpn_grenade_f1_s] = true,
[clsid.wpn_grenade_rgd5_s] = true,
[clsid.wpn_grenade_launcher] = true,
[clsid.wpn_grenade_fake] = true}
artefact_classes = {
[clsid.art_bast_artefact] = true,
[clsid.art_black_drops] = true,
[clsid.art_dummy] = true,
[clsid.art_electric_ball] = true,
[clsid.art_faded_ball] = true,
[clsid.art_galantine] = true,
[clsid.art_gravi] = true,
[clsid.art_gravi_black] = true,
[clsid.art_mercury_ball] = true,
[clsid.art_needles] = true,
[clsid.art_rusty_hair] = true,
[clsid.art_thorn] = true,
[clsid.art_zuda] = true,
[clsid.artefact] = true,
[clsid.artefact_s] = true}
printf ("start_game_callback called")
smart_names.init_smart_names_table()
task_manager.clear_task_manager()
sound_theme.load_sound()
xr_sound.start_game_callback()
dialog_manager.fill_phrase_table()
xr_s.init()
sim_objects.clear()
sim_board.clear()
sr_light.clean_up ()
pda.add_quick_slot_items_on_game_start()
-- Tåñòèðîâàíèå îïòèìèçàöèè
--local test_object = test_object.test_object_class()
--test_object:test()
end
--' Lñòàëîñòü
function on_actor_critical_power()
end
function on_actor_critical_max_power()
end
--' ³ðîâîòå÷åíèå
function on_actor_bleeding()
end
function on_actor_satiety()
end
--' ³àäèàöèÿ
function on_actor_radiation()
end
--' ³àêëèíèëî îðóæèå
function on_actor_weapon_jammed()
end
--' íå ìîæåò õîäèòü èççà âåñà
function on_actor_cant_walk_weight()
end
--' ïñè âîçäåéñòâèå
function on_actor_psy()
end
function give_info (info)
db.actor:give_info_portion(info)
end
function disable_info (info)
if has_alife_info(info) then
printf("*INFO*: disabled npc='single_player' id='%s'", info)
db.actor:disable_info_portion(info)
end
end
function create_ammo(section, position, lvi, gvi, pid, num)
local ini = system_ini()
local num_in_box = ini:r_u32(section, "box_size")
local t = {}
while num > num_in_box do
local obj = alife():create_ammo(section, position, lvi, gvi, pid, num_in_box)
table.insert(t, obj)
num = num - num_in_box
end
local obj = alife():create_ammo(section, position, lvi, gvi, pid, num)
table.insert(t, obj)
return t
end
ammo_section = {}
ammo_section["ammo_9x18_fmj"] = true
ammo_section["ammo_9x18_pmm"] = true
ammo_section["ammo_9x19_fmj"] = true
ammo_section["ammo_9x19_pbp"] = true
ammo_section["ammo_5.45x39_fmj"] = true
ammo_section["ammo_5.45x39_ap"] = true
ammo_section["ammo_5.56x45_ss190"] = true
ammo_section["ammo_5.56x45_ap"] = true
ammo_section["ammo_5.7x28_fmj"] = true
ammo_section["ammo_5.7x28_ap"] = true
ammo_section["ammo_7.62x54_7h1"] = true
ammo_section["ammo_9x39_pab9"] = true
ammo_section["ammo_gauss"] = true
ammo_section["ammo_9x39_ap"] = true
ammo_section["ammo_11.43x23_fmj"] = true
ammo_section["ammo_11.43x23_hydro"] = true
ammo_section["ammo_12x70_buck"] = true
ammo_section["ammo_12x76_zhekan"] = true
ammo_section["ammo_pkm_100"] = true
quest_section = {}
-- ïðåîáðàçóåò ñòðîêó â ñîîòâåòñòâèè ñî çíà÷åíèåì
function get_param_string(src_string , obj)
--printf("src_string is [%s] obj name is [%s]", tostring(src_string), obj:name())
local script_ids = db.script_ids[obj:id()]
local out_string, num = string.gsub(src_string, "%$script_id%$", tostring(script_ids))
if num > 0 then
return out_string , true
else
return src_string , false
end
end
local save_markers = {}
-- Ôóíêöèè äëÿ ïðîâåðêè êîððåêòíîñòè ñåéâ ëîàä
function set_save_marker(p, mode, check, prefix)
-- îïðåäåëÿåì êëþ÷ ìàðêåðà.
local result = ""
-- if debug ~= nil then
-- local info_table = debug.getinfo(2)
-- local script_name = string.gsub(info_table.short_src, "%.script", "")
-- script_name = string.gsub(script_name, "gamedata\\scripts\\", "")
-- result = script_name
-- end
-- if prefix ~= nil then
result = result .. "_" .. prefix
-- end
if check == true then
if save_markers[result] == nil then
abort("Trying to check without marker %s", result)
end
if mode == "save" then
local dif = p:w_tell() - save_markers[result]
printf(result..": SAVE DIF: %s", dif)
if dif >= 8000 then
printf("WARNING! may be this is problem save point")
end
if dif >= 10240 then
-- abort("You are saving too much")
end
p:w_u16(dif)
else
local c_dif = p:r_tell() - save_markers[result]
local dif = p:r_u16()
if dif ~= c_dif then
abort("INCORRECT LOAD [%s].[%s][%s]", result, dif, c_dif)
else
printf(result..": LOAD DIF: %s", dif)
end
end
return
end
if mode == "save" then
printf(result..": set save marker: %s", p:w_tell())
save_markers[result] = p:w_tell()
if p:w_tell() > 16000 then
abort("You are saving too much")
end
else
printf(result..": set load marker: %s", p:r_tell())
save_markers[result] = p:r_tell()
end
end
-- ïåðåâîäèò âåêòîð â ñòðîêó.
function vec_to_str (vector)
if vector == nil then return "nil" end
return string.format("[%s:%s:%s]", vector.x, vector.y, vector.z)
end
-- âûâîäèò â ëîã ñòýê âûçîâà ôóíêöèé.
function callstack()
if debug ~= nil then
log(debug.traceback(2))
end
end
-- ìåíÿåò team:squad:group îáüåêòà.
function change_team_squad_group(se_obj, team, squad, group)
local cl_obj = db.storage[se_obj.id] and db.storage[se_obj.id].object
if cl_obj ~= nil then
cl_obj:change_team(team, squad, group)
else
se_obj.team = team
se_obj.squad = squad
se_obj.group = group
end
--printf("_G:TSG: [%s][%s][%s]", tostring(se_obj.team), tostring(se_obj.squad), tostring(se_obj.group))
end
-- Story_ID -------------------------------------------------------------
function add_story_object(obj_id , story_obj_id)
story_objects.get_story_objects_registry():register(obj_id , story_obj_id)
end
function get_story_object(story_obj_id)
local obj_id = story_objects.get_story_objects_registry():get(story_obj_id)
if obj_id == nil then return nil end
return (db.storage[obj_id] and db.storage[obj_id].object) or (level ~= nil and level.object_by_id(obj_id))
end
function get_object_story_id(obj_id)
return story_objects.get_story_objects_registry():get_story_id(obj_id)
end
function get_story_object_id(story_obj_id)
return story_objects.get_story_objects_registry().id_by_story_id[story_obj_id]
end
function unregister_story_object_by_id(obj_id)
story_objects.get_story_objects_registry():unregister_by_id(obj_id)
end
function unregister_story_id(story_id)
story_objects.get_story_objects_registry():unregister_by_story_id(story_id)
end
-----------------------------------------------------------------------------------------------
-- Ïîëó÷èòü ñêâàä îáüåêòà!!!!!
function get_object_squad(object)
if object == nil then abort("You are trying to get squad_object from NIL object!!!") end
local obj_id = nil
if type(object.id) == "function" then
obj_id = object:id()
else
obj_id = object.id
end
local se_obj = alife():object(obj_id)
if se_obj and se_obj.group_id ~= 65535 then
return alife():object(se_obj.group_id)
end
return nil
end
function get_story_squad(story_id)
local squad_id = get_story_object_id(story_id)
return squad_id and alife():object(squad_id)
end
--Ïðîâåðêà ïî âðåìåííîìó èíòåðâàëó.
function in_time_interval(val1, val2)
local game_hours = level.get_time_hours()
if val1 >= val2 then
return game_hours < val2 or game_hours >= val1
else
return game_hours < val2 and game_hours >= val1
end
end
function show_all_ui(show)
local hud = get_hud()
if(show) then
level.show_indicators()
-- db.actor:restore_weapon()
db.actor:disable_hit_marks(false)
hud:show_messages()
else
if db.actor:is_talking() then
db.actor:stop_talk()
end
level.hide_indicators_safe()
hud:HideActorMenu()
hud:HidePdaMenu()
hud:hide_messages()
-- db.actor:hide_weapon()
db.actor:disable_hit_marks(true)
end
end

View file

@ -0,0 +1,94 @@
-- actor_menu_mode -----
-- int mode:
-- 0 = Undefined = çàêðûòî
-- 1 = Inventory
-- 2 = Trade
-- 3 = Upgrade
-- 4 = DeadBodySearch
-- 10 = Talk dialog show
-- 11 = Talk dialog hide
local last_mode = 0
xr_meet_dialog_closed = false
xr_meet_trade_closed = false
xr_meet_upgrade_closed = false
dead_body_searching = false
function actor_menu_mode(mode)
if(mode==0) then
if(last_mode==1) then
inventory_wnd_closed()
elseif(last_mode==2) then
trade_wnd_closed()
elseif(last_mode==3) then
upgrade_wnd_closed()
elseif(last_mode==4) then
dead_body_search_wnd_closed()
end
last_mode = 0
elseif(mode==1) then
last_mode = 1
inventory_wnd_opened()
elseif(mode==2) then
last_mode = 2
trade_wnd_opened()
elseif(mode==3) then
last_mode = 3
upgrade_wnd_opened()
elseif(mode==4) then
last_mode = 4
dead_body_search_wnd_opened()
elseif(mode==10) then
dialog_wnd_showed()
elseif(mode==11) then
dialog_wnd_closed()
end
end
function inventory_wnd_opened()
printf("---:>Inventory opened")
end
function inventory_wnd_closed()
printf("---:>Inventory closed")
end
function trade_wnd_opened()
xr_meet_dialog_closed = false
printf("---:>Trade opened")
end
function trade_wnd_closed()
printf("---:>Trade closed")
xr_meet_trade_closed = true
end
function upgrade_wnd_opened()
xr_meet_dialog_closed = false
printf("---:>Upgrade opened")
end
function upgrade_wnd_closed()
printf("---:>Upgrade closed")
xr_meet_upgrade_closed = true
end
function dead_body_search_wnd_opened()
printf("---:>DeadBodySearch opened")
dead_body_searching = true
end
function dead_body_search_wnd_closed()
printf("---:>DeadBodySearch closed")
dead_body_searching = false
end
function dialog_wnd_showed()
printf("---:>Talk Dialog show")
end
function dialog_wnd_closed()
printf("---:>Talk Dialog hide")
xr_meet_dialog_closed = true
end

View file

@ -0,0 +1,73 @@
--[[------------------------------------------------------------------------------------------------------------------
Êëàññ "actor_proxy". Îáåñïå÷èâàåò ïîääåðæêó àêò¸ðà, äàæå åñëè îí â îôëàéíå.
×óãàé Àëåêñàäð
--------------------------------------------------------------------------------------------------------------------]]
class "actor_proxy"
-- êîíñòðóêòîð
function actor_proxy:__init()
self.initialized = false
end
-- èíèöèàëèçàöèÿ.
-- ïðîèñõîäèò òîëüêî â ìîìåíò ïåðâîãî ïîñëå ñòàðòà ñèìóëÿòîðà îáðàùåíèÿ.
function actor_proxy:init()
if not self.initialized then
-- printf( "actor_proxy: init" )
self.online = false
self.alife = alife()
if self.alife then
self.actor_id = self.alife:actor().id
end
self.actor = nil
self.initialized = true
end
end
-- äåèíèöèàëèçàöèÿ.
-- ïðîèñõîäèò â ìîìåíò äåðåãèñòðàöèè ñåðâåðíûõ îáúåêòîâ.
-- âûçûâàåòñÿ èç se_smart_terrain:on_unregister() TODO remove this hack
function actor_proxy:deinit()
if self.initialized then
-- printf( "actor_proxy: deinit" )
self.alife = nil
self.actor = nil
self.initialized = false
end
end
-- Ïîëó÷åíèå ID èãðîêà
function actor_proxy:id()
self:init()
return self.actor_id
end
function actor_proxy:has_info( name )
self:init()
has_alife_info(name)
end
function actor_proxy:dont_has_info( name )
self:init()
if self.online then
-- printf( "actor_proxy: dont_has_info online: info=%s", name )
return not has_alife_info( name )
else
-- printf( "actor_proxy: dont_has_info offline: info=%s", name )
return not has_alife_info( self.actor_id, name )
end
end
-- ðîæäåíèå àêò¸ðà â îíëàéí
function actor_proxy:net_spawn( obj )
self:init()
self.online = true
self.actor = obj
end
-- óõîä àêò¸ðà èç îíëàéíà
function actor_proxy:net_destroy()
self:init()
self.online = false
self.actor = nil
end

View file

@ -0,0 +1,218 @@
--[[
This script handles the serialization of data using the marshal library and the saving of this data to disk depending
on save game name. What this means is that you can save entire tables to disk instead of saving to object packet.
This script was created to alleviate issues with using packets to save dynamic data (pstor) which lead to save corruption.
Also it removes some restrictions on what you can save.
*only store valid lua types such as numbers, strings, boolean, functions or tables that contain these valid types. Userdata needs to have a special
__persist function defined in it's metatable. See how it is done for CTime in _G.script
*Supposedly you can save userdata if you write a proper __persist method for the metatable but I have failed to achieve proper results with serializing CTime.
*You must register for 'save_state' and 'load_state' and add your own table to m_data for it to be encoded then stored in *.scoc
*Although marshal is pretty fast, keep in mind that encoding/decoding a ton of data, saves will start to noticeablely take longer to save/load.
*For testing/debugging you can uncomment the print_table calls in save_state and load_state. It will save the before and after tables to print_table.txt in your main directory.
by: Alundaio
--]]
local m_data = {}
-- store stuff that you want to persist even offline
m_data.se_object = {}
-- store stuff only for online objects. When object goes offline this table is purged.
m_data.game_object = {}
-- PDA known contacts
-- m_data.actor_contacts = {}
saved_game_extension_ex = save_extension() .. "_data"
local function on_pstor_load_all(obj,packet)
local id = obj:id()
local state = get_game_object_state(obj,false)
if (state and db.storage[id]) then
if (state.pstor_all) then
db.storage[id].pstor = state.pstor_all
state.pstor_all = nil
end
if (state.pstor_ctime) then
db.storage[id].pstor_ctime = state.pstor_ctime
state.pstor_ctime = nil
end
end
end
function on_game_start()
if not isMarshal then
return
end
--RegisterScriptCallback("on_pstor_load_all",on_pstor_load_all)
end
-- called from engine!
function CALifeStorageManager_before_save(fname)
if not isMarshal then
return
end
--printf("CALifeStorageManager_before_save BEFORE callback")
m_data.GAME_VERSION = GAME_VERSION
SendScriptCallback("save_state",m_data)
--printf("CALifeStorageManager_before_save AFTER callback")
-- save pstor
for id,t in pairs(db.storage) do
if (m_data.game_object[id]) then
if (t.pstor and not is_empty(t.pstor)) then
m_data.game_object[id].pstor_all = t.pstor
end
-- serialization with game.CTime.__persist
if (t.pstor_ctime and not is_empty(t.pstor_ctime)) then
m_data.game_object[id].pstor_ctime = t.pstor_ctime
end
end
end
--ProcessEventQueueState(m_data,true)
-- clean out game_object table of empty sub tables
for id,tbl in pairs(m_data.game_object) do
for k,v in pairs(tbl) do
if (type(v) == "table" and is_empty(v)) then
m_data.game_object[id][k] = nil
end
end
end
local data = marshal.encode(m_data)
if not (data) then
return
end
local path = getFS():update_path('$game_saves$', '')
lfs.mkdir(path) -- incase savegame folder doesn't exist yet
path = path .. fname:sub(0,-6):lower() .. saved_game_extension_ex
local savegame = io.open(path,"wb")
if not (io.type(savegame) == "file") then
printf("Error: Unable to write to %s",path)
return
end
--printf("axr_main: saving custom data %s",path)
savegame:write(data)
savegame:close()
--printf("CALifeStorageManager_before_save FINISHED")
end
-- called from engine!
function CALifeStorageManager_after_save(fname)
if ffx_path_utils then
fname = ffx_path_utils.get_file_name(fname, false)
end
local _path = getFS():update_path('$game_saves$', '')
SendScriptCallback("save_file_created", _path, fname)
end
-- called from engine!
function CALifeStorageManager_new_game(fname)
if ffx_path_utils then
fname = ffx_path_utils.get_file_name(fname, false)
end
local _path = getFS():update_path('$game_saves$', '')
SendScriptCallback("new_game_created", _path, fname)
end
-- called from engine!
function CALifeStorageManager_save(fname)
--printf("CALifeStorageManager_save START FINISHED")
end
-- called from engine
function CALifeStorageManager_load(fname)
if not isMarshal then
return
end
local path = fname:sub(0,-6) .. saved_game_extension_ex
--alun_utils.debug_write(strformat("CALifeStorageManager_load %s",path))
local savegame = io.open(path,"rb")
if not (io.type(savegame) == "file") then
return
end
local data = savegame:read("*all")
savegame:close()
if not (data and data ~= "") then
printf("Error: Failed to read %s",path)
return
end
m_data = marshal.decode(data)
--ProcessEventQueueState(m_data,false)
-- For debugging save state
--alun_utils.print_table(m_data,"m_data_on_load ("..path..")")
SendScriptCallback("load_state",m_data)
if ffx_path_utils then
fname = ffx_path_utils.get_file_name(fname, false)
end
local _path = getFS():update_path('$game_saves$', '')
SendScriptCallback("save_file_loaded", _path, fname)
--alun_utils.debug_write(strformat("CALifeStorageManager_load END"))
end
function get_state()
return m_data
end
function decode(t)
return marshal.decode(t)
end
-- storage based on ID but verified by object name
function get_game_object_state(obj,create_if_dont_exist)
local id = obj:id()
local name = obj:name()
if not (m_data.game_object[id]) then
if not (create_if_dont_exist) then
return
end
m_data.game_object[id] = {}
m_data.game_object[id].name = name
end
return m_data.game_object[id]
end
function get_se_obj_state(se_obj,create_if_dont_exist)
local id = se_obj.id
local name = se_obj:name()
if not (m_data.se_object[id]) then
if not (create_if_dont_exist) then
return
end
m_data.se_object[id] = {}
m_data.se_object[id].name = name
end
return m_data.se_object[id]
end

View file

@ -0,0 +1,39 @@
function main()
local spawn_table = { bench_sunshafts = { weather_name = "sun_shafts",
effector_name = "marsh_benchmark",
effector_id = 106081,
enable_light = false
},
bench_rain = { weather_name = "default_rain",
effector_name = "marsh_benchmark",
effector_id = 106082,
enable_light = false
},
bench_day = { weather_name = "default_clear",
effector_name = "marsh_benchmark",
effector_id = 106082,
enable_light = false
},
bench_night = { weather_name = "night",
effector_name = "marsh_benchmark",
effector_id = 106083,
enable_light = true
}
}
local pos1 = string.find(command_line(), "%(")
local pos2 = string.find(command_line(), "/", pos1)
if pos1 and pos2 then
local spawn_name = string.sub(command_line(), pos1+1, pos2-1)
if spawn_table[spawn_name] then
weather = true
level.set_weather(spawn_table[spawn_name].weather_name, true)
if spawn_table[spawn_name].enable_light then
light = true
end
level.add_cam_effector2( "benchmarks\\"..spawn_table[spawn_name].effector_name..".anm",
spawn_table[spawn_name].effector_id,
false,
"xr_effects.quit")
end
end
end

View file

@ -0,0 +1,61 @@
--'******************************************************
--'* Áèíäåð îáúåêòà ïîëÿ àíîìàëèé.
--'******************************************************
fields_by_names = {}
function bind(obj)
obj:bind_object(anomaly_field_binder(obj))
end
class "anomaly_field_binder" (object_binder)
function anomaly_field_binder:__init(obj) super(obj)
self.last_update = time_global()
end
function anomaly_field_binder:reload(section)
object_binder.reload(self, section)
end
function anomaly_field_binder:reinit()
object_binder.reinit(self)
db.storage[self.object:id()] = {}
self.st = db.storage[self.object:id()]
end
function anomaly_field_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
db.add_zone(self.object)
db.add_obj(self.object)
fields_by_names[self.object:name()] = self
return true
end
function anomaly_field_binder:net_destroy()
db.del_zone( self.object )
db.del_obj(self.object)
db.storage[self.object:id()] = nil
fields_by_names[self.object:name()] = nil
object_binder.net_destroy(self)
end
function anomaly_field_binder:set_enable(bEnable)
if(bEnable) then
self.object:enable_anomaly()
else
self.object:disable_anomaly()
end
end
function anomaly_field_binder:update(delta)
object_binder.update(self, delta)
if(time_global()-self.last_update<10000) then
return
end
self.last_update = time_global()
end
-- Standart function for save
function anomaly_field_binder:net_save_relevant()
return true
end

View file

@ -0,0 +1,470 @@
--'******************************************************
--'* Áèíäåð îáúåêòà çîíû àíîìàëèé .
--'******************************************************
artefact_ways_by_id = {}
artefact_points_by_id = {}
parent_zones_by_artefact_id = {}
ANOMAL_ZONE_SECT = "anomal_zone"
function bind(obj)
obj:bind_object(anomaly_zone_binder(obj))
end
class "anomaly_zone_binder" (object_binder)
function anomaly_zone_binder:__init(obj) super(obj)
self.ini = obj:spawn_ini()
if not self.ini:section_exist(ANOMAL_ZONE_SECT) then
printf( "[anomal_zone %s] no configuration!", obj:name() )
self.disabled = true
return
end
local filename = utils.cfg_get_string(self.ini, ANOMAL_ZONE_SECT, "cfg", nil, false, "", nil)
if filename then
self.ini = ini_file(filename)
end
local ini = self.ini
self.artefact_ways_by_id = {}
self.artefact_points_by_id = {}
self.disabled = false
self.turned_off = false
self.artefacts_table = {}
self.start_artefacts_table = {}
self.artefacts_coeff_table = {}
self.path_table = {}
self.fields_table = {}
self.mines_table = {}
self.respawn_tries_table = {}
self.max_artefacts_table = {}
self.forces_table = {}
self.spawned_count = 0
self.respawn_artefacts = true
self.forced_spawn = false
self.forced_spawn_override = false
self.forced_artefact = ""
self.layers_count = utils.cfg_get_number(ini, ANOMAL_ZONE_SECT, "layers_count", nil, false, 1)
self.cur_layer = "layer_"..math.random(1,self.layers_count)
self.custom_placement = self.layers_count>1
local def_respawn_tries = utils.cfg_get_number(ini, ANOMAL_ZONE_SECT, "respawn_tries", nil, false, 2)
local def_max_artefacts = utils.cfg_get_number(ini, ANOMAL_ZONE_SECT, "max_artefacts", nil, false, 3)
local def_app_force_xz = utils.cfg_get_number(ini, ANOMAL_ZONE_SECT, "applying_force_xz", nil, false, 200)
local def_app_force_y = utils.cfg_get_number(ini, ANOMAL_ZONE_SECT, "applying_force_y", nil, false, 400)
local def_arts = utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "artefacts", nil, false, "", nil)
local def_start_arts = utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "start_artefact",nil, false, "", nil)
local def_ways = utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "artefact_ways", nil, false, "", nil)
local def_field_name = utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "field_name", nil, false, "", nil)
local def_coeff_sect_name= utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "coeffs_section",nil, false, "", "{+actor_was_in_many_bad_places} coeff2, coeff")
local def_coeffs = utils.cfg_get_string(ini, ANOMAL_ZONE_SECT, "coeff", nil, false, "", nil)
for i = 1, self.layers_count do
local section = "layer_"..i
self.respawn_tries_table[section] = utils.cfg_get_number(ini, section, "artefact_count", nil, false, def_respawn_tries)
self.respawn_tries_table[section] = utils.cfg_get_number(ini, section, "respawn_tries", nil, false, self.respawn_tries_table[section])
self.max_artefacts_table[section] = utils.cfg_get_number(ini, section, "max_artefacts", nil, false, def_max_artefacts)
self.forces_table[section] = {}
self.forces_table[section].xz = utils.cfg_get_number(ini, section, "applying_force_xz", nil, false, def_app_force_xz)
self.forces_table[section].y = utils.cfg_get_number(ini, section, "applying_force_y", nil, false, def_app_force_y)
local arts = utils.cfg_get_string(ini, section, "artefacts", nil, false, "", def_arts)
if arts == nil then
abort("There is no field 'artefacts' in section [%s] in obj [%s]", section, obj:name())
end
self.artefacts_table[section] = parse_names(arts)
local start_arts = utils.cfg_get_string(ini, section, "start_artefact", nil, false, "", def_start_arts)
if start_arts ~= nil then
self.forced_spawn = true
self.start_artefacts_table[section] = parse_names(start_arts)
end
local coeffs_section = utils.cfg_get_string(ini, section, "coeffs_section", nil, false, "", def_coeff_sect_name)
local parsed_condlist = xr_logic.parse_condlist(nil, "anomal_zone_binder", "coeff_condlist", coeffs_section)
local coeffs_sect_name = xr_logic.pick_section_from_condlist(get_story_object("actor"), nil, parsed_condlist)
local coeffs = utils.cfg_get_string(ini, section, coeffs_sect_name, nil, false, "", def_coeffs)
if coeffs ~= nil then
self.artefacts_coeff_table[section] = parse_nums(coeffs)
else
self.artefacts_coeff_table[section] = {}
end
local path = utils.cfg_get_string(ini, section, "artefact_ways", nil, false, "", def_ways)
if path == nil then
abort("There is no field 'artefact_ways' in section [%s] in obj [%s]", section, obj:name())
end
self.path_table[section] = parse_names(path)
if #self.path_table[section] < self.max_artefacts_table[section] then
--abort("Not enough ways for anomal zone [%s], in section [%s], must be at least [%s]", tostring(obj:name()), tostring(section), tostring(self.max_artefacts_table[section]))
end
if(self.custom_placement) then
local field = utils.cfg_get_string(ini, section, "field_name", nil, false, "", def_field_name)
if field == nil then
--abort("There is no field 'field_name' in section [%s] in obj [%s]", section, obj:name())
self.fields_table[section] = {}
else
self.fields_table[section] = parse_names(field)--field
end
local mines_section = utils.cfg_get_string(ini, section, "mines_section", nil, true, "", nil)
if mines_section == nil then
abort("There is no field 'mines_section' in section [%s] in obj [%s]", section, obj:name())
end
if ini:line_count(mines_section) == 0 then
--abort("There is no 'mines_names' in section [%s] in obj [%s]", mines_section, obj:name())
end
self.mines_table[section] = {}
if ini:line_count(mines_section) > 0 then
for i = 0, ini:line_count(mines_section)-1 do
temp1, mine_name, temp2 = ini:r_line(mines_section, i, "", "")
table.insert(self.mines_table[section],mine_name)
end
end
end
end
self.respawn_tries = self.respawn_tries_table[self.cur_layer]
self.max_artefacts = self.max_artefacts_table[self.cur_layer]
self.applying_force_xz = self.forces_table[self.cur_layer].xz
self.applying_force_y = self.forces_table[self.cur_layer].y
end
function anomaly_zone_binder:disable_anomaly_fields()
if not(self.custom_placement) then
self.disabled = true
return
end
local layer = self.cur_layer
local anom_fields = bind_anomaly_field.fields_by_names
local counter = 0
for k,v in pairs(self.fields_table) do
if(k~=layer) then
for kk, vv in pairs(self.fields_table[k]) do
if(anom_fields[vv]~=nil) then
anom_fields[vv]:set_enable(false)
else
counter = counter + 1
end
end
end
end
for k,v in pairs(self.mines_table) do
if(k~=layer) then
for kk,vv in pairs(self.mines_table[k]) do
if(anom_fields[vv]~=nil) then
anom_fields[vv]:set_enable(false)
else
counter = counter + 1
end
end
end
end
if(counter==0) then
self.disabled = true
end
if not self.turned_off then
for kk, vv in pairs(self.fields_table[layer]) do
if(anom_fields[vv]~=nil) then
anom_fields[vv]:set_enable(true)
end
end
for kk,vv in pairs(self.mines_table[layer]) do
if(anom_fields[vv]~=nil) then
anom_fields[vv]:set_enable(true)
end
end
end
end
function anomaly_zone_binder:respawn_artefacts_and_replace_anomaly_zone()
local anom_fields = bind_anomaly_field.fields_by_names
self.respawn_artefacts = true
if(self.custom_placement) then
local layer = self.cur_layer
for k,v in pairs(self.fields_table[layer]) do
if(anom_fields[v]~=nil) then
anom_fields[v]:set_enable(false)
end
end
for k,v in pairs(self.mines_table[layer]) do
if(anom_fields[v]~=nil) then
anom_fields[v]:set_enable(false)
end
end
layer = "layer_"..math.random(1,self.layers_count)
for k,v in pairs(self.fields_table[layer]) do
if(anom_fields[v]~=nil) then
anom_fields[v]:set_enable(true)
end
end
for k,v in pairs(self.mines_table[layer]) do
if(anom_fields[v]~=nil) then
anom_fields[v]:set_enable(true)
end
end
self.cur_layer = layer
self.respawn_tries = self.respawn_tries_table[self.cur_layer]
self.max_artefacts = self.max_artefacts_table[self.cur_layer]
self.applying_force_xz = self.forces_table[self.cur_layer].xz
self.applying_force_y = self.forces_table[self.cur_layer].y
end
end
function anomaly_zone_binder:spawn_artefact_randomly()
local layer = self.cur_layer
local rnd_artefact
if self.forced_spawn_override then
rnd_artefact = self.forced_artefact
self.forced_spawn_override = false
elseif self.forced_spawn then
rnd_artefact = self.start_artefacts_table[layer][#self.start_artefacts_table[layer]]
self.forced_spawn = false
else
if math.random(1,100) > 17 then
return
end
local coeff_total = 0
for k, v in pairs(self.artefacts_coeff_table[layer]) do
coeff_total = coeff_total + v
end
if coeff_total == 0 then
for i = 1, #self.artefacts_table[layer] do
self.artefacts_coeff_table[layer][i] = 1
coeff_total = coeff_total + 1
end
end
local rnd = math.random(1, coeff_total)
for i = 1, #self.artefacts_table[layer] do
local chance = self.artefacts_coeff_table[layer][i]
if rnd <= chance then
rnd_artefact = self.artefacts_table[layer][i]
break
end
rnd = rnd - chance
end
end
local rnd_path_name = self:get_artefact_path()
local rnd_path = patrol(rnd_path_name)
local rnd_path_point = math.random(0, rnd_path:count() - 1)
local artefact_obj = alife():create( rnd_artefact,
rnd_path:point(rnd_path_point),
self.object:level_vertex_id(),
self.object:game_vertex_id())
artefact_ways_by_id[artefact_obj.id] = rnd_path_name
artefact_points_by_id[artefact_obj.id] = rnd_path_point
self.artefact_ways_by_id[artefact_obj.id] = rnd_path_name
self.artefact_points_by_id[artefact_obj.id] = rnd_path_point
parent_zones_by_artefact_id[artefact_obj.id] = self
self.spawned_count = self.spawned_count + 1
end
function anomaly_zone_binder:get_artefact_path()
local temp_table = {}
for k,v in pairs(self.path_table[self.cur_layer]) do
local f_spawned = false
for kk,vv in pairs(self.artefact_ways_by_id) do
if vv ~= nil and v == vv then
f_spawned = true
end
end
if not f_spawned then
table.insert(temp_table, v)
end
end
if #temp_table < 1 then
--abort("No free way to spawn artefact in anomal zone [%s]", tostring(self.object:name()))
return self.path_table[self.cur_layer][math.random(1, #self.path_table[self.cur_layer])]
end
local rnd_path_name = temp_table[math.random(1, #temp_table)]
return rnd_path_name
end
function anomaly_zone_binder:set_forced_override(artefact_name)
self.forced_artefact = artefact_name
self.forced_spawn_override = true
printf("set forced override for zone [%s], artefact [%s]", tostring(self.object:name()), tostring(artefact_name))
end
function anomaly_zone_binder:reload(section)
object_binder.reload(self, section)
end
function anomaly_zone_binder:reinit()
object_binder.reinit(self)
db.storage[self.object:id()] = {}
self.st = db.storage[self.object:id()]
end
function anomaly_zone_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
db.add_anomaly(self)
db.add_obj(self.object)
return true
end
function anomaly_zone_binder:net_destroy()
db.del_anomaly(self)
db.del_obj(self.object)
db.storage[self.object:id()] = nil
object_binder.net_destroy(self)
end
function anomaly_zone_binder:update(delta)
object_binder.update(self, delta)
if (not self.turned_off) and (self.spawned_count < self.max_artefacts) and self.respawn_artefacts then
local cnt = self.respawn_tries
if cnt > self.max_artefacts - self.spawned_count then
cnt = self.max_artefacts - self.spawned_count
end
if cnt ~= 0 then
for i=1, cnt do
self:spawn_artefact_randomly()
end
end
self.respawn_artefacts = false
elseif (not self.turned_off) and (self.spawned_count >= self.max_artefacts) and self.respawn_artefacts then
self.respawn_artefacts = false
end
if not(self.disabled) then
self:disable_anomaly_fields()
end
end
function anomaly_zone_binder:turn_off()
self.turned_off = true
self:disable_anomaly_fields()
for k,v in pairs(self.artefact_ways_by_id) do
alife():release(alife():object(tonumber(k)), true)
artefact_ways_by_id[k] = nil
artefact_points_by_id[k] = nil
parent_zones_by_artefact_id[k] = nil
end
self.spawned_count = 0
self.artefact_ways_by_id = {}
self.artefact_points_by_id = {}
end
function anomaly_zone_binder:turn_on(f_af)
self.turned_off = false
self:disable_anomaly_fields()
if f_af then
self.respawn_artefacts = true
else
self.respawn_artefacts = false
end
end
function anomaly_zone_binder:on_artefact_take(obj)
local id
if(type(obj.id)=="number") then
id = obj.id
else
id = obj:id()
end
artefact_ways_by_id[id] = nil
artefact_points_by_id[id] = nil
self.artefact_ways_by_id[id] = nil
self.artefact_points_by_id[id] = nil
self.spawned_count = self.spawned_count - 1
pda.change_anomalies_names()
end
-- Standart function for save
function anomaly_zone_binder:net_save_relevant()
return true
end
-- Saving anomaly zone
function anomaly_zone_binder:save(thread)
set_save_marker(thread, "save", false, "anomaly_zone_binder")
object_binder.save(self, thread)
local count = 0
for k,v in pairs(self.artefact_ways_by_id) do
count = count + 1
end
thread:w_u16(count)
for k,v in pairs(self.artefact_ways_by_id) do
thread:w_u16(k)
thread:w_stringZ(v)
end
----------------optimize this---------------------------------------------------
local count = 0
for k,v in pairs(self.artefact_points_by_id) do
count = count + 1
end
thread:w_u16(count)
for k,v in pairs(self.artefact_points_by_id) do
thread:w_u16(k)
thread:w_u8(v)
end
--------------------------------------------------------------------------------
thread:w_u8(self.spawned_count)
thread:w_bool(self.respawn_artefacts)
thread:w_bool(self.forced_spawn)
thread:w_bool(self.forced_spawn_override)
thread:w_stringZ(self.forced_artefact)
local layer_num = tonumber(string.sub(self.cur_layer, string.find(self.cur_layer, "_")+1, string.len(self.cur_layer)))
if(layer_num) then
thread:w_u8(layer_num)
else
thread:w_u8(-1)
end
thread:w_bool(self.turned_off)
set_save_marker(thread, "save", true, "anomaly_zone_binder")
end
-- Loading anomaly zone
function anomaly_zone_binder:load(thread)
set_save_marker(thread, "load", false, "anomaly_zone_binder")
object_binder.load(self, thread)
local count = thread:r_u16()
for i=1,count do
local art_id = thread:r_u16()
local way_name = thread:r_stringZ()
artefact_ways_by_id[art_id] = way_name
self.artefact_ways_by_id[art_id] = way_name
parent_zones_by_artefact_id[art_id] = self
end
----------------optimize this---------------------------------------------------
local count = thread:r_u16()
for i=1,count do
local art_id = thread:r_u16()
local point_name = thread:r_u8()
artefact_points_by_id[art_id] = point_name
self.artefact_points_by_id[art_id] = point_name
end
--------------------------------------------------------------------------------
self.spawned_count = thread:r_u8()
self.respawn_artefacts = thread:r_bool()
self.forced_spawn = thread:r_bool()
self.forced_spawn_override = thread:r_bool()
self.forced_artefact = thread:r_stringZ()
local layer_num = thread:r_u8()
if(layer_num~=255) then
self.cur_layer = "layer_"..layer_num
end
self.turned_off = thread:r_bool()
set_save_marker(thread, "load", true, "anomaly_zone_binder")
end

View file

@ -0,0 +1,68 @@
--'******************************************************
--'* Áèíäåð îáúåêòà àðòåôàêò .
--'******************************************************
function printf()
end
function bind(obj)
obj:bind_object(artefact_binder(obj))
end
class "artefact_binder" (object_binder)
function artefact_binder:__init(obj) super(obj)
db.storage[self.object:id()] = { }
end
function artefact_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
db.add_obj(self.object)
local artefact = self.object:get_artefact()
local id = self.object:id()
if bind_anomaly_zone.artefact_ways_by_id[id] ~= nil then
local anomal_zone = bind_anomaly_zone.parent_zones_by_artefact_id[id]
local force_xz = anomal_zone.applying_force_xz
local force_y = anomal_zone.applying_force_y
artefact:FollowByPath(bind_anomaly_zone.artefact_ways_by_id[id],bind_anomaly_zone.artefact_points_by_id[id],vector():set(force_xz,force_y,force_xz))
-- artefact:FollowByPath(bind_anomaly_zone.artefact_ways_by_id[id],0,vector():set(force_xz,force_y,force_xz))
end
self.first_call = true
return true
end
function artefact_binder:update(delta)
object_binder.update(self, delta)
printf("pl:art [%s] pos %s", self.object:name(), vec_to_str(self.object:position()))
if self.first_call == true then
local ini = self.object:spawn_ini()
if not (ini and ini:section_exist("fixed_bone")) then
return
end
local bone_name = ini:r_string("fixed_bone", "name")
local ph_shell = self.object:get_physics_shell()
if not ph_shell then
--printf("no ph shell")
return
end
local ph_element = ph_shell:get_element_by_bone_name(bone_name)
if ph_element:is_fixed() then
--printf("OBJECT FIXED")
else
--printf("FIXING OBJECT")
ph_element:fix()
end
self.first_call = false
end
end
function artefact_binder:net_destroy(server_object)
db.del_obj(self.object)
object_binder.net_destroy(self)
end

View file

@ -0,0 +1,66 @@
function bind(obj)
obj:bind_object(camp_binder( obj ))
end
-- Òàáëèöà, ñîäåðæàùàÿ êåìïû
camps = {}
CAMP_SECTION = "camp"
----------------------------------------------------------------------------------------------------
class "camp_binder" ( object_binder )
function camp_binder:__init(obj, char_ini) super(obj)
end
function camp_binder:reload(section)
object_binder.reload(self, section)
end
function camp_binder:reinit()
object_binder.reinit(self)
camps[self.object:id()] = { object = self.object }
end
function camp_binder:net_spawn(data)
if not object_binder.net_spawn( self,data ) then
return false
end
local ini = self.object:spawn_ini()
if ini:section_exist(CAMP_SECTION) then
local filename = utils.cfg_get_string(ini, CAMP_SECTION, "cfg", nil, false, "", nil)
if filename then
ini = ini_file(filename)
end
--printf("!!!!!")
camps[self.object:id()].camp = sr_camp.CCampManager(self.object, ini)
end
return true
end
function camp_binder:net_destroy()
camps[self.object:id()] = nil
object_binder.net_destroy(self)
end
-- âûçûâàåòñÿ èç îáíîâëåíèÿ àêò¸ðà!
function camp_binder:update(delta)
local cc = camps[self.object:id()]
if cc ~= nil then
cc.camp:update()
end
end
function camp_binder:net_save_relevant()
return true
end
function camp_binder:save(packet)
set_save_marker(packet, "save", false, "camp_binder")
object_binder.save(self, packet)
set_save_marker(packet, "save", true, "camp_binder")
end
function camp_binder:load(reader)
set_save_marker(reader, "load", false, "camp_binder")
object_binder.load(self, reader)
set_save_marker(reader, "load", true, "camp_binder")
end

View file

@ -0,0 +1,78 @@
--'******************************************************
--'* Áèíäåð îáúåêòà êîñòðà .
--'******************************************************
campfire_table_by_smart_names = {}
function bind(obj)
obj:bind_object(campfire_binder(obj))
end
class "campfire_binder" (object_binder)
function campfire_binder:__init(obj) super(obj)
self.campfire = obj:get_campfire()
end
function campfire_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
local smart_name = string.gsub(self.object:name(), "_campfire_%d*", "")
if sim_board.get_sim_board().smarts_by_names[smart_name] then
self.campfire:turn_off()
if campfire_table_by_smart_names[smart_name] == nil then
campfire_table_by_smart_names[smart_name] = {}
end
campfire_table_by_smart_names[smart_name][self.object:id()] = self.campfire
end
return true
end
function campfire_binder:update(delta)
object_binder.update(self, delta)
--[[ printf("campfire_update!!!")
local kamp = xr_kamp.kamps[string.gsub(self.object:name(), "_campfire", "")]
if kamp ~= nil and kamp.population > 0 then
if self.campfire:is_on() then
if (level.get_time_hours() >= 4 and level.get_time_hours() < 21) and level.get_time_minutes() >= campfire_timeout[self.object:name()] then
printf("turning off campfire %s %s %s",tostring(level.get_time_hours() >= 6 and level.get_time_hours() < 21),tostring(self.population),tostring(campfire:is_on()))
self.campfire:turn_off()
printf("turning off campfire %s %s %s",tostring(level.get_time_hours() >= 6 and level.get_time_hours() < 21),tostring(self.population),tostring(campfire:is_on()))
end
else
if (level.get_time_hours() < 4 or level.get_time_hours() >= 21) and level.get_time_minutes() >= campfire_timeout[self.object:name()] then
printf("turning on campfire %s %s %s",tostring(level.get_time_hours() >= 6 and level.get_time_hours() < 21),tostring(self.population),tostring(campfire:is_on()))
self.campfire:turn_on()
end
end
else
self.campfire:turn_off()
end ]]--
end
function turn_on_campfires_by_smart_name(smart_name)
local smart_campfires = campfire_table_by_smart_names[smart_name]
if smart_campfires ~= nil and not empty(smart_campfires) then
for k,v in pairs (smart_campfires) do
if not v:is_on() then
v:turn_on()
end
end
end
end
function turn_off_campfires_by_smart_name(smart_name)
local smart_campfires = campfire_table_by_smart_names[smart_name]
if smart_campfires ~= nil and not empty(smart_campfires) then
for k,v in pairs (smart_campfires) do
if v:is_on() then
v:turn_off()
end
end
end
end

View file

@ -0,0 +1,96 @@
--------------------------------------------------------------------------------
-- Crow binding ----------------------------------------------------------------
-- Made by Peacemaker ----------------------------------------------------------
-- 25.12.07 --------------------------------------------------------------------
--------------------------------------------------------------------------------
crow_storage = {}
crow_counter = 0
-- Standart function for object binding
function bind(obj)
-- local new_binder = crow_binder(obj)
obj:bind_object(crow_binder(obj))
end
--------------------------------------------------------------------------------
-- Class "crow_binder"
--------------------------------------------------------------------------------
class "crow_binder" (object_binder)
-- Class constructor
function crow_binder:__init(obj) super(obj)
self.body_timer = 0
end
-- Class update
function crow_binder:update(delta)
-- standart update
object_binder.update(self, delta)
if not(self.object:alive()) and (self.body_timer<=time_global()-120000) and (self.body_timer~=0) then
-- if crow is killed and body lays down for two minutes - release it
printf("releasing object ["..self.object:name().."]")
alife():release(alife():object(self.object:id()), true)
end
end
-- Reload object
function crow_binder:reload(section)
object_binder.reload(self, section)
end
-- Reinitialize object
function crow_binder:reinit()
self.body_timer = 0
object_binder.reinit(self)
db.storage[self.object:id()] = {}
self.st = db.storage[self.object:id()]
end
-- Net spawn
function crow_binder:net_spawn(sobject)
if not(object_binder.net_spawn(self, sobject)) then
return false
end
db.add_obj(self.object)
bind_crow.crow_storage[self.object:id()] = self.object:id()
bind_crow.crow_counter = bind_crow.crow_counter + 1
self.object:set_callback(callback.death, self.death_callback, self)
return true
end
-- Net destroy
function crow_binder:net_destroy()
self.object:set_callback(callback.death, nil)
if (bind_crow.crow_storage[self.object:id()] ~= nil) then --*Crow FIX*
bind_crow.crow_storage[self.object:id()] = nil
bind_crow.crow_counter = bind_crow.crow_counter - 1
if (bind_crow.crow_counter < 0) then --*Crow FIX*
bind_crow.crow_counter = 0 --*Crow FIX*
end --*Crow FIX*
end --*Crow FIX*
db.del_obj(self.object)
object_binder.net_destroy(self)
end
-- Crow death callback
function crow_binder:death_callback(victim, who)
self.body_timer = time_global()
if (bind_crow.crow_storage[self.object:id()] ~= nil) then --*Crow FIX*
bind_crow.crow_storage[self.object:id()] = nil
bind_crow.crow_counter = bind_crow.crow_counter - 1
if (bind_crow.crow_counter < 0) then --*Crow FIX*
bind_crow.crow_counter = 0 --*Crow FIX*
end --*Crow FIX*
end --*Crow FIX*
end
-- Standart function for save
function crow_binder:net_save_relevant()
return true
end
-- Saving crow
function crow_binder:save(package)
set_save_marker(package, "save", false, "crow_binder")
object_binder.save(self, package)
xr_logic.save_obj(self.object, package)
package:w_u32(self.body_timer)
set_save_marker(package, "save", true, "crow_binder")
end
-- Loading crow
function crow_binder:load(reader)
set_save_marker(reader, "load", false, "crow_binder")
object_binder.load(self, reader)
xr_logic.load_obj(self.object, reader)
self.body_timer = reader:r_u32()
set_save_marker(reader, "load", true, "crow_binder")
end

View file

@ -0,0 +1,217 @@
ANIMATED_OBJECT_SECT = "animated_object"
--------------------------------------------------------------------------------
-- Animated doors' binder
--------------------------------------------------------------------------------
function bind(obj)
obj:bind_object(door_binder_labx8(obj))
db.storage[obj:id()] = {}
end
--------------------------------------------------------------------------------
class "door_binder_labx8" (object_binder)
function door_binder_labx8:__init(obj) super(obj)
local ini = obj:spawn_ini()
if not ini:section_exist(ANIMATED_OBJECT_SECT) then
printf( "[animated object %s] no configuration!", obj:name() )
return
end
local filename = utils.cfg_get_string(ini, ANIMATED_OBJECT_SECT, "cfg", nil, false, "", nil)
if filename then
ini = ini_file(filename)
end
-- self.idle = 5000
self.is_idle = true
self.is_play_fwd = false
-- self.idle_end = 0
local idle_snd = utils.cfg_get_string(ini, ANIMATED_OBJECT_SECT, "idle_snd", nil, false, "", "device\\airtight_door_idle")
local start_snd = utils.cfg_get_string(ini, ANIMATED_OBJECT_SECT, "start_snd", nil, false, "", "device\\airtight_door_start")
local stop_snd = utils.cfg_get_string(ini, ANIMATED_OBJECT_SECT, "stop_snd", nil, false, "", "device\\airtight_door_stop")
if idle_snd ~= nil and idle_snd ~= "nil" then
self.idle_snd = sound_object(idle_snd)
end
if start_snd then
self.start_snd = sound_object(start_snd)
end
if stop_snd ~= nil and stop_snd ~= "nil" then
self.stop_snd = sound_object(stop_snd)
end
self.tip = xr_logic.parse_condlist(nil, "door_binder_labx8", "tip_condlist", utils.cfg_get_string(ini, ANIMATED_OBJECT_SECT, "tip", nil, false, "", "none"))
local on_use = "true"
local on_start = "true"
local on_stop = "true"
if(ini:line_exist(ANIMATED_OBJECT_SECT, "on_use")) then
on_use = ini:r_string(ANIMATED_OBJECT_SECT, "on_use")
end
self.on_use = xr_logic.parse_condlist(nil, "door_binder_labx8", "on_use", on_use)
if(ini:line_exist(ANIMATED_OBJECT_SECT, "on_start")) then
on_start = ini:r_string(ANIMATED_OBJECT_SECT, "on_start")
end
self.on_start = xr_logic.parse_condlist(nil, "door_binder_labx8", "on_start", on_start)
if(ini:line_exist(ANIMATED_OBJECT_SECT, "on_stop")) then
on_stop = ini:r_string(ANIMATED_OBJECT_SECT, "on_stop")
end
self.on_stop = xr_logic.parse_condlist(nil, "door_binder_labx8", "on_stop", on_stop)
self.idle_delay = utils.cfg_get_number(ini, ANIMATED_OBJECT_SECT, "idle_delay", nil, false, 2000)
self.start_delay = utils.cfg_get_number(ini, ANIMATED_OBJECT_SECT, "start_delay", nil, false, 0)
self.loaded = false
self.anim_time = 0
end
function door_binder_labx8:net_spawn(server_object)
if not(object_binder.net_spawn(self, server_object)) then
return false
end
db.add_anim_obj(self.object, self)
self.object:get_physics_object():stop_anim()
self.object:get_physics_object():anim_time_set(0)
self.object:set_callback(callback.script_animation, self.animation_end_callback, self)
self.object:set_callback(callback.use_object, self.use_callback, self)
return true
end
function door_binder_labx8:net_destroy()
if self.idle_snd then
self.idle_snd:stop()
end
if self.start_snd then
self.start_snd:stop()
end
if self.stop_snd then
self.stop_snd:stop()
end
self.object:set_callback(callback.script_animation, nil)
db.del_anim_obj(self.object)
object_binder.net_destroy(self)
end
function door_binder_labx8:update(delta)
object_binder.update(self, delta)
if self.anim_time and self.loaded then
self.object:get_physics_object():anim_time_set(self.anim_time)
self.anim_time = nil
end
if not self.is_idle then
-- if(self.idle_end<=game.time()) then
if self.is_play_fwd then
self.object:get_physics_object():run_anim_forward()
else
self.object:get_physics_object():run_anim_back()
end
-- end
else
self.object:get_physics_object():stop_anim()
if self.anim_time then
self.object:get_physics_object():anim_time_set(self.anim_time)
end
if self.idle_snd then
self.idle_snd:stop()
end
end
local tip_string = xr_logic.pick_section_from_condlist(get_story_object("actor"), nil, self.tip)
if tip_string ~= "none" then
self.object:set_tip_text(tip_string)
else
self.object:set_tip_text("")
end
end
function door_binder_labx8:anim_forward()
if self.idle_snd then
self.idle_snd:stop()
end
self.object:get_physics_object():stop_anim()
-- self.idle_end = self.idle + game.time()
if self.start_snd then
self.start_snd:play_at_pos(self.object, self.object:position(), self.start_delay/1000, sound_object.s3d)
end
if self.idle_snd then
self.idle_snd:play_at_pos(self.object, self.object:position(), (self.start_delay + self.idle_delay)/1000, sound_object.s3d + sound_object.looped)
end
self.is_idle = false
self.is_play_fwd = true
xr_logic.pick_section_from_condlist(get_story_object("actor"), obj, self.on_start)
end
function door_binder_labx8:anim_backward()
if self.idle_snd then
self.idle_snd:stop()
end
self.object:get_physics_object():stop_anim()
-- self.idle_end = self.idle + game.time()
if self.start_snd then
self.start_snd:play_at_pos(self.object, self.object:position(), self.start_delay/1000, sound_object.s3d)
end
if self.idle_snd then
self.idle_snd:play_at_pos(self.object, self.object:position(), (self.start_delay + self.idle_delay)/1000, sound_object.s3d + sound_object.looped)
end
self.is_idle = false
self.is_play_fwd = false
xr_logic.pick_section_from_condlist(get_story_object("actor"), obj, self.on_start)
end
function door_binder_labx8:anim_stop()
self.object:get_physics_object():stop_anim()
self.is_idle = true
if self.stop_snd then
self.stop_snd:play_at_pos(self.object, self.object:position(), 0, sound_object.s3d)
end
self.anim_time = self.object:get_physics_object():anim_time_get()
xr_logic.pick_section_from_condlist(get_story_object("actor"), obj, self.on_stop)
end
function door_binder_labx8:animation_end_callback(is_end)
if is_end then
if self.stop_snd then
self.stop_snd:play_at_pos(self.object, self.object:position(), 0, sound_object.s3d)
end
self.is_idle = true
self.anim_time = self.object:get_physics_object():anim_time_get()
xr_logic.pick_section_from_condlist(get_story_object("actor"), obj, self.on_stop)
end
end
function door_binder_labx8:use_callback(obj)
xr_logic.pick_section_from_condlist(get_story_object("actor"), obj, self.on_use)
end
-- Standart function for save
function door_binder_labx8:net_save_relevant()
return true
end
-- Saving
function door_binder_labx8:save(packet)
set_save_marker(packet, "save", false, "door_binder_labx8")
object_binder.save(self, packet)
xr_logic.save_obj(self.object, packet)
packet:w_bool(self.is_idle)
packet:w_bool(self.is_play_fwd)
-- packet:w_u32(self.idle_end)
packet:w_float(self.object:get_physics_object():anim_time_get())
set_save_marker(packet, "save", true, "door_binder_labx8")
end
-- Loading
function door_binder_labx8:load(packet)
set_save_marker(packet, "load", false, "door_binder_labx8")
object_binder.load(self, packet)
xr_logic.load_obj(self.object, packet)
self.is_idle = packet:r_bool()
self.is_play_fwd = packet:r_bool()
-- self.idle_end = packet:r_u32()
self.anim_time = packet:r_float()
self.loaded = true
set_save_marker(packet, "load", true, "door_binder_labx8")
end

View file

@ -0,0 +1,24 @@
--'******************************************************
--'* Áèíäåð îáúåêòà ãðóïïèðîâêè.
--'******************************************************
function bind(obj)
obj:bind_object(faction_binder(obj))
end
class "faction_binder" (object_binder)
function faction_binder:__init(obj) super(obj)
end
function faction_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
--' ïîëó÷èòü ññûëêó íà íàñòîÿùèé ñåðâåðíûé îáúåêò
self.faction = alife():object(self.object:id())
return true
end
function faction_binder:update(delta)
object_binder.update(self, delta)
self.faction:update()
end

View file

@ -0,0 +1,223 @@
--[[------------------------------------------------------------------------------------------------
Helicoter binding
×óãàé Àëåêñàíäð
Ñäåëàòü:
- íàñòðîéêè â ltx
--------------------------------------------------------------------------------------------------]]
---------------------------------------------------------------------------------------------
-- Ôóíêöèÿ äëÿ áèíäà
---------------------------------------------------------------------------------------------
function bind( obj )
-- printf( "BIND HELICOPTER id=%d", obj:id() )
local ini = obj:spawn_ini()
if ini and ini:section_exist("logic") then
obj:bind_object( heli_binder( obj, ini ) )
end
end
---------------------------------------------------------------------------------------------
-- Áèíäåð âåðòîë¸òîâ
---------------------------------------------------------------------------------------------
class "heli_binder" ( object_binder )
function heli_binder:__init( obj, ini ) super( obj )
self.ini = ini
self.initialized = false
self.loaded = false
self.heli_fire = heli_fire.get_heli_firer(obj)
end
function heli_binder:reload( section )
object_binder.reload( self, section )
end
function heli_binder:reinit()
object_binder.reinit( self )
--printf( "heli_binder:reinit()" )
db.storage[self.object:id()] = {}
self.st = db.storage[self.object:id()]
self.heliObject = self.object:get_helicopter()
self.object:set_callback( callback.helicopter_on_point, self.on_point, self )
self.object:set_callback( callback.helicopter_on_hit, self.on_hit, self )
self.st.combat = heli_combat.heli_combat( self.object, self.heliObject )
self.last_hit_snd_timeout = 0
local ltx = system_ini()
self.flame_start_health = utils.cfg_get_number( ltx, "helicopter", "flame_start_health", self.object, true )
local object_ini = self.object:spawn_ini()
self.snd_hit = utils.cfg_get_string( object_ini, "helicopter", "snd_hit", self.object, false, "", "heli_hit")
self.snd_damage = utils.cfg_get_string( object_ini, "helicopter", "snd_damage", self.object, false, "", "heli_damaged")
self.snd_down = utils.cfg_get_string( object_ini, "helicopter", "snd_down", self.object, false, "", "heli_down")
-- íà ñëó÷àé çàãðóçêè
self.st.last_alt = self.heliObject:GetRealAltitude()
self.st.alt_check_time = time_global() + 1000
end
function heli_binder:update( delta )
object_binder.update( self, delta )
--printf( "heli_binder update" )
-- printf( "%d", self.object:level_vertex_light( db.actor:level_vertex_id() ) )
if not self.initialized and db.actor then
self.initialized = true
xr_logic.initialize_obj( self.object, self.st, self.loaded, db.actor, modules.stype_heli )
end
if self.st.active_section ~= nil then
xr_logic.issue_event( self.object, self.st[self.st.active_scheme], "update", delta )
end
self.object:info_clear()
local active_section = db.storage[self.object:id()].active_section
if active_section then
self.object:info_add('section -- ' .. active_section)
end
self:check_health()
xr_sound.update(self.object:id())
end
function heli_binder:net_spawn( data )
if not object_binder.net_spawn( self, data ) then
return false
end
db.add_obj( self.object )
db.add_heli( self.object )
return true
end
function heli_binder:net_destroy()
db.del_obj( self.object )
db.del_heli( self.object )
object_binder.net_destroy( self )
end
function heli_binder:net_save_relevant()
return true
end
function heli_binder:save( packet )
object_binder.save( self, packet )
set_save_marker(packet, "save", false, "heli_binder")
--printf( "heli_binder: save")
xr_logic.save_obj( self.object, packet )
set_save_marker(packet, "save", true, "heli_binder")
self.st.combat:save( packet )
end
function heli_binder:load( packet )
self.loaded = true
set_save_marker(packet, "load", false, "heli_binder")
--printf("generic_object_binder:load(): self.object:name()='%s'", self.object:name())
object_binder.load( self, packet )
--printf( "heli_binder: load")
xr_logic.load_obj( self.object, packet )
set_save_marker(packet, "load", true, "heli_binder")
self.st.combat:load( packet )
end
function heli_binder:check_health()
local heli = self.heliObject
--printf( "heli health: %d", heli:GetfHealth() )
if not heli.m_dead then
local health = get_heli_health( self.heliObject, self.st )
if health < self.flame_start_health and not heli.m_flame_started then
heli_start_flame( self.object )
-- xr_sound.set_sound_play(self.object:id(), self.snd_damage)
end
if health <= 0.005 and not self.st.immortal then
heli_die( self.object )
-- xr_sound.set_sound_play(self.object:id(), self.snd_down)
end
end
end
------------------------------ callbacks ---------------------------------
function heli_binder:on_hit( power, impulse, hit_type, enemy_id )
--printf( "heli_binder: hit callback")
local enemy = level.object_by_id( enemy_id )
local enemy_cls_id = get_clsid( enemy )
self.heli_fire.enemy = enemy
self.heli_fire:update_hit()
-- åñëè îáèä÷èê àêò¸ð èëè ñòàëêåð, òî ñäåëàòü åãî ñâîèì âðàãîì
if enemy_cls_id == clsid.actor or enemy_cls_id == clsid.script_stalker then
-- if not self.st.combat.enemy_id then
-- self.st.combat.enemy_id = enemy_id
-- end
if self.st.hit then
xr_logic.issue_event( self.object, self.st.hit, "hit_callback", self.object, power, nil, enemy, nil )
end
end
-- ïèëîòû ðóãàþòñÿ ïî ðàöèè
if self.last_hit_snd_timeout < time_global() then
-- xr_sound.set_sound_play(self.object:id(), self.snd_hit)
self.last_hit_snd_timeout = time_global() + math.random( 4000, 8000 )
end
end
function heli_binder:on_point( distance, position, path_idx )
if self.st.active_section ~= nil then
xr_logic.issue_event( self.object, self.st[self.st.active_scheme], "waypoint_callback", self.object, nil, path_idx )
end
end
--------------------------------------------------------------------------
function get_heli_health( heli, st )
local health
if st.invulnerable then
health = 1
heli:SetfHealth( health )
else
health = heli:GetfHealth()
if health < 0 then
heli:SetfHealth( 0 )
health = 0
end
end
return health
end
function is_heli_alive( obj )
return get_heli_health( obj:get_helicopter(), db.storage[obj:id()] ) > 0.005
end
function heli_start_flame( obj )
obj:get_helicopter():StartFlame()
end
function heli_die( obj )
local heli = obj:get_helicopter()
local st = db.storage[obj:id()]
heli:Die()
db.del_heli( obj )
st.last_alt = heli:GetRealAltitude()
st.alt_check_time = time_global() + 1000
end

View file

@ -0,0 +1,72 @@
--------------------------------------------------------------------------------
-- Level changer binding -------------------------------------------------------
-- Made by Peacemaker ----------------------------------------------------------
-- 25.12.07 --------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Standart function for object binding
function bind(obj)
-- local new_binder = crow_binder(obj)
obj:bind_object(lchanger_binder(obj))
end
--------------------------------------------------------------------------------
-- Class "crow_binder"
--------------------------------------------------------------------------------
class "lchanger_binder" (object_binder)
-- Class constructor
function lchanger_binder:__init(obj) super(obj)
end
-- Class update
function lchanger_binder:update(delta)
-- standart update
object_binder.update(self, delta)
end
-- Reload object
function lchanger_binder:reload(section)
object_binder.reload(self, section)
end
-- Reinitialize object
function lchanger_binder:reinit()
object_binder.reinit(self)
db.storage[self.object:id()] = {}
self.st = db.storage[self.object:id()]
end
-- Net spawn
function lchanger_binder:net_spawn(sobject)
if not(object_binder.net_spawn(self, sobject)) then
return false
end
if string.find(command_line(), "-designer") then
return true
end
local obj = self.object
db.add_obj(obj)
self.st.s_obj = alife():object(obj:id())
obj:enable_level_changer(self.st.s_obj.enabled)
obj:set_level_changer_invitation(self.st.s_obj.hint)
return true
end
-- Net destroy
function lchanger_binder:net_destroy()
db.del_obj(self.object)
object_binder.net_destroy(self)
end
-- Standart function for save
function lchanger_binder:net_save_relevant()
return true
end
-- Saving level changer
function lchanger_binder:save(package)
set_save_marker(package, "save", false, "lchanger_binder")
object_binder.save(self, package)
xr_logic.save_obj(self.object, package)
set_save_marker(package, "save", true, "lchanger_binder")
end
-- Loading level changer
function lchanger_binder:load(reader)
set_save_marker(reader, "load", false, "lchanger_binder")
object_binder.load(self, reader)
xr_logic.load_obj(self.object, reader)
set_save_marker(reader, "load", true, "lchanger_binder")
end

View file

@ -0,0 +1,321 @@
-----------------------------------------------------------------------------------
-- Monster binding
-----------------------------------------------------------------------------------
function bind(obj)
printf("_bp: monster.bind: name='%s', id='%d'", obj:name(), obj:id())
-- Äëÿ ñïàóíà
--xr_spawner.spawn_client(obj)
local new_binder = generic_object_binder(obj)
obj:bind_object(new_binder)
end
local last_update = 0 -- combat
------------------------------------------------------------------------------------
class "generic_object_binder" (object_binder)
function generic_object_binder:__init(obj) super(obj)
self.loaded = false
end
function generic_object_binder:reload(section)
object_binder.reload(self, section)
end
function generic_object_binder:reinit()
object_binder.reinit(self)
db.storage[self.object:id()] = { }
self.st = db.storage[self.object:id()]
self.object:set_callback(callback.patrol_path_in_point, self.waypoint_callback, self)
self.object:set_callback(callback.hit, self.hit_callback, self)
self.object:set_callback(callback.death, self.death_callback, self)
self.object:set_callback(callback.sound, self.hear_callback, self)
end
function generic_object_binder:update(delta)
object_binder.update(self, delta)
if xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] and self.object:best_enemy() == nil then
xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] = nil
end
local squad = get_object_squad(self.object)
local object_alive = self.object:alive()
--' printf("_bp: generic_object_binder: UPDATE [name='%s' time=%d]",
--' self.object:name(), time_global())
if not object_alive then
return
end
local st = db.storage[self.object:id()]
if st ~= nil and st.active_scheme ~= nil then
xr_logic.try_switch_to_another_section(self.object, st[st.active_scheme], db.actor)
end
-- Àïäåéò îòðÿäà
if squad ~= nil then
if squad:commander_id() == self.object:id() then
squad:update()
end
end
self.object:info_clear()
local active_section = db.storage[self.object:id()] and db.storage[self.object:id()].active_section
if active_section then
self.object:info_add("section: " .. active_section)
end
local best_enemy = self.object:best_enemy()
if best_enemy then
self.object:info_add("enemy: " .. best_enemy:name())
end
self.object:info_add(self.object:name().." ["..self.object:team().."]["..self.object:squad().."]["..self.object:group().."]")
if alife():object(self.object:id()) == nil then
return
end
if squad ~= nil then
self.object:info_add("squad_id: " .. squad:section_name())
if squad.current_action ~= nil then
local target = squad.assigned_target_id and alife():object(squad.assigned_target_id) and alife():object(squad.assigned_target_id):name()
self.object:info_add("current_action: " .. squad.current_action.name .."["..tostring(target).."]")
end
end
-- Åñëè åñòü âðàã , òî èäåì â êîìáàò !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if self.object:get_enemy() then
if xr_logic.mob_captured(self.object) then
xr_logic.mob_release(self.object)
end
return
end
if squad and squad.current_action and squad.current_action.name == "reach_target" then
local squad_target = simulation_objects.get_sim_obj_registry().objects[squad.assigned_target_id]
if squad_target == nil then return end
-- printf("_bp: mob_reach_task:reset_scheme: %s", self.object:name())
local target_pos, target_lv_id, target_gv_id = squad_target:get_location()
-- if not xr_logic.mob_captured(self.object) then
xr_logic.mob_capture(self.object, true)
-- end
if squad:commander_id() == self.object:id() then
action(self.object, move(move.walk_with_leader, target_pos),
cond(cond.move_end))
else
local commander_pos = alife():object(squad:commander_id()).position
if commander_pos:distance_to(self.object:position()) > 10 then
action(self.object, move(move.run_with_leader, target_pos),
cond(cond.move_end))
else
action(self.object, move(move.walk_with_leader, target_pos),
cond(cond.move_end))
end
end
return
end
if self.st.active_section ~= nil then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "update", delta)
end
end
function generic_object_binder:extrapolate_callback()
-- Ïðîâåðÿåì, ÷òî îáúåêò åùå â îíëàéíå
if db.storage[self.object:id()] == nil or
db.storage[self.object:id()].object == nil
then
return
end
local cur_pt = self.object:get_current_point_index()
if self.object:get_script() == false then
return false
end
local patrol_path = self.object:patrol()
if not level.patrol_path_exists(patrol_path) then
return false
--abort("bind_monster:extrapolate_callback(). There is no patrol path [%s]", tostring(patrol_path))
end
if patrol(patrol_path):flags(cur_pt):get() == 0 then
--printf("_bp: generic_object_binder: extrapolate_callback: cur_pt = %d: true", cur_pt)
return true
end
--printf("_bp: generic_object_binder: extrapolate_callback: cur_pt = %d: false", cur_pt)
return false
end
function generic_object_binder:waypoint_callback(obj, action_type, index)
if self.st.active_section ~= nil then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "waypoint_callback", obj, action_type, index)
end
end
function generic_object_binder:death_callback(victim, who)
printf("stop_dead_id"..self.object:id())
xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] = nil
self:hit_callback(victim, 1, vector():set(0,0,0), who, "from_death_callback")
if who:id() == db.actor:id() then
xr_statistic.inc_killed_monsters_counter()
xr_statistic.set_best_monster(self.object)
end
if self.st.mob_death then
xr_logic.issue_event(self.object, self.st.mob_death, "death_callback", victim, who)
end
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "death_callback", victim, who)
end
--' Íàíîñèì íåáîëüøîé èìïóëüñ âïåðåä.
local h = hit()
h.draftsman = self.object
h.type = hit.fire_wound
h.direction = db.actor:position():sub(self.object:position())
h:bone("pelvis")
h.power = 1
h.impulse = 10
self.object:hit(h)
local obj_clsid = self.object:clsid()
if obj_clsid == clsid.poltergeist_s then
printf("releasing object ["..self.object:name().."]")
if alife():object(self.object:id()) ~= nil then
alife():release(alife():object(self.object:id()), true)
end
end
end
function generic_object_binder:hit_callback(obj, amount, local_direction, who, bone_index)
-- printf("HIT_CALLBACK: [%s] amount[%s]", obj:name(), amount)
if(who:id()==db.actor:id()) then
xr_statistic.set_best_weapon(amount)
end
if self.st.hit then
xr_logic.issue_event(self.object, self.st.hit, "hit_callback", obj, amount, local_direction, who, bone_index)
end
if amount > 0 then
printf("HIT_CALLBACK: %s amount=%s bone=%s who:id() = [%s] actor:id() = [%s]", obj:name(), amount, tostring(bone_index), who:id(), db.actor:id())
end
end
function generic_object_binder:hear_callback(self, who_id, sound_type, sound_position, sound_power)
if who_id == self:id() then
return
end
xr_hear.hear_callback(self, who_id, sound_type, sound_position, sound_power)
end
function generic_object_binder:net_spawn(sobject)
if not object_binder.net_spawn(self, sobject) then
return false
end
local on_offline_condlist = db.storage[self.object:id()] and db.storage[self.object:id()].overrides and db.storage[self.object:id()].overrides.on_offline_condlist
if on_offline_condlist ~= nil then
xr_logic.pick_section_from_condlist(db.actor, self.object, on_offline_condlist)
end
if not self.object:alive() then
return true
end
if alife():object(self.object:id()) == nil then
return false
end
-- local pos = self.object:position()
-- printf("net_spawn mpos[%s][%s][%s]", tostring(pos.x), tostring(pos.y), tostring(pos.z))
db.add_obj(self.object)
--******************************* Òåëåïîðò íà ïåðâóþ òî÷êó ïóòè ðàáîòû ñìàðòòåððåéíà...*****************************
local se_obj = alife():object(self.object:id())
if db.spawned_vertex_by_id[se_obj.id] ~= nil then
self.object:set_npc_position(level.vertex_position(db.spawned_vertex_by_id[se_obj.id]))
db.spawned_vertex_by_id[se_obj.id] = nil
elseif db.offline_objects[se_obj.id] ~= nil and db.offline_objects[se_obj.id].level_vertex_id ~= nil then
printf("changing position for object[%s] from %s to %s : level vertex [%s] to [%s]", se_obj:name(), vec_to_str(se_obj.position), vec_to_str(level.vertex_position(db.offline_objects[se_obj.id].level_vertex_id)), tostring(se_obj.m_level_vertex_id), tostring(db.offline_objects[se_obj.id].level_vertex_id))
self.object:set_npc_position(level.vertex_position(db.offline_objects[se_obj.id].level_vertex_id))
elseif se_obj.m_smart_terrain_id ~= 65535 then
local smart_terrain = alife():object(se_obj.m_smart_terrain_id)
if smart_terrain.arriving_npc[se_obj.id] == nil then
local smart_task = smart_terrain.job_data[smart_terrain.npc_info[se_obj.id].job_id].alife_task
self.object:set_npc_position(smart_task:position())
end
end
--******************************************************************************************************************
smart_terrain.setup_gulag_and_logic_on_spawn( self.object, self.st, sobject, modules.stype_mobile, self.loaded)
return true
end
function generic_object_binder:net_destroy()
self.object:set_callback(callback.death, nil)
self.object:set_callback(callback.patrol_path_in_point, nil)
self.object:set_callback(callback.hit, nil)
self.object:set_callback(callback.sound, nil)
xr_sound.stop_sounds_by_id(self.object:id())
xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] = nil
local st = db.storage[self.object:id()]
if st and st.active_scheme then
xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy")
end
-- Çàïîìèíàåì ïîçèöèþ è àêòèâíóþ ñåêöèþ --------
if db.offline_objects[self.object:id()] then
db.offline_objects[self.object:id()].level_vertex_id = self.object:level_vertex_id()
db.offline_objects[self.object:id()].active_section = db.storage[self.object:id()].active_section
end
------------------------------------------------n
db.del_obj(self.object)
db.storage[self.object:id()] = nil
object_binder.net_destroy(self)
end
function generic_object_binder:reload(section)
object_binder.reload(self, section)
--printf("generic_object_binder:reload(): self.object:name()='%s'", self.object:name())
end
function generic_object_binder:net_save_relevant()
--printf("generic_object_binder:net_save_relevant(): self.object:name()='%s'", self.object:name())
return true
end
function generic_object_binder:save(packet)
set_save_marker(packet, "save", false, "generic_object_binder")
object_binder.save(self, packet)
xr_logic.save_obj(self.object, packet)
set_save_marker(packet, "save", true, "generic_object_binder")
end
function generic_object_binder:load(reader)
self.loaded = true
set_save_marker(reader, "load", false, "generic_object_binder")
object_binder.load(self, reader)
xr_logic.load_obj(self.object, reader)
set_save_marker(reader, "load", true, "generic_object_binder")
end

View file

@ -0,0 +1,175 @@
---------------------------------------------------------------------------------------------------
-- Physic objects binding
----------------------------------------------------------------------------------------------------
function init(obj)
printf("_bp: init(): name='%s'", obj:name())
----------------------------------------------------------------------------------------
-- Íîâûå ñõåìû
----------------------------------------------------------------------------------------
local ini = obj:spawn_ini()
-- Áèíäèòü ïðåäìåò íåò ñìûñëà, åñëè ó íåãî íåò ñåêöèè logic
if not (ini and ini:section_exist("logic")) then
-- Ïðîæåêòîð íóæíî áèíäèòü äàæå áåç logic
if obj:clsid() ~= clsid.inventory_box then
return
end
end
db.storage[obj:id()] = { }
local new_binder = generic_physics_binder(obj)
obj:bind_object(new_binder)
end
---------------------------------------------------------------------------------------------
class "generic_physics_binder" (object_binder)
function generic_physics_binder:__init(obj) super(obj)
self.initialized = false
self.loaded = false
end
function generic_physics_binder:reload(section)
object_binder.reload(self, section)
end
function generic_physics_binder:reinit()
object_binder.reinit(self)
printf("generic_physics_binder:reinit()")
printf("_bp: generic_physics_binder: %s", self.object:name())
self.st = db.storage[self.object:id()]
end
function generic_physics_binder:update(delta)
object_binder.update(self, delta)
if not self.initialized and db.actor then
self.initialized = true
xr_logic.initialize_obj(self.object, self.st, self.loaded, db.actor, modules.stype_item)
end
self.object:info_clear()
local active_section = db.storage[self.object:id()].active_section
if active_section then
self.object:info_add("section: " .. active_section)
end
self.object:info_add("name: [" .. self.object:name() .. "] id [" .. self.object:id() .. "]")
if self.st.active_section ~= nil or (self.object:spawn_ini() ~= nil and self.object:spawn_ini():section_exist("drop_box") == true) then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "update", delta)
self.object:set_callback(callback.hit, generic_physics_binder.hit_callback, self)
self.object:set_callback(callback.death, generic_physics_binder.death_callback, self)
self.object:set_callback(callback.use_object, generic_physics_binder.use_callback, self)
end
if self.object:clsid() == clsid.inventory_box then
self.object:set_callback(callback.use_object, generic_physics_binder.use_callback, self)
end
xr_sound.update(self.object:id())
end
function generic_physics_binder:net_spawn(data)
if not object_binder.net_spawn(self, data) then
return false
end
if self.object:section() == "physic_door" then
db.level_doors[self.object:id()] = self.object:position()
end
if(self.object:spawn_ini()) then
if(self.object:spawn_ini():section_exist("drop_box")) then
self.box_items = xr_box.ph_item_box(self.object)
end
if(self.object:spawn_ini():section_exist("level_spot")) then
if(self.object:spawn_ini():line_exist("level_spot", "actor_box")) then
level.map_add_object_spot(self.object:id(), "ui_pda2_actor_box_location", "st_ui_pda_actor_box")
end
end
end
db.add_obj(self.object)
return true
end
function generic_physics_binder:net_destroy()
if level.map_has_object_spot(self.object:id(), "ui_pda2_actor_box_location") ~= 0 then
level.map_remove_object_spot(self.object:id(), "ui_pda2_actor_box_location")
end
xr_sound.stop_sounds_by_id(self.object:id())
local st = db.storage[self.object:id()]
if st.active_scheme then
xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy")
end
local on_offline_condlist = db.storage[self.object:id()] and db.storage[self.object:id()].overrides and db.storage[self.object:id()].overrides.on_offline_condlist
if on_offline_condlist ~= nil then
xr_logic.pick_section_from_condlist(db.actor, self.object, on_offline_condlist)
end
if self.particle ~= nil then
self.particle:stop()
end
db.del_obj(self.object)
db.storage[self.object:id()] = nil
object_binder.net_destroy(self)
end
function generic_physics_binder:net_save_relevant()
--printf("generic_physics_binder:net_save_relevant(): self.object:name()='%s'", self.object:name())
return true
end
function generic_physics_binder:save(packet)
printf("generic_physics_binder:save(): self.object:name()='%s'", self.object:name())
object_binder.save(self, packet)
set_save_marker(packet, "save", false, "physics_binder")
xr_logic.save_obj(self.object, packet)
set_save_marker(packet, "save", true, "physics_binder")
end
function generic_physics_binder:load(reader)
self.loaded = true
printf("generic_physics_binder:load(): self.object:name()='%s'", self.object:name())
object_binder.load(self, reader)
set_save_marker(reader, "load", false, "physics_binder")
xr_logic.load_obj(self.object, reader)
set_save_marker(reader, "load", true, "physics_binder")
end
function generic_physics_binder:use_callback(obj, who)
if obj:clsid() == clsid.inventory_box then
local box_name = obj:name()
-- treasure_manager.use_box(obj, who)
end
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who)
end
end
function generic_physics_binder:hit_callback(obj, amount, local_direction, who, bone_index)
printf("_bp: generic_physics_binder:hit_callback: obj='%s'", obj:name())
if self.st.ph_on_hit then
xr_logic.issue_event(self.object, self.st.ph_on_hit, "hit_callback", obj, amount, local_direction, who, bone_index)
end
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "hit_callback", obj, amount, local_direction, who, bone_index)
end
end
function generic_physics_binder:death_callback(victim, who)
printf("_bp: generic_physics_binder:death_callback: obj='%s'", victim:name())
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "death_callback", victim, who)
end
if self.particle ~= nil then
self.particle:stop()
end
if self.object:spawn_ini() ~= nil and self.object:spawn_ini():section_exist("drop_box") == true then
self.box_items:spawn_items()
end
end

View file

@ -0,0 +1,121 @@
--[[------------------------------------------------------------------------------------------------
Space restrictor binder
×óãàé Àëåêñàíäð
Ïðèìå÷àíèÿ:
- îáíîâëåíèé ó ðåñòðèêòîðîâ íåòó, ïîýòîìó äëÿ òåõ, êîìó íàäî, àêò¸ð âûçûâàåò èñêóññòâåííî íà ñâî¸ì îáíîâëåíèè
--------------------------------------------------------------------------------------------------]]
function bind( obj )
obj:bind_object( restrictor_binder( obj ) )
end
----------------------------------------------------------------------------------------------------
class "restrictor_binder" ( object_binder )
function restrictor_binder:__init(obj, char_ini) super(obj)
self.initialized = false
self.loaded = false
end
function restrictor_binder:reload(section)
object_binder.reload(self, section)
end
function restrictor_binder:reinit()
object_binder.reinit(self)
db.storage[self.object:id()] = { }
self.st = db.storage[self.object:id()]
end
function restrictor_binder:net_spawn(data)
if not object_binder.net_spawn( self,data ) then
return false
end
db.add_zone(self.object)
db.add_obj(self.object)
local obj_id = self.object:id()
if(xr_sound.looped_sound[obj_id]) then
for k,v in pairs(xr_sound.looped_sound[obj_id]) do
xr_sound.play_sound_looped(obj_id, k)
end
end
--' Åñëè ýòî ðåñòèêòîð èíôîðìàöèîííîé òåððèòîðèè - çàðåãèñòðèòü åãî.
local ini = self.object:spawn_ini()
if not ini then
return true
end
if ini:section_exist("information_sector") then
sr_danger.register_new_sector(self.object)
end
if ini:section_exist("apply_on_combat") then
combat_restrictor.register_combat_restrictor(self.object)
end
return true
end
function restrictor_binder:net_destroy()
xr_sound.stop_sounds_by_id(self.object:id())
local st = db.storage[self.object:id()]
if st.active_scheme then
xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy")
end
db.del_zone( self.object )
db.del_obj(self.object)
db.storage[self.object:id()] = nil
object_binder.net_destroy(self)
end
-- âûçûâàåòñÿ èç îáíîâëåíèÿ àêò¸ðà!(ÁÐÅÕÍß!!!!!!!)
function restrictor_binder:update(delta)
if not self.initialized and db.actor then
self.initialized = true
xr_logic.initialize_obj(self.object, self.st, self.loaded, db.actor, modules.stype_restrictor)
end
self.object:info_clear()
local active_section = db.storage[self.object:id()] and db.storage[self.object:id()].active_section
if active_section then
self.object:info_add("section: " .. active_section)
end
self.object:info_add("name: [" .. self.object:name() .. "] id [" .. self.object:id() .. "]")
if self.st.active_section ~= nil then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "update", delta)
end
xr_sound.update(self.object:id())
end
function restrictor_binder:net_save_relevant()
return true
end
function restrictor_binder:save(packet)
set_save_marker(packet, "save", false, "restrictor_binder")
object_binder.save(self, packet)
xr_logic.save_obj(self.object, packet)
set_save_marker(packet, "save", true, "restrictor_binder")
end
function restrictor_binder:load(reader)
set_save_marker(reader, "load", false, "restrictor_binder")
self.loaded = true
printf( "restrictor_binder:load" )
object_binder.load(self, reader)
xr_logic.load_obj(self.object, reader)
set_save_marker(reader, "load", true, "restrictor_binder")
end

View file

@ -0,0 +1,154 @@
function init(obj)
printf("_bp: init(): name='%s'", obj:name())
db.storage[obj:id()] = { }
local new_binder = signal_light_binder(obj)
obj:bind_object(new_binder)
end
---------------------------------------------------------------------------------------------
class "signal_light_binder" (object_binder)
function signal_light_binder:__init(obj) super(obj)
self.need_turn_off = true
-- self.initialized = false
self.loaded = false
end
function signal_light_binder:reload(section)
object_binder.reload(self, section)
end
function signal_light_binder:reinit()
object_binder.reinit(self)
db.signal_light[self.object:name()] = self
end
function signal_light_binder:update(delta)
object_binder.update(self, delta)
local obj = self.object
if self.start_time == nil then
if self.need_turn_off then
obj:get_hanging_lamp():turn_off()
self.need_turn_off = false
self.loaded = false
end
return
end
local fly_time = time_global() - self.start_time
if self.loaded then
self.start_time = self.start_time + time_global() - self.delta_time
self.delta_time = nil
self.loaded = false
fly_time = time_global() - self.start_time
if fly_time < 1500 then
obj:set_const_force(vector():set(0,1,0), 180+math.floor(fly_time/5), 1500-fly_time)
obj:start_particles("weapons\\light_signal", "link")
elseif fly_time < 20000 then
obj:set_const_force(vector():set(0,1,0), 33, 20000-fly_time)
obj:start_particles("weapons\\light_signal", "link")
end
return
end
-- Ãëàâíûé öèêë ïîëåòà ñèãíàëêè
if fly_time > 28500 then
self:stop()
return
end
if fly_time > 20500 then
self:stop_light()
return
end
if fly_time > 1500 then
if self.slow_fly_started ~= true then
self:slow_fly()
obj:start_particles("weapons\\light_signal", "link")
obj:get_hanging_lamp():turn_on()
end
end
end
function signal_light_binder:net_spawn(data)
if not object_binder.net_spawn(self, data) then
return false
end
return true
end
function signal_light_binder:net_destroy()
db.signal_light[self.object:name()] = nil
object_binder.net_destroy(self)
end
function signal_light_binder:launch()
if not(db.actor) then
return false
end
if self.start_time ~= nil then
return false
end
local obj = self.object
obj:set_const_force(vector():set(0,1,0), 180, 1500)
--obj:start_particles("weapons\\light_signal", "link")
--obj:get_hanging_lamp():turn_on()
self.start_time = time_global()
self.slow_fly_started = false
return true
end
function signal_light_binder:slow_fly()
self.slow_fly_started = true
self.object:set_const_force(vector():set(0,1,0), 30, 20000)
end
function signal_light_binder:stop_light()
self.slow_fly_started = false
local obj = self.object
obj:stop_particles("weapons\\light_signal", "link")
obj:get_hanging_lamp():turn_off()
end
function signal_light_binder:stop()
self.start_time = nil
end
function signal_light_binder:is_flying()
return self.start_time ~= nil
end
-- Standart function for save
function signal_light_binder:net_save_relevant()
return true
end
function signal_light_binder:save(packet)
set_save_marker(packet, "save", false, "signal_light_binder")
object_binder.save(self, packet)
if self.start_time == nil then
packet:w_u32(-1)
else
packet:w_u32(time_global()-self.start_time)
end
packet:w_bool(self.slow_fly_started==true)
set_save_marker(packet, "save", true, "signal_light_binder")
end
function signal_light_binder:load(reader)
set_save_marker(reader, "load", false, "signal_light_binder")
object_binder.load(self, reader)
local time = reader:r_u32()
if time ~= 4294967296 then
self.start_time = time_global() - time
end
self.slow_fly_started = reader:r_bool()
self.loaded = true
self.delta_time = time_global()
set_save_marker(reader, "load", true, "signal_light_binder")
end

View file

@ -0,0 +1,30 @@
--'******************************************************
--'* Áèíäåð îáúåêòà ñìàðò êàâåð .
--'******************************************************
registered_smartcovers = {}
function bind(obj)
obj:bind_object(smart_cover_binder(obj))
end
class "smart_cover_binder" (object_binder)
function smart_cover_binder:__init(obj) super(obj)
end
function smart_cover_binder:net_spawn(server_object)
if not object_binder.net_spawn(self, server_object) then
return false
end
registered_smartcovers[self.object:name()] = self.object
printf("smart_cover_binder.net_spawn() smart_cover [%s] is registered %s", self.object:name(), vec_to_str(self.object:direction()))
return true
end
function smart_cover_binder:net_destroy()
registered_smartcovers[self.object:name()] = nil
printf("smart_cover_binder.net_destroy() smart_cover [%s] is unregistered", self.object:name())
object_binder.net_destroy(self)
end
function smart_cover_binder:update(delta)
object_binder.update(self, delta)
end

View file

@ -0,0 +1,70 @@
--[[------------------------------------------------------------------------------------------------------------------
Smart terrain binder
Íóæåí äëÿ òîãî, ÷òîáû ñåðâåðíûé îáúåêò smart terrain ïîëó÷àë îáíîâëåíèÿ.
×óãàé Àëåêñàíäð
--------------------------------------------------------------------------------------------------------------------]]
function bind( obj )
local ini = obj:spawn_ini()
if not ini then
return
end
if ini:section_exist( "gulag1" ) or ini:section_exist( "smart_terrain" ) then
if obj:clsid() == clsid.smart_terrain then
if alife() then
obj:bind_object( smart_terrain_binder( obj ) )
else
printf( "No simulation! SMART_TERRAIN '%s' disabled.", obj:name() )
end
else
abort( "You must use SMART_TERRAIN instead of SCRIPT_ZONE %s", obj:name() )
end
end
end
----------------------------------------------------------------------------------------------------------------------
class "smart_terrain_binder" ( object_binder )
function smart_terrain_binder:__init( obj ) super( obj )
end
function smart_terrain_binder:net_spawn( server_object )
if not object_binder.net_spawn( self, server_object ) then
return false
end
-- ïîëó÷èòü ññûëêó íà íàñòîÿùèé ñåðâåðíûé îáúåêò
self.se_smart_terrain = alife():object( server_object.id )
db.add_zone( self.object )
db.add_smart_terrain( self.se_smart_terrain )
return true
end
function smart_terrain_binder:net_destroy()
xr_sound.stop_sounds_by_id(self.object:id())
db.del_zone( self.object )
db.del_smart_terrain( self.se_smart_terrain )
object_binder.net_destroy( self )
end
function smart_terrain_binder:net_Relcase( obj )
-- printf( "smart_terrain_binder.net_Relcase: self.object=%s obj=%s", self.object:name(), obj:name() )
if self.se_smart_terrain.npc_info[obj:id()] then
--self.se_smart_terrain.gulag:object_setup_offline( obj:id(), true )
-- TODO: Çàìåíèòü íà àíàëîã
end
end
function smart_terrain_binder:update( delta )
object_binder.update( self, delta )
self.se_smart_terrain:update()
end

View file

@ -0,0 +1,597 @@
function init (obj)
xr_motivator.AddToMotivator(obj)
end
function actor_init (npc)
npc:bind_object(actor_binder(npc))
end
local game_difficulty_by_num = {
[0] = "gd_novice",
[1] = "gd_stalker",
[2] = "gd_veteran",
[3] = "gd_master"
}
local weapon_hide = {}
local primary_objects_filled = false
----------------------------------------------------------------------------------------------------------------------
class "actor_binder" (object_binder)
----------------------------------------------------------------------------------------------------------------------
function actor_binder:__init (obj) super(obj)
self.bCheckStart = false
self.weather_manager = level_weathers.get_weather_manager()
self.surge_manager = surge_manager.get_surge_manager()
--self.actor_detector = xr_detector.actor_detector()
self.last_level_name = nil
self.deimos_intensity = nil
-- self.actor_weapon_on_start = true
self.loaded_active_slot = 3
self.loaded_slot_applied = false
self.last_detective_achievement_spawn_time = nil
self.last_mutant_hunter_achievement_spawn_time = nil
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_spawn(data)
-- printf("actor net spawn")
level.show_indicators()
self.bCheckStart = true
self.weapon_hide = false -- спрятано или нет оружие при разговоре.
self.weapon_hide_in_dialog = false
weapon_hide = {} -- устанавливаем глобальный дефолтовый флаг.
if object_binder.net_spawn(self,data) == false then
return false
end
db.add_actor(self.object)
db.actor.deimos_intensity = self.deimos_intensity
self.deimos_intensity = nil
if self.st.disable_input_time == nil then
level.enable_input()
end
xr_s.on_game_load() --' Distemper 03.2008 --
self.weather_manager:reset()
--' Загружаем настройки дропа
death_manager.init_drop_settings()
--'Устанавливаем ссылку на таскменеджер
self.task_manager = task_manager.get_task_manager()
self.spawn_frame = device().frame
self.already_jumped = false
-- self.loaded = false
benchmark.main() --' Distemper 06.2008 --
return true
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_destroy()
xr_sound.stop_sounds_by_id(self.object:id())
local board_factions = sim_board.get_sim_board().players
if(board_factions) then
for k,v in pairs (board_factions) do
xr_sound.stop_sounds_by_id(v.id)
end
end
if(actor_stats.remove_from_ranking~=nil)then
actor_stats.remove_from_ranking(self.object:id())
end
level.show_weapon(true)
db.del_actor(self.object)
self.object:set_callback(callback.inventory_info, nil)
self.object:set_callback(callback.article_info, nil)
self.object:set_callback(callback.on_item_take, nil)
self.object:set_callback(callback.on_item_drop, nil)
self.object:set_callback(callback.task_state, nil)
self.object:set_callback(callback.level_border_enter, nil)
self.object:set_callback(callback.level_border_exit, nil)
self.object:set_callback(callback.take_item_from_box, nil)
self.object:set_callback(callback.use_object, nil)
-- IX-Ray
self.object:set_callback(callback.actor_before_death, nil)
-- END IX-Ray
log("--------->"..tostring(_G.amb_vol))
log("--------->"..tostring(_G.mus_vol))
if(_G.amb_vol~=0) then
get_console():execute("snd_volume_eff "..tostring(_G.amb_vol))
_G.amb_vol = 0
end
if(_G.mus_vol~=0) then
get_console():execute("snd_volume_music "..tostring(_G.mus_vol))
_G.mus_vol = 0
end
if sr_psy_antenna.psy_antenna then
sr_psy_antenna.psy_antenna:destroy()
sr_psy_antenna.psy_antenna = false
end
xrs_dyn_music.finish_theme()
xr_s.on_actor_destroy()
object_binder.net_destroy(self)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:reinit()
object_binder.reinit(self)
local npc_id = self.object:id()
db.storage[npc_id] = { }
self.st = db.storage[npc_id]
self.st.pstor = nil
self.object:set_callback(callback.inventory_info, self.info_callback, self)
self.object:set_callback(callback.on_item_take, self.on_item_take, self)
self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats
self.object:set_callback(callback.task_state, self.task_callback, self)
self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
self.object:set_callback(callback.use_object, self.use_inventory_item, self)
-- IX-Ray
self.object:set_callback(callback.actor_before_death, self.on_actor_before_death, self)
-- END IX-Ray
end
-- IX-Ray
-- actor before death callback
-- IMPORTANT: if you wish to kill actor you need to call db.actor:kill(level.object_by_id(whoID), true) in actor_before_death callback, to ensure all objects are properly destroyed.
function actor_binder:on_actor_before_death(whoID)
local killer = level.object_by_id(whoID) or db.actor
db.actor:kill(killer, true)
end
-- END IX-Ray
----------------------------------------------------------------------------------------------------------------------
function actor_binder:take_item_from_box(box, item)
local box_name = box:name()
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:info_callback(npc, info_id)
printf("*INFO*: npc='%s' id='%s'", npc:name(), info_id)
--' Сюжет
-- Отметки на карте
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_trade (item, sell_bye, money)
if sell_bye == true then
game_stats.money_trade_update (money)
else
game_stats.money_trade_update (-money)
end
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:article_callback(npc, group, name)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_take (obj)
printf("on_item_take [%s]", obj:name())
if isArtefact(obj) then
local anomal_zone = bind_anomaly_zone.parent_zones_by_artefact_id[obj:id()]
if anomal_zone ~= nil then
anomal_zone:on_artefact_take(obj)
else
bind_anomaly_zone.artefact_ways_by_id[obj:id()] = nil
end
local artefact = obj:get_artefact()
artefact:FollowByPath("NULL",0,vector():set(500,500,500))
xr_statistic.inc_founded_artefacts_counter(obj:id())
--[[
local s_art = alife():object(obj:id())
if(s_art) then
xr_statistic.inc_founded_artefacts_counter(s_art:section_name())
else
xr_statistic.inc_founded_artefacts_counter()
end
]]
end
treasure_manager.get_treasure_manager():on_item_take(obj:id())
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_drop (obj)
end
function actor_binder:use_inventory_item(obj)
if(obj) then
local s_obj = alife():object(obj:id())
if(s_obj) and (s_obj:section_name()=="drug_anabiotic") then
xr_effects.disable_ui_only(db.actor, nil)
level.add_cam_effector("camera_effects\\surge_02.anm", 10, false, "bind_stalker.anabiotic_callback")
level.add_pp_effector("surge_fade.ppe", 11, false)
give_info("anabiotic_in_process")
_G.mus_vol = get_console():get_float("snd_volume_music")
_G.amb_vol = get_console():get_float("snd_volume_eff")
get_console():execute("snd_volume_music 0")
get_console():execute("snd_volume_eff 0")
end
end
end
function anabiotic_callback()
level.add_cam_effector("camera_effects\\surge_01.anm", 10, false, "bind_stalker.anabiotic_callback2")
local rnd = math.random(35,45)
local m = surge_manager.get_surge_manager()
if(m.started) then
local tf = level.get_time_factor()
local diff_sec = math.ceil(game.get_game_time():diffSec(m.inited_time)/tf)
if(rnd>(m.surge_time-diff_sec)*tf/60) then
m.time_forwarded = true
m.ui_disabled = true
m:kill_all_unhided()
m:end_surge()
end
end
level.change_game_time(0,0,rnd)
level_weathers.get_weather_manager():forced_weather_change()
printf("anabiotic_callback: time forwarded on [%d]", rnd)
end
function anabiotic_callback2()
xr_effects.enable_ui(db.actor, nil)
get_console():execute("snd_volume_music "..tostring(_G.mus_vol))
get_console():execute("snd_volume_eff "..tostring(_G.amb_vol))
_G.amb_vol = 0
_G.mus_vol = 0
disable_info("anabiotic_in_process")
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:task_callback(_task, _state)
if _state ~= task.fail then
if _state == task.completed then
news_manager.send_task(db.actor, "complete", _task)
else
news_manager.send_task(db.actor, "new", _task)
end
end
task_manager.task_callback(_task, _state)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:update(delta)
object_binder.update(self, delta)
if string.find(command_line(), "-designer") then
return
end
if self.already_jumped==false and jump_level.need_jump==true and (device().frame > self.spawn_frame+2000) then
jump_level.try_to_jump()
self.already_jumped = true
return
end
-- Вызов апдейта переноса игрока проводником
if travel_func ~= nil then
travel_func()
end
-- DEBUG slowdown
--slowdown.update()
local time = time_global()
game_stats.update (delta, self.object)
-- апдейт погоды
self.weather_manager:update()
self:check_detective_achievement()
self:check_mutant_hunter_achievement()
--' Апдейт саундменеджера
xr_sound.update(self.object:id())
-- Обновление отключения ввода с клавиатуры.
if self.st.disable_input_time ~= nil and
game.get_game_time():diffSec(self.st.disable_input_time) >= self.st.disable_input_idle
then
level.enable_input()
self.st.disable_input_time = nil
end
-- Апдейт прятание оружия игрока во время диалога
if self.object:is_talking() then
if self.weapon_hide_in_dialog == false then
self.object:hide_weapon()
printf("hiding weapon!!!")
self.weapon_hide_in_dialog = true
end
else
if self.weapon_hide_in_dialog == true then
printf("restoring weapon!!!")
self.object:restore_weapon()
self.weapon_hide_in_dialog = false
end
end
-- Апдейт прятание оружия игрока в зоне sr_no_weapon
if check_for_weapon_hide_by_zones() == true then
if self.weapon_hide == false then
printf("hiding weapon!!!")
self.object:hide_weapon()
self.weapon_hide = true
end
else
if self.weapon_hide == true then
printf("restoring weapon!!!")
self.object:restore_weapon()
self.weapon_hide = false
end
end
-- обновление пси-антенны
if sr_psy_antenna.psy_antenna then
sr_psy_antenna.psy_antenna:update(delta)
end
--[[
--' Вывод сообщения о большой радиации
if self.object.radiation >= 0.7 then
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_radiation_danger")
if custom_static == nil then
hud:AddCustomStatic("cs_radiation_danger", true)
hud:GetCustomStatic("cs_radiation_danger"):wnd():TextControl():SetTextST("st_radiation_danger")
end
else
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_radiation_danger")
if custom_static ~= nil then
hud:RemoveCustomStatic("cs_radiation_danger")
end
end
]]--
if self.bCheckStart then
printf("SET DEFAULT INFOS")
if not has_alife_info("global_dialogs") then
self.object:give_info_portion("global_dialogs")
end
if not has_alife_info("level_changer_icons") then
self.object:give_info_portion("level_changer_icons")
end
self.bCheckStart = false
-- if self.actor_weapon_on_start == true then
-- db.actor:activate_slot(3)
-- self.actor_weapon_on_start = false
-- end
end
-- device().precache_frame == 0 and
if not self.loaded_slot_applied then
self.object:activate_slot(self.loaded_active_slot)
self.loaded_slot_applied = true
end
xr_s.on_actor_update(delta)
if(self.surge_manager) then
if(self.f_surge_manager_loaded ~= true) then
self.surge_manager:initialize()
self.f_surge_manager_loaded = true
end
if(self.surge_manager.levels_respawn[level.name()]) then
self.surge_manager:respawn_artefacts_and_replace_anomaly_zone()
end
self.surge_manager:update()
end
-- Апдейт доступности для симуляции.
simulation_objects.get_sim_obj_registry():update_avaliability(alife():actor())
-- Not used
--if not self.loaded then
-- get_console():execute("dump_infos")
-- self.loaded = true
--end
treasure_manager.get_treasure_manager():update()
if not(primary_objects_filled) then
pda.fill_primary_objects()
primary_objects_filled = true
end
pda.fill_sleep_zones()
SendScriptCallback("update") -- IX-Ray
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:save(packet)
set_save_marker(packet, "save", false, "actor_binder")
object_binder.save(self, packet)
--' Сохраняем уровень сложности
packet:w_u8(level.get_game_difficulty())
--' Сохраняем данные об отключенном вводе
if self.st.disable_input_time == nil then
packet:w_bool(false)
else
packet:w_bool(true)
utils.w_CTime(packet, self.st.disable_input_time)
end
xr_logic.pstor_save_all(self.object, packet)
self.weather_manager:save(packet)
release_body_manager.get_release_body_manager():save(packet)
self.surge_manager:save(packet)
sr_psy_antenna.save( packet )
packet:w_bool(sim_board.get_sim_board().simulation_started)
xr_sound.actor_save(packet)
packet:w_stringZ(tostring(self.last_level_name))
xr_statistic.save(packet)
treasure_manager.get_treasure_manager():save(packet)
local n = 0
for k,v in pairs(db.script_ids) do
n = n + 1
end
packet:w_u8(n)
for k,v in pairs (db.script_ids) do
packet:w_u16(k)
packet:w_stringZ(v)
end
task_manager.get_task_manager():save(packet)
-- packet:w_bool(self.actor_weapon_on_start)
packet:w_u8(self.object:active_slot())
local deimos_exist = false
for k,v in pairs(db.zone_by_name) do
if(db.storage[v:id()] and db.storage[v:id()].active_scheme=="sr_deimos") then
deimos_exist = true
packet:w_bool(true)
packet:w_float(db.storage[v:id()].sr_deimos.intensity)
end
end
if not deimos_exist then
packet:w_bool(false)
end
if self.last_detective_achievement_spawn_time == nil then
packet:w_bool(false)
else
packet:w_bool(true)
utils.w_CTime(packet, self.last_detective_achievement_spawn_time)
end
if self.last_mutant_hunter_achievement_spawn_time == nil then
packet:w_bool(false)
else
packet:w_bool(true)
utils.w_CTime(packet, self.last_mutant_hunter_achievement_spawn_time)
end
set_save_marker(packet, "save", true, "actor_binder")
SendScriptCallback("save", packet) -- IX-Ray
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:load(reader)
set_save_marker(reader, "load", false, "actor_binder")
object_binder.load(self, reader)
--' Загружаем уровень сложности
local game_difficulty = reader:r_u8()
printf("load game_difficulty %s", tostring(game_difficulty))
get_console():execute("g_game_difficulty "..game_difficulty_by_num[game_difficulty])
local stored_input_time = reader:r_u8()
if stored_input_time == true then
self.st.disable_input_time = utils.r_CTime(reader)
end
xr_logic.pstor_load_all(self.object, reader)
self.weather_manager:load(reader)
release_body_manager.get_release_body_manager():load(reader)
-- self.surge_manager:initialize()
self.surge_manager:load(reader)
self.f_surge_manager_loaded = true
sr_psy_antenna.load(reader)
sim_board.get_sim_board().simulation_started = reader:r_bool()
xr_sound.actor_load(reader)
local n = reader:r_stringZ()
if(n~="nil") then
self.last_level_name = n
end
xr_statistic.load(reader)
treasure_manager.get_treasure_manager():load(reader)
n = reader:r_u8()
for i = 1,n do
db.script_ids[reader:r_u16()] = reader:r_stringZ()
end
task_manager.get_task_manager():load(reader)
-- self.actor_weapon_on_start = reader:r_bool()
self.loaded_active_slot = reader:r_u8()
self.loaded_slot_applied = false
local b = reader:r_bool()
if(b) then
self.deimos_intensity = reader:r_float()
end
local stored_achievement_time = reader:r_bool()
if stored_achievement_time == true then
self.last_detective_achievement_spawn_time = utils.r_CTime(reader)
end
stored_achievement_time = reader:r_bool()
if stored_achievement_time == true then
self.last_mutant_hunter_achievement_spawn_time = utils.r_CTime(reader)
end
set_save_marker(reader, "load", true, "actor_binder")
SendScriptCallback("load", reader) -- IX-Ray
end
--*************************************************************
--* Подспаун вещей в ящики *
--*************************************************************
local detective_achievement_items = { "medkit",
"antirad",
"bandage"}
local mutant_hunter_achievement_items = { "ammo_5.45x39_ap",
"ammo_5.56x45_ap",
"ammo_9x39_ap",
"ammo_5.56x45_ap",
"ammo_12x76_zhekan"}
local function spawn_achivement_items(items_table, count, inv_box_story_id)
local inv_box = alife():object(get_story_object_id(inv_box_story_id))
for i = 1,count do
alife():create(items_table[math.random(#items_table)],
inv_box.position,
inv_box.m_level_vertex_id,
inv_box.m_game_vertex_id,
inv_box.id)
end
end
function actor_binder:check_detective_achievement()
if not has_alife_info("detective_achievement_gained") then
return
end
if self.last_detective_achievement_spawn_time == nil then
self.last_detective_achievement_spawn_time = game.get_game_time()
end
if game.get_game_time():diffSec(self.last_detective_achievement_spawn_time) > 43200 then
spawn_achivement_items(detective_achievement_items, 4, "zat_a2_actor_treasure")
xr_effects.send_tip(db.actor, nil, {"st_detective_news","got_medicine"})
self.last_detective_achievement_spawn_time = game.get_game_time()
end
end
function actor_binder:check_mutant_hunter_achievement()
if not has_alife_info("mutant_hunter_achievement_gained") then
return
end
if self.last_mutant_hunter_achievement_spawn_time == nil then
self.last_mutant_hunter_achievement_spawn_time = game.get_game_time()
end
if game.get_game_time():diffSec(self.last_mutant_hunter_achievement_spawn_time) > 43200 then
spawn_achivement_items(mutant_hunter_achievement_items, 5, "jup_b202_actor_treasure")
xr_effects.send_tip(db.actor, nil, {"st_mutant_hunter_news","got_ammo"})
self.last_mutant_hunter_achievement_spawn_time = game.get_game_time()
end
end
----------------------------------------------------------------------------------------------------------------------
function check_for_weapon_hide_by_zones()
for k,v in pairs(weapon_hide) do
if v == true then
return true
end
end
return false
end
-- Weapon functions
function hide_weapon(zone_id)
printf("[WEAPON_CONTROL]:hiding weapon from zone [%s] in section [%s]!!!", zone_id, db.storage[zone_id].active_section)
weapon_hide[zone_id] = true
end
function restore_weapon(zone_id)
printf("[WEAPON_CONTROL]:restoring weapon from zone [%s] in section [%s]!!!", zone_id, db.storage[zone_id].active_section)
weapon_hide[zone_id] = false
end

View file

@ -0,0 +1,108 @@
--test_effector = {
-- start = {
-- {anim = "scenario_cam\\marsh\\camera_mar_02_up", looped = false, global_cameffect = false},
-- },
-- idle = {
-- {anim = "scenario_cam\\marsh\\camera_mar_03_idle", looped = "{+test_info_1} false", global_cameffect = false},
-- },
-- finish = {
-- {anim = "scenario_cam\\marsh\\camera_mar_04_on_foot", looped = false, global_cameffect = false},
-- }
-- }
--
--mar_intro_effector = {
-- start = {
-- {anim = "scenario_cam\\marsh\\camera_mar_01", looped = false, global_cameffect = true},
-- },
-- idle = {
-- {anim = "scenario_cam\\marsh\\camera_mar_02_up", looped = false, global_cameffect = true},
-- {anim = "scenario_cam\\marsh\\camera_mar_03_idle", looped = "{+mar_intro_scene_2_end} false", global_cameffect = true},
-- {anim = "scenario_cam\\marsh\\camera_mar_04_on_foot", looped = false, global_cameffect = true},
-- },
-- finish = {
-- }
-- }
pri_a15_cameffector = {
start = {
},
idle = {
{anim = "scenario_cam\\pripyat\\pri_a15_cam_01", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_02", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_03", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_04", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_05", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_06", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out +pri_a15_wanderer_out +pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_07", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out +pri_a15_wanderer_out +pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_08", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out +pri_a15_sokolov_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_09", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_10", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_11", looped = "false", global_cameffect = true, enabled = "{+pri_a15_sokolov_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_12", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_13", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_14", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_15", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_16", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_17", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_17_1", looped = "false", global_cameffect = true, enabled = "{+pri_a15_all_dead} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_18", looped = "false", global_cameffect = true, enabled = "{+pri_a15_all_dead} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_19", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_20", looped = "false", global_cameffect = true, enabled = "{+pri_a15_sokolov_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_21", looped = "false", global_cameffect = true, enabled = "{+pri_a15_sokolov_out +pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_22", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_23", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_24", looped = "false", global_cameffect = true, enabled = "{+pri_a15_vano_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_25", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_25_1", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_26", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_27", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_28", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_29", looped = "false", global_cameffect = true, enabled = "{+pri_a15_zulus_out} false, true"},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_30", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_31", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_a15_cam_32", looped = "false", global_cameffect = true}
},
finish = {
}
}
jup_b219_descent_camera = {
start = {
},
idle = {
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_1", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_2", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_3", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_4", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_5", looped = "false", global_cameffect = true, enabled = "{+jup_a10_vano_agree_go_und} true, false"},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_6", looped = "false", global_cameffect = true, enabled = "{+jup_b218_monolith_hired} true, false"},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_7", looped = "false", global_cameffect = true, enabled = "{+jup_b218_soldier_hired} true, false"},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_8", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_9", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\Jupiter\\jup_b219_cam_10", looped = "false", global_cameffect = true, enabled = "true %+jup_b219_entering_underpass%"},
},
finish = {
}
}
pri_b305_camera_2 = {
start = {
},
idle = {
{anim = "scenario_cam\\pripyat\\pri_b305_catscene_2_dialog_with_kovalsky_01", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_b305_catscene_2_dialog_with_kovalsky_02", looped = "false", global_cameffect = true},
},
finish = {
}
}
pri_b305_camera_5 = {
start = {
},
idle = {
{anim = "scenario_cam\\pripyat\\pri_b305_catscene_5_dialog_with_strelok_1", looped = "false", global_cameffect = true},
{anim = "scenario_cam\\pripyat\\pri_b305_catscene_5_dialog_with_strelok_2", looped = "false", global_cameffect = true},
},
finish = {
}
}

View file

@ -0,0 +1,10 @@
class "CCE_NewAttachableItem" (attachable_item)
function CCE_NewAttachableItem:__init() super()
printf ("CCE_NewAttachableItem::CCE_NewAttachableItem called!")
end
function CCE_NewAttachableItem:__finalize()
printf ("CCE_NewAttachableItem::~CCE_NewAttachableItem called!")
end

View file

@ -0,0 +1,20 @@
class "C_new_game_sv_Deathmatch" (game_sv_Deathmatch)
function C_new_game_sv_Deathmatch:__init() super()
printf ("C_new_game_sv_Deathmatch::C_new_game_sv_Deathmatch called!")
self.type = game_types.GAME_NEWDM
end
function C_new_game_sv_Deathmatch:__finalize()
printf ("C_new_game_sv_Deathmatch::~C_new_game_sv_Deathmatch called!")
end
function C_new_game_sv_Deathmatch:type_name()
printf ("C_new_game_sv_Deathmatch::type_name called!")
return "new_dm"
end
function Money_SetStart (id_who)
end

View file

@ -0,0 +1,99 @@
function _printf(ss)
--if editor() == false then
-- printf(ss)
--end
end
-- -i -noprefetch -ltx user_andy.ltx -external -start server(andy_test_switch/single) client(localhost)
--client entity
class "ce_switcher" (CGameObject)
function ce_switcher:__init() super()
self.m_state = 0
_printf("ce_switcher:__init() is called (%d)",self.m_state)
end
function ce_switcher:SetState(s)
if self.m_state == s then
return
end
local old = self.m_state
self.m_state = s
self:OnStateChanged(old, self.m_state)
end
function ce_switcher:GetState()
return self.m_state;
end
function ce_switcher:PlayAnim(anim_name)
local visual = self:Visual()
local ska = visual:dcast_PKinematicsAnimated()
ska:PlayCycle(anim_name)
end
function ce_switcher:Load(section)
CGameObject.Load(self, section)
end
function ce_switcher:shedule_Update(dt)
CGameObject.shedule_Update(self,dt)
end
function ce_switcher:net_Export(packet)
_printf("ce_switcher:net_Export called")
CGameObject.net_Export(self, packet)
packet:w_u32(self.m_state)
_printf("ce_switcher:net_Export done")
end
function ce_switcher:net_Import(packet)
_printf("ce_switcher:net_Import called")
CGameObject.net_Import(self, packet)
self.m_state = packet:r_u32()
_printf("ce_switcher:net_Import done")
end
function ce_switcher:net_Spawn(se_object)
_printf("ce_switcher:net_Spawn called")
CGameObject.net_Spawn(self, se_object)
self.m_state = se_object.m_state
local anm = se_object:getStartupAnimation()
self:PlayAnim(anm)
self:setVisible(1)
self:setEnabled(1)
_printf("ce_switcher:net_Spawn done")
return true;
end
function ce_switcher:net_Destroy()
CGameObject.net_Destroy(self)
end
function ce_switcher:OnStateChanged(old_state, new_state)
if new_state==0 then
self:PlayAnim("idle")
end
if new_state==1 then
self:PlayAnim("idle_on")
end
end
function ce_switcher:use(who)
printf("----ce_switcher used " )
if self.m_state==0 then
self:SetState(1)
else
self:SetState(0)
end
return true;
end

View file

@ -0,0 +1,145 @@
-- run_string check_logic_path.check()
local path_fields = { "path_walk", "path_main", "path_home", "center_point" }
function check()
for smart_name,smart in pairs(smart_terrain.smart_terrains_by_name) do
--printf("checking smart ---> %s", smart_name)
for k,v in pairs(smart.job_data) do
--printf(" checking work --> %s", v.section)
local ltx = v.ini_file or smart.ltx
check_ini(ltx, v.section, smart, v.prefix_name)
end
end
end
local section_to_check = {}
function get_sections(ini, active_section_cond)
for k,cond in pairs(active_section_cond) do
if cond.section ~= nil then
if section_to_check[cond.section] ~= true then
section_to_check[cond.section] = true
local switch_sections = xr_logic.cfg_get_switch_conditions(ini, cond.section)
if switch_sections ~= nil and switch_sections ~= "" then
for kk, v in pairs(switch_sections) do
get_sections(ini, v.condlist)
end
end
end
end
end
end
function check_ini(ini, section, smart, prefix_name)
section_to_check = {}
local active_section_cond = xr_logic.cfg_get_condlist(ini, section, "active")
get_sections(ini, active_section_cond.condlist)
--print_table(section_to_check)
for sect,v in pairs(section_to_check) do
local path_field
for i,vv in pairs(path_fields) do
if ini:line_exist(sect, vv) then
path_field = vv
break
end
end
if path_field ~= nil then
local prefix
if prefix_name ~= nil then
prefix = prefix_name
else
prefix = smart:name()
end
local path_walk = utils.cfg_get_string(ini, sect, path_field, smart, false, prefix)
--printf(" check path %s", path_walk)
local patrol_walk = patrol(path_walk)
-- Ïðîâåðêà íàëè÷èÿ ïóòè
if not patrol_walk then
printf("path_walk [%s] doesnt exist in the game", path_walk)
end
-- Åñëè ýòî âàëê ïóòü, ïðîâåðÿåì åñòü ëè ëóê.
local patrol_look = nil
if path_field == "path_walk" then
local path_look_name = utils.cfg_get_string(ini, sect, "path_look", smart, false, prefix)
if path_look_name ~= nil then
--printf(" checking path look %s", tostring(path_look_name))
patrol_look = patrol(path_look_name)
if not patrol_look then
printf("path_look [%s] doesnt exist in the game", path_look_name)
end
end
end
-- Èòåðèðóåìñÿ ïî òî÷êàì ïàòðóëüíîãî ïóòè
local cnt = patrol_walk:count()
for pt = 0, cnt - 1 do
local point = patrol_walk:point(pt)
-- Ïðîâåðêà ÷òî òî÷êà íà ÀÈ êàðòå
local level_vertex_id = patrol_walk:level_vertex_id(pt)
if level_vertex_id == nil then
printf("path_walk [%s] point [%s] is not on the AI map (no_level_id)", path_walk, pt)
end
-- local vertex_position = level.vertex_position(level_vertex_id)
-- if vertex_position:distance_to_sqr(point) > 0.49 then
-- printf("path_walk [%s] point [%s] is not on the AI map (by_distance)", path_walk, pt)
-- end
-- Ïðîâåðêà ÷òî åñòü ñîîòâåòñòâóþùèé ëóê ïóòü.
if patrol_look ~= nil then
local flags = patrol_walk:flags(pt)
local look_cnt = patrol_look:count()
local is_found = false
for look_pt = 0, look_cnt - 1 do
local look_flags = patrol_walk:flags(look_pt)
if flags:equal(look_flags) then
is_found = true
break
end
end
if cnt == 1 and not_is_found then
printf("path_walk [%s] is one-point walk path without corresponding look points", path_walk)
end
else
-- Ñïåøë êåéñ íà ñëó÷àé êîãäà îäíîòî÷å÷íûì ïóòü âîëêà
if cnt == 1 then
printf("path_walk [%s] is one-point walk path without path_look", path_walk)
end
end
end
end
end
end
function main()
check()
end

View file

@ -0,0 +1,137 @@
prefetch("_G")
function cs_register(factory,client_object_class,server_object_class,clsid,script_clsid)
factory:register (client_object_class,server_object_class,clsid,script_clsid)
end
function c_register(factory,client_object_class,clsid,script_clsid)
if (editor() == false) then
factory:register(client_object_class,clsid,script_clsid)
end
end
function s_register(factory,server_object_class,clsid,script_clsid)
factory:register(server_object_class,clsid,script_clsid)
end
function register(object_factory)
-- GENERAL ---------------------------------------------------------------------------------------------------------------------------
c_register (object_factory, "ui_main_menu.main_menu", "MAIN_MNU", "main_menu")
cs_register (object_factory, "ce_smart_zone", "smart_terrain.se_smart_terrain", "SMRTTRRN", "smart_terrain")
cs_register (object_factory, "CLevelChanger", "se_level_changer.se_level_changer", "LVL_CHNG", "level_changer_s")
cs_register (object_factory, "CActor", "se_actor.se_actor", "S_ACTOR", "script_actor")
cs_register (object_factory, "CAI_Stalker", "se_stalker.se_stalker", "AI_STL_S", "script_stalker")
cs_register (object_factory, "CHelicopter", "se_heli.se_heli", "C_HLCP_S", "script_heli")
cs_register (object_factory, "ce_smart_zone", "se_zones.se_restrictor", "SPC_RS_S", "script_restr")
cs_register (object_factory, "CPhysicObject", "se_item.se_physic", "O_PHYS_S", "script_phys")
cs_register (object_factory, "smart_cover_object", "se_smart_cover.se_smart_cover", "SMRT_C_S", "smartcover_s")
cs_register (object_factory, "CDestroyablePhysicsObject", "se_item.se_physic", "O_DSTR_S", "destrphys_s")
cs_register (object_factory, "hanging_lamp", "se_item.se_lamp", "SO_HLAMP", "hlamp_s")
-- ARTEFACTS --------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CElectricBall", "se_artefact.se_artefact", "SCRPTART", "artefact_s")
-- MONSTERS ---------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CAI_Bloodsucker", "se_monster.se_monster", "SM_BLOOD", "bloodsucker_s")
cs_register (object_factory, "CAI_Boar", "se_monster.se_monster", "SM_BOARW", "boar_s")
cs_register (object_factory, "CAI_Dog", "se_monster.se_monster", "SM_DOG_S", "dog_s")
cs_register (object_factory, "CAI_Flesh", "se_monster.se_monster", "SM_FLESH", "flesh_s")
cs_register (object_factory, "CAI_PseudoDog", "se_monster.se_monster", "SM_P_DOG", "pseudodog_s")
cs_register (object_factory, "CBurer", "se_monster.se_monster", "SM_BURER", "burer_s")
cs_register (object_factory, "CCat", "se_monster.se_monster", "SM_CAT_S", "cat_s")
cs_register (object_factory, "CChimera", "se_monster.se_monster", "SM_CHIMS", "chimera_s")
cs_register (object_factory, "CController", "se_monster.se_monster", "SM_CONTR", "controller_s")
cs_register (object_factory, "CFracture", "se_monster.se_monster", "SM_IZLOM", "fracture_s")
cs_register (object_factory, "CPoltergeist", "se_monster.se_monster", "SM_POLTR", "poltergeist_s")
cs_register (object_factory, "CPseudoGigant", "se_monster.se_monster", "SM_GIANT", "gigant_s")
cs_register (object_factory, "CZombie", "se_monster.se_monster", "SM_ZOMBI", "zombie_s")
cs_register (object_factory, "CSnork", "se_monster.se_monster", "SM_SNORK", "snork_s")
cs_register (object_factory, "CTushkano", "se_monster.se_monster", "SM_TUSHK", "tushkano_s")
cs_register (object_factory, "CPsyDog", "se_monster.se_monster", "SM_DOG_P", "psy_dog_s")
cs_register (object_factory, "CPsyDogPhantom", "se_monster.se_monster", "SM_DOG_F", "psy_dog_phantom_s")
-- DEVICES ----------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CTorch", "se_item.se_item_torch", "TORCH_S", "device_torch_s")
cs_register (object_factory, "CScientificDetector", "se_item.se_detector", "DET_SCIE", "detector_scientific_s")
cs_register (object_factory, "CEliteDetector", "se_item.se_detector", "DET_ELIT", "detector_elite_s")
cs_register (object_factory, "CAdvancedDetector", "se_item.se_detector", "DET_ADVA", "detector_advanced_s")
cs_register (object_factory, "CSimpleDetector", "se_item.se_detector", "DET_SIMP", "detector_simple_s")
cs_register (object_factory, "CScope", "se_item.se_item", "WP_SCOPE", "wpn_scope_s")
cs_register (object_factory, "CSilencer", "se_item.se_item", "WP_SILEN", "wpn_silencer_s")
cs_register (object_factory, "CGrenadeLauncher", "se_item.se_item", "WP_GLAUN", "wpn_grenade_launcher_s")
-- OUTFITS ----------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CStalkerOutfit", "se_item.se_outfit", "E_STLK", "equ_stalker_s")
cs_register (object_factory, "CHelmet", "se_item.se_helmet", "E_HLMET", "equ_helmet_s")
-- WEAPONS ----------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CWeaponBinoculars", "se_item.se_weapon_magazined", "WP_BINOC", "wpn_binocular_s")
cs_register (object_factory, "CWeaponKnife", "se_item.se_weapon", "WP_KNIFE", "wpn_knife_s")
cs_register (object_factory, "CWeaponBM16", "se_item.se_weapon_shotgun", "WP_BM16", "wpn_bm16_s")
cs_register (object_factory, "CWeaponGroza", "se_item.se_weapon_magazined_w_gl", "WP_GROZA", "wpn_groza_s")
cs_register (object_factory, "CWeaponSVD", "se_item.se_weapon_magazined", "WP_SVD", "wpn_svd_s")
cs_register (object_factory, "CWeaponAK74", "se_item.se_weapon_magazined_w_gl", "WP_AK74", "wpn_ak74_s")
cs_register (object_factory, "CWeaponLR300", "se_item.se_weapon_magazined", "WP_LR300", "wpn_lr300_s")
cs_register (object_factory, "CWeaponHPSA", "se_item.se_weapon_magazined", "WP_HPSA", "wpn_hpsa_s")
cs_register (object_factory, "CWeaponPM", "se_item.se_weapon_magazined", "WP_PM", "wpn_pm_s")
cs_register (object_factory, "CWeaponRG6", "se_item.se_weapon_shotgun", "WP_RG6", "wpn_rg6_s")
cs_register (object_factory, "CWeaponRPG7", "se_item.se_weapon_magazined", "WP_RPG7", "wpn_rpg7_s")
cs_register (object_factory, "CWeaponShotgun", "se_item.se_weapon_shotgun", "WP_SHOTG", "wpn_shotgun_s")
cs_register (object_factory, "CWeaponAutomaticShotgun", "se_item.se_weapon_automatic_shotgun", "WP_ASHTG", "wpn_auto_shotgun_s")
-- cs_register (object_factory, "CWeaponMagazined", "se_item.se_weapon_magazined", "WP_MAGAZ", "wpn_magazined_s")
cs_register (object_factory, "CWeaponSVU", "se_item.se_weapon_magazined", "WP_SVU", "wpn_svu_s")
cs_register (object_factory, "CWeaponUSP45", "se_item.se_weapon_magazined", "WP_USP45", "wpn_usp45_s")
cs_register (object_factory, "CWeaponVal", "se_item.se_weapon_magazined", "WP_VAL", "wpn_val_s")
cs_register (object_factory, "CWeaponVintorez", "se_item.se_weapon_magazined", "WP_VINT", "wpn_vintorez_s")
cs_register (object_factory, "CWeaponWalther", "se_item.se_weapon_magazined", "WP_WALTH", "wpn_walther_s")
--cs_register (object_factory, "CWeaponStatMgun", "se_item.se_mgun", "W_STMGUN", "wpn_stat_mgun")
-- ANOMALY ZONES ---------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CHairsZone", "se_zones.se_zone_visual", "ZS_BFUZZ", "zone_bfuzz_s")
cs_register (object_factory, "CMosquitoBald", "se_zones.se_zone_anom", "ZS_MBALD", "zone_mbald_s")
cs_register (object_factory, "CMincer", "se_zones.se_zone_anom", "ZS_GALAN", "zone_galant_s")
cs_register (object_factory, "CMincer", "se_zones.se_zone_anom", "ZS_MINCE", "zone_mincer_s")
cs_register (object_factory, "CRadioactiveZone", "se_zones.se_zone_anom", "ZS_RADIO", "zone_radio_s")
cs_register (object_factory, "CTorridZone", "se_zones.se_zone_torrid", "ZS_TORRD", "zone_torrid_s")
-- AMMO ------------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CWeaponAmmo", "se_item.se_ammo", "AMMO_S", "wpn_ammo_s")
cs_register (object_factory, "CWeaponAmmo", "se_item.se_ammo", "S_VOG25", "wpn_ammo_vog25_s")
cs_register (object_factory, "CWeaponAmmo", "se_item.se_ammo", "S_OG7B", "wpn_ammo_og7b_s")
cs_register (object_factory, "CWeaponAmmo", "se_item.se_ammo", "S_M209", "wpn_ammo_m209_s")
-- GRENADES --------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CF1", "se_item.se_grenade", "G_F1_S", "wpn_grenade_f1_s")
cs_register (object_factory, "CRGD5", "se_item.se_grenade", "G_RGD5_S", "wpn_grenade_rgd5_s")
-- EATABLE ---------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CMedkit", "se_item.se_eatable", "S_MEDKI", "obj_medkit_s")
cs_register (object_factory, "CMedkit", "se_item.se_eatable", "S_BANDG", "obj_bandage_s")
cs_register (object_factory, "CAntirad", "se_item.se_eatable", "S_ANTIR", "obj_antirad_s")
cs_register (object_factory, "CFoodItem", "se_item.se_eatable", "S_FOOD", "obj_food_s")
cs_register (object_factory, "CBottleItem", "se_item.se_eatable", "S_BOTTL", "obj_bottle_s")
-- INVENTORY BOX ---------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CInventoryBox", "se_item.se_invbox", "S_INVBOX", "inventory_box_s")
-- EXPLOSIVE -------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CExplosiveItem", "se_item.se_explosive", "S_EXPLO", "obj_explosive_s")
-- PDA -------------------------------------------------------------------------------------------------------------------------
cs_register (object_factory, "CPda", "se_item.se_pda", "S_PDA", "obj_pda_s")
-- ONLINE_OFFLINE_GROUP --------------------------------------------------------------------------------------------------------------
s_register (object_factory, "sim_squad_scripted.sim_squad_scripted", "ON_OFF_S", "online_offline_group_s")
end

View file

@ -0,0 +1,77 @@
combat_sectors = {}
function register_combat_restrictor(restrictor)
if combat_sectors[restrictor:name()] == nil then
combat_sectors[restrictor:name()] = restrictor
end
end
function apply_combat_restrictor(npc)
-- èòåðèðóåìñÿ ïî ðåñòðèêòîðàì, èùåì â êîòîðîì ìû íàõîäèìñÿ è àïïëàèì åãî
local npc_position = npc:position()
for k,v in pairs(combat_sectors) do
if v:inside(npc_position) then
npc:add_restrictions(k, "")
end
end
end
function clear_combat_restrictor(npc)
local out_restr = utils.parse_names(npc:out_restrictions())
for k,v in pairs(out_restr) do
if combat_sectors[v] ~= nil then
npc:remove_restrictions(v, "")
end
end
end
function accessible_job(se_obj, way_name)
local obj = db.storage[se_obj.id]
if obj == nil then
return false
end
-- Áåðåì êëèåíòñêèé îáúåêò ÍÏÑ
obj = obj.object
if obj == nil then
return false
end
local npc_position = obj:position()
local job_position = patrol(way_name):point(0)
-- Áåðåì ðåñòðèêòîð ïî ïîçèöèè ïóòè
-- Áåðåì ðåñòðèêòîð ïî ïîçèöèè ÍÏÑ
local is_npc_inside = false
for k,v in pairs(combat_sectors) do
if v:inside(npc_position) then
is_npc_inside = true
if v:inside(job_position) then
return true
end
end
end
-- Åñëè îíè ñîâïàäàþò - òî èñòèíà, èíà÷å ëîæü.
return is_npc_inside ~= true
end
function get_job_restrictor(way_name)
-- Áåðåì ñìàðò ïî ïîçèöèè ïóòè
local job_position = patrol(way_name):point(0)
for k,v in pairs(combat_sectors) do
if v:inside(job_position) then
return k
end
end
-- Âîçâðàùàåì åãî èìÿ
return ""
end

View file

@ -0,0 +1,196 @@
--'******************************************************
--'* Ìåíåäæåð äëÿ âûáîðà êàâåðîâ â òåêóùåì ñìàðòå.
--'******************************************************
class "CCover_manager"
function CCover_manager:__init(smart)
self.squads = {}
self.cover_table = {}
self.board = sim_board.get_sim_board()
self.is_valid = false
-- self.name = smart:name()
-- self.sid = math.random(1,100000)
end
function CCover_manager:register_squad(squad)
-- printf("CCover_manager:register_squad() name[%s] sid[%s]", tostring(self.name), tostring(self.sid))
if squad.player_id ~= "monster" then
self.squads[squad.id] = true
self.is_valid = false
end
end
function CCover_manager:unregister_squad(squad)
-- printf("CCover_manager:unregister_squad() name[%s] sid[%s]", tostring(self.name), tostring(self.sid))
if self.squads[squad.id] == nil then
return
end
self.squads[squad.id] = nil
self.is_valid = false
end
function CCover_manager:calculate_covers(position)
--printf("CCover_manager:calculate_covers() valid[%s]", tostring(self.is_valid))
--callstack()
if self.is_valid == true then
return
end
self.is_valid = true
local npc_table = {}
for k,v in pairs(self.squads) do
local squad = alife():object(k)
for kk in squad:squad_members() do
if db.storage[kk.id] ~= nil then
local npc_object = db.storage[kk.id].object
table.insert(npc_table, npc_object)
end
end
end
for k,v in pairs(npc_table) do
v:register_in_combat()
end
self.cover_table = {}
for k,v in pairs(npc_table) do
v:find_best_cover(position)
end
for k,v in pairs(npc_table) do
local cover = v:find_best_cover(position)
if cover ~= nil then
--printf("!!! %s: %s [%s]", v:name(), cover:level_vertex_id(), tostring(cover:is_smart_cover()))
self.cover_table[v:id()] = {cover_vertex_id = cover:level_vertex_id(), cover_position = cover:position(),
look_pos = position, is_smart_cover = cover:is_smart_cover()}
--else
--printf("!!! nil")
end
end
for k,v in pairs(npc_table) do
v:unregister_in_combat()
end
end
function CCover_manager:save(packet)
set_save_marker(packet, "save", false, "CCover_manager")
packet:w_bool(self.is_valid)
-- ñîõðàíÿòü ðåãèñòðåííûå ñêâàäû
local n = 0
for k,v in pairs(self.cover_table) do
n = n + 1
end
packet:w_u8(n)
for k,v in pairs(self.cover_table) do
packet:w_u16(k)
packet:w_u32(v.cover_vertex_id)
packet:w_float(v.cover_position.x)
packet:w_float(v.cover_position.y)
packet:w_float(v.cover_position.z)
packet:w_float(v.look_pos.x)
packet:w_float(v.look_pos.y)
packet:w_float(v.look_pos.z)
packet:w_bool(v.is_smart_cover)
end
set_save_marker(packet, "save", true, "CCover_manager")
end
function CCover_manager:load(packet)
set_save_marker(packet, "load", false, "CCover_manager")
self.is_valid = packet:r_bool()
local n = packet:r_u8()
for i = 1,n do
local npc_id = packet:r_u16()
local cover_vertex_id = packet:r_u32()
local cover_position = vector():set(0,0,0)
cover_position.x = packet:r_float()
cover_position.y = packet:r_float()
cover_position.z = packet:r_float()
local look_pos = vector():set(0,0,0)
look_pos.x = packet:r_float()
look_pos.y = packet:r_float()
look_pos.z = packet:r_float()
local is_smart_cover = packet:r_bool()
self.cover_table[npc_id] = {cover_vertex_id = cover_vertex_id, cover_position = cover_position,
look_pos = look_pos, is_smart_cover = is_smart_cover}
end
set_save_marker(packet, "load", true, "CCover_manager")
end
-- Åñòü ëè ó îáúåêòà âûáðàííûé ñìàðò êàâåð
function has_smart_cover(se_obj, smrttrn)
local cmanager = smrttrn.combat_manager.cover_manager
local npc_id = se_obj.id
local cover = cmanager.cover_table[npc_id]
if cover == nil then
return false
end
if cover.is_smart_cover ~= true then
return false
end
local npc_storage = db.storage[npc_id]
if npc_storage == nil then
return false
end
local npc_obj = npc_storage.object
local level_id = game_graph():vertex(smrttrn.m_game_vertex_id):level_id()
local smrt_cover = se_smart_cover.registered_smartcovers_by_lv_id[level_id][cover.cover_vertex_id]
if smrt_cover == nil then
return false
end
local smrt_cover_object = bind_smart_cover.registered_smartcovers[smrt_cover:name()]
if npc_obj:suitable_smart_cover(smrt_cover_object) then
return true
end
return false
end
-- Åñòü ëè ó îáúåêòà âûáðàííûé êàâåð
function has_cover(se_obj, smrttrn)
local cmanager = smrttrn.combat_manager.cover_manager
local cover = cmanager.cover_table[se_obj.id]
if cover == nil then
return false
end
if cover.is_smart_cover then
local npc_storage = db.storage[npc_id]
if npc_storage == nil then
return true
end
local npc_obj = npc_storage.object
local level_id = game_graph():vertex(smrttrn.m_game_vertex_id):level_id()
local smrt_cover = se_smart_cover.registered_smartcovers_by_lv_id[level_id][cover.cover_vertex_id]
if smrt_cover == nil then
return true
end
local smrt_cover_object = bind_smart_cover.registered_smartcovers[smrt_cover:name()]
if npc_obj:suitable_smart_cover(smrt_cover_object) then
return false
end
end
return true
end
-- Ïîëó÷èòü âûáðàííûé êàâåð îáúåêòà
function get_cover(obj, smrttrn)
local cmanager = smrttrn.combat_manager.cover_manager
return cmanager.cover_table[obj:id()]
end

104
gamedata/scripts/db.script Normal file
View file

@ -0,0 +1,104 @@
--[[------------------------------------------------------------------------------------------------
Áàçà äàííûõ æèâûõ îíëàéíîâûõ îáúåêòîâ, çîí è ðåñòðèêòîðîâ, àêò¸ðà
×óãàé Àëåêñàíäð
--------------------------------------------------------------------------------------------------]]
zone_by_name = {}
script_ids = {}
storage = {}
actor = nil
actor_proxy = actor_proxy.actor_proxy()
heli = {}
camp_storage = {}
story_by_id = {}
smart_terrain_by_id = {}
info_restr = {}
strn_by_respawn = {}
heli_enemies = {}
heli_enemy_count = 0
anim_obj_by_name = {}
goodwill = {sympathy = {}, relations = {}}
story_object = {}
signal_light = {}
offline_objects = {}
anomaly_by_name = {}
level_doors = {} -- Ñîäåðæèò ñïèñîê âñåõ äâåðåé íà óðîâíå (÷òîáû íïñ ìîãëè ïî íåìó ïðîáåãàòüñÿ è îòêðûâàòü äâåðè, ðÿäîì ñ êîòîðûìè îíè ñòîÿò.
no_weap_zones = {}
spawned_vertex_by_id= {}
function add_enemy( obj )
heli_enemies[heli_enemy_count] = obj
heli_enemy_count = heli_enemy_count + 1
end
function delete_enemy( e_index )
heli_enemies[e_index] = nil
end
function add_obj( obj )
printf("adding object %s",obj:name())
storage[obj:id()].object = obj
end
function del_obj( obj )
storage [obj:id()] = nil
end
function add_zone( zone )
zone_by_name[zone:name()] = zone
end
function del_zone( zone )
zone_by_name[zone:name()] = nil
end
function add_anomaly( anomaly )
anomaly_by_name[anomaly.object:name()] = anomaly
end
function del_anomaly( anomaly )
anomaly_by_name[anomaly.object:name()] = nil
end
function add_actor( obj )
actor = obj
actor_proxy:net_spawn( obj )
add_obj( obj )
end
function del_actor()
del_obj( actor )
actor_proxy:net_destroy()
actor = nil
end
function add_heli(obj)
heli[obj:id()] = obj
end
function del_heli(obj)
heli[obj:id()] = nil
end
function add_smart_terrain( obj )
smart_terrain_by_id[obj.id] = obj
end
function del_smart_terrain( obj )
smart_terrain_by_id[obj.id] = nil
end
function add_anim_obj(anim_obj, binder)
anim_obj_by_name[anim_obj:name()] = binder
add_obj(anim_obj)
end
function del_anim_obj(anim_obj)
anim_obj_by_name[anim_obj:name()] = nil
del_obj(anim_obj)
end

View file

@ -0,0 +1,271 @@
--' Êëþ÷åì ÿâëÿåòñÿ ãðóïïèðîâêà ïåðñîíàæà. Çíà÷åíèåì ÿâëÿåòñÿ òàáëèöà, ñîäåðæàøàÿ èìåíà ñåêöèé ïðåäìåòîâ.
local item_by_community = {}
--' Çàâèñèìîñòè â ñïàóíå ïðåäìåòîâ. Ïðåäìåò ñïàóíèòüñÿ òîëüêî åñëè åñòü õîòÿ áû îäèí èç çàâèñèìûõ.
local item_dependence = {}
--' Ìíîæèòåëè è ìèíèìàêñû äëÿ âûïàäåíèÿ âåùåé â çàâèñèìîñòè îò óðîâíÿ
local mul_by_level = {}
local count_by_level = {}
--' Ïðåäìåòû, êîòîðûå íåëüçÿ óäàëÿòü (êâåñòîâûå íàïðèìåð)
local always_keep_item = {}
--' Ïðåäìåòû, îòíîñÿùèåñÿ ê ïàòðîíàì. Èõ íàäî ñïàóíèòü äðóãèì ìåòîäîì.
ammo_sections = {}
local death_ini = ini_file("misc\\death_generic.ltx")
function init_drop_settings()
local community_list = { "stalker", "dolg", "freedom", "bandit", "army", "zombied", "ecolog", "killer", "monolith" }
for k,v in pairs(community_list) do
--' Íåîáõîäèìî çàïîëíèòü òàáëèöó
item_by_community[v] = {}
if death_ini:section_exist(v) then
local n = death_ini:line_count(v)
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line(v,i,"","")
item_by_community[v][id] = 100*tonumber(value)
end
end
end
--' Çàïîëíÿåì òàáëèöó çàâèñèìîñòåé
local n = death_ini:line_count("item_dependence")
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line("item_dependence",i,"","")
item_dependence[id] = {}
local vvv = parse_names(value)
for k,v in pairs(vvv) do
item_dependence[id][v] = true
end
end
--' Ìíîæèòåëè è ìèíèìàêñû äëÿ âûïàäåíèÿ âåùåé â çàâèñèìîñòè îò óðîâíÿ
local level_name = level.name()
if not death_ini:section_exist(level_name) then
level_name = "default"
end
local n = death_ini:line_count(level_name)
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line(level_name,i,"","")
mul_by_level[id] = tonumber(value)
end
local item_count_section = "item_count_" .. level.get_game_difficulty()
local n = death_ini:line_count(item_count_section)
for i=0,n-1 do
result, id, value = death_ini:r_line(item_count_section,i,"","")
--' Íóæíî ðàñïàðñèòü value â äâà çíà÷åíèÿ
local t = parse_nums(value)
if t[1] == nil then
abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))
end
local min = t[1]
local max = t[2]
if max == nil then
max = min
end
if mul_by_level[id] == nil then
mul_by_level[id] = 0
end
min = tonumber(min) * mul_by_level[id]
max = tonumber(max) * mul_by_level[id]
count_by_level[id] = {min = min, max = max}
end
--' Ïðåäìåòû, êîòîðûå íåëüçÿ óäàëÿòü (êâåñòîâûå íàïðèìåð)
local n = death_ini:line_count("keep_items")
for i=0,n-1 do
result, id, value = death_ini:r_line("keep_items",i,"","")
if value == "true" then
always_keep_item[id] = true
end
end
--' Ïðåäìåòû, îòíîñÿùèåñÿ ê ïàòðîíàì. Èõ íàäî ñïàóíèòü äðóãèì ìåòîäîì.
ammo_sections = {}
local n = death_ini:line_count("ammo_sections")
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line("ammo_sections",i,"","")
ammo_sections[id] = true
end
end
class "drop_manager"
function drop_manager:__init(npc)
self.npc = npc
end
function drop_manager:create_release_item()
--' Ñïðàøèâàåì ó ñåðâåðíîãî îáúåêòà ãåíåðèëèñü ëè ïðåäìåòû
local se_obj = alife():object(self.npc:id())
if se_obj == nil or se_obj.death_droped == true then
return
end
se_obj.death_droped = true
--' Çàïóñêàåì èòåðàòîð íà óäàëåíèå ïðåäìåòîâ
self.npc:iterate_inventory(keep_item, self.npc)
--' Ïðîâåðêà íà îòñóòñòâèå ñïàóíà ëóòà
local ini = self.npc:spawn_ini()
if ini and ini:section_exist("dont_spawn_loot") then
return
end
local st = db.storage[self.npc:id()]
local st_ini = st and st.ini
if st_ini and st_ini:line_exist(st.section_logic , "dont_spawn_loot") then
return
end
--' Äîñïàâíèâàåì íåîáõîäèìîå êîëè÷åñòâî èòåìîâ:
--' Íåîáõîäèìî ñîñòàâèòü ñïèñîê îáúåêòîâ êîòîðûå ìîãóò áûòü çàñïàâíåíû äëÿ ïåðñîíàæà
local spawn_items = item_by_community[character_community(self.npc)]
if spawn_items == nil then
return
end
for k,v in pairs(spawn_items) do
--' Ïî êàæäîìó îáúåêòó íåîáõîäèìî ïîëó÷èòü çàâèñèìîñòè
if check_item_dependence(self.npc, k) == true then
--' Ïî êàæäîìó îáúåêòó íåîáõîäèìî ïîëó÷èòü êîëè÷åñòâî
if count_by_level[k] == nil then
abort("Incorrect count settings in death_manager for object[%s]", k)
end
local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
--' Íåîáõîäèìî çàñïàâíèòü íóæíîå êîëè÷åñòâî.
create_items(self.npc, k, number, v)
end
end
end
--' Ôóíêöèÿ âûçûâàåòñÿ äëÿ êàæäîãî ïðåäìåòà, åñëè âåðíåò false òî ïðåäìåò óäàëèòñÿ.
function keep_item(npc, item)
local section = item:section()
local ini = npc:spawn_ini()
if ini and ini:section_exist("keep_items")
and section ~= "guitar_a"
and section ~= "harmonica_a"
and section ~= "wpn_binoc"
and section ~= "device_torch"
and section ~= "device_pda" then
return
end
if isArtefact(item) then
return
end
-- printf("keep_item:item ["..item:name().."] npc_name ["..npc:name().."]")
if section == "bolt" then
return
end
if always_keep_item[section] == true then
return
end
--printf("item name [%s]", item:name())
if isWeapon(item) and not(get_clsid(item)==clsid.wpn_grenade_rgd5_s or get_clsid(item)==clsid.wpn_grenade_f1_s) then
set_weapon_drop_condition(item)
return
end
if xr_corpse_detection.lootable_table[section] == true and ammo_sections[section] == nil then
return
end
alife():release(alife():object(item:id()), true)
--[[
local item_id = item:id()
local item_in_slot = npc:item_in_slot(2)
if item_in_slot ~= nil and item_in_slot:id() == item_id then
--' Òóò íàäî óìåíüøèòü êîíäèøí îðóæèÿ
item:set_condition((math.random(40)+40)/100)
return
end
item_in_slot = npc:item_in_slot(3)
if item_in_slot ~= nil and item_in_slot:id() == item_id then
--' Òóò íàäî óìåíüøèòü êîíäèøí îðóæèÿ
item:set_condition((math.random(40)+40)/100)
return
end
-- npc:mark_item_dropped(item)
local item_in_slot = npc:item_in_slot(4)
if item_in_slot ~= nil and item_in_slot:id() == item_id then
return
end
if not npc:marked_dropped(item) then
-- printf("releasing object ["..item:name().."]")
alife():release(alife():object(item:id()), true)
end
]]
end
function set_weapon_drop_condition(item)
local condition = (math.random(40)+40)/100
--printf("condition [%s]", tostring(condition))
item:set_condition(condition)
end
--' Ôóíêöèÿ ñïàâíèò íåîáõîäèìîå ÷èñëî ïðåäìåòîâ
function create_items(npc, section, number, rnd)
--'printf("create %s of %s", tostring(number), tostring(section))
if ammo_sections[section] == true then
if number > 0 then
create_ammo(section,
npc:position(),
npc:level_vertex_id(),
npc:game_vertex_id(),
npc:id(),
number)
end
else
for i=1,number do
--' Ïðîâåðÿåì âåðîÿòíîñòü ïîÿâèòü êàæäûé îáúåêò â îòäåëüíîñòè
if math.random(100) <= rnd then
alife():create(section,
npc:position(),
npc:level_vertex_id(),
npc:game_vertex_id(),
npc:id())
end
end
end
end
--' Ôóíêöèÿ ïðîâåðÿåò åñòü ëè õîòü îäèí èç çàâèñèìûõ îáúåêòîâ ó ïåðñîíàæà
function check_item_dependence(npc, section)
if item_dependence[section] == nil then
return true
end
local d_flag = true
for k,v in pairs(item_dependence[section]) do
local obj = npc:object(k)
if obj ~= nil and npc:marked_dropped(obj) ~= true then
return true
end
d_flag = false
end
return d_flag
end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,987 @@
function is_npc_in_current_smart(first_speaker, second_speaker, smart_name)
local npc = who_is_npc(first_speaker, second_speaker)
local smart = xr_gulag.get_npc_smart(npc)
if not smart then return false end
return smart:name() == smart_name
end
function break_dialog(first_speaker, second_speaker, id)
first_speaker:stop_talk()
second_speaker:stop_talk()
end
function update_npc_dialog(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.storage[npc:id()].meet.meet_manager:update()
xr_meet.process_npc_usability(npc)
xr_motivator.update_logic(npc)
end
function disable_talk_self(first_speaker, second_speaker)
first_speaker:disable_talk()
end
function disable_talk_victim(first_speaker, second_speaker)
second_speaker:disable_talk()
end
function punch(first_speaker, second_speaker)
--abort("KICK ASS !!!!")
--xr_punch.punch[first_speaker:id()] = second_speaker
db.storage[second_speaker:id()].punch.enabled = true
end
function get_money_then_leave(first_speaker, second_speaker)
db.storage[first_speaker:id()].meet.enabled = false
db.storage[first_speaker:id()].robber.enabled = true
end
function is_wounded(first_speaker, second_speaker)
-- if db.storage[first_speaker:id()].wounded ~= nil and
-- db.storage[first_speaker:id()].wounded.wound_manager.can_use_medkit == true
-- then
-- return false
-- end
local npc = who_is_npc(first_speaker, second_speaker)
return xr_wounded.is_wounded(npc)
end
--[[
function is_opp_wounded(first_speaker, second_speaker, dialog_id)
if db.storage[second_speaker:id()].wounded ~= nil and
db.storage[second_speaker:id()].wounded.wound_manager.can_use_medkit == true
then
return false
end
return xr_wounded.is_wounded(second_speaker)
end
]]--
function is_not_wounded(first_speaker, second_speaker, dn)
return not is_wounded(first_speaker, second_speaker)
end
function actor_have_medkit(first_speaker, second_speaker)
return first_speaker:object("medkit") ~= nil or
first_speaker:object("medkit_army") ~= nil or
first_speaker:object("medkit_scientic") ~= nil
end
function actor_hasnt_medkit(first_speaker, second_speaker)
return actor_have_medkit(first_speaker, second_speaker) == false
end
function actor_have_bandage(first_speaker, second_speaker)
return first_speaker:object("bandage") ~= nil
end
function transfer_medkit(first_speaker, second_speaker)
if first_speaker:object("medkit") ~= nil then
dialogs.relocate_item_section(second_speaker, "medkit", "out")
--alife():release(alife():object(second_speaker:object("medkit"):id()), true)
elseif first_speaker:object("medkit_army") ~= nil then
dialogs.relocate_item_section(second_speaker, "medkit_army", "out")
--alife():release(alife():object(second_speaker:object("medkit_army"):id()), true)
else
dialogs.relocate_item_section(second_speaker, "medkit_scientic", "out")
--alife():release(alife():object(second_speaker:object("medkit_scientic"):id()), true)
end
alife():create("medkit_script", second_speaker:position(), second_speaker:level_vertex_id(), second_speaker:game_vertex_id(), second_speaker:id())
--' Òóò íàäî àíëî÷èòü àïòå÷êó äëÿ èñïîëüçîâàíèÿ.
xr_wounded.unlock_medkit(second_speaker)
if second_speaker:relation(first_speaker) ~= game_object.enemy then
second_speaker:set_relation(game_object.friend, first_speaker)
end
first_speaker:change_character_reputation(10);
end
function transfer_bandage(first_speaker, second_speaker)
dialogs.relocate_item_section(second_speaker, "bandage", "out")
second_speaker:set_relation(game_object.friend, first_speaker)
end
function kill_yourself(npc, actor)
npc:kill(actor)
end
--' Use this function instead.
function relocate_item_section(victim, section, type, amount)
if db.actor then
if not amount then
amount = 1
end
for i = 1, amount do
if type == "in" then
--' Òðàíñôåðèòü íóæíî òîëüêî êâåñòîâûå ïðåäìåòû.
if quest_section[section] == true and victim ~= nil and victim:object(section) ~= nil then
victim:transfer_item(victim:object(section), db.actor)
else
alife():create(section,
db.actor:position(),
db.actor:level_vertex_id(),
db.actor:game_vertex_id(),
db.actor:id())
end
elseif type == "out" then
if victim == nil then
abort("Couldn't relocate item to NULL")
end
db.actor:transfer_item(db.actor:object(section), victim)
end
end
if death_manager.ammo_sections[section] == true then
local ltx = system_ini()
local box_size = ltx:r_s32(section, "box_size")
amount = amount * box_size
end
news_manager.relocate_item(db.actor, type, section, amount)
end
end
function relocate_money(victim, num, type)
if db.actor then
if type == "in" then
db.actor:give_money(num)
game_stats.money_quest_update (num)
elseif type == "out" then
if victim == nil then
abort("Couldn't relocate money to NULL")
end
db.actor:transfer_money(num, victim)
game_stats.money_quest_update(-num)
end
news_manager.relocate_money(db.actor, type, num)
end
end
--'---------------------------------------------------------------------------------
--' DIALOG ALLOWED
--'---------------------------------------------------------------------------------
--function dialog_allowed(object, victim, id)
-- if id ~= nil then
---- printf("*DIALOGS*: dialog_allowed: %s", id)
-- else
---- printf("*DIALOGS*: dialog_allowed: nil")
-- end
-- if db.storage[victim:id()].actor_dialogs ~= nil then
-- for k,v in pairs(db.storage[victim:id()].actor_dialogs) do
-- if v == id then return true end
-- end
-- end
-- return false
--end
--function dialog_not_disable(object, victim, id)
-- if id ~= nil then
---- printf("*DIALOGS*: dialog_disable:%s", id)
-- else
---- printf("*DIALOGS*: dialog_disable:nil")
-- end
-- if db.storage[victim:id()].actor_disable ~= nil then
-- for k,v in pairs(db.storage[victim:id()].actor_disable) do
-- if v == id then return false end
-- end
-- end
-- return true
--end
function allow_wounded_dialog(object, victim, id)
if db.storage[victim:id()].wounded == nil then
return false
end
if db.storage[victim:id()].wounded.help_dialog == id then
return true
end
return false
end
--function allow_guide_dialog(object, victim, id)
-- local section = db.storage[victim:id()].active_section
-- printf("active_section %s", tostring(section))
-- if section == nil then
-- return false
-- end
-- if string.find(section, "conductor", 1) ~= nil then
-- return true
-- end
-- return false
--end
-----------------------------------------------------------------------------------
-- LEVELS
-----------------------------------------------------------------------------------
--function level_escape(first_speaker, second_speaker)
-- return level.name() == "l01_escape"
--end
--
--function level_garbage(first_speaker, second_speaker)
-- return level.name() == "l02_garbage"
--end
--
--function level_agroprom(first_speaker, second_speaker)
-- return level.name() == "l03_agroprom_ai2" or level.name() == "l03_agroprom"
--end
function level_zaton(first_speaker, second_speaker)
return level.name() == "zaton"
end
function level_jupiter(first_speaker, second_speaker)
return level.name() == "jupiter"
end
function level_pripyat(first_speaker, second_speaker)
return level.name() == "pripyat"
end
function not_level_zaton(first_speaker, second_speaker)
return level.name() ~= "zaton"
end
function not_level_jupiter(first_speaker, second_speaker)
return level.name() ~= "jupiter"
end
function not_level_pripyat(first_speaker, second_speaker)
return level.name() ~= "pripyat"
end
-----------------------------------------------------------------------------------
-- Relation functions
-----------------------------------------------------------------------------------
function is_friend(first_speaker, second_speaker)
return first_speaker:relation(second_speaker) == game_object.friend
end
function is_not_friend(first_speaker, second_speaker)
return not is_friend(first_speaker, second_speaker)
end
function become_friend(first_speaker, second_speaker)
first_speaker:set_relation(game_object.friend, second_speaker)
end
-----------------------------------------------------------------------------------
-- Community
-----------------------------------------------------------------------------------
function actor_in_dolg(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "dolg" then
return true
end
end
return false
end
function actor_not_in_dolg(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "dolg" then
return false
end
end
return true
end
function actor_set_dolg(actor, npc)
printf("ACTOR NOW IN [DOLG] COMMUNITY")
sim_board.get_sim_board():set_actor_community("dolg")
return true
end
function actor_in_freedom(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "freedom" then
return true
end
end
return false
end
function actor_not_in_freedom(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "freedom" then
return false
end
end
return true
end
function actor_set_freedom(actor, npc)
printf("ACTOR NOW IN [FREEDOM] COMMUNITY")
sim_board.get_sim_board():set_actor_community("freedom")
return true
end
function actor_in_bandit(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "bandit" then
return true
end
end
return false
end
function actor_not_in_bandit(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "bandit" then
return false
end
end
return true
end
function actor_set_bandit(actor, npc)
printf("ACTOR NOW IN [BANDIT] COMMUNITY")
sim_board.get_sim_board():set_actor_community("bandit")
return true
end
function actor_in_stalker(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "stalker" then
return true
end
end
return false
end
function actor_not_in_stalker(actor, npc)
for k,v in pairs(sim_board.get_sim_board().players) do
if v.community_player == true and v.player_name == "stalker" then
return false
end
end
return true
end
function actor_set_stalker(actor, npc)
printf("ACTOR NOW IN [STALKER] COMMUNITY")
sim_board.get_sim_board():set_actor_community("stalker")
return true
end
function actor_clear_community(actor, npc)
printf("ACTOR NOW IN [NEUTRAL] COMMUNITY")
sim_board.get_sim_board():set_actor_community("none")
return true
end
function npc_stalker(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
return character_community(npc) == "stalker"
end
function npc_bandit(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
return character_community(npc) == "bandit"
end
function npc_freedom(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
return character_community(npc) == "freedom"
end
function npc_dolg(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
return character_community(npc) == "dolg"
end
function npc_army(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
return character_community(npc) == "army"
end
-----------------------------------------------------------------------------------
-- Money functions
-----------------------------------------------------------------------------------
function has_2000_money(first_speaker, second_speaker)
return first_speaker:money() >= 2000
end
-----------------------------------------------------------------------------------
-- TRADE
-----------------------------------------------------------------------------------
--' Èíèöèàëèçàöèÿ òîðãîâëè
function trade_init(seller, buyer)
db.storage[seller:id()].meet.begin_wait_to_see.begin = time_global()/1000
xr_position.setPosition(db.storage[seller:id()].meet.Seller,
db.storage[seller:id()].meet.Seller:level_vertex_id())
db.storage[seller:id()].meet.Buyer = buyer
end
function want_trade(seller, buyer)
if seller:relation(buyer) == game_object.friend or
seller:relation(buyer) == game_object.neutral
then
return true
else
return false
end
end
function dont_want_trade(seller, buyer)
return not want_trade(seller,buyer)
end
----------------------------------------------------------------------------------
-- Íîâûå ôóíêöèè òðàíñôåðà ïðåäìåòîâ â äèàëîãàõ!!!
----------------------------------------------------------------------------------
function relocate_item_section_to_actor(first_speaker, second_speaker, section, amount)
-- Ñíà÷àëà âûÿñíèì êòî èç íèõ àêòåð
local npc = who_is_npc(first_speaker, second_speaker)
local v = 0
--' Òðàíñôåðèòü íóæíî òîëüêî êâåñòîâûå ïðåäìåòû.
if not amount then
amount = 1
end
local function transfer_object_item(temp, item)
--printf("item:section(): [%s]", item:section())
if (item:section() == section and v ~= 0) then
npc:transfer_item(item, db.actor)
v = v - 1
end
end
if amount > 1 then
v = amount
npc:iterate_inventory(transfer_object_item, nil)
else
if npc:object(section) ~= nil then
npc:transfer_item(npc:object(section), db.actor)
else
alife():create(section,
db.actor:position(),
db.actor:level_vertex_id(),
db.actor:game_vertex_id(),
db.actor:id())
end
end
if v ~= 0 then
for i = 1, v do
alife():create(section,
db.actor:position(),
db.actor:level_vertex_id(),
db.actor:game_vertex_id(),
db.actor:id())
end
end
if death_manager.ammo_sections[section] == true then
local ltx = system_ini()
local box_size = ltx:r_s32(section, "box_size")
amount = amount * box_size
end
news_manager.relocate_item(db.actor, "in", section, amount)
end
function relocate_money_to_actor(first_speaker, second_speaker, num)
db.actor:give_money(num)
game_stats.money_quest_update (num)
news_manager.relocate_money(db.actor, "in", num)
end
function relocate_money_from_actor(first_speaker, second_speaker, num)
local victim = who_is_npc(first_speaker, second_speaker)
if victim == nil then
abort("Couldn't relocate money to NULL")
end
db.actor:transfer_money(num, victim)
game_stats.money_quest_update(-num)
news_manager.relocate_money(db.actor, "out", num)
end
--[[ Old one
function relocate_item_section_from_actor(first_speaker, second_speaker, section)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:transfer_item(db.actor:object(section), npc)
news_manager.relocate_item(db.actor, "out", section)
end
]]--
function who_is_actor(first_speaker, second_speaker)
local npc = second_speaker
if db.actor:id() ~= npc:id() then
npc = first_speaker
end
return npc
end
--section - Èìÿ ñåêöèè äëÿ ïåðåäà÷è; amount - êîëè÷åñòâî, òàêæå ïðèíèìàåò ñòðèíã "all"
function relocate_item_section_from_actor(first_speaker, second_speaker, section, amount)
local npc = who_is_npc(first_speaker, second_speaker)
local actor = who_is_actor(first_speaker, second_speaker)
local i = 0
--printf("Amount [%s]", tostring(amount))
if not amount then
amount = 1
end
local function transfer_object_item(temp, item)
--printf("item:section(): [%s]", item:section())
if (item:section() == section and i ~= 0) then
db.actor:transfer_item(item, npc)
i = i - 1
end
end
if amount == "all" then
i = -1
actor:iterate_inventory(transfer_object_item, nil)
amount = (i+1)*(-1)
i = 0
elseif amount > 1 then
i = amount
actor:iterate_inventory(transfer_object_item, nil)
elseif amount < 1 then
abort("Wrong parameters in function 'relocate_item_section_from_actor'!")
else
actor:transfer_item(actor:object(section), npc)
end
if i~=0 then
assert("Actor do not has enough items! Transferred [%s], needed [%s]", tostring(amount - i), tostring(amount))
end
if death_manager.ammo_sections[db.actor.section] == true then
local ltx = system_ini()
local box_size = ltx:r_s32(section, "box_size")
amount = amount * box_size
end
news_manager.relocate_item(db.actor, "out", section, amount - i)
end
function actor_has_item(first_speaker, second_speaker, section)
return db.actor:object(section) ~= nil
end
function npc_has_item(first_speaker, second_speaker, section)
local npc = who_is_npc(first_speaker, second_speaker)
return npc:object(section) ~= nil
end
function who_is_npc(first_speaker, second_speaker)
local npc = second_speaker
if db.actor:id() == npc:id() then
npc = first_speaker
end
return npc
end
--------------------------------------------------------------------------------
function transfer_any_pistol_from_actor(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_pistol, npc)
if(db.actor.pistol~=nil) then
db.actor:transfer_item(db.actor:object(db.actor.pistol), npc)
news_manager.relocate_item(db.actor, "out", db.actor.pistol)
db.actor.pistol = nil
end
end
function is_pistol(npc, item)
local section = item:section()
if(section=="wpn_beretta")
or(section=="wpn_colt1911")
or(section=="wpn_desert_eagle")
or(section=="wpn_fort")
or(section=="wpn_hpsa")
or(section=="wpn_pb")
or(section=="wpn_pm")
or(section=="wpn_usp")
or(section=="wpn_walther") then
db.actor.pistol = section
end
end
function have_actor_any_pistol(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_pistol, npc)
if(db.actor.pistol~=nil) then
return true
else
return false
end
end
--------------------------------------------------------------------------------
function transfer_any_gun_from_actor(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_gun, npc)
if(db.actor.gun~=nil) then
db.actor:transfer_item(db.actor:object(db.actor.gun), npc)
news_manager.relocate_item(db.actor, "out", db.actor.gun)
db.actor.gun = nil
end
end
function is_gun(npc, item)
local section = item:section()
if(section=="wpn_abakan")
or(section=="wpn_ak74")
or(section=="wpn_ak74u")
or(section=="wpn_groza")
or(section=="wpn_sig550")
or(section=="wpn_vintorez") then
db.actor.gun = section
end
end
function have_actor_any_gun(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_gun, npc)
if(db.actor.gun~=nil) then
return true
else
return false
end
end
--------------------------------------------------------------------------------
function transfer_any_shootgun_from_actor(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_shootgun, npc)
if(db.actor.shootgun~=nil) then
db.actor:transfer_item(db.actor:object(db.actor.shootgun), npc)
news_manager.relocate_item(db.actor, "out", db.actor.shootgun)
db.actor.shootgun = nil
end
end
function is_shootgun(npc, item)
local section = item:section()
if(section=="wpn_bm16")
or(section=="wpn_toz34")
or(section=="wpn_wincheaster1300")
or(section=="wpn_spas12") then
db.actor.shootgun = section
end
end
function have_actor_any_shootgun(first_speaker, second_speaker)
local npc = who_is_npc(first_speaker, second_speaker)
db.actor:iterate_inventory(is_shootgun, npc)
if(db.actor.shootgun~=nil) then
return true
else
return false
end
end
--------------------------------------------------------------------------------
-- ALIFE SUPPORT
--------------------------------------------------------------------------------
function disable_ui(first_speaker, second_speaker)
xr_effects.disable_ui(first_speaker, second_speaker)
end
function disable_ui_only(first_speaker, second_speaker)
xr_effects.disable_ui_only(first_speaker, second_speaker)
end
function is_surge_running(first_speaker, second_speaker)
return surge_manager.get_surge_manager().started == true
end
function is_surge_not_running(first_speaker, second_speaker)
return surge_manager.get_surge_manager().finished == true
end
---------------------
function quest_dialog_heli_precond(first_speaker, second_speaker)
if (has_alife_info("jup_b9_heli_1_searched") and
has_alife_info("zat_b100_heli_2_searched") and
has_alife_info("zat_b28_heli_3_searched") and
has_alife_info("jup_b8_heli_4_searched") and
has_alife_info("zat_b101_heli_5_searched")) or
has_alife_info("pri_b305_actor_wondered_done") then
return false
end
return true
end
function quest_dialog_military_precond(first_speaker, second_speaker)
if has_alife_info("zat_b28_heli_3_searched") or has_alife_info("jup_b9_blackbox_decrypted") then
if not (has_alife_info("zat_b28_heli_3_searched") and has_alife_info("jup_b9_blackbox_decrypted")) then
return true
end
end
return false
end
function quest_dialog_squad_precond(first_speaker, second_speaker)
return not (has_alife_info("jup_b218_monolith_hired") and has_alife_info("jup_b218_soldier_hired") and has_alife_info("jup_a10_vano_agree_go_und"))
end
function quest_dialog_toolkits_precond(first_speaker, second_speaker)
if has_alife_info("zat_a2_mechanic_toolkit_search") and not has_alife_info("zat_b3_task_end") then
return true
elseif has_alife_info("jup_b217_tech_instruments_start") and not has_alife_info("jup_b217_task_end") then
return true
end
return false
end
function squad_not_in_smart_b101(first_speaker, second_speaker)
local smart = "zat_b101"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b103(first_speaker, second_speaker)
local smart = "zat_b103"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b104(first_speaker, second_speaker)
local smart = "zat_b104"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b213(first_speaker, second_speaker)
local smart = "jup_b213"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b214(first_speaker, second_speaker)
local smart = "jup_b214"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b304(first_speaker, second_speaker)
local smart = "pri_b304_monsters_smart_terrain"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b303(first_speaker, second_speaker)
local smart = "pri_b303"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b40(first_speaker, second_speaker)
local smart = "zat_b40_smart_terrain"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b18(first_speaker, second_speaker)
local smart = "zat_b18"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b6(first_speaker, second_speaker)
local smart = "jup_b41"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b205(first_speaker, second_speaker)
local smart = "jup_b205_smart_terrain"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_not_in_smart_b47(first_speaker, second_speaker)
local smart = "jup_b47"
return not is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_in_smart_zat_base(first_speaker, second_speaker)
local smart = "zat_stalker_base_smart"
return is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function squad_in_smart_jup_b25(first_speaker, second_speaker)
local smart = "jup_a6"
return is_npc_in_current_smart(first_speaker, second_speaker, smart)
end
function spartak_is_alive(first_speaker, second_speaker)
return xr_conditions.is_alive(nil,nil,{"zat_b7_stalker_victim_1"})
end
function tesak_is_alive(first_speaker, second_speaker)
return xr_conditions.is_alive(nil,nil,{"zat_b103_lost_merc_leader"})
end
function gonta_is_alive(first_speaker, second_speaker)
return xr_conditions.is_alive(nil,nil,{"zat_b103_lost_merc_leader"})
end
function mityay_is_alive(first_speaker, second_speaker)
return xr_conditions.is_alive(nil,nil,{"jup_a12_stalker_assaulter"})
end
function dolg_can_work_for_sci(first_speaker, second_speaker)
return not (has_alife_info("jup_a6_freedom_leader_bunker_guards_work") or has_alife_info("jup_a6_freedom_leader_bunker_scan_work"))
end
function dolg_can_not_work_for_sci(first_speaker, second_speaker)
return has_alife_info("jup_a6_freedom_leader_bunker_guards_work") or has_alife_info("jup_a6_freedom_leader_bunker_scan_work")
end
function freedom_can_work_for_sci(first_speaker, second_speaker)
return not (has_alife_info("jup_a6_duty_leader_bunker_guards_work") or has_alife_info("jup_a6_duty_leader_bunker_scan_work"))
end
function freedom_can_not_work_for_sci(first_speaker, second_speaker)
return has_alife_info("jup_a6_duty_leader_bunker_guards_work") or has_alife_info("jup_a6_duty_leader_bunker_scan_work")
end
function monolith_leader_is_alive(first_speaker, second_speaker)
if not (has_alife_info("jup_b4_monolith_squad_in_freedom") or has_alife_info("jup_b4_monolith_squad_in_duty")) then
return xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_monolith_skin"})
end
if has_alife_info("jup_b4_monolith_squad_in_freedom") then
return xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_freedom_skin"})
elseif has_alife_info("jup_b4_monolith_squad_in_duty") then
return xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_duty_skin"})
end
return false
end
function monolith_leader_dead_or_hired(first_speaker, second_speaker)
if has_alife_info("jup_b218_soldier_hired") then
return true
end
if not (has_alife_info("jup_b4_monolith_squad_in_freedom") or has_alife_info("jup_b4_monolith_squad_in_duty")) then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_monolith_skin"})
end
if has_alife_info("jup_b4_monolith_squad_in_freedom") then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_freedom_skin"})
elseif has_alife_info("jup_b4_monolith_squad_in_duty") then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_duty_skin"})
end
return true
end
function monolith_leader_dead_or_dolg(first_speaker, second_speaker)
if has_alife_info("jup_b218_soldier_hired") then
return true
end
if not (has_alife_info("jup_b4_monolith_squad_in_freedom") or has_alife_info("jup_b4_monolith_squad_in_duty")) then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_monolith_skin"})
end
if has_alife_info("jup_b4_monolith_squad_in_freedom") then
return true
elseif has_alife_info("jup_b4_monolith_squad_in_duty") then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_duty_skin"})
end
return true
end
function monolith_leader_dead_or_freedom(first_speaker, second_speaker)
if has_alife_info("jup_b218_soldier_hired") then
return true
end
if not (has_alife_info("jup_b4_monolith_squad_in_freedom") or has_alife_info("jup_b4_monolith_squad_in_duty")) then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_monolith_skin"})
end
if has_alife_info("jup_b4_monolith_squad_in_freedom") then
return not xr_conditions.is_alive(nil,nil,{"jup_b4_monolith_squad_leader_freedom_skin"})
elseif has_alife_info("jup_b4_monolith_squad_in_duty") then
return true
end
return true
end
-- Medic support
function medic_magic_potion(first_speaker, second_speaker)
db.actor.health = 1
db.actor.power = 1
db.actor.radiation = -1
db.actor.bleeding = 1
end
function actor_needs_bless(first_speaker, second_speaker)
if db.actor.health < 1 or
db.actor.radiation > 0 or
db.actor.bleeding > 0 then
return true
end
return false
end
function actor_is_damn_healthy(first_speaker, second_speaker)
return not actor_needs_bless(first_speaker, second_speaker)
end
function leave_zone_save(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_zone_to_reality"})
end
function save_uni_travel_zat_to_jup(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_zat_to_jup"})
end
function save_uni_travel_zat_to_pri(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_zat_to_pri"})
end
function save_uni_travel_jup_to_zat(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_jup_to_zat"})
end
function save_uni_travel_jup_to_pri(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_jup_to_pri"})
end
function save_uni_travel_pri_to_zat(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_pri_to_zat"})
end
function save_uni_travel_pri_to_jup(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_uni_travel_pri_to_jup"})
end
function save_jup_b218_travel_jup_to_pas(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_jup_b218_travel_jup_to_pas"})
end
function save_pri_a17_hospital_start(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_pri_a17_hospital_start"})
end
function save_jup_a10_gonna_return_debt(first_speaker, second_speaker)
if not has_alife_info("jup_a10_avtosave") then
xr_effects.scenario_autosave(db.actor,nil,{"st_save_jup_a10_gonna_return_debt"})
db.actor:give_info_portion("jup_a10_avtosave")
end
end
function save_jup_b6_arrived_to_fen(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_jup_b6_arrived_to_fen"})
end
function save_jup_b6_arrived_to_ash_heap(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_jup_b6_arrived_to_ash_heap"})
end
function save_jup_b19_arrived_to_kopachy(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_jup_b19_arrived_to_kopachy"})
end
function save_zat_b106_arrived_to_chimera_lair(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_zat_b106_arrived_to_chimera_lair"})
end
function save_zat_b5_met_with_others(first_speaker, second_speaker)
xr_effects.scenario_autosave(db.actor,nil,{"st_save_zat_b5_met_with_others"})
end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,244 @@
function pri_b301_zulus_reward(first_speaker, second_speaker)
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "wpn_pkm_zulus")
end
function pri_a17_reward(first_speaker, second_speaker)
if has_alife_info("pri_a17_reward_well") then
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 7500)
elseif has_alife_info("pri_a17_reward_norm") then
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 4000)
elseif has_alife_info("pri_a17_reward_bad") then
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 3000)
end
end
function actor_has_pri_a17_gauss_rifle(first_speaker, second_speaker)
return db.actor:object("pri_a17_gauss_rifle") ~= nil
end
function actor_hasnt_pri_a17_gauss_rifle(first_speaker, second_speaker)
return not actor_has_pri_a17_gauss_rifle(first_speaker, second_speaker)
end
-- ïåðåäà÷à àðòåôàêòà èãðîêó îò ïðîâîäíèêà â ïàìÿòü î âûïîëíåííîì çàäàíèèÿ íà Þïèòåðå
function transfer_artifact_af_baloon(first_speaker, second_speaker)
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_baloon")
end
-- ïëàòà çà òåëåïîðò èãðîêà íà Çàòîí ÷åðåç Þïèòåð (äèàëîã ñ ïðîâîäíèêîì ñ Þïèòåðà)
function pay_cost_to_guide_to_zaton(first_speaker, second_speaker)
if has_alife_info("zat_b215_gave_maps") then
dialogs.relocate_money_from_actor(first_speaker, second_speaker, 1000)
else
dialogs.relocate_money_from_actor(first_speaker, second_speaker, 3000)
end
end
-- ïðîâåðêà, ïëàòåæåñïîñîáíîñòè èãðîêà çà òåëåïîðò íà Çàòîí ÷åðåç Þïèòåð
function jup_b43_actor_has_10000_money(first_speaker, second_speaker)
if has_alife_info("zat_b215_gave_maps") then
return db.actor:money() >= 3000
end
return db.actor:money() >= 5000
end
function jup_b43_actor_do_not_has_10000_money(first_speaker, second_speaker)
return not jup_b43_actor_has_10000_money(first_speaker, second_speaker)
end
-- ïëàòà çà òåëåïîðò èãðîêà íà Þïèòåð (äèàëîã ñ ïðîâîäíèêîì ñ Þïèòåðà)
function pay_cost_to_guide_to_jupiter(first_speaker, second_speaker)
dialogs.relocate_money_from_actor(first_speaker, second_speaker, 7000)
end
-- ïðîâåðêà ïëàòåæåñïîñîáíîñòè èãðîêà çà òåëåïîðò íà Þïèòåð
function jup_b43_actor_has_7000_money(first_speaker, second_speaker)
return db.actor:money() >= 7000
end
function jup_b43_actor_do_not_has_7000_money(first_speaker, second_speaker)
return db.actor:money() < 7000
end
-- Pripyat B35
function pri_b35_transfer_svd(first_speaker, second_speaker)
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "wpn_svd")
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "ammo_7.62x54_7h1")
end
function pri_b35_give_actor_reward(first_speaker, second_speaker)
local amount = 1
if has_alife_info("pri_b35_secondary") then amount = 3 end
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "ammo_7.62x54_7h1", amount)
end
-- Medic support
local medic_items_table = {
["basic"] = {
["conserva"] = 2,
["medkit_army"] = 2,
["antirad"] = 2,
["bandage"] = 4,
},
["advanced"] = {
["conserva"] = 3,
["medkit_army"] = 3,
["antirad"] = 3,
["bandage"] = 5,
},
["elite"] = {
["conserva"] = 4,
["medkit_army"] = 5,
["antirad"] = 5,
["bandage"] = 8,
},
}
function pri_a25_medic_give_kit(first_speaker, second_speaker)
local kit = "basic"
if has_alife_info("pri_a25_actor_needs_medikit_advanced_supply") then
kit = "advanced"
elseif has_alife_info("pri_a25_actor_needs_medikit_elite_supply") then
kit = "elite"
end
for k,v in pairs(medic_items_table) do
if k == kit then
for kk,vv in pairs(v) do
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, kk, vv)
end
disable_info(k)
end
end
end
local supp_table = {
["supply_ammo_1"] = {["ammo_9x18_fmj"] = 2, ["ammo_9x18_pmm"] = 1},
["supply_ammo_2"] = {["ammo_9x19_fmj"] = 2, ["ammo_9x19_pbp"] = 1},
["supply_ammo_3"] = {["ammo_11.43x23_fmj"] = 2, ["ammo_11.43x23_hydro"] = 1},
["supply_ammo_4"] = {["ammo_12x70_buck"] = 10, ["ammo_12x76_zhekan"] = 5},
["supply_ammo_5"] = {["ammo_5.45x39_fmj"] = 2, ["ammo_5.45x39_ap"] = 1},
["supply_ammo_6"] = {["ammo_5.56x45_ss190"] = 2, ["ammo_5.56x45_ap"] = 1},
["supply_ammo_7"] = {["ammo_9x39_pab9"] = 1, ["ammo_9x39_ap"] = 1},
["supply_ammo_8"] = {["ammo_7.62x54_7h1"] = 1},
["supply_ammo_9"] = {["ammo_pkm_100"] = 1},
["supply_grenade_1"] = {["grenade_rgd5"] = 3, ["grenade_f1"] = 2},
["supply_grenade_2"] = {["ammo_vog-25"] = 3},
["supply_grenade_3"] = {["ammo_m209"] = 3},
}
function pri_a22_army_signaller_supply(first_speaker, second_speaker)
for k,v in pairs(supp_table) do
if has_alife_info(k) then
for kk,vv in pairs(v) do
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, kk, vv)
end
disable_info(k)
end
end
end
function pri_a22_give_actor_outfit (first_speaker, second_speaker)
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "military_outfit")
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "helm_battle")
end
-- Pripyat B305
function pri_b305_actor_has_strelok_notes(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_01") ~= nil
or db.actor:object("jup_b10_notes_02") ~= nil
or db.actor:object("jup_b10_notes_03") ~= nil
end
function pri_b305_actor_has_strelok_note_1(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_01") ~= nil
and db.actor:object("jup_b10_notes_02") == nil
and db.actor:object("jup_b10_notes_03") == nil
end
function pri_b305_actor_has_strelok_note_2(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_02") ~= nil
and db.actor:object("jup_b10_notes_01") == nil
and db.actor:object("jup_b10_notes_03") == nil
end
function pri_b305_actor_has_strelok_note_3(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_03") ~= nil
and db.actor:object("jup_b10_notes_01") == nil
and db.actor:object("jup_b10_notes_02") == nil
end
function pri_b305_actor_has_strelok_note_12(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_01") ~= nil
and db.actor:object("jup_b10_notes_02") ~= nil
and db.actor:object("jup_b10_notes_03") == nil
end
function pri_b305_actor_has_strelok_note_13(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_01") ~= nil
and db.actor:object("jup_b10_notes_03") ~= nil
and db.actor:object("jup_b10_notes_02") == nil
end
function pri_b305_actor_has_strelok_note_23(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_02") ~= nil
and db.actor:object("jup_b10_notes_03") ~= nil
and db.actor:object("jup_b10_notes_01") == nil
end
function pri_b305_actor_has_strelok_note_all(first_speaker, second_speaker)
return db.actor:object("jup_b10_notes_01") ~= nil
and db.actor:object("jup_b10_notes_02") ~= nil
and db.actor:object("jup_b10_notes_03") ~= nil
end
function pri_b305_sell_strelok_notes(first_speaker, second_speaker)
local amount = 0
local items_table = {
"jup_b10_notes_01",
"jup_b10_notes_02",
"jup_b10_notes_03",
}
for k,v in pairs(items_table) do
if db.actor:object(v) ~= nil then
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, v)
amount = amount + 1
end
end
if db.actor:object("wpn_gauss") ~= nil then
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "ammo_gauss", 2)
else
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "medkit_scientic", 3)
end
if amount > 1 then
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_fire")
end
if amount > 2 then
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_glass")
db.actor:give_info_portion("pri_b305_all_strelok_notes_given")
end
end
function pri_a17_sokolov_is_not_at_base(first_speaker, second_speaker)
if has_alife_info("pri_a15_sokolov_out") and has_alife_info("pas_b400_sokolov_dead") then
return true
-- elseif has_alife_info("pri_a16_sokolov_on_pripyat") and not xr_conditions.squad_exist(nil,nil, {"pri_a16_sokolov_squad"}) then
-- return true
end
return false
end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
function register(object_factory)
end
function get_game_clsid(game_type_option,is_server)
if(is_server==true) then
if(game_type_option == "single") then
return "SV_SINGL" end
if(game_type_option == "deathmatch") then
return "SV_DM" end
if(game_type_option == "teamdeathmatch") then
return "SV_TDM" end
if(game_type_option == "artefacthunt") then
return "SV_AHUNT" end
if(game_type_option == "capturetheartefact") then
return "SV_CTA" end
end
if(is_server==false) then
if(game_type_option == "single") then
return "CL_SINGL" end
if(game_type_option == "deathmatch") then
return "CL_DM" end
if(game_type_option == "teamdeathmatch") then
return "CL_TDM" end
if(game_type_option == "artefacthunt") then
return "CL_AHUNT" end
if(game_type_option == "capturetheartefact") then
return "CL_CTA" end
end
return ""
end

View file

@ -0,0 +1,344 @@
-- îòíîøåíèå ïåðñîíàæà ê àêòåðó (èëè äðóãîìó NPC) âû÷èñëÿåòñÿ ïî ôîðìóëå:
-- attitude = personal_goodwill + -- ëè÷íîå îòíîøåíèå ïåðñîíàæà ê àêòåðó (åñëè ðàíüøå íå âñòðå÷àëèñü, òî 0)
-- community_goodwill + -- îòíîøåíèå ãðóïïèðîâêè ïåðñîíàæà ëè÷íî ê àêòåðó (åñëè ðàíüøå êîíòàêòîâ íå áûëî, òî 0)
-- community_to_community + -- îòíîøåíèå ãðóïïèðîâêè ïåðñîíàæà ê ãðóïïèðîâêå àêòåðà èç [communities_relations]
-- reputation_goodwill + -- îòíîøåíèå ðåïóòàöèè ïåðñîíàæà ê ðåïóòàöèè àêòåðà èç [reputation_relations]
-- rank_goodwill -- îòíîøåíèå ðàíãà ïåðñîíàæà ê ðàíãó àêòåðà èç [rank_relations]
FRIENDS = 1000
NEUTRALS = 0
ENEMIES = -1000
default_sympathy = 0.01
game_relations_by_num = { [0] = "friend",
[1] = "neutral",
[2] = "enemy",
}
temp_goodwill_table = {}
function set_factions_community(faction, faction_to, new_community)
if(faction~=nil) and (faction~="none") and (faction_to~="none") then
local community = 0
if(new_community=="enemy") then
community = -5000
elseif(new_community=="friend") then
community = 5000
end
set_factions_community_num(faction, faction_to, community)
else
--printf("No such faction community: "..tostring(faction))
end
end
function set_factions_community_num(faction, faction_to, new_community_num)
if(faction~=nil) and (faction~="none") and (faction_to~="none") then
relation_registry.set_community_relation(faction, faction_to, new_community_num)
else
--printf("No such faction community: "..tostring(faction))
end
end
function change_factions_community_num(faction_name, obj_id, delta)
if(faction_name~=nil) and (faction_name~="none") and (obj_id ~= nil) then
relation_registry.change_community_goodwill(faction_name, obj_id, delta)
else
printf("No such faction community: "..tostring(faction))
end
end
function get_factions_community(faction, faction_to)
if(faction~=nil) and (faction~="none") and (faction_to~="none") then
return relation_registry.community_relation(faction, faction_to)
else
--printf("No such faction community: "..tostring(faction))
return nil
end
end
function is_factions_friends(faction, faction_to)
if(faction~=nil) and (faction~="none") and (faction_to~="none") then
return relation_registry.community_relation(faction, faction_to)>=FRIENDS
else
--printf("No such faction community: "..tostring(faction))
return false
end
end
function is_factions_enemies(faction, faction_to)
if(faction~=nil) and (faction~="none") and (faction_to~="none") then
return relation_registry.community_relation(faction, faction_to)<=ENEMIES
else
--printf("No such faction community: "..tostring(faction))
return false
end
end
function get_npcs_relation(npc1, npc2)
return npc1 and npc2 and npc1:relation(npc2)
end
function set_npcs_relation(npc1, npc2, new_relation)
local goodwill = 0
if(new_relation=="enemy") then
goodwill = -1000
elseif(new_relation=="friend") then
goodwill = 1000
end
if npc1 and npc2 then
npc1:force_set_goodwill(goodwill, npc2)
else
abort("Npc not set in goodwill function!!!")
end
end
function get_npc_sympathy(npc)
return npc:sympathy()
end
function set_npc_sympathy(npc, new_sympathy)
if(new_sympathy<0) then
new_sympathy = 0
elseif(new_sympathy>1) then
new_sympathy = 1
end
if npc then
npc:set_sympathy(new_sympathy)
else
abort("Npc not set in sympathy function!!!")
end
end
function set_squad_goodwill(squad_id, new_goodwill)
printf("Applying new game relation [%s] between squad [%s] and npc [%s] !", new_goodwill, squad_id, "actor")
local squad = get_story_squad(squad_id)
if squad == nil then
if type(squad_id) == "string" then
printf("there is no story squad with id [%s]", squad_id)
return
else
squad = alife():object(squad_id)
end
end
if squad then
squad:set_squad_relation(new_goodwill)
else
abort("There is no squad [%s] in sim_board", squad_id)
end
end
function set_squad_goodwill_to_npc(npc, squad_id, new_goodwill)
printf("Applying new game relation [%s] between squad [%s] and npc [%s] !", new_goodwill, squad_id, npc:name())
local goodwill = 0
if(new_goodwill=="enemy") then
goodwill = -1000
elseif(new_goodwill=="friend") then
goodwill = 1000
end
local squad = get_story_squad(squad_id)
if squad == nil then
if type(squad_id) == "string" then
printf("there is no story squad with id [%s]", squad_id)
return
else
squad = alife():object(squad_id)
end
end
if squad then
for k in squad:squad_members() do
if npc then
k.object:force_set_goodwill(goodwill, npc:id())
alife():object(npc:id()):force_set_goodwill(goodwill, k.id)
end
end
else
abort("There is no squad [%s] in sim_board", squad_id)
end
end
function set_squad_community_goodwill(squad_id, community, new_goodwill)
local goodwill = 0
if(new_goodwill=="enemy") then
goodwill = -1000
elseif(new_goodwill=="friend") then
goodwill = 1000
end
local squad = get_story_squad(squad_id)
if squad == nil then
if type(squad_id) == "string" then
printf("there is no story squad with id [%s]", squad_id)
return
else
squad = alife():object(squad_id)
end
end
if squad then
for k in squad:squad_members() do
local obj = db.storage[k.id] and db.storage[k.id].object
if(obj) then
obj:set_community_goodwill(community, goodwill)
end
end
else
abort("There is no squad [%s] in sim_board", squad_id)
end
end
function set_level_faction_community(obj)
if(temp_goodwill_table.communities~=nil) then
for k,v in pairs(temp_goodwill_table.communities) do
if(character_community(obj)==k) then
for kk,vv in pairs(v) do
if(kk==obj:id()) and db.actor then
relation_registry.set_community_goodwill(k, db.actor:id(), vv)
-- run_string xr_effects.set_level_faction_community(nil, nil, {"bandit", "peacemaker_selo", "friend"})
obj:force_set_goodwill(vv, db.actor)
v[kk] = nil
end
end
end
end
end
end
function check_all_squad_members(squad_name, goodwill)
local squad = get_story_squad(squad_name)
if squad == nil then return false end
if db.actor == nil then return false end
for k in squad:squad_members() do
local is_enemy
if goodwill == "enemy" then
--printf("npc id = [%s]", k)
-- if (db.storage[k] ~= nil) and (db.storage[k].object ~= nil) then
-- printf("goodwill is [%s]", tostring(db.storage[k].object:general_goodwill(db.actor)))
--end
is_enemy = db.storage[k.id] and db.storage[k.id].object and db.storage[k.id].object:general_goodwill(db.actor)<=ENEMIES
else
is_enemy = db.storage[k.id] and db.storage[k.id].object and db.storage[k.id].object:general_goodwill(db.actor)>=FRIENDS
end
if is_enemy then
return true
end
end
return false
end
function get_squad_goodwill_to_actor_by_id(squad_id)
local squad = alife():object(squad_id)
if(squad==nil) then
abort("No such squad %s in board", tostring(squad_id))
return false
end
if(squad.relationship~=nil) then
--printf(" squad_relation %s", tostring(squad.relationship))
return squad.relationship
else
local goodwill = "neutral"
if(relation_registry.community_relation(squad:get_squad_community(), alife():actor():community())>=FRIENDS) then
goodwill = "friend"
elseif(relation_registry.community_relation(squad:get_squad_community(), alife():actor():community())<=ENEMIES) then
goodwill = "enemy"
end
return goodwill
end
end
function get_squad_goodwill_to_actor(squad_name)
local squad = get_story_squad(squad_name)
if(squad==nil) then
abort("No such squad %s in board", tostring(squad_name))
return false
end
if(squad.relationship~=nil) then
--printf(" squad_relation %s", tostring(squad.relationship))
return squad.relationship
else
local goodwill = "neutral"
if(relation_registry.community_relation(squad:get_squad_community(), alife():actor():community())>=FRIENDS) then
goodwill = "friend"
elseif(relation_registry.community_relation(squad:get_squad_community(), alife():actor():community())<=ENEMIES) then
goodwill = "enemy"
end
return goodwill
end
end
function is_squad_enemy_to_actor(squad_name)
return get_squad_goodwill_to_actor(squad_name)=="enemy"
end
function is_squad_friend_to_actor(squad_name)
return get_squad_goodwill_to_actor(squad_name)=="friend"
end
function is_squad_neutral_to_actor(squad_name)
return get_squad_goodwill_to_actor(squad_name)=="neutral"
end
function set_gulag_relation_actor(smart_name, relation)
local gulag = xr_gulag.get_gulag_by_name(smart_name)
local goodwill = 0
if(relation=="enemy") then
goodwill = -1000
elseif(relation=="friend") then
goodwill = 1000
end
for k,v in pairs(gulag.npc_info) do
local object = db.storage[v.se_obj.id] and db.storage[v.se_obj.id].object
if(object) then
object:force_set_goodwill(goodwill, db.actor)
object:set_community_goodwill(character_community(db.actor), goodwill)
end
end
end
function get_gulag_relation_actor(smart_name, relation)
local gulag = xr_gulag.get_gulag_by_name(smart_name)
if gulag then
local goodwill = 0
local npc_count = 0
for k,v in pairs(gulag.npc_info) do
local object = db.storage[v.se_obj.id] and db.storage[v.se_obj.id].object
if object and db.actor then
goodwill = goodwill + object:general_goodwill(db.actor)
npc_count = npc_count + 1
end
end
if npc_count ~= 0 then
local delta = goodwill/npc_count
if relation == "enemy" and delta <= ENEMIES then
return true
elseif relation == "friend" and delta >= FRIENDS then
return true
elseif relation == "neutral" and delta < FRIENDS and delta > ENEMIES then
return true
end
end
end
return false
end
function get_squad_relation_to_actor_by_id(squad_id)
local squad = alife():object(squad_id)
if(squad==nil) then
abort("No such squad %s in board", tostring(squad_id))
end
local goodwill = 0
local npc_count = 0
for k in squad:squad_members() do
local object = db.storage[k.id] and db.storage[k.id].object
if object and db.actor then
goodwill = goodwill + object:general_goodwill(db.actor)
npc_count = npc_count + 1
end
end
if npc_count ~= 0 then
local delta = goodwill/npc_count
if delta <= ENEMIES then
return "enemy"
elseif delta >= FRIENDS then
return "friends"
elseif delta < FRIENDS and delta > ENEMIES then
return "neutral"
end
end
return "enemy"
end

View file

@ -0,0 +1,134 @@
----------------------------------------------------------
local old_time = 0 --need for update filter
local stats = {} --information table
local filter_time = 1000 --filter time
local additional_time = 0
--constants
local actor_position = 0
local actor_item_drop = 1
local actor_item_take = 2
local actor_item_use = 3
local actor_update_task = 4
local actor_money_trade = 5
local actor_money_quest = 6
local actor_money_total = 7
----------------------------------------------------------
function initialize ()
stats = {}
end
----------------------------------------------------------
function shutdown ()
printf ("GAME STATS START AT LEVEL [%s]", level.name ())
local l_name = level.name ()
for a = 1, #stats, 1 do
if stats[a].id == actor_position then
printf ("[stats][%s][%s][%d][%f,%f,%f][%f, %f, %f]", l_name, stats[a].time, stats[a].id, stats[a].position.x, stats[a].position.y, stats[a].position.z, stats[a].health, stats[a].radiation, stats[a].satiety)
elseif stats[a].id == actor_item_take then
printf ("[stats][%s][%s][%d][%f,%f,%f][%s]", l_name, stats[a].time, stats[a].id, stats[a].position.x, stats[a].position.y, stats[a].position.z, stats[a].item_name)
elseif stats[a].id == actor_item_drop then
printf ("[stats][%s][%s][%d][%f,%f,%f][%s]", l_name, stats[a].time, stats[a].id, stats[a].position.x, stats[a].position.y, stats[a].position.z, stats[a].item_name)
elseif stats[a].id == actor_money_trade or stats[a].id == actor_money_quest or stats[a].id == actor_money_total then
printf ("[stats][%s][%s][%d][%f,%f,%f][%d]", l_name, stats[a].time, stats[a].id, stats[a].position.x, stats[a].position.y, stats[a].position.z, stats[a].money)
end
end
stats = {}
end
----------------------------------------------------------
function update (delta, actor)
additional_time = additional_time + delta
if additional_time < filter_time then
return
end
additional_time = 0
local t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_position,
position = actor:position (),
health = actor.health,
radiation = actor.radiation,
satiety = actor.satiety
}
table.insert (stats, t)
end
----------------------------------------------------------
function update_task (id_task, subtask, id_state, actor)
local state
if subtask == 0 then
if id_state == task.fail then
state = "fail"
elseif id_state == task.completed then
state = "complete"
else
state = "new"
end
else
state = "update"
end
local t =
{
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_update_task,
position = actor:position (),
task = string.format ("%s, %s, %s", id_task, subtask, state)
}
table.insert (stats, t)
end
----------------------------------------------------------
function update_take_item (object, actor)
local t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_item_take,
position = actor:position (),
item_name = object:name ()
}
table.insert (stats, t)
end
----------------------------------------------------------
function update_drop_item (object, actor)
local t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_item_drop,
position = db.actor:position (),
item_name = object:name ()
}
table.insert (stats, t)
end
----------------------------------------------------------
function money_trade_update (money_i)
local t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_money_trade,
position = db.actor:position (),
money = money_i
}
table.insert (stats, t)
t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_money_total,
position = db.actor:position (),
money = db.actor:money ()
}
table.insert (stats, t)
end
----------------------------------------------------------
function money_quest_update (money_i)
local t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_money_quest,
position = db.actor:position (),
money = money_i
}
table.insert (stats, t)
t = {
time = game.get_game_time ():timeToString (game.CTime.TimeToSeconds),
id = actor_money_total,
position = db.actor:position (),
money = db.actor:money ()
}
table.insert (stats, t)
end
----------------------------------------------------------

View file

@ -0,0 +1,26 @@
game_types={
--s.t.a.l.k.e.r internal types, do not change
eGameIDNoGame = 0,
eGameIDSingle = 1, --u32(1) << 0,
eGameIDDeathmatch = 2, --u32(1) << 1,
eGameIDTeamDeathmatch = 4, --u32(1) << 2,
eGameIDArtefactHunt = 8, --u32(1) << 3,
eGameIDCaptureTheArtefact = 16, --u32(1) << 4,
eGameIDDominationZone = 32, --u32(1) << 5,
eGameIDTeamDominationZone = 64, --u32(1) << 6,
--backward compatibility
GAME_ANY = 0,
GAME_SINGLE = 1,
GAME_DEATHMATCH = 2,
GAME_CTF = 3,
GAME_ASSAULT = 4,
GAME_CS = 5,
GAME_TEAMDEATHMATCH = 6,
GAME_ARTEFACTHUNT = 7,
--script game types
GAME_LASTSTANDING = 100,
GAME_DUMMY = 255 --max(unsigned8)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,775 @@
--[[------------------------------------------------------------------------------------------------
Óíèâåðñàëüíàÿ áîåâàÿ ñõåìà âåðòîë¸òà
×óãàé Àëåêñàíäð
 îòëè÷èå îò ñòàëêåðîâ áîåâàÿ ñõåìà íå ÿâëÿåòñÿ îòäåëüíûì äåéñòâèåì, à âûçûâàåòñÿ èç äðóãèõ ñõåì.
--------------------------------------------------------------------------------------------------]]
local combat_type_flyby = 0 -- àòàêà ïðîë¸òàìè íàä öåëüþ
local combat_type_round = 1 -- êðóæåíèå âîêðóã ïîçèöèè, àòàêà êðóæàñü âîêðóã öåëè
local combat_type_search = 2 -- ïîèñê âðàãà, êðóæåíèå âîêðóã òî÷êè, ãäå ïîñëåäíèé ðàç âèäåë, àòàêà êðóæàñü âîêðóã öåëè
local combat_type_retreat = 3 -- óë¸ò çà ïðåäåëû óðîâíÿ
local flyby_state_to_attack_dist = 0
local flyby_state_to_enemy = 1
local combat_type_change_delay = 5000
local visibility_delay = 3000
local search_shoot_delay = 2000
local round_shoot_delay = 2000
local dummy_vector = vector()
local debug_combat_type
function debug_switch_combat_type()
if debug_combat_type == combat_type_flyby then
debug_combat_type = combat_type_search
else
debug_combat_type = combat_type_flyby
end
end
function distance_2d( a, b )
return math.sqrt( (b.x-a.x)^2 + (b.z-a.z)^2 )
end
-- ïåðåñå÷åíèå ëó÷à è êðóãà.
-- p - òî÷êà íà÷àëà ëó÷à, v - íàïðàâëåíèå ëó÷à (îðò), o - öåíòð êðóãà, r - ðàäèóñ êðóãà
-- òî÷êà p äîëæíà áûòü âíóòðè êðóãà
function cross_ray_circle( p, v, o, r )
local po = vector():set( o ):sub( p )
local vperp = vector():set( -v.z, 0, v.x )
local l = math.sqrt( ( r ^ 2 ) - ( vector():set( po ):dotproduct( vperp ) ^ 2 ) )
return vector():set( p ):add( vector():set( v ):mul( vector():set( po ):dotproduct( v ) + l ) )
end
----------------------------------------------------------------------------------------------------
class "heli_combat"
function heli_combat:__init( object, heliObject )
self.st = db.storage[object:id()]
self.object = object
self.heliObject = heliObject
self.initialized = false
self.level_max_y = level.get_bounding_volume().max.y
local ltx = system_ini()
self.flyby_attack_dist = utils.cfg_get_number( ltx, "helicopter", "flyby_attack_dist", self.object, true )
self.search_attack_dist = utils.cfg_get_number( ltx, "helicopter", "search_attack_dist", self.object, true )
self.default_safe_altitude = utils.cfg_get_number( ltx, "helicopter", "safe_altitude", self.object, true ) + self.level_max_y
self.m_max_mgun_dist = utils.cfg_get_number( ltx, "helicopter", "max_mgun_attack_dist", self.object, true )
self.default_velocity = utils.cfg_get_number( ltx, "helicopter", "velocity", self.object, true )
self.search_velocity = utils.cfg_get_number( ltx, "helicopter", "search_velocity", self.object, true )
self.round_velocity = utils.cfg_get_number( ltx, "helicopter", "round_velocity", self.object, true )
self.vis_time_quant = utils.cfg_get_number( ltx, "helicopter", "vis_time_quant", self.object, true )
self.vis_threshold = utils.cfg_get_number( ltx, "helicopter", "vis_threshold", self.object, true )
self.vis_inc = utils.cfg_get_number( ltx, "helicopter", "vis_inc", self.object, true ) * self.vis_time_quant * 0.001
self.vis_dec = utils.cfg_get_number( ltx, "helicopter", "vis_dec", self.object, true ) * self.vis_time_quant * 0.001
self.vis = 0
self.vis_next_time = 0
self.forget_timeout = utils.cfg_get_number( ltx, "helicopter", "forget_timeout", self.object, true ) * 1000
self.flame_start_health = utils.cfg_get_number( ltx, "helicopter", "flame_start_health", self.object, true )
self.attack_before_retreat = false
self.enemy_forgetable = true
self.section_changed = false
debug_combat_type = nil
end
function heli_combat:read_custom_data( ini, section )
self.combat_use_rocket = utils.cfg_get_bool ( ini, section, "combat_use_rocket", self.object, false, true )
self.combat_use_mgun = utils.cfg_get_bool ( ini, section, "combat_use_mgun", self.object, false, true )
-- self.combat_ignore = utils.cfg_get_bool ( ini, section, "combat_ignore", self.object, false, false )
local combat_ignore = utils.cfg_get_string( ini, section, "combat_ignore", self.object, false, "", nil )
if combat_ignore then
self.combat_ignore = xr_logic.parse_condlist( self.object, section, "combat_ignore", combat_ignore )
else
self.combat_ignore = nil
end
local combat_enemy = utils.cfg_get_string( ini, section, "combat_enemy", self.object, false, "", nil )
self:set_enemy_from_custom_data( combat_enemy )
self.max_velocity = utils.cfg_get_number( ini, section, "combat_velocity", self.object, false, self.default_velocity )
self.safe_altitude = utils.cfg_get_number( ini, section, "combat_safe_altitude", self.object, false,
self.default_safe_altitude ) + self.level_max_y
self.section_changed = true
end
-- óñòàíîâêà âðàãà ïî custom data
-- åñëè âðàã óñòàíîâèëñÿ ýòîé ôóíêöèåé, òî îí íå áóäåò çàáûâàòüñÿ ïðè äëèòåëüíîé ïîòåðå âèäèìîñòè!
-- åñëè óñòàíîâèëñÿ íîâûé âðàã, òî combat áóäåò ïåðåèíèöèàëèçèðîâàí
function heli_combat:set_enemy_from_custom_data( combat_enemy )
if combat_enemy == nil then
self.enemy_forgetable = true
else
if combat_enemy == "actor" then
if db.actor then
self.enemy_id = db.actor:id()
else
self:forget_enemy()
end
elseif combat_enemy == "nil" then
self:forget_enemy()
else
self.enemy_id = id_by_sid( tonumber( combat_enemy ) )
end
if self.enemy_id then
self.enemy_forgetable = false
self.initialized = false
else
self.enemy_forgetable = true
self:forget_enemy()
end
end
end
function heli_combat:set_combat_type( new_combat_type )
if new_combat_type ~= self.combat_type then
self.flyby_initialized = false
self.round_initialized = false
self.search_initialized = false
self.combat_type = new_combat_type
end
end
function heli_combat:initialize()
self.enemy_last_seen_pos = self.enemy:position()
self.enemy_last_seen_time = 0
self.enemy_last_spot_time = nil
self.can_forget_enemy = false
self.section_changed = true
-- self:set_combat_type( combat_type_flyby )
-- self:set_combat_type( combat_type_search )
self.combat_type = combat_type_flyby
self.change_combat_type_time = nil
self.change_combat_type_allowed = true
self.heliObject.m_max_mgun_dist = self.m_max_mgun_dist
self.flyby_states_for_one_pass = 2
self.object:set_fastcall( self.fastcall, self )
self.initialized = true
end
function heli_combat:save( packet )
-- packet:w_bool( self.retreat_already )
set_save_marker(packet, "save", false, "heli_combat")
printf( "heli_combat:save level_changing=%s", tostring( utils.level_changing() ) )
if utils.level_changing() then
packet:w_bool( false )
set_save_marker(packet, "save", true, "heli_combat")
return
end
packet:w_bool( self.initialized )
if self.initialized then
local t = time_global()
packet:w_s16 ( self.enemy_id )
packet:w_u32 ( t - self.enemy_last_seen_time )
packet:w_bool( self.can_forget_enemy )
packet:w_bool( self.enemy_forgetable )
packet:w_vec3( self.enemy_last_seen_pos )
packet:w_u8 ( self.combat_type )
if self.combat_type == combat_type_search then
packet:w_u32 ( self.change_dir_time - t )
packet:w_u32 ( self.change_pos_time - t )
packet:w_bool( self.flight_direction )
packet:w_vec3( self.center_pos )
elseif self.combat_type == combat_type_flyby then
packet:w_s16( self.flyby_states_for_one_pass )
end
end
set_save_marker(packet, "save", true, "heli_combat")
end
function heli_combat:load( packet )
printf( "heli_combat:LOAD level_changing=%s", tostring( utils.level_changing() ) )
-- self.retreat_already = packet:r_bool()
set_save_marker(packet, "load", false, "heli_combat")
self.initialized = packet:r_bool()
printf("initialized = [%s]", tostring(self.initialized))
if self.initialized then
local t = time_global()
printf("t = [%s]", tostring(t))
self.enemy_last_seen_pos = vector()
self.enemy_id = packet:r_s16()
printf("self.enemy_id = [%s]", tostring(self.enemy_id))
self.enemy_last_seen_time = t - packet:r_u32()
printf("self.enemy_last_seen_time = [%s]", tostring(self.enemy_last_seen_time))
self.can_forget_enemy = packet:r_bool()
printf("self.can_forget_enemy = [%s]", tostring(self.can_forget_enemy))
self.enemy_forgetable = packet:r_bool()
printf("self.enemy_forgetable = [%s]", tostring(self.enemy_forgetable))
packet:r_vec3( self.enemy_last_seen_pos )
printf("self.enemy_last_seen_pos = [%s]", vec_to_str(self.enemy_last_seen_pos))
self.combat_type = packet:r_u8()
printf("self.combat_type = [%s]", tostring(self.combat_type))
if self.combat_type == combat_type_search then
self.center_pos = vector()
self.change_dir_time = packet:r_u32() + t
printf("self.change_dir_time = [%s]", tostring(self.change_dir_time))
self.change_pos_time = packet:r_u32() + t
printf("self.change_pos_time = [%s]", tostring(self.change_pos_time))
self.flight_direction = packet:r_bool()
printf("self.flight_direction = [%s]", tostring(self.flight_direction))
packet:r_vec3( self.center_pos )
printf("self.center_pos = [%s]", vec_to_str(self.center_pos))
elseif self.combat_type == combat_type_flyby then
self.flyby_states_for_one_pass = packet:r_s16()
printf("self.flyby_states_for_one_pass = [%s]", tostring(self.flyby_states_for_one_pass))
end
end
set_save_marker(packet, "load", true, "heli_combat")
end
function heli_combat:waypoint_callback()
if self.enemy_id and not self:combat_ignore_check() then
self.was_callback = true
printf( "heli_combat:waypoint_callback" )
return true
else
return false
end
end
-- Îáíîâëåíèå ïàðàìåòðîâ âåðòîë¸òà, çàäàâàåìûõ â custom data.
-- Íóæíî äåëàòü íà êàæäîì îáíîâëåíèè íà ñëó÷àé, åñëè âî âðåìÿ áîÿ ëîãèêà ïåðåêëþ÷èëàñü íà äðóãóþ ñåêöèþ.
function heli_combat:update_custom_data_settings()
if self.section_changed then
self.heliObject.m_use_rocket_on_attack = self.combat_use_rocket
self.heliObject.m_use_mgun_on_attack = self.combat_use_mgun
if self.combat_type == combat_type_flyby then
printf( "heli_combat:update_custom_data_settings SetMaxVelocity=%d", self.max_velocity )
self.heliObject:SetMaxVelocity( self.max_velocity )
end
self.section_changed = false
end
end
function heli_combat:update_enemy_visibility()
self.object:info_add( "vis=" .. self.vis )
if self.vis >= self.vis_threshold then
self.enemy_last_seen_time = time_global()
self.enemy_last_seen_pos = self.enemy:position()
return true
else
return false
end
end
function heli_combat:forget_enemy()
self.enemy_id = nil
self.enemy = nil
self.initialized = false
end
function heli_combat:update_forgetting()
if ( ( self.enemy_forgetable and self.can_forget_enemy ) and
( time_global() - self.enemy_last_seen_time > self.forget_timeout ) ) or not self.enemy:alive()
then
self:forget_enemy()
end
end
function heli_combat:update_combat_type( see_enemy )
-- do return combat_type_flyby end
-- DEBUG
if debug_combat_type ~= nil then
self:set_combat_type( debug_combat_type )
return
end
--------
local ct = self.combat_type
-- printf( "flyby_states_for_one_pass=%d", self.flyby_states_for_one_pass )
if self.combat_type == combat_type_flyby then
if self.flyby_states_for_one_pass <= 0 then
if self.attack_before_retreat then
ct = combat_type_retreat
else
ct = combat_type_round
end
end
elseif self.combat_type == combat_type_round then
if see_enemy then
if distance_2d( self.object:position(), self.enemy:position() ) > self.flyby_attack_dist + 70 --and
-- not self.flyby_pass_finished
then
ct = combat_type_flyby
end
else
ct = combat_type_search
end
if bind_heli.get_heli_health( self.heliObject, self.st ) < self.flame_start_health then
self.attack_before_retreat = true
self.heliObject.m_use_rocket_on_attack = true
ct = combat_type_flyby
end
elseif self.combat_type == combat_type_search then
if see_enemy then
if distance_2d( self.object:position(), self.enemy:position() ) > self.flyby_attack_dist then
ct = combat_type_flyby
else
ct = combat_type_round
end
end
if bind_heli.get_heli_health( self.heliObject, self.st ) < self.flame_start_health then
self.attack_before_retreat = true
self.heliObject.m_use_rocket_on_attack = true
ct = combat_type_flyby
end
end
-- printf( "combat_type = %s", tostring( self.combat_type ) )
self:set_combat_type( ct )
-- printf( "combat_type = %s", tostring( self.combat_type ) )
end
-- íóæíî ëè èãíîðèðîâàòü âðàãà
function heli_combat:combat_ignore_check()
return self.combat_ignore ~= nil and xr_logic.pick_section_from_condlist( db.actor, self.object, self.combat_ignore ) ~= nil
end
-- ÷àñòîå îáíîâëåíèå.
-- íóæíî äëÿ îòñëåæèâàíèÿ âèäèìîñòè âðàãà
function heli_combat:fastcall()
if self.initialized then
if self.vis_next_time < time_global() then
self.vis_next_time = time_global() + self.vis_time_quant
if self.heliObject:isVisible( self.enemy ) then
self.vis = self.vis + self.vis_inc
if self.vis > 100 then
self.vis = 100
end
else
self.vis = self.vis - self.vis_dec
if self.vis < 0 then
self.vis = 0
end
end
end
return false
else
return true
end
end
-- Îáíîâëåíèå áîåâîé ñõåìû. Âûçûâàåòñÿ èç îáíîâëåíèé ñõåì ëîãèêè âåðòîë¸òà.
-- âîçâðàùàåò true, åñëè áîé àêòèâåí (òî åñòü íåòó combat_ignore è åñòü âðàã)
function heli_combat:update()
if self.enemy_id then
self.enemy = level.object_by_id( self.enemy_id )
if not self.enemy then
self:forget_enemy()
return false
end
else
return false
end
if self:combat_ignore_check() then
return false
end
self:update_custom_data_settings()
if not self.initialized then
self:initialize()
end
local see_enemy = self:update_enemy_visibility()
self:update_combat_type( see_enemy )
-- FIXME
-- self.heliObject:GetSpeedInDestPoint(0)
if self.combat_type == combat_type_search then
self:search_update( see_enemy )
elseif self.combat_type == combat_type_round then
self:round_update( see_enemy )
elseif self.combat_type == combat_type_flyby then
self:flyby_update( see_enemy )
elseif self.combat_type == combat_type_retreat then
self:retreat_update()
end
self:update_forgetting()
return true
end
-- ïîñ÷èòàòü òî÷êó íà çàäàííîì ðàäèóñå îò ïîñëåäíåé âèäèìîé ïîçèöèè âðàãà â òåêóùåì íàïðàâëåíèè ñêîðîñòè âåðòîë¸òà
function heli_combat:calc_position_in_radius( r )
local p = self.object:position()
p.y = 0
local v = self.heliObject:GetCurrVelocityVec()
v.y = 0
v:normalize()
local o = self.enemy_last_seen_pos
o.y = 0
local ret = cross_ray_circle( p, v, o, r )
ret.y = self.safe_altitude
return ret
end
----------------------------------------------------------------------------------------------
-- Ôóíöèèè êðóæàùåãî áîÿ
----------------------------------------------------------------------------------------------
function heli_combat:round_initialize()
self.change_dir_time = 0
self.change_pos_time = 0
self.center_pos = self.enemy_last_seen_pos
self.flight_direction = random_choice( true, false )
self.change_combat_type_allowed = true
self.round_begin_shoot_time = 0
printf( "heli_combat:round_initialize SetMaxVelocity=%d", self.round_velocity )
self.heliObject:SetMaxVelocity( self.round_velocity )
self.heliObject:SetSpeedInDestPoint( self.round_velocity )
self.heliObject:UseFireTrail( false )
self.round_initialized = true
self:round_setup_flight( self.flight_direction )
end
function heli_combat:round_setup_flight( direction )
self.center_pos = self.enemy_last_seen_pos
self.center_pos.y = self.safe_altitude
printf( "heli_combat:round_setup_flight GoPatrolByRoundPath" )
self.heliObject:GoPatrolByRoundPath( self.center_pos, self.search_attack_dist, direction )
self.heliObject:LookAtPoint( self.enemy:position(), true )
end
function heli_combat:round_update_shooting( see_enemy )
if see_enemy then
if self.round_begin_shoot_time then
if self.round_begin_shoot_time < time_global() then
self.heliObject:SetEnemy( self.enemy )
end
else
self.round_begin_shoot_time = time_global() + round_shoot_delay
end
else
self.heliObject:ClearEnemy()
self.round_begin_shoot_time = nil
end
end
function heli_combat:round_update_flight( see_enemy )
-- ìåíÿòü âðåìÿ îò âðåìåíè íàïðàâëåíèå îáë¸òà
--[[ if self.change_dir_time < time_global() then
local t
if see_enemy then
t = math.random( 6000, 10000 )
else
t = math.random( 15000, 20000 )
end
self.change_dir_time = time_global() + t --+ 1000000
printf( "heli_combat: going by round path, t=%d", t )
self.flight_direction = not self.flight_direction
self:round_setup_flight( self.flight_direction )
return
end
]]
-- ïåðèîäè÷åñêè ïðîâåðòü, íå ïåðåìåñòèëñÿ ëè âðàã è äîñòàòî÷íî ëè ó âåðòîë¸òà çäîðîâüÿ
if self.change_pos_time < time_global() then
self.change_pos_time = time_global() + 2000
if not self.can_forget_enemy and
distance_2d( self.object:position(), self.enemy_last_seen_pos ) <= self.search_attack_dist
then
self.can_forget_enemy = true
end
if distance_2d( self.center_pos, self.enemy_last_seen_pos ) > 10 then
printf( "heli_combat: enemy has changed his position" )
self:round_setup_flight( self.flight_direction )
end
end
end
function heli_combat:round_update( see_enemy )
if not self.round_initialized then
self:round_initialize()
end
-- printf( "heli_combat: round_update" )
self:round_update_shooting( see_enemy )
self:round_update_flight ( see_enemy )
end
----------------------------------------------------------------------------------------------
-- Ôóíöèèè äëÿ ïîèñêà âðàãà (ñêîïèðîâàíî ñ êðóæàùåãî áîÿ)
----------------------------------------------------------------------------------------------
function heli_combat:search_initialize()
self.change_speed_time = time_global() + math.random( 5000, 7000 ) --+ 1000000
self.speed_is_0 = true
self.change_pos_time = 0
self.center_pos = self.enemy_last_seen_pos
self.flight_direction = random_choice( true, false )
self.change_combat_type_allowed = true
self.search_begin_shoot_time = 0
self.heliObject:UseFireTrail( false )
self.search_initialized = true
self:search_setup_flight()
end
function heli_combat:search_setup_flight()
self.center_pos = self.enemy_last_seen_pos
self.center_pos.y = self.safe_altitude
local v
if self.speed_is_0 then
v = 0
else
v = self.search_velocity
end
printf( "heli_combat:search_setup_flight SetMaxVelocity=%d", v )
self.heliObject:SetMaxVelocity( v )
self.heliObject:SetSpeedInDestPoint( v )
printf( "heli_combat:search_setup_flight GoPatrolByRoundPath" )
self.heliObject:GoPatrolByRoundPath( self.center_pos, self.search_attack_dist, self.flight_direction )
self.heliObject:LookAtPoint( self.enemy:position(), true )
end
function heli_combat:search_update_shooting( see_enemy )
if see_enemy then
if self.search_begin_shoot_time then
if self.search_begin_shoot_time < time_global() then
self.heliObject:SetEnemy( self.enemy )
end
else
self.search_begin_shoot_time = time_global() + search_shoot_delay
end
else
self.heliObject:ClearEnemy()
self.search_begin_shoot_time = nil
end
end
function heli_combat:search_update_flight( see_enemy )
-- îñòàíàâëèâàòüñÿ è âîçîáíîâëÿòü äâèæåíèå âðåìÿ îò âðåìåíè
if self.change_speed_time < time_global() then
local t
t = math.random( 8000, 12000 )
self.change_speed_time = time_global() + t
self.speed_is_0 = not self.speed_is_0
-- self.flight_direction = not self.flight_direction
self:search_setup_flight( self.flight_direction )
return
end
-- ïåðèîäè÷åñêè ïðîâåðòü, íå ïåðåìåñòèëñÿ ëè âðàã è äîñòàòî÷íî ëè ó âåðòîë¸òà çäîðîâüÿ
if self.change_pos_time < time_global() then
self.change_pos_time = time_global() + 2000
if not self.can_forget_enemy and
distance_2d( self.object:position(), self.enemy_last_seen_pos ) <= self.search_attack_dist
then
self.can_forget_enemy = true
end
if distance_2d( self.center_pos, self.enemy_last_seen_pos ) > 10 then
printf( "heli_combat: enemy has changed his position" )
self:search_setup_flight( self.flight_direction )
end
end
end
function heli_combat:search_update( see_enemy )
if not self.search_initialized then
self:search_initialize()
end
-- printf( "heli_combat: search_update" )
self:search_update_shooting( see_enemy )
self:search_update_flight ( see_enemy )
end
----------------------------------------------------------------------------------------------
-- Ôóíöèèè äëÿ áîÿ ñ ïðîë¸òàìè íàä öåëüþ
----------------------------------------------------------------------------------------------
function heli_combat:flyby_initialize()
self:flyby_set_initial_state()
self.state_initialized = false
self.was_callback = false
self.flyby_states_for_one_pass = 2
self.flyby_initialized = true
printf( "heli_combat:flyby_initialize SetMaxVelocity=%d", self.max_velocity )
self.heliObject:SetMaxVelocity( self.max_velocity )
self.heliObject:SetSpeedInDestPoint( self.max_velocity )
self.heliObject:LookAtPoint( dummy_vector, false )
end
function heli_combat:flyby_set_initial_state()
-- if self.object:position():distance_to( self.enemy_last_seen_pos ) < self.flyby_attack_dist then
if distance_2d( self.object:position(), self.enemy_last_seen_pos ) < self.flyby_attack_dist then
-- self.heliObject:LookAtPoint( dummy_vector, false )
self.state = flyby_state_to_attack_dist
else
-- self.heliObject:LookAtPoint( self.enemy:position(), true )
self.state = flyby_state_to_enemy
end
end
function heli_combat:flyby_update_flight( see_enemy )
if self.was_callback then
if self.state == flyby_state_to_attack_dist then
printf( "switch state -> ENEMY" )
self.state = flyby_state_to_enemy
elseif self.state == flyby_state_to_enemy then
printf( "switch state -> DIST" )
self.state = flyby_state_to_attack_dist
end
self.was_callback = false
self.state_initialized = false
end
if self.state == flyby_state_to_attack_dist then
if not self.state_initialized then
local p = self:calc_position_in_radius( self.flyby_attack_dist )
-- printf( "heli_combat:flyby_update_flight 1 SetDestPosition %f %f %f", p.x, p.y, p.z )
self.heliObject:SetDestPosition( p )
self.heliObject:ClearEnemy()
self.change_combat_type_allowed = false
self.state_initialized = true
end
elseif self.state == flyby_state_to_enemy then
if not self.state_initialized then
self.heliObject:SetEnemy( self.enemy )
self.heliObject:UseFireTrail( true )
self.flyby_states_for_one_pass = self.flyby_states_for_one_pass - 1
self.state_initialized = true
end
local p = self.enemy_last_seen_pos
p:set( p.x, self.safe_altitude, p.z )
self.change_combat_type_allowed = distance_2d( self.object:position(), p ) > self.search_attack_dist
-- printf( "heli_combat:flyby_update_flight 2 SetDestPosition %f %f %f", p.x, p.y, p.z )
self.heliObject:SetDestPosition( p )
end
end
function heli_combat:flyby_update( see_enemy )
if not self.flyby_initialized then
self:flyby_initialize()
end
-- printf( "heli_combat: flyby_update" )
self:flyby_update_flight( see_enemy )
-- printf( "speed in dest point %d", self.heliObject:GetSpeedInDestPoint(0) )
end
----------------------------------------------------------------------------------------------
-- Ôóíöèèè äëÿ óëåòàíèÿ çà ïðåäåëû óðîâíÿ
----------------------------------------------------------------------------------------------
function heli_combat:retreat_initialize()
self.retreat_initialized = true
self.heliObject:SetMaxVelocity( self.max_velocity )
self.heliObject:SetSpeedInDestPoint( self.max_velocity )
self.heliObject:LookAtPoint( dummy_vector, false )
self.heliObject:SetDestPosition( self:calc_position_in_radius( 5000 ) )
self.heliObject:ClearEnemy()
end
function heli_combat:retreat_update()
if not self.retreat_initialized then
self:retreat_initialize()
end
-- printf( "heli_combat: retreat_update" )
end

View file

@ -0,0 +1,199 @@
--[[------------------------------------------------------------------------------------------------
Helicopter combat
Àíäðóùåíêî Èâàí
--------------------------------------------------------------------------------------------------]]
local heli_firer = {}
function get_heli_firer(obj)
if heli_firer[obj:id()] == nil then
heli_firer[obj:id()] = heli_fire(obj)
end
return heli_firer[obj:id()]
end
class "heli_fire"
function heli_fire:__init(obj)
self.obj = obj
self.enemy_ = nil
self.fire_point = nil
self.enemy = nil
self.enemy_id = nil
self.flag_by_enemy = true
self.hit_count = 0
self.fire_id = nil
self.enumy_die = true
self.enemy_time = time_global()
self.upd_vis = 0
self.show_health = false
end
function heli_fire:update_enemy_state()
local heli = self.obj:get_helicopter()
--' printf("update_enemy_state()")
if self.hit_count > 2 then
self.hit_count = 0
self.flag_by_enemy = true
end
if self.enemy and self.enemy_die and self.enemy_ == "all" then
self:update_enemy_arr()
end
if self.enemy and time_global() - self.enemy_time > self.upd_vis * 1000 then
--'printf("self.upd_vis = %d", self.upd_vis);
if not heli:isVisible( self.enemy )then
if self.enemy_ == "all" then
self:update_enemy_arr()
end
end
self.enemy_time = time_global()
end
if self.enemy then
if not heli:isVisible( self.enemy )then
self.flag_by_enemy = true
end
end
self:set_enemy()
end
function heli_fire:cs_heli()
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_heli_health")
if custom_static == nil then
hud:AddCustomStatic("cs_heli_health", true)
local xml = CScriptXmlInit()
xml:ParseFile("heli_progress.xml")
local st = hud:GetCustomStatic("cs_heli_health")
local w = st:wnd()
self.heli_progress = xml:InitProgressBar ("heli_health", w )
self:set_cs_heli_progress_health()
end
end
function heli_fire:set_cs_heli_progress_health()
local heli = self.obj:get_helicopter()
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_heli_health")
local xml = CScriptXmlInit()
xml:ParseFile("heli_progress.xml")
if custom_static then
hud:AddCustomStatic("cs_heli_health", true)
local st = hud:GetCustomStatic("cs_heli_health")
local w = st:wnd()
local _progr = heli:GetfHealth()*100
if _progr > 0 then
self.heli_progress:Show(true)
self.heli_progress:SetProgressPos(_progr)
else
self.heli_progress:Show(false)
self.show_healt = false
hud:RemoveCustomStatic("cs_heli_health")
end
end
end
function heli_fire:cs_remove()
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_heli_health")
if custom_static then
hud:RemoveCustomStatic("cs_heli_health")
end
end
function heli_fire:set_enemy()
local heli = self.obj:get_helicopter()
if self.flag_by_enemy then
heli:ClearEnemy()
--'printf("ClearEnemy()")
self.enemy_die = false
if self.enemy then
if heli:isVisible( self.enemy ) then
heli:SetEnemy( self.enemy)
self.flag_by_enemy = false
end
else
if self.enemy_ then
if self.enemy_ == "actor" then
if db.actor then
self.enemy = db.actor
end
else
if self.enemy_ == "all" then
self:update_enemy_arr()
else
if self.enemy_ ~= "nil" then
self.enemy_id = id_by_sid( tonumber( self.enemy_ ) )
self.enemy = level.object_by_id( self.enemy_id )
end
end
end
end
if self.enemy then
heli:SetEnemy( self.enemy)
--'printf("set_enemy(self.enemy, actor or SID)")
else
self.enemy_die = true
end
self.flag_by_enemy = false
end
end
if not self.enemy_die and self.enemy:death_time() > 0 then
--'printf("ClearEnemy()")
heli:ClearEnemy()
self.enemy_die = true
end
if self.enemy_die and self.fire_point then
heli:SetEnemy(self.fire_point)
end
end
function heli_fire:update_hit()
if self.show_health then
self:set_cs_heli_progress_health()
else
self:cs_remove()
end
if self.enemy:id() == self.fire_id then
if self.enemy_ ~= "nil" then
self.hit_count = self.hit_count + 1
else
self.hit_count = 0
end
else
self.fire_id = self.enemy:id()
self.hit_count = 1
end
end
function heli_fire:update_enemy_arr()
--'printf("update_enemy_arr()")
local heli = self.obj:get_helicopter()
local index = 0
local min_dist2D = 65000
--' printf("heli_enemy_count=%d", db.heli_enemy_count)
while index < db.heli_enemy_count do
if db.heli_enemies[index] then
if heli:isVisible( db.heli_enemies[index] ) then
if distance_2d( self.obj:position(), db.heli_enemies[index]:position() ) < min_dist2D then
self.enemy = db.heli_enemies[index]
min_dist2D = distance_2d( self.obj:position(), db.heli_enemies[index]:position() )
self.flag_by_enemy = true
end
end
end
index = index + 1
end
if heli:isVisible( db.actor ) and random_choice( false, true) or db.heli_enemy_count==0 then
if distance_2d( self.obj:position(), db.actor:position() ) <= min_dist2D*2 then
self.enemy = db.actor
min_dist2D = distance_2d( self.obj:position(), db.actor:position() )
end
end
end
function distance_2d( a, b )
return math.sqrt( (b.x-a.x)^2 + (b.z-a.z)^2 )
end

View file

@ -0,0 +1,180 @@
--[[------------------------------------------------------------------------------------------------
Helicopter movement
Àíäðóùåíêî Èâàí
--------------------------------------------------------------------------------------------------]]
local heli_flyer = {}
function get_heli_flyer(obj)
if heli_flyer[obj:id()] == nil then
heli_flyer[obj:id()] = heli_fly(obj)
end
return heli_flyer[obj:id()]
end
class "heli_fly"
function heli_fly:__init(obj)
self.obj = obj
self.block_flook = false
self.dist_by_look = 0
self.heliLAccFW = 6
self.heliLAccBW = 4
self.max_velocity = 0
self.point_arr = {}
self.dest_point = nil
self.point_by_look = vector():set(0,0,0)
end
function heli_fly:fly_on_point_with_vector(dest_point, dest_direction, dest_velocity, flag_to_wp_callback, flag_by_null_velocity)
--' printf("fly_on_point_with_vector()")
local heli = self.obj:get_helicopter()
local curr_heli_position = self.obj:position() -- òåêóùàÿ ïîçèöèÿ
local curr_heli_direction = self.obj:direction() -- åäèíè÷íûé âåêòîð òåêóùåãî íàïðàâëåíèÿ
local curr_heli_velocity = heli:GetCurrVelocity() -- òåêóùàÿ ñêîðîñòü
dest_velocity = dest_velocity * 1000 / 3600
if not flag_to_wp_callback then
--------------Ðàñ÷åòû------------------------------------------------------------------------------------------------------------------------------------------------------
local a_speed = 0
local time_by_fly = 0
local rez_point = vector():set(0,0,0) -- òî÷êà, ÷åðåç êîòîðóþ ïðîëåòèì, ÷òî-áû ïîïàñòü â çàäàííóþ òî÷êó, è âûéòè íà çàäàííóþ ñêîðîñòü
local d_path -- d_path - äîïóñê ðàññòîÿíèÿ ïîïàäàíèÿ â òî÷êó
-------------------------------------------------------------
if dest_velocity >= curr_heli_velocity then
-------------------------------------------------------------
a_speed= self.heliLAccFW -- óñêîðåíèå ðàçãîíà, áåðåì èç helicopter.ltx
d_path = curr_heli_velocity * 2 / a_speed
-------------------------------------------------------------
else
-------------------------------------------------------------
a_speed= - self.heliLAccBW -- óñêîðåíèå òîðìîæåíèÿ, áåðåì èç helicopter.ltx
d_path = - curr_heli_velocity * 2 / a_speed
-------------------------------------------------------------
end
time_by_fly = (dest_velocity - curr_heli_velocity)/a_speed -- t=(v2-v1)/a -- t - âðåìÿ, çà êîòîðîå çàòîðìîçèì/ðàçãîíèìñÿ. a - óñêîðåíèå òîðìîæåíèÿ/ðàçãîíà, áåðåì èç helicopter.ltx
local delta = curr_heli_velocity * time_by_fly + a_speed * time_by_fly * time_by_fly / 2 -- ðàññòîÿíèå äëÿ âûõîäà íà çàäàííóþ ñêîðîñòü s=v0t+(at^2)/2
if delta >= d_path then
self.point_arr[0] = curr_heli_position
self.point_arr[1] = dest_point
self.point_arr[2] = curr_heli_direction
rez_point = self:calc_point()
if not self.block_flook then
rez_point.x = rez_point.x + curr_heli_direction.x * delta / 2
rez_point.z = rez_point.z + curr_heli_direction.z * delta / 2
end
flag_to_wp_callback = true
else
rez_point = dest_point
flag_to_wp_callback = false
end
self.dest_point = rez_point
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
else
self.dest_point = dest_point
flag_to_wp_callback = false
end
heli:SetDestPosition( self.dest_point )
self:correct_velocity()
if flag_by_null_velocity then
heli:SetSpeedInDestPoint(0)
else
heli:SetSpeedInDestPoint(heli:GetMaxVelocity())
end
return flag_to_wp_callback
end
function heli_fly:get_block_flook()
return self.block_flook
end
function heli_fly:calc_point()
local rez_point = vector():set(0,0,0)
local xxArr = {}
xxArr[0] = self.point_arr[0].x
xxArr[1] = self.point_arr[1].x
xxArr[2] = self.point_arr[2].x
local yyArr = {}
yyArr[0] = self.point_arr[0].y
yyArr[1] = self.point_arr[1].y
yyArr[2] = self.point_arr[2].y
local zzArr = {}
zzArr[0] = self.point_arr[0].z
zzArr[1] = self.point_arr[1].z
zzArr[2] = self.point_arr[2].z
rez_point.y = (self.point_arr[0].y + self.point_arr[1].y)/2
if rez_point.y == self.point_arr[0].y then
rez_point.z = (self.point_arr[0].z + self.point_arr[1].z)/2
if rez_point.z == self.point_arr[0].z then
rez_point.x = (self.point_arr[0].x + self.point_arr[1].x)/2
rez_point.z = self:lagrange(rez_point.x, xxArr, zzArr)
else
rez_point.x = self:lagrange(rez_point.z, zzArr, xxArr)
end
else
rez_point.x = self:lagrange(rez_point.y, yyArr, xxArr)
rez_point.z = self:lagrange(rez_point.y, yyArr, zzArr)
end
--' printf("fly_point[x=%d; y=%d; z=%d;]",rez_point.x, rez_point.y, rez_point.z);
return rez_point
end
function heli_fly:lagrange(x, xArr, yArr)
local i, j
local m, s
s = 0
for i=0,2 do
m = yArr[i]
for j=0,2 do
if j ~= i then
m = m * (x - xArr[j]) / (xArr[i] - xArr[j])
end
end
s = s + m
end
return s
end
function heli_fly:correct_velocity()
local heli = self.obj:get_helicopter()
local curr_heli_velocity = heli:GetCurrVelocity() --' òåêóùàÿ ñêîðîñòü
local dist_to_dest_point = heli:GetDistanceToDestPosition()
local a_speed = self.heliLAccFW
local dest_velocity
dest_velocity = ((2*a_speed*dist_to_dest_point + curr_heli_velocity^2)/3)^(1/2)
if self.max_velocity*1000/3600 < dest_velocity then
dest_velocity = self.max_velocity*1000/3600
end
heli:SetMaxVelocity(dest_velocity)
--' printf("dist_to_dest_point %s", dist_to_dest_point);
--' printf("dest_velocity end = %d", dest_velocity);
end
function heli_fly:look_at_position()
if self.block_flook then
local heli = self.obj:get_helicopter()
heli:LookAtPoint( self.point_by_look, true )
end
end
function heli_fly:set_block_flook(fl_block)
self.block_flook = fl_block
end
function heli_fly:set_look_point(l_point)
self.point_by_look = l_point
end

View file

@ -0,0 +1,53 @@
--[[------------------------------------------------------------------------------------------------
Helicopter look
Àíäðóùåíêî Èâàí
--------------------------------------------------------------------------------------------------]]
local heli_looker = {}
function get_heli_looker(obj)
if heli_looker[obj:id()] == nil then
heli_looker[obj:id()] = heli_look(obj)
end
return heli_looker[obj:id()]
end
class "heli_look"
function heli_look:__init(obj)
self.obj = obj
self.look_point = vector():set(0,0,0)
self.look_state = false
end
function heli_look:calc_look_point(dest_point, look_state)
self.look_state = look_state
if look_state and dest_point then
local heli = self.obj:get_helicopter()
local dist_to_dest_point = heli:GetDistanceToDestPosition()
local new_direction = vector():set(0,0,0) --' åä. âåêòîð çàäàííîãî íàïðàâëåíèÿ
local curr_heli_position = self.obj:position() --' òåêóùàÿ ïîçèöèÿ
local curr_heli_direction = self.obj:direction() --' åäèíè÷íûé âåêòîð òåêóùåãî íàïðàâëåíèÿ
local heli_velocity = heli:GetSpeedInDestPoint(0)
local curr_heli_velocity = heli:GetCurrVelocity() --' òåêóùàÿ ñêîðîñòü
new_direction.x = (dest_point.x - curr_heli_position.x)/dist_to_dest_point
new_direction.y = (dest_point.y - curr_heli_position.y)/dist_to_dest_point
new_direction.z = (dest_point.z - curr_heli_position.z)/dist_to_dest_point
local delta
if heli_velocity <= 0 then
delta = 0
else
delta = curr_heli_velocity/heli_velocity
if delta > 2 then
delta = 2
end
end
self.look_point.x = heli_velocity^2 * (curr_heli_direction.x + new_direction.x / 2 * (2 - delta))
self.look_point.y = heli_velocity^2 * (curr_heli_direction.y + new_direction.y / 2 * (2 - delta))
self.look_point.z = heli_velocity^2 * (curr_heli_direction.z + new_direction.z / 2 * (2 - delta))
heli:LookAtPoint( self.look_point, look_state )
end
end

View file

@ -0,0 +1,294 @@
--[[------------------------------------------------------------------------------------------------
Helicopter movement
Àíäðóùåíêî Èâàí
--------------------------------------------------------------------------------------------------]]
local state_move = 0
----------------------------------------------------------------------------------------------------
class "heli_move"
function heli_move:__init( obj, storage )
self.object = obj
self.heliObject = obj:get_helicopter()
self.a = storage
self.heli_fly = heli_fly.get_heli_flyer(obj)
self.heli_fire = heli_fire.get_heli_firer(obj)
self.heli_look = heli_look.get_heli_looker(obj)
end
function heli_move:reset_scheme( loading )
printf("heli_move: reset_scheme: %s", self.object:name())
self.a.signals = {}
self.heliObject:TurnEngineSound( self.a.engine_sound )
----------------------------------Âåéïîèíòû - Íà÷àëî------------------------------------------------
if not level.patrol_path_exists(self.a.path_move) then
abort("Patrol path %s doesnt exist", self.a.path_move)
end
self.patrol_move = patrol(self.a.path_move)
self.patrol_move_info = utils.path_parse_waypoints(self.a.path_move)
if self.a.path_look then
if self.a.path_look == "actor" then
self.heli_fly:set_look_point(db.actor:position())
self:update_look_state()
else
self.patrol_look = patrol(self.a.path_look)
self.heli_fly:set_look_point(self.patrol_look:point( 0 ))
self:update_look_state()
if not self.patrol_look then
abort("object '%s': unable to find path_look '%s' on the map",
self.object:name(), self.a.path_look)
end
end
else
self.patrol_look = nil
end
self.max_velocity = self.a.max_velocity
if loading then
self.state = xr_logic.pstor_retrieve( self.object, "st" )
self.last_index = xr_logic.pstor_retrieve( self.object, "li" ) or nil
self.next_index = xr_logic.pstor_retrieve( self.object, "ni" ) or nil
self.was_callback = xr_logic.pstor_retrieve( self.object, "wc" )
else
self.last_index = nil
self.next_index = nil
self.heli_fly.max_velocity = self.max_velocity
self.heli_fly.heliLAccFW = self.max_velocity / 15
self.heli_fly.heliLAccBW = 2 * self.heli_fly.heliLAccFW / 3
self.heliObject:SetLinearAcc(self.heli_fly.heliLAccFW, self.heli_fly.heliLAccBW);
self.heliObject:SetMaxVelocity( self.max_velocity )
self.state = nil
self.stop_point = nil
self.by_stop_fire_fly = false
self.was_callback = false
self._flag_to_wp_callback = false
self.heli_fire.enemy_ = self.a.enemy_
self.heli_fire.enemy = nil
self.heli_fire.flag_by_enemy = true
if self.a.fire_point then
self.heli_fire.fire_point = patrol(self.a.fire_point):point( 0 )
end
if self.a.max_mgun_dist then
self.heliObject.m_max_mgun_dist = self.a.max_mgun_dist
end
if self.a.max_rocket_dist then
self.heliObject.m_max_rocket_dist = self.a.max_rocket_dist
end
if self.a.min_mgun_dist then
self.heliObject.m_min_mgun_dist = self.a.min_mgun_dist
end
if self.a.min_rocket_dist then
self.heliObject.m_min_rocket_dist = self.a.min_rocket_dist
end
if self.a.use_mgun then
self.heliObject.m_use_mgun_on_attack = true
else
self.heliObject.m_use_mgun_on_attack = false
end
if self.a.use_rocket then
self.heliObject.m_use_rocket_on_attack = true
else
self.heliObject.m_use_rocket_on_attack = false
end
self.heli_fire.upd_vis = self.a.upd_vis
self.heli_fire:update_enemy_state()
self:update_movement_state()
if self.a.show_health then
self.heli_fire:cs_remove()
self.heli_fire.show_health = true
self.heli_fire:cs_heli()
else
self.heli_fire.show_health = false
self.heli_fire:cs_remove()
end
self.heliObject:UseFireTrail(self.a.fire_trail)
end
end
function heli_move:save()
xr_logic.pstor_store( self.object, "st", self.state )
----------------------------------Âåéïîèíòû - Íà÷àëî------------------------------------------------
xr_logic.pstor_store( self.object, "li", self.last_index or false )
xr_logic.pstor_store( self.object, "ni", self.next_index or false )
----------------------------------Âåéïîèíòû - Êîíåö-------------------------------------------------
xr_logic.pstor_store( self.object, "wc", self.was_callback )
end
function heli_move:update( delta )
if xr_logic.try_switch_to_another_section(self.object, self.a, db.actor) then
return
end
--self.heli_fire:update_enemy_state()
if self.was_callback then
self:update_movement_state()
self.was_callback = false
end
if self.a.path_look then
if self.a.path_look == "actor" then
self.heli_fly:set_look_point(db.actor:position())
if self.a.stop_fire then
if self.heliObject:isVisible( db.actor ) then
if not self.by_stop_fire_fly then
self.stop_point = self.object:position()
self.by_stop_fire_fly = true
self.was_callback = true
--'printf("Stop Fire!")
end
else
--'printf("Fly to next point!")
self.by_stop_fire_fly = false
self.was_callback = true
end
end
end
self:update_look_state()
end
if not self.a.path_look and self.heli_look.look_state then
self.heli_look:calc_look_point(self.heli_fly.dest_point, true)
end
end
function heli_move:update_movement_state()
--'printf("update_movement_state()")
self.state = state_move
if self.patrol_move then
if not self.last_index then
self.last_index = 0
self.next_index = 1
else
self.next_index = self.last_index + 1
if self.next_index >= self.patrol_move:count() then
self.next_index = 0
end
end
end
if not self.by_stop_fire_fly then
if self.patrol_move:count() > 2 then
self._flag_to_wp_callback = self.heli_fly:fly_on_point_with_vector(
self.patrol_move:point( self.last_index ),
self.patrol_move:point( self.next_index ),
self.max_velocity, self._flag_to_wp_callback, false)
else
if self.patrol_move:count() > 1 then
self._flag_to_wp_callback = self.heli_fly:fly_on_point_with_vector(
self.patrol_move:point( self.last_index ),
self.patrol_move:point( self.next_index ),
self.max_velocity, true, true)
else
self._flag_to_wp_callback = self.heli_fly:fly_on_point_with_vector(
self.patrol_move:point( self.last_index ),
self.patrol_move:point( self.last_index ),
self.max_velocity, true, true)
end
end
else
self._flag_to_wp_callback = self.heli_fly:fly_on_point_with_vector(
self.stop_point,
self.stop_point,
self.max_velocity, true, false)
self._flag_to_wp_callback = true
end
end
function heli_move:update_look_state()
--' printf("update_look_state()")
self.heli_fly:set_block_flook(true)
self.heli_fly:look_at_position()
end
function heli_move:waypoint_callback( obj, action_type, index )
----------------------------------Âåéïîèíòû - Íà÷àëî------------------------------------------------
if not self._flag_to_wp_callback then
--'printf("heli_pos=[%d;%d;%d]",self.object:position().x,self.object:position().y,self.object:position().z)
--'printf("dist_to_dest_point=%d",self.heliObject:GetDistanceToDestPosition())
if self.patrol_move then
if index == self.last_index then
return
end
if index ~= -1 then
self.last_index = index
else
--' Âûäàòü êîëëáåê
if self.patrol_move_info[self.last_index] ~= nil then
local signal = self.patrol_move_info[self.last_index]["sig"]
if signal ~= nil then
self.a.signals[signal] = true
end
end
if self.patrol_move:count()>1 then
self.last_index = self.next_index
end
end
end
end
----------------------------------Âåéïîèíòû - Êîíåö-------------------------------------------------
--' printf("Dist To Dest Point: %s", self.heliObject:GetDistanceToDestPosition())
--' printf("heli_move:waypoint_callback(): name=%s, index=%d", self.object:name(), index)
self.was_callback = true
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder( npc, ini, scheme, section, storage )
printf( "DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section )
local new_action = heli_move( npc, storage )
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events( npc, storage, new_action )
end
function set_scheme( npc, ini, scheme, section )
local a = xr_logic.assign_storage_and_bind( npc, ini, scheme, section )
a.logic = xr_logic.cfg_get_switch_conditions( ini, section, npc )
a.path_move = utils.cfg_get_string( ini, section, "path_move", npc, true, "")
a.path_look = utils.cfg_get_string( ini, section, "path_look", npc, false, "")
a.max_velocity = utils.cfg_get_number( ini, section, "max_velocity", npc, true, max_velocity )
a.enemy_ = utils.cfg_get_string( ini, section, "enemy", npc, false, "")
a.fire_point = utils.cfg_get_string( ini, section, "fire_point", npc, false, "")
a.max_mgun_dist = utils.cfg_get_number( ini, section, "max_mgun_attack_dist", npc, false )
a.max_rocket_dist = utils.cfg_get_number( ini, section, "max_rocket_attack_dist", npc, false )
a.min_mgun_dist = utils.cfg_get_number( ini, section, "min_mgun_attack_dist", npc, false )
a.min_rocket_dist = utils.cfg_get_number( ini, section, "min_rocket_attack_dist", npc, false )
a.use_rocket = utils.cfg_get_bool( ini, section, "use_rocket", npc, false, true )
a.use_mgun = utils.cfg_get_bool( ini, section, "use_mgun", npc, false, true )
a.engine_sound = utils.cfg_get_bool( ini, section, "engine_sound", npc, false, true )
a.upd_vis = utils.cfg_get_number( ini, section, "upd_vis", npc, false, 10 )
a.stop_fire = utils.cfg_get_bool( ini, section, "stop_fire", npc, false, false )
a.show_health = utils.cfg_get_bool( ini, section, "show_health", npc, false, false )
a.fire_trail = utils.cfg_get_bool( ini, section, "fire_trail", npc, false, false )
local st = db.storage[npc:id()]
st.invulnerable = utils.cfg_get_bool( ini, section, "invulnerable", npc, false, false )
st.immortal = utils.cfg_get_bool( ini, section, "immortal", npc, false, false )
st.mute = utils.cfg_get_bool( ini, section, "mute", npc, false, false )
end

View file

@ -0,0 +1,63 @@
-- çâóê ðåàêöèè ïèëîòîâ âåðòîë¸òà íà ðàçíûå ñîáûòèÿ
-- ×óãàé
snd_see_enemy = {
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_1]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_2]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_3]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_4]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_5]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_6]] ),
xr_sound.get_safe_sound_object( [[helicopter\see_enemy_7]] )
}
snd_hit = {
xr_sound.get_safe_sound_object( [[helicopter\hit_1]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_2]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_3]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_4]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_5]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_6]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_7]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_8]] ),
xr_sound.get_safe_sound_object( [[helicopter\hit_9]] )
}
snd_damaged = {
xr_sound.get_safe_sound_object( [[helicopter\damage_1]] ),
xr_sound.get_safe_sound_object( [[helicopter\damage_2]] ),
xr_sound.get_safe_sound_object( [[helicopter\damage_3]] ),
xr_sound.get_safe_sound_object( [[helicopter\damage_4]] )
}
snd_down = {
xr_sound.get_safe_sound_object( [[helicopter\death_1]] ),
xr_sound.get_safe_sound_object( [[helicopter\death_2]] ),
xr_sound.get_safe_sound_object( [[helicopter\death_3]] ),
xr_sound.get_safe_sound_object( [[helicopter\death_4]] ),
xr_sound.get_safe_sound_object( [[helicopter\death_5]] ),
xr_sound.get_safe_sound_object( [[helicopter\death_6]] )
}
--------------------------------------------------------------------------------
function play_snd( st, snd_set, priority )
if not st.mute and
( not st.snd_obj or
not st.snd_obj:playing() or
st.snd_priority < priority )
then
stop_snd( st )
st.snd_obj = snd_set[math.random( 1, #snd_set )]
st.snd_obj:play( db.actor, 0, sound_object.s2d )
st.snd_priority = priority
end
end
function stop_snd( st )
if st.snd_obj then
st.snd_obj:stop()
end
end

View file

@ -0,0 +1,244 @@
---------------------------------------------------------------------------------------------
--' funtions for upgerade items ----------------------------------------------------
--' Made by Distemper ----------------------------------------------------------------
--' 03.08 --------------------------------------------------------------------------------
--' ôóíêöèÿ äîñòóïíîñòè àïãðåéäà
--' function precondition_functor_a( param1, section )
--' ôóíêöèÿ ïðèìåíåíèÿ àïãðåéäà (îòíèìàíèå äåíåã)
--' function effect_functor_a( param2, section )
--' ôóíêöèÿ îòîáðàæåíèÿ íóæíûõ ñäåäñòâ äëÿ àïãðåéäà
--' function prereq_functor_a( param3, section )
--' ôóíêöèÿ âðåìåííî íå èñïîëüçóåòüñÿ
--' function prereq_tooltip_functor_a( param3 )
--' ôóíêöèè äëÿ îòîáðàæåíèÿ ñâîéñòâ àïãðåéäîâ
--' function property_functor_a( param1, name )
--' function property_functor_b( param1, name )
--' function property_functor_c( param1, name )
--' ôóíêöèÿ äëÿ îòîáðàæåíèÿ ñïåöèàëèçàöèè òåõíèêà
--------------------------------------------------------------------------------------------
cur_hint = nil
local issue_condlist = true
local mechanic_name = ""
local char_ini = ini_file("item_upgrades.ltx")
local param_ini = ini_file("misc\\stalkers_upgrade_info.ltx")
local cur_price_percent = 1
function precondition_functor_a( param1, section )
if(param_ini:line_exist(mechanic_name.."_upgr", section)) then
local param = param_ini:r_string(mechanic_name.."_upgr", section)
if(param) then
if(param=="false") then
return 1
elseif(param~="true") then
local possibility_table = xr_logic.parse_condlist(victim, mechanic_name.."_upgr", section, param)
local possibility = xr_logic.pick_section_from_condlist(db.actor, victim, possibility_table)
if not(possibility) or (possibility=="false") then
return 2
end
end
end
end
if(db.actor) then
local price = math.floor(char_ini:r_u32(section, "cost")*cur_price_percent)
local cash = db.actor:money()
if(cash<price) then
return 2
end
end
return 0
end
function effect_functor_a( param2, section, loading ) --( string, string, int )
if loading == 0 then
local money = char_ini:r_u32(section, "cost")
db.actor:give_money(math.floor(money*-1*cur_price_percent))
end
end
function get_upgrade_cost(section)
if db.actor then
local price = math.floor(char_ini:r_u32(section, "cost")*cur_price_percent)
return game.translate_string("st_upgr_cost")..": "..price
end
return " "
end
function get_possibility_string(mechanic_name, possibility_table)
local str = ""
if(cur_hint) then
for k,v in pairs(cur_hint) do
str = str.."\\n - "..game.translate_string(v)
end
end
if(str=="") then
str = " - add hints for this upgrade"
end
return str
end
function prereq_functor_a( param3, section )
local str = ""
if(param_ini:line_exist(mechanic_name.."_upgr", section)) then
local param = param_ini:r_string(mechanic_name.."_upgr", section)
if(param) then
if(param=="false") then
return str
else
cur_hint = nil
local possibility_table = xr_logic.parse_condlist(victim, mechanic_name.."_upgr", section, param)
local possibility = xr_logic.pick_section_from_condlist(db.actor, victim, possibility_table)
if not(possibility) or (possibility=="false") then
str = str..get_possibility_string(mechanic_name, possibility_table)
end
end
end
end
if(db.actor) then
local price = math.floor(char_ini:r_u32(section, "cost")*cur_price_percent)
local cash = db.actor:money()
if(cash<price) then
return str.."\\n - "..game.translate_string("st_upgr_enough_money")--.." "..price-cash.." RU"
end
end
return str
end
function property_functor_a( param1, name )
local prorerty_name = char_ini:r_string(name, "name")
local t_prorerty_name = game.translate_string(prorerty_name)
local section_table = utils.parse_names(param1)
local section_table_n = #section_table
local section = section_table[1]
if(section_table_n==0) then
return ""
end
local value = 0
local sum = 0
for i = 1,section_table_n do
if not(char_ini:line_exist(section_table[i], "value")) or not(char_ini:r_string(section_table[i], "value")) then
return t_prorerty_name
end
value = char_ini:r_string(section_table[i], "value")
if(name~="prop_night_vision") then
sum = sum + tonumber(value)
else
sum = tonumber(value)
end
end
if(sum<0) then
value = sum
else
value = "+"..sum
end
if(name=="prop_ammo_size" or name=="prop_artefact") then
return t_prorerty_name.." "..value
elseif(name=="prop_restore_bleeding" or name=="prop_restore_health" or name=="prop_power") then
if(name=="prop_power") then
value = "+"..tonumber(value)*2
end
-- local str = string.format("%s %4.1f", t_prorerty_name, value)
-- return str
return t_prorerty_name.." "..value
elseif(name=="prop_tonnage" or name=="prop_weightoutfit" or name=="prop_weight") then
local str = string.format("%s %5.2f %s", t_prorerty_name, value, game.translate_string("st_kg"))
return str
elseif(name=="prop_night_vision") then
if(tonumber(value)==1) then
return t_prorerty_name
else
return game.translate_string(prorerty_name.."_"..tonumber(value))
end
elseif(name=="prop_no_buck" or name=="prop_autofire") then
return t_prorerty_name
end
return t_prorerty_name.." "..value.."%"
end
function property_functor_b( param1, name )
return issue_property( param1, name )
end
function property_functor_c( param1, name )
return issue_property( param1, name )
end
function need_victim(obj)
victim = obj
end
function issue_property( param1, name )
local prorerty_name = char_ini:r_string(name, "name")
local t_prorerty_name = game.translate_string(prorerty_name)
local value_table = utils.parse_names(param1)
local section = value_table[1]
if section then
if not char_ini:line_exist(section, "value") or not char_ini:r_string(section, "value") then
return t_prorerty_name
end
local value = char_ini:r_string(section, "value")
return t_prorerty_name.." "..string.sub(value, 2, -2)
else
return t_prorerty_name
end
end
local function how_much_repair( item_name, item_condition )
local ltx = system_ini()
local cost = ltx:r_u32(item_name, "cost")
local class = ltx:r_string(item_name, "class")
local cof = 0.6
return math.floor(cost*(1-item_condition)*cof * cur_price_percent)
end
function can_repair_item( item_name, item_condition, mechanic ) --( string, float, string )
if(item_name=="pri_a17_gauss_rifle") then
return false
end
local price = how_much_repair( item_name, item_condition )
if db.actor:money() < price then
return false
end
return true
end
function question_repair_item( item_name, item_condition, can, mechanic ) --( string, float, bool, string )
if(item_name=="pri_a17_gauss_rifle") then
return game.translate_string("st_gauss_cannot_be_repaired")
end
local price = how_much_repair( item_name, item_condition )
if db.actor:money() < price then
return game.translate_string("st_upgr_cost")..": "..price.." RU\\n"..game.translate_string("ui_inv_not_enought_money")..": "..price-db.actor:money().." RU"
end
return game.translate_string("st_upgr_cost").." "..price.." RU. "..game.translate_string("ui_inv_repair").."?"
end
function effect_repair_item( item_name, item_condition )
if mechanic_name ~= "kat_cs_commander" then
local price = how_much_repair( item_name, item_condition )
db.actor:give_money(-price)
end
end
function can_upgrade_item( item_name, mechanic )
mechanic_name = mechanic
setup_discounts()
if param_ini:line_exist(mechanic, "he_upgrade_nothing") then
return false
end
if not param_ini:line_exist(mechanic, item_name) then
return false
end
return true
end
function setup_discounts()
if param_ini:line_exist(mechanic_name, "discount_condlist") then
local condlist = param_ini:r_string(mechanic_name, "discount_condlist")
local parsed = xr_logic.parse_condlist(db.actor, nil, nil, condlist)
xr_logic.pick_section_from_condlist(db.actor, nil, parsed)
end
end
function mech_discount(perc)
cur_price_percent = perc
end

View file

@ -0,0 +1,49 @@
math.randomseed(time_global())
_G.isMarshal = marshal ~= nil
_G.isLfs = lfs ~= nil
_G.bit_and = bit.band
_G.bit_or = bit.bor
_G.bit_xor = bit.bxor
_G.bit_not = bit.bnot
--// Some X-Ray block
_G.DebugLog = false
_G.log = function (str)
if DebugLog then
SemiLog(str)
end
if DebuggerMode then
LuaPanda.printToVSCode(str,1,2)
end
end
function register(object_factory)
class_registrator.cs_register(object_factory, "CCar", "se_car.se_car", "SCRPTCAR", "car_s")
end
_G.convert_class_name = function(obj)
if obj then
local name = class_info(obj).name
if name == "game_object" then
return "client"
else
return "server"
end
else
return "nil"
end
end
_G.g_EnablePrintfXRScript = false
-- используется для выявления сигнатур функций которые заложены в xr_conditions
_G.printf_xrscript = function(fmt, ...)
if g_EnablePrintfXRScript then
log(debug.traceback(1))
printf(fmt, ...)
end
end

View file

@ -0,0 +1,47 @@
local intercepts =
{
save = {},
load = {},
update = {},
save_state = {},
load_state = {}
}
function RegisterScriptCallback(name, func_or_userdata)
if (func_or_userdata == nil) then
SemiLog("! func_or_userdata == nil")
callstack()
end
if (name == nil) then
SemiLog("! name == nil")
callstack()
end
if (intercepts == nil) then
SemiLog("! intercepts == nil")
callstack()
end
if (intercepts[name]) then
intercepts[name][func_or_userdata] = true
end
end
function UnregisterScriptCallback(name, func_or_userdata)
if (intercepts[name]) then
intercepts[name][func_or_userdata] = nil
end
end
function SendScriptCallback(name,...)
if (intercepts[name]) then
for func_or_userdata,v in pairs(intercepts[name]) do
if (type(func_or_userdata) == "function") then
func_or_userdata(...)
elseif (func_or_userdata[name]) then
func_or_userdata[name](func_or_userdata,...)
end
end
end
end

View file

@ -0,0 +1,34 @@
--// General
jit.opt.start(2)
string.gfind = string.gmatch
math.mod = math.fmod
--// LuaPandas
DebuggerMode = false
function debug_jit_off()
if DebuggerMode then
if jit then jit.off() end
end
end
function debug_jit_on()
if DebuggerMode then
if jit then jit.on() end
end
end
function debugger_attach()
if DebuggerMode then
debug_jit_off()
LuaPanda.reConnect()
debug_jit_on()
else
debug_jit_off()
SemiLog('LuaPanda starting...')
LuaPanda.start("127.0.0.1", 8818)
DebuggerMode = true
debug_jit_on()
end
end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,149 @@
-----------------------------------------------------------------------------
-- LuaSocket helper module
-- Author: Diego Nehab
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local string = require("string")
local math = require("math")
local socket = require("socket.core")
local _M = socket
-----------------------------------------------------------------------------
-- Exported auxiliar functions
-----------------------------------------------------------------------------
function _M.connect4(address, port, laddress, lport)
return socket.connect(address, port, laddress, lport, "inet")
end
function _M.connect6(address, port, laddress, lport)
return socket.connect(address, port, laddress, lport, "inet6")
end
function _M.bind(host, port, backlog)
if host == "*" then host = "0.0.0.0" end
local addrinfo, err = socket.dns.getaddrinfo(host);
if not addrinfo then return nil, err end
local sock, res
err = "no info on address"
for i, alt in base.ipairs(addrinfo) do
if alt.family == "inet" then
sock, err = socket.tcp4()
else
sock, err = socket.tcp6()
end
if not sock then return nil, err end
sock:setoption("reuseaddr", true)
res, err = sock:bind(alt.addr, port)
if not res then
sock:close()
else
res, err = sock:listen(backlog)
if not res then
sock:close()
else
return sock
end
end
end
return nil, err
end
_M.try = _M.newtry()
function _M.choose(table)
return function(name, opt1, opt2)
if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1
end
local f = table[name or "nil"]
if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
else return f(opt1, opt2) end
end
end
-----------------------------------------------------------------------------
-- Socket sources and sinks, conforming to LTN12
-----------------------------------------------------------------------------
-- create namespaces inside LuaSocket namespace
local sourcet, sinkt = {}, {}
_M.sourcet = sourcet
_M.sinkt = sinkt
_M.BLOCKSIZE = 2048
sinkt["close-when-done"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function(self, chunk, err)
if not chunk then
sock:close()
return 1
else return sock:send(chunk) end
end
})
end
sinkt["keep-open"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function(self, chunk, err)
if chunk then return sock:send(chunk)
else return 1 end
end
})
end
sinkt["default"] = sinkt["keep-open"]
_M.sink = _M.choose(sinkt)
sourcet["by-length"] = function(sock, length)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function()
if length <= 0 then return nil end
local size = math.min(socket.BLOCKSIZE, length)
local chunk, err = sock:receive(size)
if err then return nil, err end
length = length - string.len(chunk)
return chunk
end
})
end
sourcet["until-closed"] = function(sock)
local done
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function()
if done then return nil end
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
if not err then return chunk
elseif err == "closed" then
sock:close()
done = 1
return partial
else return nil, err end
end
})
end
sourcet["default"] = sourcet["until-closed"]
_M.source = _M.choose(sourcet)
return _M

View file

@ -0,0 +1,35 @@
need_jump = false
local levels = {
zaton = "jupiter",
jupiter = "jupiter_underground",
jupiter_underground = "pripyat",
pripyat = "labx8",
labx8 = "end",
}
function try_to_jump()
local dest_level
if need_jump == true then
local console = get_console()
console:execute("flush")
console:execute("save build_save_" .. tostring(time_global()) )
for k,v in pairs(levels) do
if level.name() == k then
if v ~= "end" then
dest_level = v
else
printf("BUILD:QUIT!!!")
need_jump = false
dest_level = "zaton"
end
printf("BUILD:jumping to level [%s] from level [%s]", tostring(dest_level), tostring(k))
console:execute("flush")
console:execute("jump_to_level "..dest_level)
break
end
end
end
end

View file

@ -0,0 +1,4 @@
function main ()
db.actor:give_info_portion("zat_b38_underground_door_open")
db.actor:give_info_portion("zat_b38_disappearance_stalkers_find_to_be_missing_hunter_give")
end

View file

@ -0,0 +1,180 @@
class "PsyAntennaPP" (effector)
function PsyAntennaPP:__init() super(1001,10000000)
self.params = effector_params();
end
function PsyAntennaPP:process(pp)
pp:assign (self.params);
effector.process(self,pp);
return true;
end
class "PsyAntenna"
pa_phase={
phIdle = 0,
phStarting = 1,
phWorking = 2,
phStopping = 3
}
function PsyAntenna:__init ()
-- ----------------------------------------------------------------------------------------
-- settings
-- ----------------------------------------------------------------------------------------
-- phantom gen
-- ----------------------------------------------------------------------------------------
self.phantom_max = 0 --8 --10 --max phantoms
self.phantom_spawn_probability = 0.1; -- spawn probability (0..1)
self.phantom_spawn_radius = 30.0; -- average radius 30.0m +-15m
self.phantom_spawn_height = 2.5 --3 -- average height from actor pos +-1.5m
-- antenna
self.hit_amplitude = 1.0; -- hit_amplitude*hit_factor.a
-- pause time [from]=to
self.idle_time = {};
self.idle_time[20] = 21;
-- ----------------------------------------------------------------------------------------
-- postprocess
-- ----------------------------------------------------------------------------------------
self.base_amplitude = color(0.2,0.15,0.0); -- max base color diff [0.0-0.5]
self.gray_amplitude = 0.5; -- gray max intensity [0.0-1.0]
self.add_factor = 0.1; --0.3 -- factor * color_animator(RGB) [0.0-1.0]
self.dual_amplitude = 0.075 --0.05 -- H&V same [0.0-0.2]
self.gray_color = color(0.33,0.33,0.33); -- RGB [0.0-1.0]
self.noise_var = noise(0.9,0.3,30); -- intensity, grain, fps [0.0-1.0,0.0-1.0,1-100]
-- ----------------------------------------------------------------------------------------
-- class variables initialize
self.phase = pa_phase.phIdle;
self.power_factor = fcolor();
self.eff_time = 0;
self.starting_anim = color_animator ("levels\\psy_antenna\\starting");
self.starting_time = self.starting_anim:length ();
self.working_anim = color_animator ("levels\\psy_antenna\\working");
self.stopping_anim = color_animator ("levels\\psy_antenna\\stopping");
self.stopping_time = self.stopping_anim:length();
self.hit_time = 0;
self.intensity = 0;
self.pp = PsyAntennaPP();
self.pp:start ();
end
function PsyAntenna:__finalize ()
self.pp:finish ();
end;
g_PsyAntenna = PsyAntenna();
function PsyAntenna:construct ()
end
function PsyAntenna:load (packet)
set_save_marker(packet, "load", false, "psy_antenna")
self.phase = packet:r_u32()
set_save_marker(packet, "load", true, "psy_antenna")
end
function PsyAntenna:save (packet)
set_save_marker(packet, "save", false, "psy_antenna")
packet:r_u32 (self.phase)
set_save_marker(packet, "save", true, "psy_antenna")
end
function PsyAntenna:is_idle_time (tm)
if tm>=13 and tm<14 then return true;
elseif tm>=20 and tm<21 then return true;
end;
return false;
end
function PsyAntenna:update_postprocess ()
self.pp.params.color_base = color(0.5+self.base_amplitude.r*self.intensity,0.5+self.base_amplitude.g*self.intensity,0.5+self.base_amplitude.b*self.intensity);
self.pp.params.color_gray = color(self.gray_color.r,self.gray_color.g,self.gray_color.b);
self.pp.params.color_add = color(self.power_factor.r*self.add_factor,self.power_factor.g*self.add_factor,self.power_factor.b*self.add_factor);
self.pp.params.gray = self.gray_amplitude*self.intensity;
self.pp.params.dual = duality(self.dual_amplitude*self.power_factor.a,self.dual_amplitude*self.power_factor.a);
-- self.pp.params.noise = self.noise_var;
end
function PsyAntenna:update_psy_hit (dt)
local d_time = time_global()-self.hit_time;
if d_time>200 and self.power_factor.a>0.01 then
self.hit_time = time_global();
local psy_hit = hit();
psy_hit.power = self.power_factor.a*self.hit_amplitude;
psy_hit.direction = vector():set( 0, 0, 0 );
psy_hit.impulse = 0;
psy_hit.draftsman = db.actor;
psy_hit.type = hit.telepatic;
db.actor:hit (psy_hit);
end;
end
function PsyAntenna:generate_phantoms ()
if self.power_factor.a>0.1 then
if math.random()<self.phantom_spawn_probability then
if phantom_manager:phantom_count()<self.phantom_max then
local yaw = math.pi*2.0*math.random();
local radius = self.phantom_spawn_radius*(math.random()/2.0+0.5);
local height = self.phantom_spawn_height*math.random();
local a_pos = db.actor:position();
local pos = vector():set(math.sin(yaw)*radius+a_pos.x,a_pos.y+height,math.cos(yaw)*radius+a_pos.z);
phantom_manager.spawn_phantom(pos);
end;
end;
end;
end
function PsyAntenna:switch_to_phase (ph)
self.phase = ph;
self.eff_time = 0;
self.power_factor:set (0,0,0,0);
end
function PsyAntenna:phase_starting ()
self.intensity = self.eff_time/self.starting_time;
if self.eff_time>self.starting_time then
self:switch_to_phase (pa_phase.phWorking);
else
self.power_factor:set (self.starting_anim:calculate(self.eff_time/1000));
end;
end
function PsyAntenna:phase_working ()
self.intensity = 1.0;
local h = level.get_time_hours();
if self:is_idle_time(h) then
self:switch_to_phase (pa_phase.phStopping);
else
self.power_factor:set (self.working_anim:calculate(self.eff_time/1000));
self:generate_phantoms ();
end;
end
function PsyAntenna:phase_stopping ()
self.intensity = 1.0-self.eff_time/self.stopping_time;
if self.eff_time>self.stopping_time then
self:switch_to_phase (pa_phase.phIdle);
else
self.power_factor:set (self.stopping_anim:calculate(self.eff_time/1000));
end;
end
function PsyAntenna:phase_idle ()
local h = level.get_time_hours();
if false==self:is_idle_time(h) then
self:switch_to_phase (pa_phase.phStarting);
end;
end
function PsyAntenna:update (dt)
self.eff_time = self.eff_time + dt;
if self.phase==pa_phase.phStarting then self:phase_starting ();
elseif self.phase==pa_phase.phWorking then self:phase_working ();
elseif self.phase==pa_phase.phStopping then self:phase_stopping ();
elseif self.phase==pa_phase.phIdle then self:phase_idle (); end;
if (self.intensity<0.0) then self.intensity=0.0; end;
if (self.intensity>1.0) then self.intensity=1.0; end;
self:update_postprocess ();
self:update_psy_hit (dt);
end
function main()
while db.actor==nil do wait(); end;
if false==has_alife_info("psy_antenna_off") then
g_PsyAntenna:construct ();
local prev_time = time_global();
while 1 do
wait ();
local dt = time_global()-prev_time;
prev_time = time_global();
g_PsyAntenna:update (dt);
end
end
end

View file

@ -0,0 +1,240 @@
local weather_manager = nil
--18.02.2008 - added dynamic weather
class "WeatherManager"
function WeatherManager:__init()
self.wfx_time = 0
self.weather_fx = nil
self.update_time = 0
self.update_level = ""
self.forced_weather_change_on_time_change = false
self.last_hour = 0
self.state={}
self.graphs={}
self.graphs_ini = ini_file("environment\\dynamic_weather_graphs.ltx")
if not self.graphs_ini then
abort("error when open weather_dynamic_graphs.ltx")
end
end
-- Âûçûâàåòñÿ ïîñëå load(). Ñîñòîÿíèå ïîãîäû óæå çàãðóæåíî.
function WeatherManager:reset()
printf("WeatherManager:WeatherManager():Reset()")
-- Çàãðóçèòü êîíäëèñò ñ ïîãîäîé.
local ini = ini_file("game.ltx")
local weather = utils.cfg_get_string(ini, level.name(), "weathers", db.actor, false, "", "[default]")
local postprocess = utils.cfg_get_string(ini, level.name(), "postprocess", db.actor, false, "")
if postprocess ~= nil then
printf("LEVEL POSTPROCESS: level: [%s], postprocess: [%s]", level.name(), postprocess)
level.add_pp_effector(postprocess, 999, true)
else
printf("LEVEL POSTPROCESS: level: [%s], postprocess: [none]", level.name())
level.remove_pp_effector(999)
end
if weather == "[default]" then
-- ñåòèì äåôîëòîâóþ ïîãîäó
self.weather_list = xr_logic.parse_condlist(db.actor, level.name(), "weather", "[default]")
else
self.weather_list = xr_logic.parse_condlist(db.actor, level.name(), "weather", weather)
end
self:select_weather(true)
self.last_hour=level.get_time_hours()
end
function WeatherManager:forced_weather_change()
self.forced_weather_change_on_time_change = true
end
-- Îáíîâëÿåì ïîãîäó ðàç â ÷àñ.
function WeatherManager:update()
if(level.is_wfx_playing()) then
self.weather_fx = level.get_weather()
else
self.weather_fx = nil
end
if not benchmark.weather then
if self.last_hour~=level.get_time_hours() then
self.last_hour=level.get_time_hours()
for lvl,st in pairs(self.state) do
st.current_state=st.next_state
st.next_state=get_next_state(st.graph,st.current_state)
end
-- Óñòàíàâëèâàåì ïîãîäó íà òåêóùåì óðîâíå
self:select_weather(false)
end
end
end
function WeatherManager:select_weather(now)
local weather = xr_logic.pick_section_from_condlist(db.actor, db.actor, self.weather_list)
local graph=self:get_graph_by_name(weather)
local weather_section_name=""
-- Ïðîâåðèì, ñîâïàäàåò ëè òåêóùèé ãðàô óðîâíÿ ñ ïîëó÷åííûì ïî êîíäëèñòó...
if graph==nil then
-- Ïåðåõîäèì íà ñòàòèêó
self.state[weather]=nil
weather_section_name=weather
else
-- Íîâàÿ ïîãîäà - äèíàìè÷åñêàÿ. Ïðîâåðèì, íóæíî ëè ìåíÿòü/óñòàíàâëèâàòü ãðàô
if self.state[weather]==nil or self.state[weather].graph_name~=weather then
-- Ãðàô èçìåíèëñÿ. Ïåðåõîäèì íà íåãî.
self.state[weather]=self:init_by_graph(graph,weather)
-- else
-- now = false
end
-- Ïîëó÷àåì íàçâàíèå ñåêöèè ïî òåêóùåìó ñîñòîÿíèþ.
local st=self.state[weather]
--weather_section_name="dw_"..st.current_state.."_"..st.next_state.."_"..level.get_time_hours()
weather_section_name="default_"..st.current_state
end
if now then
self.last_hour=level.get_time_hours()
end
if self.forced_weather_change_on_time_change then
now = true
self.forced_weather_change_on_time_change = false
end
if not(self.weather_fx) then
level.set_weather(weather_section_name,now)
else
level.start_weather_fx_from_time(self.weather_fx, self.wfx_time)
end
printf("WEATHER: '%s' now '%s'", weather_section_name, tostring(now))
-- if xrs_news then
-- xrs_news.news_call(1,1,nil,nil,weather_section_name,nil)
-- end
end
-- Âîçâðàùàåò íà÷àëüíîå ñîñòîÿíèå ïîãîäû.
function WeatherManager:init_by_graph(graph,graph_name)
local cur_state=get_next_state(graph,"")
local next_state=get_next_state(graph,cur_state)
return {current_state=cur_state,next_state=next_state,graph_name=graph_name,graph=graph}
end
-- Âîçâðàùàåò îäíî èç ñëåäóþùèõ ñîñòîÿíèé ãðàôà, ñîãëàñíî ïðîïèñàííûì âåðîÿòíîñòÿì.
function get_next_state(graph,state)
local sum=0
for st,prob in pairs(graph) do
--if state==st then prob=prob*2 end
sum=sum+prob
end
local rnd=math.random()*sum
local next_state
for st,prob in pairs(graph) do
--if state==st then prob=prob*2 end
next_state=st
rnd=rnd-prob
if (rnd<=0) then
break
end
end
return next_state
end
-- Óñòàíàâëèâàåì ñîñòîÿíèå ìåíåäæåðà, ðàñïàðñèâàÿ ñòðîêó ñîñòîÿíèÿ
function WeatherManager:set_state_as_string(ss)
self.state={}
for lvlstring in string.gmatch(ss,"[^;]+") do
local i,j,grname,curs,nexs=string.find(lvlstring,"([^=]+)=([^,]+),([^,]+)")
if not grname then
abort("WeatherManager:set_state_as_string: malformed state string. "..ss)
end
--local lvl_name=self:unpack_level(lvl)
local current_state=self:unpack_state(curs)
local next_state=self:unpack_state(nexs)
local graph_name=self:unpack_graph_name(grname)
local graph=self:get_graph_by_name(graph_name)
if graph==nil then
-- Ñòàðàÿ ñîõðàí¸íêà? Áóäåì ñ÷èòàòü ÷òî íà ýòîì óðîâíå - ñòàòè÷åñêàÿ ïîãîäà
else
self.state[graph_name]={current_state=current_state,next_state=next_state,graph_name=graph_name,graph=graph}
end
end
end
-- Ïðåîáðàçóåì òåêóùåå ñîñòîÿíèå ìåíåäæåðà â ñòðîêó
function WeatherManager:get_state_as_string()
local lvlstrings={}
for lvl_name,st in pairs(self.state) do
--local lvl=self:pack_level(lvl_name)
local curs=self:pack_state(st.current_state)
local nexs=self:pack_state(st.next_state)
local grn=self:pack_graph_name(st.graph_name)
table.insert(lvlstrings,grn.."="..curs..","..nexs)
end
return table.concat(lvlstrings,";")
end
-- Ïîëó÷èòü ãðàô (òàáëèöó ïåðåõîäîâ ñîñòîÿíèé ïîãîäû) ïî åãî íàçâàíèþ è íàçâàíèþ èãðîâîãî óðîâíÿ
function WeatherManager:get_graph_by_name(name)
if not self.graphs[name] then
self.graphs[name] = xr_s.parse_ini_section_to_array(self.graphs_ini,name)
end
return self.graphs[name]
end
-- Çàïàêîâàòü íàçâàíèå âåðøèíû ãðàôà
function WeatherManager:pack_state(state)
-- Ïîêà ïàêîâàòü íå áóäåì.
return state
end
-- Ðàñïàêîâàòü íàçâàíèå âåðøèíû ãðàôà
function WeatherManager:unpack_state(st)
-- Ïîêà ïàêîâàòü íå áóäåì
return st
end
-- Çàïàêîâàòü íàçâàíèå ãðàôà ïåðåõîäîâ ïîãîäû
function WeatherManager:pack_graph_name(graph_name)
-- Ïîêà ïàêîâàòü íå áóäåì.
return graph_name
end
-- Ðàñïàêîâàòü íàçâàíèå ãðàôà ïåðåõîäîâ ïîãîäû
function WeatherManager:unpack_graph_name(grn)
-- Ïîêà ïàêîâàòü íå áóäåì
return grn
end
function WeatherManager:load(F)
set_save_marker(F, "load", false, "WeatherManager")
printf("WEATHER LOAD")
--self.update_level = F:r_stringZ();
local state_string = F:r_stringZ();
printf("str = "..state_string)
if state_string == "" then
printf("str = empty string")
end
self:set_state_as_string(state_string)
self.update_time = F:r_u32();
local str = F:r_stringZ()
if(str~="nil") then
self.weather_fx = str
self.wfx_time = F:r_float()
end
set_save_marker(F, "load", true, "WeatherManager")
end
function WeatherManager:save(F)
set_save_marker(F, "save", false, "WeatherManager")
printf("WEATHER SAVE")
--F:w_stringZ(self.update_level);
printf("str = "..tostring(self:get_state_as_string()))
if self:get_state_as_string() == "" then
printf("str = empty string")
end
F:w_stringZ(self:get_state_as_string())
F:w_u32(self.update_time)
F:w_stringZ(tostring(self.weather_fx))
if(self.weather_fx) then
F:w_float(level.get_wfx_time())
end
set_save_marker(F, "save", true, "WeatherManager")
end
function get_weather_manager ()
if weather_manager == nil then
weather_manager = WeatherManager()
end
return weather_manager
end

View file

@ -0,0 +1,196 @@
tips_table = {
[1] = "all",
[2] = "all",
[3] = "all",
[4] = "all",
[5] = "all",
[6] = "all",
[7] = "all",
[8] = "all",
[9] = "all",
[10] = "all",
[11] = "all",
[12] = "all",
[13] = "all",
[14] = "all",
[15] = "all",
[16] = "all",
[17] = "all",
[18] = "all",
[19] = "all",
[20] = "all",
[21] = "all",
[22] = "all",
[23] = "all",
[24] = "all",
[25] = "all",
[26] = "all",
[27] = "all",
[28] = "all",
[29] = "all",
[30] = "all",
[31] = "all",
[32] = "all",
[33] = "all",
[34] = "all",
[35] = "all",
[36] = "all",
[37] = "all",
[38] = "all",
[39] = "all",
[40] = "all",
[41] = "all",
[42] = "all",
[43] = "all",
[44] = "all",
[45] = "all",
[46] = "all",
[47] = "all",
[48] = "all",
[49] = "all",
[50] = "all",
[51] = "all",
[52] = "all",
[53] = "all",
[54] = "all",
[55] = "all",
[56] = "all",
[57] = "all",
[58] = "all",
[59] = "all",
[60] = "all",
[61] = "all",
[62] = "all",
[63] = "all",
[64] = "all",
[65] = "all",
[66] = "all",
[67] = "all",
[68] = "all",
[69] = "all",
[60] = "all",
[61] = "all",
[62] = "all",
[63] = "all",
[64] = "all",
[65] = "all",
[66] = "all",
[67] = "all",
[68] = "all",
[69] = "all",
[70] = "all",
[71] = "all",
[72] = "all",
[73] = "all",
[74] = "all",
[75] = "all",
[76] = "all",
[77] = "all",
[78] = "all",
[79] = "all",
[80] = "all",
[81] = "all",
[82] = "all",
[83] = "all",
[84] = "all",
[85] = "all",
[86] = "all",
[87] = "all",
[88] = "all",
[89] = "all",
[90] = "all",
[91] = "all",
[92] = "all",
[93] = "all",
[94] = "all",
[95] = "all",
[96] = "all",
[97] = "all",
[98] = "all",
[99] = "all",
[100] = "all",
}
mp_tips_table = {
[1] = "all",
[2] = "all",
[3] = "all",
[4] = "all",
[5] = "all",
[6] = "all",
[7] = "all",
[8] = "all",
[9] = "all",
[10] = "all",
[11] = "all",
[12] = "all",
[13] = "all",
[14] = "all",
[15] = "all",
[16] = "all",
[17] = "all",
[18] = "all",
[19] = "all",
[20] = "all",
[21] = "all",
[22] = "all",
[23] = "all",
[24] = "all",
[25] = "all",
[26] = "all",
[27] = "all",
[28] = "all",
[29] = "all",
[30] = "all",
[31] = "all",
[32] = "all",
[33] = "all",
[34] = "all",
[35] = "all",
[36] = "all",
[37] = "all",
[38] = "all",
[39] = "all",
[40] = "all",
[41] = "all",
[42] = "all",
[43] = "all",
[44] = "all",
[45] = "all",
[46] = "all",
[47] = "all",
[48] = "all",
[49] = "all",
[50] = "all",
[51] = "all",
[52] = "all",
[53] = "all",
[54] = "all",
[55] = "all",
}
function get_tip_number(level_name)
local tbl = {}
for i=1,#tips_table do
if(tips_table[i]==level_name or tips_table[i]=="all") then
table.insert(tbl, i)
end
end
if(#tbl==0) then
return 1
else
return tbl[math.random(#tbl)]
end
end
function get_mp_tip_number(level_name)
local tbl = {}
for i=1,#tips_table do
if(mp_tips_table[i]==level_name or mp_tips_table[i]=="all") then
table.insert(tbl, i)
end
end
if(#tbl==0) then
return 1
else
return tbl[math.random(#tbl)]
end
end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,117 @@
local base = _G
local xml = xml
module("xml")
-- symbolic name for tag index, this allows accessing the tag by var[xml.TAG]
TAG = 0
-- sets or returns tag of a LuaXML object
function tag(var,tag)
if base.type(var)~="table" then return end
if base.type(tag)=="nil" then
return var[TAG]
end
var[TAG] = tag
end
-- creates a new LuaXML object either by setting the metatable of an existing Lua table or by setting its tag
function new(arg)
if base.type(arg)=="table" then
base.setmetatable(arg,{__index=xml, __tostring=xml.str})
return arg
end
local var={}
base.setmetatable(var,{__index=xml, __tostring=xml.str})
if base.type(arg)=="string" then var[TAG]=arg end
return var
end
-- appends a new subordinate LuaXML object to an existing one, optionally sets tag
function append(var,tag)
if base.type(var)~="table" then return end
local newVar = new(tag)
var[#var+1] = newVar
return newVar
end
-- converts any Lua var into an XML string
function str(var,indent,tagValue)
if base.type(var)=="nil" then return end
local indent = indent or 0
local indentStr=""
for i = 1,indent do indentStr=indentStr.." " end
local tableStr=""
if base.type(var)=="table" then
local tag = var[0] or tagValue or base.type(var)
local s = indentStr.."<"..tag
for k,v in base.pairs(var) do -- attributes
if base.type(k)=="string" then
if base.type(v)=="table" and k~="_M" then -- otherwise recursiveness imminent
tableStr = tableStr..str(v,indent+1,k)
else
s = s.." "..k.."=\""..encode(base.tostring(v)).."\""
end
end
end
if #var==0 and #tableStr==0 then
s = s.." />\n"
elseif #var==1 and base.type(var[1])~="table" and #tableStr==0 then -- single element
s = s..">"..encode(base.tostring(var[1])).."</"..tag..">\n"
else
s = s..">\n"
for k,v in base.ipairs(var) do -- elements
if base.type(v)=="string" then
s = s..indentStr.." "..encode(v).." \n"
else
s = s..str(v,indent+1)
end
end
s=s..tableStr..indentStr.."</"..tag..">\n"
end
return s
else
local tag = base.type(var)
return indentStr.."<"..tag.."> "..encode(base.tostring(var)).." </"..tag..">\n"
end
end
-- saves a Lua var as xml file
function save(var,filename)
if not var then return end
if not filename or #filename==0 then return end
local file = base.io.open(filename,"w")
file:write("<?xml version=\"1.0\"?>\n<!-- file \"",filename, "\", generated by LuaXML -->\n\n")
file:write(str(var))
base.io.close(file)
end
-- recursively parses a Lua table for a substatement fitting to the provided tag and attribute
function find(var, tag, attributeKey,attributeValue)
-- check input:
if base.type(var)~="table" then return end
if base.type(tag)=="string" and #tag==0 then tag=nil end
if base.type(attributeKey)~="string" or #attributeKey==0 then attributeKey=nil end
if base.type(attributeValue)=="string" and #attributeValue==0 then attributeValue=nil end
-- compare this table:
if tag~=nil then
if var[0]==tag and ( attributeValue == nil or var[attributeKey]==attributeValue ) then
base.setmetatable(var,{__index=xml, __tostring=xml.str})
return var
end
else
if attributeValue == nil or var[attributeKey]==attributeValue then
base.setmetatable(var,{__index=xml, __tostring=xml.str})
return var
end
end
-- recursively parse subtags:
for k,v in base.ipairs(var) do
if base.type(v)=="table" then
local ret = find(v, tag, attributeKey,attributeValue)
if ret ~= nil then return ret end
end
end
end

View file

@ -0,0 +1,9 @@
function _printf(fmt,...)
log(string.format(fmt,...))
end
function collect_info(npc, type)
collectgarbage("collect")
collectgarbage("collect")
_printf("MEMUSAGE [%s]->[%s] %d Kb",npc:name(), type, collectgarbage("count"))
end

View file

@ -0,0 +1,344 @@
----------------------------------------------------------------------------------------------------
-- Mob Camp
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Jim
----------------------------------------------------------------------------------------------------
local STATE_CAMP = 1
local STATE_ALIFE = 2
local STATE_MOVE_HOME = 3
class "mob_camp"
----------------------------------------------------------------------------------------------------
-- CONSTRUCTION SCHEME
----------------------------------------------------------------------------------------------------
function mob_camp:__init(obj, storage)
self.object = obj
self.st = storage
end
----------------------------------------------------------------------------------------------------
-- RESET SCHEME
----------------------------------------------------------------------------------------------------
function mob_camp:reset_scheme()
printf("Camp: reset_scheme: %s", self.object:name())
xr_logic.mob_capture (self.object, true)
mob_state_mgr.set_state (self.object, db.actor, self.st.state)
-- reset signals
self.st.signals = {}
-- initialize look point
self.look_path = patrol(self.st.look_point)
if not self.look_path then
_G.abort("object '%s': unable to find look_point '%s' on the map",
self.object:name(), self.st.look_point)
end
-- initialize home point
if self.st.home_point then
self.home_path = patrol(self.st.home_point)
if not self.home_path then
_G.abort("object '%s': unable to find home_point '%s' on the map",
self.object:name(), self.st.home_point)
end
else
self.home_path = nil
end
-- checkings
-- if there is home path and look path - point count must be equal
if self.home_path then
if (self.home_path:count() ~= self.look_path:count()) then
_G.abort("object '%s': you must setup home path points count must be equal to look path points count!", self.object:name())
end
end
-- save position and node of object
self.camp_position = vector():set(self.object:position())
self.camp_node = self.object:level_vertex_id()
self.state_current = STATE_CAMP
self.state_prev = self.state_current
-- select cur point
self.cur_point_index = 0
self:select_current_home_point(true)
self.time_point_changed = time_global()
self.prev_enemy = false
-- check enemy transfering
if self.st.skip_transfer_enemy then
self.object:skip_transfer_enemy(true)
end
end
----------------------------------------------------------------------------------------------------
-- UPDATE
----------------------------------------------------------------------------------------------------
function mob_camp:update(delta)
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
-- if dead then release
if not self.object:alive() then
xr_logic.mob_release(self.object)
return
end
-- update point changer
if (self.time_point_changed + self.st.time_change_point < time_global()) then
self:select_current_home_point(false)
self.time_point_changed = time_global()
end
-- update fsm
self:select_state ()
self:execute_state ()
end
----------------------------------------------------------------------------------------------------
-- SERVICE FUNCTIONS
----------------------------------------------------------------------------------------------------
function mob_camp:select_current_home_point(first_call)
local prev_point_index = self.cur_point_index
if self.home_path then
-- fill table of free points
local free_points = {}
if (db.camp_storage[self.st.home_point] == nil) then
db.camp_storage[self.st.home_point] = {}
end
for i = 1, self.home_path:count() do
if (db.camp_storage[self.st.home_point][i] == nil) or
(db.camp_storage[self.st.home_point][i] == false) then
table.insert(free_points, i)
end
end
if (#free_points < 1) then
if first_call == true then
_G.abort("Mob_Camp : too many campers for home path")
end
else
local free_points_index = math.random(1, #free_points)
self.cur_point_index = free_points[free_points_index]-1
end
if not first_call then
if prev_point_index ~= self.cur_point_index then
db.camp_storage[self.st.home_point][prev_point_index+1] = false
end
end
db.camp_storage[self.st.home_point][self.cur_point_index+1] = true
else
self.cur_point_index = math.random(0, self.look_path:count() - 1)
end
end
---------------------------------------------------------------------------------
function mob_camp:select_state()
self.state_prev = self.state_current
local home_position = self.camp_position
local home_node = self.camp_node
if self.home_path then
home_position = self.home_path:point(self.cur_point_index)
home_node = self.home_path:level_vertex_id(self.cur_point_index)
end
-- if enemy
local enemy = self.object:get_enemy()
-- if enemy just appeared - signal
if enemy ~= nil then
if not self.prev_enemy then
self.st.signals["enemy"] = true
end
self.prev_enemy = true
else
self.prev_enemy = false
end
if enemy ~= nil then
local enemy_dist = enemy:position():distance_to(home_position)
--local my_dist = self.object:position():distance_to(home_position)
if (self.state_prev == STATE_MOVE_HOME) and (enemy_dist > self.st.home_min_radius) then
elseif (self.state_prev == STATE_ALIFE) and (enemy_dist > self.st.home_max_radius) then
self.state_current = STATE_MOVE_HOME
elseif (self.state_prev == STATE_CAMP) and (enemy_dist > self.st.home_min_radius) then
else
self.state_current = STATE_ALIFE
end
end
-- select MOVE_HOME OR CAMP
if (enemy == nil) or ((enemy ~= nil) and (self.state_current ~= STATE_ALIFE) ) then
-- check if we go home
if (home_position:distance_to(self.object:position()) > 1) and
(home_node ~= self.object:level_vertex_id()) then
self.state_current = STATE_MOVE_HOME
else
-- we are on place - camp!
self.state_current = STATE_CAMP
end
end
-- Îòïóñêàòü â alife ìîíñòðîâ, êîòîðûõ îáñòðåëÿëè
local h = self.object:get_monster_hit_info()
if (enemy == nil) and (h.who) and (h.time ~= 0) and (IsMonster(h.who) or IsStalker(h.who))then
local dist = self.object:position():distance_to(home_position)
if (dist < self.st.home_min_radius) then
self.state_current = STATE_ALIFE
end
end
end
----------------------------------
-- EXECUTE_STATE
function mob_camp:execute_state()
-- DBG
-- if (self.state_current ~= self.state_prev) then
-- local str1 = ""
-- local str2 = ""
--
-- if self.state_current == STATE_CAMP then str1 = "STATE_CAMP" end
-- if self.state_current == STATE_JUMP then str1 = "STATE_JUMP" end
-- if self.state_current == STATE_ALIFE then str1 = "STATE_ALIFE" end
-- if self.state_current == STATE_MOVE_HOME then str1 = "STATE_MOVE_HOME" end
--
-- if self.state_prev == STATE_CAMP then str2 = "STATE_CAMP" end
-- if self.state_prev == STATE_JUMP then str2 = "STATE_JUMP" end
-- if self.state_prev == STATE_ALIFE then str2 = "STATE_ALIFE" end
-- if self.state_prev == STATE_MOVE_HOME then str2 = "STATE_MOVE_HOME" end
--
-- printf("~MOB_CAMP: From [%s] To [%s]", str2, str1)
-- end
if (self.state_current == STATE_ALIFE) and (self.state_prev == STATE_ALIFE) then
return
end
if (self.state_current == STATE_ALIFE) and (self.state_prev ~= STATE_ALIFE) then
xr_logic.mob_release(self.object)
return
end
if (self.state_current ~= STATE_ALIFE) and (self.state_prev == STATE_ALIFE) then
xr_logic.mob_capture(self.object, true)
end
-- STATE_CAMP
if self.state_current == STATE_CAMP then
-- handle look point
if not self.object:action() then
action( self.object,
anim(anim.stand_idle),
look(look.point, self.look_path:point(self.cur_point_index)),
cond(cond.look_end)
)
end
return
end
-- STATE_MOVE_HOME
if self.state_current == STATE_MOVE_HOME then
if not self.object:action() then
local home_position = self.camp_position
local home_node = self.camp_node
if self.home_path then
home_position = self.home_path:point(self.cur_point_index)
home_node = self.home_path:level_vertex_id(self.cur_point_index)
end
action( self.object,
move(move.run_fwd,
home_node,
home_position),
cond(cond.move_end))
end
return
end
end
function mob_camp:deactivate()
if self.home_path then
db.camp_storage[self.st.home_point][self.cur_point_index+1] = false
end
self.object:skip_transfer_enemy(false)
end
function mob_camp:net_destroy()
if self.home_path then
db.camp_storage[self.st.home_point][self.cur_point_index+1] = false
end
self.object:skip_transfer_enemy(false)
end
----------------------------------------------------------------------------------------------------
-- ADD_TO_BINDER
----------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_camp(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
end
----------------------------------------------------------------------------------------------------
-- SET_SCHEME
----------------------------------------------------------------------------------------------------
function set_scheme(npc, ini, scheme, section, gulag_name)
local storage = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
storage.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
storage.state = mob_state_mgr.get_state(ini, section, npc)
storage.look_point = utils.cfg_get_string(ini, section, "path_look", npc, false, gulag_name)
storage.home_point = utils.cfg_get_string(ini, section, "path_home", npc, false, gulag_name)
storage.time_change_point = utils.cfg_get_number(ini, section, "time_change_point", npc, false, 10000)
storage.home_min_radius = utils.cfg_get_number(ini, section, "home_min_radius", npc, false, 30)
storage.home_max_radius = utils.cfg_get_number(ini, section, "home_max_radius", npc, false, 40)
-- check min and max radius
if storage.home_min_radius > storage.home_max_radius then
_G.abort("Mob_Camp : Home Min Radius MUST be < Max Radius")
end
-- check if there is look point (must be!)
if (not storage.look_point) or (not patrol(storage.look_point)) then
_G.abort("Mob_Camp : object '%s': unable to find look_point '%s' on the map",
npc:name(), storage.look_point)
end
-- load transfer enemy flag ()
storage.skip_transfer_enemy = ini:line_exist( section, "skip_transfer_enemy")
end

View file

@ -0,0 +1,47 @@
----------------------------------------------------------------------------------------------------
-- Mob combat
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
----------------------------------------------------------------------------------------------------
class "mob_combat"
function mob_combat:__init(obj, storage)
self.object = obj
self.st = storage
end
function mob_combat:combat_callback()
printf("_bp: mob_combat:combat_callback()")
if self.st.enabled and self.object:get_enemy() then
if db.storage[self.object:id()].active_scheme then
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
end
end
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_combat(npc, storage)
storage.action = new_action
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.enabled = true
end
function disable_scheme(npc, scheme)
local st = db.storage[npc:id()][scheme]
if st then
st.enabled = false
end
end

View file

@ -0,0 +1,44 @@
----------------------------------------------------------------------------------------------------
-- Mob death
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
----------------------------------------------------------------------------------------------------
class "mob_death"
function mob_death:__init(obj, storage)
self.object = obj
self.st = storage
end
function mob_death:death_callback(victim, who)
if who ~= nil then
printf("mob_death: [%s] killed by [%s]", victim:name(), who:name())
local death = db.storage[victim:id()].death
if not death then
death = {}
db.storage[victim:id()].death = death
end
death.killer = who:id()
death.killer_name = who:name()
else
printf("mob_death: [%s] killed by [Unknown]", victim:name())
death.killer = -1
death.killer_name = nil
end
if xr_logic.try_switch_to_another_section(victim, self.st, db.actor) then
return
end
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
local action = mob_death(npc, storage)
xr_logic.subscribe_action_for_events(npc, storage, action)
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)
end

View file

@ -0,0 +1,130 @@
----------------------------------------------------------------------------------------------------
-- Mob Home
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Jim
----------------------------------------------------------------------------------------------------
local def_min_radius = 10
local def_mid_radius = 20
local def_max_radius = 70
class "mob_home"
----------------------------------------------------------------------------------------------------
-- CONSTRUCTION SCHEME
----------------------------------------------------------------------------------------------------
function mob_home:__init(obj, storage)
self.object = obj
self.st = storage
end
----------------------------------------------------------------------------------------------------
-- RESET SCHEME
----------------------------------------------------------------------------------------------------
function mob_home:reset_scheme()
printf("DEBUG: reset_scheme: npc:name()='%s'", self.object:name())
--[[
Äîáàâëåíî: Haron
Îïèñàíèå: Òåïåðü ìîæíî çàäàâàòü ðàäèóñû home_min_radius è home_max_radius âî ôëàãàõ
ïóòè path_home. Äëÿ ýòîãî ââåäåíû ôëàãè minr, maxr. Îíè äîëæíû áûòü
ïðîïèñàíû â ïåðâîé òî÷êå ïóòè. Ó ðàäèóñîâ çàäàíûõ â ñåêöèè ïðèîðèòåò
áîëüøèé ÷åì äëÿ òåõ ÷òî çàäàíû âî ôëàãàõ, ò.å. åñëè çàäàíî è òàì è òàì, òî
áåðóòñÿ çíà÷åíèÿ èç ñåêöèè (ñäåëàíî äëÿ îáðàòíîé ñîâìåñòèìîñòè).
--]]
mob_state_mgr.set_state (self.object, db.actor, self.st.state)
local minr, maxr, midr = def_min_radius, def_max_radius, def_mid_radius
local ptr
local path_info
local r = 0
if self.st.home ~= nil then
ptr = patrol(self.st.home)
path_info = utils.parse_waypoint_data(self.st.home, ptr:flags(0), ptr:name(0))
end
if self.st.home_min_radius then
minr = self.st.home_min_radius
else
r = path_info.minr
if r then
r = tonumber(r)
if r then
minr = r
end
end
end
if self.st.home_max_radius then
maxr = self.st.home_max_radius
else
r = path_info.maxr
if r then
r = tonumber(r)
if r then
maxr = r
end
end
end
-- check min and max radius
if minr > maxr then
abort("Mob_Home : Home Min Radius MUST be < Max Radius. Got: min radius = %d, max radius = %d.", minr, maxr)
end
--printf("DEBUG: reset_scheme: [%s] setting home path [%s]", self.object:name(), self.st.home)
if self.st.home_mid_radius then
midr = self.st.home_mid_radius
if midr <= minr or midr >= maxr then
midr = minr + (maxr - minr)/2
end
else
midr = minr + (maxr - minr)/2
end
if self.st.gulag_point then
local smrttrn = alife():object(alife():object(self.object:id()).m_smart_terrain_id)
local lvid = smrttrn and smrttrn.m_level_vertex_id
self.object:set_home(lvid, minr, maxr, self.st.aggressive, midr)
else
self.object:set_home(self.st.home, minr, maxr, self.st.aggressive, midr)
end
--self.object:set_home(self.st.home, minr, maxr, self.st.aggressive)
end
----------------------------------------------------------------------------------------------------
-- UPDATE
----------------------------------------------------------------------------------------------------
function mob_home:update(delta)
end
function mob_home:deactivate()
self.object:remove_home()
end
----------------------------------------------------------------------------------------------------
-- ADD_TO_BINDER
----------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
--printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_home(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
end
----------------------------------------------------------------------------------------------------
-- SET_SCHEME
----------------------------------------------------------------------------------------------------
function set_scheme(npc, ini, scheme, section, gulag_name)
--printf("DEBUG: set_scheme: npc:name()='%s', scheme='%s', section='%s', gulag_name='%s'", npc:name(), scheme, section, gulag_name)
local storage = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
storage.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
storage.state = mob_state_mgr.get_state (ini, section, npc)
storage.home = utils.cfg_get_string (ini, section, "path_home", npc, false, gulag_name,nil)
storage.gulag_point = utils.cfg_get_bool (ini, section, "gulag_point", npc, false, false)
storage.home_min_radius = utils.cfg_get_number (ini, section, "home_min_radius", npc, false) --, 20)
storage.home_mid_radius = utils.cfg_get_number (ini, section, "home_mid_radius", npc, false) --, 0)
storage.home_max_radius = utils.cfg_get_number (ini, section, "home_max_radius", npc, false) --, 40)
storage.aggressive = utils.cfg_get_bool (ini, section, "aggressive", npc, false, false)
end

View file

@ -0,0 +1,121 @@
----------------------------------------------------------------------------------------------------
-- Mob Jump
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Jim
----------------------------------------------------------------------------------------------------
local STATE_START_LOOK = 1
local STATE_WAIT_LOOK_END = 2
local STATE_JUMP = 3
class "mob_jump"
----------------------------------------------------------------------------------------------------
-- CONSTRUCTION SCHEME
----------------------------------------------------------------------------------------------------
function mob_jump:__init(obj, storage)
self.object = obj
self.st = storage
end
----------------------------------------------------------------------------------------------------
-- RESET SCHEME
----------------------------------------------------------------------------------------------------
function mob_jump:reset_scheme()
printf("Jump: reset_scheme: %s", self.object:name())
xr_logic.mob_capture (self.object, true)
-- reset signals
self.st.signals = {}
-- initialize jump point
self.jump_path = nil
if self.st.jump_path_name then
self.jump_path = patrol(self.st.jump_path_name)
else
self.st.jump_path_name = "[not defined]"
end
if not self.jump_path then
abort("object '%s': unable to find jump_path '%s' on the map",
self.object:name(), self.st.jump_path_name)
end
self.point = vector().add(self.jump_path:point(0), self.st.offset)
self.state_current = STATE_START_LOOK
end
----------------------------------------------------------------------------------------------------
-- UPDATE
----------------------------------------------------------------------------------------------------
function mob_jump:update(delta)
--[[
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
]]
if (self.state_current == STATE_START_LOOK) then
if not self.object:action() then
action( self.object,
look(look.point, self.point),
cond(cond.look_end)
)
self.state_current = STATE_WAIT_LOOK_END
end
elseif (self.state_current == STATE_WAIT_LOOK_END) then
if not self.object:action() then
self.state_current = STATE_JUMP
end
end
if self.state_current == STATE_JUMP then
self.object:jump(self.point, self.st.ph_jump_factor)
self.st.signals["jumped"] = true
xr_logic.mob_release(self.object)
end
end
----------------------------------------------------------------------------------------------------
-- ADD_TO_BINDER
----------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_jump(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
end
----------------------------------------------------------------------------------------------------
-- SET_SCHEME
----------------------------------------------------------------------------------------------------
function set_scheme(npc, ini, scheme, section, gulag_name)
local storage = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
storage.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
storage.jump_path_name = utils.cfg_get_string(ini, section, "path_jump", npc, false, gulag_name)
storage.ph_jump_factor = utils.cfg_get_number(ini, section, "ph_jump_factor", npc, false, 1.8)
local offset_str = utils.cfg_get_string(ini, section, "offset", npc, true, "")
printf( "offset_str=%s", offset_str )
local elems = parse_names(offset_str)
printf( "elems = %s | %s | %s", tostring(elems[1]), tostring(elems[2]), tostring(elems[3]) )
storage.offset = vector():set(tonumber(elems[1]), tonumber(elems[2]), tonumber(elems[3]))
if not ini:line_exist( section, "on_signal" ) then
utils.abort("Bad jump scheme usage! `on_signal` line must be specified")
end
end

View file

@ -0,0 +1,176 @@
class "mob_remark"
function mob_remark:__init(obj, storage)
self.object = obj
self.st = storage
end
function mob_remark:reset_scheme()
printf("_bp: mob_remark:reset_scheme: %s", self.object:name())
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
self.object:disable_talk()
xr_logic.mob_capture(self.object, not self.st.no_reset)
local anims = parse_names(self.st.anim)
local snds
if self.st.snd then
snds = parse_names(self.st.snd)
else
snds = {}
end
local sndset
local times
if self.st.time then
times = parse_names(self.st.time)
else
times = {}
end
local tm
local cnd
for num, an in pairs(anims) do
sndset = snds[num]
if times[num] then
tm = tonumber(times[num])
else
tm = 0
end
if sndset and an then
local snd = mob_sound.pick_sound_from_set(self.object, sndset, {})
if not snd then
abort("mobile '%s': section '%s': sound set '%s' does not exist",
self.object:name(), self.st.section, sndset)
end
if tm == 0 then
cnd = cond(cond.sound_end)
else
cnd = cond(cond.time_end, tm)
end
if self.st.anim_head then
--printf("__bp: action set: %d", time_global())
action(self.object, anim(an), sound(snd, "bip01_head",
MonsterSpace[self.st.anim_head]), cnd)
else
--printf("__bp: action set: %d", time_global())
if self.st.anim_movement == true then
action(self.object, anim(an, true), sound(snd, "bip01_head"), cnd)
else
action(self.object, anim(an), sound(snd, "bip01_head"), cnd)
end
end
elseif an then
if tm == 0 then
cnd = cond(cond.anim_end)
else
cnd = cond(cond.time_end, tm)
end
--printf("__bp: action set: %d", time_global())
if self.st.anim_movement == true then
local pos = self.object:position()
local dir = self.object:direction()
printf("SNORK position[%s %s %s] orientation[%s %s %s]",
pos.x, pos.y, pos.z,
dir.x, dir.y, dir.z)
action(self.object, anim(an, true), cnd)
else
action(self.object, anim(an), cnd)
end
--else
-- if npc:get_script() then
-- npc:script(false, script_name())
-- end
end
end
self.tip_sent = false
self.st.signals = {}
self.action_end_signalled = false
--printf("_bp: mob_remark:reset_scheme end")
end
function mob_remark:update(delta)
--printf("__bp: mob_remark update: %d", time_global())
--if not xr_logic.is_active(self.object, self.st) then
-- return
--end
local actor = db.actor
--[[
if xr_logic.try_switch_to_another_section(self.object, self.st, actor) then
return
end
]]
if self.st.dialog_cond and xr_logic.pick_section_from_condlist(actor, self.object,
self.st.dialog_cond.condlist) ~= nil then
--printf("_bp: enable talk")
if not self.object:is_talk_enabled() then
self.object:enable_talk()
end
else
--printf("_bp: disable talk")
if self.object:is_talk_enabled() then
self.object:disable_talk()
end
end
if not self.tip_sent then
self.tip_sent = true
if self.st.tip then
news_manager.send_tip(actor, self.st.tip)
end
end
--printf("_bp: mob_remark:update [%s]", self.object:name())
if self.object:get_script() and not self.object:action() then
--self.object:script(false, script_name())
--printf("__bp: free from script: %d", time_global())
if not self.action_end_signalled then
self.action_end_signalled = true
self.st.signals["action_end"] = true
printf("mob_remark: signalling action_end")
end
end
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_remark(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.state = mob_state_mgr.get_state(ini, section, npc)
st.dialog_cond = xr_logic.cfg_get_condlist(ini, section, "dialog_cond", npc)
-- Íå ðàáîòàåò, ò.ê. ïðè ïåðåêëþ÷åíèè ñõåì â äàííûé ìîìåíò ìîíñòð âñåãäà
-- óõîäèò èç ïîä ñêðèïòà, ñîîòâåòñòâåííî, ñáðàñûâàåò ñâîþ î÷åðåäü actions.
--st.no_reset = utils.cfg_get_bool(ini, section, "no_reset", npc, false)
st.no_reset = true
st.anim = utils.cfg_get_string(ini, section, "anim", npc, false, "")
st.anim_movement = utils.cfg_get_bool(ini, section, "anim_movement", npc, false, false) --' Àíèìàöèÿ ñ ïåðåìåùåíèåì èëè íåò
st.anim_head = utils.cfg_get_string(ini, section, "anim_head", npc, false, "")
st.tip = utils.cfg_get_string(ini, section, "tip", npc, false, "")
st.snd = utils.cfg_get_string(ini, section, "snd", npc, false, "")
st.time = utils.cfg_get_string(ini, section, "time", npc, false, "")
end

View file

@ -0,0 +1,35 @@
function get_state(ini, section, obj)
local state = utils.cfg_get_string(ini, section, "state", obj, false, "", "")
if (state == "") then
return nil
end
return state
end
function set_state(obj, actor, state)
if not state then
return
end
local obj_clsid = get_clsid(obj)
--printf("mob_state_mgr <set_state>: [%s].clsid = %s, state = %s", obj:name(), tostring(obj_clsid), state)
if obj_clsid == clsid.bloodsucker_s then
if state == "invis" then
obj:set_invisible(true)
return
elseif state == "vis" then
obj:set_invisible(false)
return
end
else
-- Ó íåîïîçíàííûõ ìîíñòðîâ ïóñòàÿ ñòðîêà ("") ÿâëÿåòñÿ äîïóñòèìûì (çàîäíî è äåôîëòíûì) ñîñòîÿíèåì
if state == "" then
return
end
end
abort("mob_state_mgr: object '%s': unknown state '%s' requested",
obj:name(), state)
end

View file

@ -0,0 +1,290 @@
----------------------------------------------------------------------------------------------------
-- Mob remarks
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
-- Èñõîäíûé ñêðèïò (trader): Evgeniy Negrobov (Jon) jon@gsc-game.kiev.ua
----------------------------------------------------------------------------------------------------
local default_wait_time = 5000 -- âðåìÿ â ms, èëè nil äëÿ anim_end condition
local default_anim_standing = anim.stand_idle
local state_moving = 0
local state_standing = 1
class "mob_walker"
function mob_walker:__init(obj, storage)
self.object = obj
self.st = storage
end
function mob_walker:reset_scheme()
printf("_bp: mob_walker:reset_scheme: %s", self.object:name())
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
self.st.signals = {}
xr_logic.mob_capture(self.object, true)
self.patrol_walk = patrol(self.st.path_walk)
if not self.patrol_walk then
abort("object '%s': unable to find path_walk '%s' on the map",
self.object:name(), self.st.path_walk)
end
if self.st.path_look then
self.patrol_look = patrol(self.st.path_look)
if not self.patrol_look then
abort("object '%s': unable to find path_look '%s' on the map",
self.object:name(), self.st.path_look)
end
else
self.patrol_look = nil
end
if self.st.path_walk_info == nil then
self.st.path_walk_info = utils.path_parse_waypoints(self.st.path_walk)
self.path_walk_info = self.st.path_walk_info
end
if self.st.path_look_info == nil then
self.st.path_look_info = utils.path_parse_waypoints(self.st.path_look)
self.path_look_info = self.st.path_look_info
end
self.state = state_moving
self.crouch = false
self.running = false
self.cur_anim_set = default_anim_standing
self.pt_wait_time = default_wait_time -- ñêîëüêî æäàòü â òî÷êå, ãäå èãðàåì àíèìàöèþ
self.scheduled_snd = nil
self.last_index = nil
self.last_look_index = nil
action(self.object, move(move.walk_fwd, patrol(self.st.path_walk, patrol.next, patrol.continue)),
cond(cond.move_end))
end
function mob_walker:update(delta)
-- printf("__bp: mob_walker update: %d", time_global())
--if not xr_logic.is_active(self.object, self.st) then
-- return
--end
local actor = db.actor
-- Ìîíñòð ïîñëå âûõîäà èç alife ìîæåò óæå áûòü íå ïîä ñêðèïòîì, ïîýòîìó âçÿòü îïÿòü ïîä ñêðèïò
if not xr_logic.mob_captured(self.object) then
self:reset_scheme()
return
end
--[[
if self:arrived_to_first_waypoint() then
if xr_logic.try_switch_to_another_section(self.object, self.st, actor) then
return
end
end
]]
if self.state == state_standing then
if not self.object:action() then
local patrol_walk_count = self.patrol_walk:count()
if patrol_walk_count == 1 and utils.stalker_at_waypoint(self.object, self.patrol_walk, 0) then
self.state = state_moving
self:waypoint_callback(self.object, nil, self.last_index)
else
self.last_look_index = nil
self.state = state_moving
self:update_movement_state() -- èäòè äàëüøå
end
end
end
end
function mob_walker:arrived_to_first_waypoint()
return self.last_index ~= nil
end
function mob_walker:waypoint_callback(obj, action_type, index)
printf("mob_walker:waypoint_callback(): name=%s, index=%d", self.object:name(), index)
if index == -1 or index == nil then
printf("ERROR: mob_walker: waypoint_callback: index is %s", if_then_else(index == -1, "-1", "nil"))
return
end
self.last_index = index
local suggested_snd = self.path_walk_info[index]["s"]
if suggested_snd then
self.scheduled_snd = suggested_snd
end
local suggested_crouch = self.path_walk_info[index]["c"]
if suggested_crouch == "true" then
self.crouch = true
else
self.crouch = false
end
local suggested_running = self.path_walk_info[index]["r"]
if suggested_running == "true" then
self.running = true
else
self.running = false
end
local sig = self.path_walk_info[index]["sig"]
if sig then
-- HACK, fixme:
local npc_id = self.object:id()
local scheme = db.storage[npc_id]["active_scheme"]
local signals = db.storage[npc_id][scheme].signals
signals[sig] = true
printf("_bp: mob_walker [%s]: SIGNALLING: %s", self.object:name(), sig)
end
local beh = self.path_walk_info[index]["b"]
if beh then
mob_state_mgr.set_state(self.object, db.actor, beh)
else
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
end
local search_for = self.path_walk_info[index].flags
if search_for:get() == 0 then
-- TODO: çàïðåòèòü îäíîòî÷å÷íûå ïóòè áåç ñîîòâåòñòâóþùåãî path_look ïî àíàëîãèè ñ move_mgr
printf("_bp: no flags")
self:update_movement_state() -- èäòè äàëüøå
return
end
local pt_chosen_idx = move_mgr.choose_look_point(self.patrol_look, self.path_look_info, search_for)
if pt_chosen_idx then
local suggested_wait_time = self.path_look_info[pt_chosen_idx]["t"]
if suggested_wait_time then
self.pt_wait_time = tonumber(suggested_wait_time)
else
local patrol_walk_count = self.patrol_walk:count()
if patrol_walk_count == 1 and utils.stalker_at_waypoint(self.object, self.patrol_walk, 0) then
self.pt_wait_time = time_infinite
else
self.pt_wait_time = default_wait_time
end
end
local suggested_anim_set = self.path_look_info[pt_chosen_idx]["a"]
if suggested_anim_set then
if suggested_anim_set == "nil" then
suggested_anim_set = nil
end
self.cur_anim_set = anim[xr_logic.pick_section_from_condlist(db.actor, self.object, suggested_anim_set)]
else
self.cur_anim_set = default_anim_standing
end
local beh = self.path_walk_info[index]["b"]
if beh then
mob_state_mgr.set_state(self.object, db.actor, beh)
else
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
end
if pt_chosen_idx ~= self.last_look_index then -- åñëè óæå ñìîòðåëè òóäà - íå ïîâîðà÷èâàòüñÿ
self:look_at_waypoint(pt_chosen_idx) -- ïîâîðà÷èâàåìñÿ
end
self.state = state_standing
self:update_standing_state()
-- Ñðàçó æå ñòàðòîâàòü update, íå æäàòü execute. Òîãäà, åñëè ìû óæå ñìîòðèì
-- â íóæíóþ ñòîðîíó - íå áóäåò ïàóçû â íåñêîëüêî ìèëëèñåêóíä íà ïîâîðîò.
self:update(true)
else
abort("object '%s': path_walk '%s', index %d: cannot find corresponding point(s) on path_look '%s'",
self.object:name(), self.path_walk, index, self.path_look)
end
end
function mob_walker:update_movement_state()
printf("_bp [%s]: update_movement_state", self.object:name())
xr_logic.mob_capture(self.object, true)
local m
if self.running then
m = move.run_fwd
elseif self.crouch then
m = move.steal
else
m = move.walk_fwd
end
if self.scheduled_snd then
printf("_bp [%s]: playing scheduled sound", self.object:name())
action(self.object, move(m, patrol(self.st.path_walk, patrol.next, patrol.continue)),
sound(sound[self.scheduled_snd]), cond(cond.move_end))
self.scheduled_snd = nil
else
action(self.object, move(m, patrol(self.st.path_walk, patrol.next, patrol.continue)), cond(cond.move_end))
end
end
function mob_walker:update_standing_state()
printf("_bp [%s]: update_standing_state", self.object:name())
xr_logic.mob_capture(self.object, true)
if self.scheduled_snd then
printf("_bp [%s]: playing scheduled sound", self.object:name())
action(self.object, anim(self.cur_anim_set, 0),
sound(sound[self.scheduled_snd]), cond(cond.time_end, self.pt_wait_time))
self.scheduled_snd = nil
else
action(self.object, anim(self.cur_anim_set, 0), cond(cond.time_end, self.pt_wait_time))
end
end
function mob_walker:deactivate()
xr_logic.mob_capture(self.object, true)
action(self.object, move(move.steal, self.patrol_walk:point(0)), cond(cond.move_end))
end
function mob_walker:look_at_waypoint(pt)
if not self.patrol_look then
return
end
local look_pt = utils.vector_copy_by_val(self.patrol_look:point(pt)):sub(self.object:position())
look_pt:normalize()
--self.object:set_sight(look.direction, look_pt, 0)
xr_logic.mob_capture(self.object, true)
action(self.object, look(look.direction, look_pt), cond(cond.look_end))
self.last_look_index = pt
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = mob_walker(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.state = mob_state_mgr.get_state(ini, section, npc)
st.no_reset = utils.cfg_get_bool(ini, section, "no_reset", npc, false)
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, false, 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.path_walk_info = nil -- Áóäóò èíèöèàëèçèðîâàíû â reset(), ñåé÷àñ ïóòè ìîãóò áûòü åùå
st.path_look_info = nil -- íå çàãðóæåíû.
end

View file

@ -0,0 +1,85 @@
-- Òèïû ñõåì:
stype_stalker = 0
stype_mobile = 1
stype_item = 2
stype_heli = 3
stype_restrictor = 4
----------------------------------------------------------------------
-- Çàãðóçêà ñõåì:
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Çàãðóçêà ìîäóëåé ñòàëêåðîâ:
----------------------------------------------------------------------
load_scheme("xr_danger", "danger", stype_stalker)
load_scheme("xr_gather_items", "gather_items", stype_stalker)
load_scheme("xr_abuse", "abuse", stype_stalker)
load_scheme("xr_walker", "walker", stype_stalker)
load_scheme("xr_remark", "remark", stype_stalker)
load_scheme("xr_cover", "cover", stype_stalker)
load_scheme("xr_sleeper", "sleeper", stype_stalker)
load_scheme("xr_kamp", "kamp", stype_stalker)
load_scheme("xr_camper", "camper", stype_stalker)
load_scheme("xr_meet", "meet", stype_stalker)
load_scheme("xr_help_wounded", "help_wounded", stype_stalker)
load_scheme("xr_corpse_detection", "corpse_detection", stype_stalker)
load_scheme("xr_combat", "combat", stype_stalker)
load_scheme("xr_death", "death", stype_stalker)
load_scheme("xr_hit", "hit", stype_stalker)
load_scheme("xr_wounded", "wounded", stype_stalker)
load_scheme("xr_meet", "actor_dialogs", stype_stalker)
load_scheme("xr_combat_ignore", "combat_ignore", stype_stalker)
load_scheme("xr_combat_zombied", "combat_zombied", stype_stalker)
load_scheme("xr_patrol", "patrol", stype_stalker)
load_scheme("xr_smartcover", "smartcover", stype_stalker)
load_scheme("xr_companion", "companion", stype_stalker)
load_scheme("xr_animpoint", "animpoint", stype_stalker)
load_scheme("xr_reach_task", "reach_task", stype_stalker)
----------------------------------------------------------------------
-- Çàãðóçêà ìîäóëåé ìîíñòðîâ:
----------------------------------------------------------------------
load_scheme("mob_remark", "mob_remark", stype_mobile)
load_scheme("mob_walker", "mob_walker", stype_mobile)
load_scheme("mob_combat", "mob_combat", stype_mobile)
load_scheme("mob_death", "mob_death", stype_mobile)
load_scheme("mob_jump", "mob_jump", stype_mobile)
load_scheme("mob_home", "mob_home", stype_mobile)
----------------------------------------------------------------------
-- Çàãðóçêà ìîäóëåé ôèçè÷åñêèõ îáúåêòîâ:
----------------------------------------------------------------------
load_scheme("ph_door", "ph_door", stype_item)
load_scheme("ph_idle", "ph_idle", stype_item)
load_scheme("ph_hit", "ph_hit", stype_item)
load_scheme("ph_on_hit", "ph_on_hit", stype_item)
load_scheme("ph_button", "ph_button", stype_item)
load_scheme("ph_code", "ph_code", stype_item)
load_scheme("ph_death", "ph_on_death", stype_item)
load_scheme("ph_minigun", "ph_minigun", stype_item)
--load_scheme("ph_target", "ph_target", stype_item)
load_scheme("ph_oscillate", "ph_oscillate", stype_item)
----------------------------------------------------------------------
-- Çàãðóçêà ìîäóëåé âåðòîë¸òà:
----------------------------------------------------------------------
load_scheme("heli_move", "heli_move", stype_heli)
----------------------------------------------------------------------
-- Çàãðóçêà ìîäóëåé ðåñòðèêòîðîâ:
----------------------------------------------------------------------
load_scheme("sr_no_weapon", "sr_no_weapon", stype_restrictor)
load_scheme("sr_teleport", "sr_teleport", stype_restrictor)
load_scheme("sr_idle", "sr_idle", stype_restrictor)
load_scheme("sr_light", "sr_light", stype_restrictor)
load_scheme("sr_timer", "sr_timer", stype_restrictor)
load_scheme("sr_psy_antenna", "sr_psy_antenna", stype_restrictor)
load_scheme("sr_postprocess", "sr_postprocess", stype_restrictor)
load_scheme("sr_particle", "sr_particle", stype_restrictor)
load_scheme("sr_cutscene", "sr_cutscene", stype_restrictor)
--load_scheme("sr_bloodsucker", "sr_bloodsucker", stype_restrictor)
load_scheme("sr_monster", "sr_monster", stype_restrictor)
--load_scheme("sr_robbery", "sr_robbery", stype_restrictor)
--load_scheme("sr_survival", "sr_survival", stype_restrictor)
load_scheme("sr_crow_spawner", "sr_crow_spawner", stype_restrictor)
--load_scheme("sr_shooting", "sr_shooting", stype_restrictor)
--load_scheme("sr_recoveritem", "sr_recoveritem", stype_restrictor)
load_scheme("sr_silence", "sr_silence", stype_restrictor)
load_scheme("sr_deimos", "sr_deimos", stype_restrictor)

View file

@ -0,0 +1,574 @@
function printf()
end
local dist_walk = 10 -- < dist_run
local dist_run = 2500
local walk_min_time = 3000
local run_min_time = 2000
local keep_state_min_time = 1500 -- ïåðåêëþ÷èâøèñü â ñîñòîÿíèå (áåã, õîäüáà, ñïðèíò), íå ïåðåêëþ÷àòüñÿ â äðóãîå N ms
local default_wait_time = 10000
local default_state_standing = "guard"
local default_state_moving1 = "patrol"
local default_state_moving2 = "patrol"
local default_state_moving3 = "patrol"
arrival_before_rotation = 0
arrival_after_rotation = 1
local state_none = 0
local state_moving = 1
local state_standing = 2
local sync = {}
-------------------------------------------------------------------------------------------------------------------------
function choose_look_point(patrol_look, path_look_info, search_for)
local this_val -- çíà÷åíèå ôëàãîâ òåêóùåé òî÷êè
local pts_found_total_weight = 0 -- êîëè÷åñòâî íàéäåííûõ òî÷åê (ñ íóæíûìè ôëàãàìè)
local pt_chosen_idx = nil -- èíäåêñ âûáðàííîé òî÷êè
local r
local num_equal_pts = 0
for look_idx = 0, patrol_look:count() - 1 do
this_val = path_look_info[look_idx].flags
if this_val:equal(search_for) then
num_equal_pts = num_equal_pts + 1
-- Íàøëè òî÷êó ñ íóæíûìè ôëàãàìè, íî ïîñêîëüêó â ïóòè ìîãóò áûòü åùå òàêèå-æå
-- òî÷êè, âîçüìåì òåêóùóþ òîëüêî ñ íåêîòîðîé âåðîÿòíîñòüþ:
-- Øàíñ, ñ êîòîðûì íà òî÷êó ïîñìîòðèò ïåðñîíàæ:
local point_look_weight = path_look_info[look_idx]["p"]
if point_look_weight then
point_look_weight = tonumber(point_look_weight)
else
point_look_weight = 100 -- ïî óìîë÷àíèþ ó âñåõ òî÷åê âåñ = 100
end
pts_found_total_weight = pts_found_total_weight + point_look_weight
r = math.random(1, pts_found_total_weight)
if r <= point_look_weight then
pt_chosen_idx = look_idx
end
end
end
return pt_chosen_idx, num_equal_pts
end
-------------------------------------------------------------------------------------------------------------------------
class "move_mgr"
function move_mgr:__init(npc)
if npc == nil then
abort("move_mgr:__init() - npc is nil, please update the script")
end
self.object = npc
end
function move_mgr:initialize(npc)
if npc ~= nil then
abort("Wrong arguments passed to move_mgr:initialize(), please update the script")
end
--printf("move_mgr:initialize()")
self.object:set_callback(callback.patrol_path_in_point, self.waypoint_callback, self)
end
--' Óäîñòîâåðÿåòñÿ, ÷òî ïóòè è ôëàæêè íà íèõ ïðîñòàâëåíû êîððåêòíî
function move_mgr:validate_paths()
if self.no_validation then
return
end
local patrol_walk_count = self.patrol_walk:count()
if patrol_walk_count == 1 then
if self.path_walk_info[0].flags:get() == 0 then
abort("object '%s': path_walk '%s' has 1 waypoint, but has no flags",
self.object:name(), self.path_walk)
end
end
end
function move_mgr:extrapolate_callback(npc)
self.can_use_get_current_point_index = true
self.current_point_init_time = time_global()
self.current_point_index = self.object:get_current_point_index()
end
function move_mgr:standing_on_terminal_waypoint()
for idx = 0, self.patrol_walk:count() - 1 do
if utils.stalker_at_waypoint(self.object, self.patrol_walk, idx) and
self.patrol_walk:terminal(idx) then
return true, idx
end
end
return false
end
--' Ìîæåò áûòü âûçâàíî âíåøíèì ñêðèïòîì ïîñëå âûçîâà reset() è äî âûçîâà finalize()
--' Âîçâðàùàåò true, åñëè ïåðñîíàæ ïðèáûë â êîíå÷íóþ òî÷êó ïóòè
function move_mgr:at_terminal_waypoint()
return self.at_terminal_waypoint_flag
end
--' Èç move_cb âåðíóòü true, ÷òîáû ïðèîñòàíîâèòü ðàáîòó ñõåìû. ×òîáû ïðîäîëæèòü äâèæåíèå,
--' íóæíî âûçâàòü ìåòîä set_movement_state, êîòîðûé âêëþ÷èò ïåðåìåùåíèå ïî âåéïîèíòàì ñ íóæíîé
--' ñêîðîñòüþ.
function move_mgr:reset(path_walk, path_walk_info, path_look, path_look_info, team, suggested_state, move_cb_info, no_validation, continue, use_default_sound)
printf("move_mgr:reset() [%s]", self.object:name())
--' ñêîëüêî æäàòü â òî÷êå, ãäå èãðàåì àíèìàöèþ
self.pt_wait_time = default_wait_time
--' Çàïîìèíàåì ìàññèâ öåëèêîì íà ñëó÷àé, åñëè ïðèäåòñÿ ñåáÿ ñáðîñèòü, ïîâòîðíî
--' âûçâàâ reset():
self.suggested_state = suggested_state
--' Ïîñëå ýòîãî ðàñïàðñèâàåì ìàññèâ:
if not suggested_state then
self.default_state_standing = default_state_standing
self.default_state_moving1 = default_state_moving1
self.default_state_moving2 = default_state_moving2
self.default_state_moving3 = default_state_moving3
else
self.default_state_standing = if_then_else(suggested_state.standing, suggested_state.standing, default_state_standing)
self.default_state_moving1 = if_then_else(suggested_state.moving, suggested_state.moving, default_state_moving1)
self.default_state_moving2 = if_then_else(suggested_state.moving, suggested_state.moving, default_state_moving2)
self.default_state_moving3 = if_then_else(suggested_state.moving, suggested_state.moving, default_state_moving3)
end
self.default_state_standing = xr_logic.parse_condlist(self.object, "move_mgr", "def_state", self.default_state_standing)
self.default_state_moving1 = xr_logic.parse_condlist(self.object, "move_mgr", "def_state", self.default_state_moving1)
self.default_state_moving2 = xr_logic.parse_condlist(self.object, "move_mgr", "def_state", self.default_state_moving2)
self.default_state_moving3 = xr_logic.parse_condlist(self.object, "move_mgr", "def_state", self.default_state_moving3)
--' Ñ ìîìåíòà âêëþ÷åíèÿ ñõåìû äîëæíà ïðîéòè êàê ìèíèìóì ñåêóíäà, ïðåæäå ÷åì
--' ïðîâåðÿòü ñîñòîÿíèå ñèíõðîíèçàöèè ñ äðóãèìè ñòàëêåðàìè (èíà÷å ïîñëå ëîàäà
--' îíè ìîãóò íå óñïåòü çàñïàâíèòüñÿ).
self.syn_signal_set_tm = time_global() + 1000
self.syn_signal = nil
self.move_cb_info = move_cb_info
--' Âîçìîæíûå èçìåíåíèÿ
--' Èçìåíèëàñü êîìàíäà
if team ~= self.team then
self.team = team
if self.team then
local s = sync[self.team]
if not s then
sync[self.team] = {}
s = sync[self.team]
end
s[self.object:id()] = false -- not synchronized
end
end
--' Èçìåíèëèñü ïóòè
if self.path_walk ~= path_walk or self.path_look ~= path_look then
self.no_validation = no_validation
self.path_walk = path_walk
self.patrol_walk = patrol(path_walk)
if not self.patrol_walk then
abort("object '%s': unable to find path_walk '%s' on the map",
self.object:name(), path_walk)
end
if not path_walk_info then
abort("object '%s': path_walk ('%s') field was supplied, but path_walk_info field is nil",
self.object:name(), path_walk)
end
self.path_walk_info = path_walk_info
if path_look then
if not path_look_info then
abort("object '%s': path_look ('%s') field was supplied, but path_look_info field is nil",
self.object:name(), path_look)
end
self.patrol_look = patrol(path_look)
if not self.patrol_look then
abort("object '%s': unable to find path_look '%s' on the map",
self.object:name(), path_look)
end
else
self.patrol_look = nil
end
self.path_look = path_look
self.path_look_info = path_look_info
--'self:validate_paths()
self.at_terminal_waypoint_flag = false
self.cur_state_standing = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_standing)
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_moving1)
self.retval_after_rotation = nil
self.sound_after_anim_start = nil
--' Ïîêà ýòîò ôëàã íå ñòàíåò true (îí áóäåò óñòàíîâëåí â extrapolate_callback), íåëüçÿ èñïîëüçîâàòü
--' çíà÷åíèå, êîòîðîå âîçâðàùàåò get_current_point_index().
self.can_use_get_current_point_index = false
self.current_point_index = nil
self.walk_until = time_global() + walk_min_time
self.run_until = time_global() + walk_min_time + run_min_time
self.keep_state_until = time_global()
self.last_index = nil
self.last_look_index = nil
self.use_default_sound = use_default_sound
self.object:patrol_path_make_inactual()
end
self:setup_movement_by_patrol_path()
end
--' ïðîäîëæèòü äâèæåíèå ñî ñëåäóþùåé òî÷êè, à íå ñ áëèæàéøåé.
--' ñîñòîÿíèå move manager-a íå ñáðàñûâàåòñÿ.
function move_mgr:continue()
printf("_bp: object '%s': continue moving", self.object:name())
self:setup_movement_by_patrol_path()
end
function move_mgr:setup_movement_by_patrol_path()
self.object:set_path_type(game_object.patrol_path)
self.object:set_detail_path_type(move.line)
if self.current_point_index then
self.object:set_start_point(self.current_point_index)
self.object:set_patrol_path(self.path_walk, patrol.next, patrol.continue, true)
else
self.object:set_patrol_path(self.path_walk, patrol.nearest, patrol.continue, true)
end
self.state = state_moving
local is_term, idx = self:standing_on_terminal_waypoint()
if is_term then
printf("_bp: object '%s': TERMINAL WAYPOINT", self.object:name())
-- Ñòîèì íà òåðìèíàëüíîé âåðøèíå ïóòè - ñðàçó èììèòèðîâàòü ïðèáûòèå
self:waypoint_callback(self.object, nil, idx)
else
-- Ðåàëüíî èäåì â âåðøèíó
self:update_movement_state()
end
local sect = self.object:section()
end
function move_mgr:arrived_to_first_waypoint()
return self.last_index ~= nil
end
--' Ïðîâåðêà ñèíõðîíèçàöèè ñ îñòàëüíûìè ñîëäàòàìè íà ïóòè.
--' Âîçâðàùàåò true, åñëè äàëüíåéøåå äâèæåíèå ðàçðåøåíî.
function move_mgr:sync_ok()
if self.team then
local s = sync[self.team]
local self_id = self.object:id()
for k, v in pairs(s) do
local obj = level.object_by_id(k)
if obj and obj:alive() then
if v ~= true then
return false
end
else
sync[self.team][k] = nil
end
end
end
return true
end
function move_mgr:update()
--printf("move_mgr:update(self.state == %s)", utils.to_str(self.state))
--printf("move_mgr:update(self.object:anims == %d)", self.object:animation_count())
if self.syn_signal and time_global() >= self.syn_signal_set_tm then
if self:sync_ok() then
self:scheme_set_signal(self.syn_signal)
self.syn_signal = nil
end
end
if self.can_use_get_current_point_index and not self:arrived_to_first_waypoint() then
local t = time_global()
if t >= self.keep_state_until then
self.keep_state_until = t + keep_state_min_time
local cur_pt = self.current_point_index
-- self.patrol_walk çäåñü ïî èäåå òî æå ñàìîå, ÷òî âåðíåò patrol(self.object:patrol()),
-- ïîýòîìó èñïîëüçóþ åãî äëÿ îïòèìèçàöèè.
local dist = self.object:position():distance_to(self.patrol_walk:point(cur_pt))
--printf("_bp: move_mgr: distance to destination waypoint: %d", dist)
if dist <= dist_walk or t < self.walk_until then
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_moving1)
elseif dist <= dist_run or t < self.run_until then
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_moving2)
else
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_moving3)
end
self:update_movement_state()
end
return
end
end
function move_mgr:set_current_state_moving(state)
self.cur_state_moving = state
self:update_movement_state()
end
function move_mgr:finalize(npc)
if self.team then
sync[self.team][self.object:id()] = nil
end
-- ÷òîáû èçáåæàòü äàëüíåéøåãî äâèæåíèÿ ïî ïóòè ïðè óñòàíîâêå ðåñòðèêòîðîâ
self.object:set_path_type(game_object.level_path)
end
--'-----------------------------------------------------------------------------
--' IMPLEMENTATION
--'-----------------------------------------------------------------------------
function move_mgr:update_movement_state()
--printf("%s UPDATE movement state to %s", self.object:name(), self.cur_state_moving)
state_mgr.set_state(self.object, self.cur_state_moving, nil, nil, nil)
end
function move_mgr:update_standing_state(look_pos, snd)
--printf("_bp [%s]: update_standing_state: snd='%s', pt_wait_time = %s path = %s", self.object:name(), utils.to_str(snd), utils.to_str(self.pt_wait_time), self.path_walk)
state_mgr.set_state(self.object, self.cur_state_standing,
{ obj = self, func = self.time_callback, turn_end_func = self.turn_end_callback },
self.pt_wait_time,
{ look_position = look_pos },
nil,
snd )
end
function move_mgr:time_callback()
--printf("_bp [%s]: time_callback", self.object:name())
local sigtm = self.path_look_info[self.last_look_index]["sigtm"]
if sigtm then
self:scheme_set_signal(sigtm)
end
--' Åñëè íåò àêòèâíîé ñõåìû - èãíîðèðîâàòü.
if db.storage[self.object:id()].active_scheme == nil then
return
end
if self.last_index and self.patrol_walk:terminal(self.last_index) then
if utils.stalker_at_waypoint(self.object, self.patrol_walk, self.last_index) then
--' Åñëè ñòîèì íà êîíå÷íîé òî÷êå ïóòè è ñ íåå íèêóäà íå ñäâèíóëèñü,
--' ñðàçó èììèòèðóåì callback íà ïðèáûòèå, ÷òîáû âêëþ÷èòü look.
self:waypoint_callback(self.object, nil, self.last_index)
return
end
--' Ñòîèì íà êîíå÷íîé òî÷êå ïóòè, íî íåòî÷íî. ×òîáû âåðíóòüñÿ íà áëèæàéøóþ
--' òî÷êó ïóòè, ñáðàñûâàåì ñõåìó. Îáðàòèòå âíèìàèíå, ÷òî çäåñü íåëüçÿ
--' ïðîñòî âûçâàòü update_movement_state, ïîòîìó ÷òî ìû ÓÆÅ áûëè â
--' êîíå÷íîé òî÷êå ïóòè è äàëüøå èäòè íåêóäà, à reset_scheme ñáðîñèò
--' íàñòðîéêè movement manager-à è âûáåðåò áëèæàéøóþ òî÷êó, êóäà è ïîéäåò.
self:reset(self.path_walk, self.path_walk_info,
self.path_look, self.path_look_info,
self.team,
self.suggested_state,
self.move_cb_info,
self.no_validation)
else
self:update_movement_state() -- èäòè äàëüøå
local syn = self.path_look_info[self.last_look_index]["syn"]
if syn then
abort("object '%s': path_walk '%s': syn flag used on non-terminal waypoint",
self.object:name(), self.path_walk)
end
end
end
function move_mgr:scheme_set_signal(sig)
local npc_id = self.object:id()
local stor = db.storage[npc_id]
--printf("_bp: object '%s': move_mgr: scheme_set_signal '%s', active scheme '%s'",
-- self.object:name(), sig, utils.to_str(stor.active_scheme))
if stor ~= nil and stor[stor.active_scheme] ~= nil then
local signals = stor[stor.active_scheme].signals
if signals ~= nil then
signals[sig] = true
end
end
end
function move_mgr:turn_end_callback()
local syn = self.path_look_info[self.last_look_index]["syn"]
if syn then
self.syn_signal = self.path_look_info[self.last_look_index]["sig"]
if not self.syn_signal then
abort("object '%s': path_look '%s': syn flag uset without sig flag", self.object:name(), self.path_look)
end
-- Îòìåòèòü, ÷òî ìû ñàìè óæå ïðèáûëè â òî÷êó ñèíõðîíèçàöèè:
if self.team then
sync[self.team][self.object:id()] = true
end
else
local sig = self.path_look_info[self.last_look_index]["sig"]
if sig then
self:scheme_set_signal(sig)
else
self:scheme_set_signal("turn_end")
end
end
local anim_synced_snd = nil
if self.sound_after_anim_start then
-- Ïðîèãðàòü çâóê ñðàçó ïîñëå îêîí÷àíèÿ ïîâîðîòà:
anim_synced_snd = self.sound_after_anim_start
self.sound_after_anim_start = nil
end
if self.retval_after_rotation then
if not self.move_cb_info then
abort("object '%s': path_look '%s': ret flag is set, but " ..
"callback function wasn't registered in move_mgr:reset()",
self.object:name(), self.path_look)
end
--' Îòêëþ÷àåì òàéìåð ïóòåì óñòàíîâêè òîãî æå ñàìîãî ñîñòîÿíèÿ, íî áåç òàéìåðà,
--' çàòåì âûçûâàåì callback.
--' Åñëè callback âåðíóë false, ò.å. ðåøèë íå âìåøèâàòüñÿ â ïåðåìåùåíèå,
--' òî âêëþ÷àåì îïÿòü òàéìåð.
--' Åñëè callback âåðíóë true - íå âîññòàíàâëèâàåì òàéìåð ò.ê. ýòî ìîãëè ñäåëàòü â
--' ñàìîì callback-å.
--' 1) Îòêëþ÷àåì òàéìåð
state_mgr.set_state(self.object, self.cur_state_standing, nil, nil, nil)
--' 2) Âûçûâàåì callback
if not self.move_cb_info then
abort("object '%s': path_look '%s': ret flag is set, but " ..
"callback function wasn't registered in move_mgr:reset()",
self.object:name(), self.path_look)
end
if self.move_cb_info.func(self.move_cb_info.obj, this.arrival_after_rotation, self.retval_after_rotation, self.last_index)
then
--' Callback ðåøèë ïåðåõâàòèòü óïðàâëåíèå ïåðåìåùåíèåì, íå âîññòàíàâëèâàåì òàéìåð
return
end
--' Callback íå ïåðåõâàòèë óïðàâëåíèå, íóæíî âîññòàíîâèòü òàéìåð:
local look_pos = self.patrol_look:point(self.last_look_index)
self:update_standing_state(look_pos, anim_synced_snd)
end
end
function move_mgr:waypoint_callback(obj, action_type, index)
--printf("move_mgr:waypoint_callback(): name=%s, index=%d", self.object:name(), index)
if index == -1 or index == nil then
--printf("ERROR: move_mgr: waypoint_callback: index is -1 or nil")
return
end
self.last_index = index
if self.patrol_walk:terminal(index) then
self.at_terminal_waypoint_flag = true
end
local suggested_state_moving = self.path_walk_info[index]["a"]
if suggested_state_moving then
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, suggested_state_moving)
if tostring(self.cur_state_moving) == "true" then
print_table(suggested_state_moving)
abort("!!!!!")
end
else
self.cur_state_moving = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_moving1)
if tostring(self.cur_state_moving) == "true" then
abort("!!!!!")
end
end
local retv = self.path_walk_info[index]["ret"]
if retv then
--printf("retv = %s", retv)
local retv_num = tonumber(retv)
if not self.move_cb_info then
abort("object '%s': path_walk '%s': ret flag is set, but " ..
"callback function wasn't registered in move_mgr:reset()",
self.object:name(), self.path_walk)
end
if self.move_cb_info.func(self.move_cb_info.obj, this.arrival_before_rotation, retv_num, index) then
return
end
end
local sig = self.path_walk_info[index]["sig"]
if sig then
self:scheme_set_signal(sig)
elseif index == #self.path_walk_info -1 then
self:scheme_set_signal("path_end")
end
local stop_probability = self.path_walk_info[index]["p"]
if not self.patrol_look or
(stop_probability and tonumber(stop_probability) < math.random(1, 100)) then
self:update_movement_state() --' èäòè äàëüøå
return
end
-- Çíà÷åíèå ôëàãîâ òî÷êè, êîòîðóþ áóäåì èñêàòü:
local search_for = self.path_walk_info[index].flags
if search_for:get() == 0 then
self:update_movement_state() --' èäòè äàëüøå
return
end
local pt_chosen_idx, num_equal_pts = choose_look_point(self.patrol_look, self.path_look_info, search_for)
--printf("_bp [%s]: pt_chosen_idx = %s", self.object:name(), utils.to_str(pt_chosen_idx))
if pt_chosen_idx then
local suggested_anim_set = self.path_look_info[pt_chosen_idx]["a"]
if suggested_anim_set then
self.cur_state_standing = xr_logic.pick_section_from_condlist(db.actor, self.object, suggested_anim_set)
else
self.cur_state_standing = xr_logic.pick_section_from_condlist(db.actor, self.object, self.default_state_standing)
end
local suggested_wait_time = self.path_look_info[pt_chosen_idx]["t"]
if suggested_wait_time then
if suggested_wait_time == '*' then
self.pt_wait_time = nil -- -1
else
local tm = tonumber(suggested_wait_time)
if tm ~= 0 and (tm < 1000 or tm > 45000) then
abort("object '%s': path_look '%s': flag 't': incorrect time specified (* or number in interval [1000, 45000] is expected)",
self.object:name(), self.path_look)
end
self.pt_wait_time = tm
end
else
self.pt_wait_time = default_wait_time
end
local retv = self.path_look_info[pt_chosen_idx]["ret"]
if retv then
self.retval_after_rotation = tonumber(retv)
else
self.retval_after_rotation = nil
end
local look_pos = self.patrol_look:point(pt_chosen_idx)
self.last_look_index = pt_chosen_idx
self:update_standing_state(look_pos, self.sound_after_anim_start)
self.state = state_standing
--' Ñðàçó æå ñòàðòîâàòü update, íå æäàòü execute. Òîãäà, åñëè ìû óæå ñìîòðèì
--' â íóæíóþ ñòîðîíó - íå áóäåò ïàóçû â íåñêîëüêî ìèëëèñåêóíä íà ïîâîðîò.
self:update()
else
abort("object '%s': path_walk '%s', index %d: cannot find corresponding point(s) on path_look '%s'",
self.object:name(), tostring(self.path_walk), tostring(index), tostring(self.path_look))
end
end

View file

@ -0,0 +1,297 @@
--news = {}
--[[
tips_icons = {
default = { 0, 658}, -- ui_iconsTotal_grouping
trader = { 332, 893}, -- ui_iconsNpc_trader
dolg = { 0, 658},
freedom = { 0, 658},
ecolog = { 498, 0}, -- ui_iconsNpc_ecolog
army = { 332, 141}, -- ui_iconsNpc_stalker_neytral_balon_6
stalker = { 0, 658},
csky = { 0, 658},
krot = { 332, 47}, -- ui_iconsNpc_stalker_neytral_rukzak_4
barman = { 332, 235}, -- ui_iconsNpc_barman
wolf = { 332, 940}, -- ui_iconsNpc_stalker_neytral_balon_1
o_soznanie = { 498, 893},
monolith = { 0, 658},
saharov = { 332, 470}, -- ui_iconsNpc_ucheniy_2
prizrak = { 0, 658},
killer = { 0, 658},
bandit = { 0, 658},
renegade = { 0, 658}
}
]]
-- ToDo - Need Pioneer icon here!
tips_icons = {
pioneer = "ui_inGame2_PD_Pervootkrivatel",
mutant_hunter = "ui_inGame2_PD_Ohotnik_na_mutantov",
detective = "ui_inGame2_PD_Sisshik",
one_of_the_lads = "ui_inGame2_PD_Svoy_paren",
kingpin = "ui_inGame2_PD_Avtoritet",
herald_of_justice = "ui_inGame2_PD_Gonets_pravosudiya",
seeker = "ui_inGame2_PD_Iskatel",
battle_systems_master = "ui_inGame2_PD_master_boevih_sistem",
high_tech_master = "ui_inGame2_PD_Master_visokih_technologiy",
skilled_stalker = "ui_inGame2_PD_Opitniy_stalker",
leader = "ui_inGame2_PD_Lider",
diplomat = "ui_inGame2_PD_Diplomat",
research_man = "ui_inGame2_PD_Nauchniy_sotrudnik",
friend_of_duty = "ui_inGame2_PD_Drug_Dolga",
friend_of_freedom = "ui_inGame2_PD_Drug_Swobodi",
balance_advocate = "ui_inGame2_PD_storonnik_ravnovesiya",
wealthy = "ui_inGame2_PD_Sostoyatelniy_klient",
keeper_of_secrets = "ui_inGame2_PD_Hranitel_tayn",
marked_by_zone = "ui_inGame2_PD_Otmecheniy_zonoy",
information_dealer = "ui_inGame2_PD_Torgovets_informatsiey",
friend_of_stalkers = "ui_inGame2_PD_Drug_Stalkerov",
got_artefact = "ui_inGame2_D_gonets_pravosudiya",
got_ammo = "ui_inGame2_D_Ohotnik_na_mutantov",
got_medicine = "ui_inGame2_D_Sisshik",
got_duty_light_armor = "ui_inGame2_D_Vipolnil_2_zadaniya_dlya_Dolga",
got_duty_heavy_armor = "ui_inGame2_D_Vipolnil_4_zadaniya_dlya_Dolga",
got_freedom_light_armor = "ui_inGame2_D_Vipolnil_2_zadaniya_dlya_Swobodi",
got_freedom_heavy_armor = "ui_inGame2_D_Vipolnil_4_zadaniya_dlya_Swobodi",
can_resupply = "ui_inGame2_Pered_zadaniyami_voennih",
recent_surge = "ui_inGame2_V_zone_nedavno_proshel_vibros",
}
function send_tip(actor, news_id, timeout, sender, showtime, sender_id)
if news_id == nil then return false end
-- printf("try to send tips for [%s]", tostring(sender_id))
if sender_id ~= nil then
local sim = alife()
if sim ~= nil then
local npc = sim:object(get_story_object_id(sender_id))
if npc ~= nil then
if npc.online then
--â îíëàéíå ïðîâåðÿåì íà ðàíåííîñòü
if xr_wounded.is_heavy_wounded_by_id(npc.id) then
printf("[PDA]Cannot send tips [%s], sender is heavy wounded", tostring(news_id))
return false
end
end
-- â äðóãèõ ñëó÷àÿõ òîëüêî íà ñìåðòü
if npc:alive() == 1 then
printf("[PDA]Cannot send tips [%s], sender is dead", tostring(news_id))
return false
end
end
end
end
if timeout == nil then timeout = 0 end
if showtime == nil then showtime = 5000 end
--' Èãðàåì äåôîëòíûé çâóê
xr_sound.set_sound_play(actor:id(), "pda_tips")
local texture = "ui_iconsTotal_grouping"
if sender ~= nil then
if type(sender) == "string" then
if tips_icons[sender] then
texture = tips_icons[sender]
end
elseif is_npc_stalker(sender:clsid()) then
texture = sender:character_icon()
end
end
local news_caption = game.translate_string("st_tip")
local news_text = game.translate_string(news_id)
-- actor:give_game_news(news_caption, news_text, texture, timeout*1000, showtime)
actor:give_game_news(news_caption, news_text, texture, timeout*1000, showtime, 0)
return true
end
function send_sound(npc, faction, point, str, str2, delay_sound)
--callstack()
if faction ~= nil then
--printf("---------------------")
--printf(tostring(faction))
local point_name = ""
if point ~= nil then
local smart = sim_board.get_sim_board().smarts[point]
if smart then
point_name = smart_names.get_smart_terrain_name(smart.smrt)
else
point_name = game.translate_string(point)
end
end
--printf(point_name)
local txt = ""
if str2 == nil then
txt = string.gsub(str, "(characters_voice\\human_..\\)([^\\]*)", "%2")
txt = string.gsub(txt, "[\\]([^\\]*)", "_%1")
else
txt = str2
end
--printf("--->"..tostring(txt))
local news_text = game.translate_string(txt)
if news_text == txt then
return
end
-- callstack()
--' Èãðàåì äåôîëòíûé çâóê
-- xr_sound.set_sound_play(db.actor:id(), "pda_tips")
local texture = "ui_iconsTotal_grouping"
if npc ~= nil and is_npc_stalker(npc:clsid()) then
texture = npc:character_icon()
else
if tips_icons[faction] then
texture = tips_icons[faction]
end
if tips_icons[point] then
texture = tips_icons[point]
end
end
-- printf("--->texture="..tostring(texture))
local news_caption = game.translate_string("st_tip").." "..game.translate_string(faction)
if point_name ~= "" then
news_caption = news_caption..". "..point_name..":"
else
news_caption = news_caption..":"
end
-- db.actor:give_game_news(news_caption, news_text, texture, 1000, 5000)
-- give_game_news(LPCSTR caption, LPCSTR news, LPCSTR texture_name, int delay, int show_time)
db.actor:give_game_news(news_caption, news_text, texture, delay_sound+1000, 5000, 1)
return true
end
end
function is_npc_stalker(class_id)
if class_id==clsid.script_stalker or
class_id==clsid.stalker then
return true
end
return false
end
local action_descr_by_type = {
new = "general_new_task",
complete = "general_complete_task",
fail = "general_fail_task",
reversed = "general_reverse_task",
updated = "general_update_task"
}
function send_task(actor, type, task)
if db.actor == nil then
return false
end
local time_on_screen = 10000
if type == "updated" then
time_on_screen = 5000
end
xr_sound.set_sound_play(db.actor:id(), "pda_task")
local news_caption = game.translate_string(action_descr_by_type[type])
local news_text = game.translate_string(task:get_title())
local icon = task:get_icon_name()
if(icon==nil) then
icon = "ui_iconsTotal_storyline"
end
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, news_text..".", icon, "iconed_answer_item")
else
db.actor:give_game_news(news_caption, news_text..".", icon, 0, time_on_screen)
end
end
function send_treasure(param)
local news_caption = ""
if(param==0) then
news_caption = game.translate_string("st_found_new_treasure")
elseif(param==1) then
news_caption = game.translate_string("st_got_treasure")
xr_sound.set_sound_play(db.actor:id(), "pda_tips")
elseif(param==2) then
news_caption = game.translate_string("st_found_old_treasure")
end
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, "", "ui_inGame2_Polucheni_koordinaty_taynika", "iconed_answer_item")
else
db.actor:give_game_news(news_caption, "", "ui_inGame2_Polucheni_koordinaty_taynika", 0, 3000)
end
end
function get_inv_name(section)
return system_ini():r_string(section,"inv_name")
end
function relocate_item(actor, type, item, amount)
if db.actor == nil then return false end
--' Èãðàåì äåôîëòíûé çâóê
if not amount then
amount = 1
end
local news_caption = ""
local news_text = ""
if type == "in" then
if amount == 1 then
news_caption = game.translate_string("general_in_item")
news_text = game.translate_string(get_inv_name(item))
else
news_caption = game.translate_string("general_in_item")
news_text = game.translate_string(get_inv_name(item)).." x"..amount
end
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, news_text, "ui_inGame2_Predmet_poluchen", "iconed_answer_item")
else
db.actor:give_game_news(news_caption, news_text, "ui_inGame2_Predmet_poluchen", 0, 3000)
end
elseif type == "out" then
if amount == 1 then
news_caption = game.translate_string("general_out_item")
news_text = game.translate_string(get_inv_name(item))
else
news_caption = game.translate_string("general_out_item")
news_text = game.translate_string(get_inv_name(item)).." x"..amount
end
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, news_text, "ui_inGame2_Predmet_otdan", "iconed_answer_item")
else
db.actor:give_game_news(news_caption, news_text, "ui_inGame2_Predmet_otdan", 0, 3000)
end
end
end
function relocate_money(actor, type, amount)
if db.actor == nil then return false end
--' Èãðàåì äåôîëòíûé çâóê
if type == "in" then
local news_caption = game.translate_string("general_in_money")
local news_text = game.translate_string(tostring(amount))
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, news_text, "ui_inGame2_Dengi_polucheni", "iconed_answer_item")
else
db.actor:give_game_news(news_caption, news_text, "ui_inGame2_Dengi_polucheni", 0, 3000)
end
elseif type == "out" then
local news_caption = game.translate_string("general_out_money")
local news_text = game.translate_string(tostring(amount))
if db.actor:is_talking() then
db.actor:give_talk_message2(news_caption, news_text, "ui_inGame2_Dengi_otdani", "iconed_answer_item")
else
db.actor:give_game_news(news_caption, news_text, "ui_inGame2_Dengi_otdani", 0, 3000)
end
end
end

View file

@ -0,0 +1,110 @@
local function empty(container)
for i,j in pairs(container) do
return false
end
return true
end
class "object_collection"
function object_collection:__init()
self.m_free = {}
self.m_given = {}
self.m_count = 0
self.m_last_id = 0
end
function object_collection:get_id()
printf("get_id called [%s]", self.m_count)
self.m_count = self.m_count + 1
if (empty(self.m_free) == true) then
self.m_last_id = self.m_last_id + 1
self.m_given[self.m_last_id] = true
return self.m_last_id
end
for i,j in pairs(self.m_free) do
self.m_free[i] = nil
self.m_given[i] = true
return i
end
end
function object_collection:remove(id)
printf("remove called [%s]", tostring(id))
if self.m_given[id] == true then
self.m_given[id] = nil
self.m_free[id] = 1
self.m_count = self.m_count - 1
end
end
function object_collection:size()
return self.m_count
end
function object_collection:save(packet)
set_save_marker(packet, "save", false, "object_collection")
printf("SAVE OBJECT COLLECTION")
printf("------- m_count %s m_last_id %s", self.m_count, self.m_last_id)
printf("-------- m_free")
print_table(self.m_free)
printf("-------- m_given")
print_table(self.m_given)
printf("--------")
packet:w_u16(self.m_count)
packet:w_u16(self.m_last_id)
local n = 0
for k,v in pairs(self.m_free) do
n = n + 1
end
packet:w_u16(n)
for k,v in pairs(self.m_free) do
packet:w_u16(k)
end
n = 0
for k,v in pairs(self.m_given) do
n = n + 1
end
packet:w_u16(n)
for k,v in pairs(self.m_given) do
packet:w_u16(k)
end
set_save_marker(packet, "save", true, "object_collection")
end
function object_collection:load(packet)
set_save_marker(packet, "load", false, "object_collection")
printf("LOAD OBJECT COLLECTION")
callstack()
self.m_count = packet:r_u16()
self.m_last_id = packet:r_u16()
local n = packet:r_u16()
self.m_free = {}
for i = 1,n do
local id = packet:r_u16()
self.m_free[id] = 1
end
n = packet:r_u16()
self.m_given = {}
for i = 1,n do
local id = packet:r_u16()
self.m_given[id] = true
end
printf("------- m_count %s m_last_id %s", self.m_count, self.m_last_id)
printf("-------- m_free")
print_table(self.m_free)
printf("-------- m_given")
print_table(self.m_given)
printf("--------")
set_save_marker(packet, "load", true, "object_collection")
end

View file

@ -0,0 +1,10 @@
function main ()
db.actor:give_info_portion("pri_a28_actor_in_zone_stay")
db.actor:give_info_portion("kingpin_gained")
db.actor:give_info_portion("sim_duty_help_harder")
db.actor:give_info_portion("jup_a10_vano_agree_go_und")
db.actor:give_info_portion("jup_b218_monolith_hired")
db.actor:give_info_portion("jup_b218_soldier_hired")
db.actor:give_info_portion("pri_a28_strelok_dead")
db.actor:give_info_portion("pri_a28_koval_dead")
end

View file

@ -0,0 +1,18 @@
function main ()
db.actor:give_info_portion("pri_a28_actor_in_zone_stay")
db.actor:give_info_portion("zat_b57_bloodsucker_lair_clear")
db.actor:give_info_portion("research_man_gained")
db.actor:give_info_portion("pri_a28_army_leaved_alive")
db.actor:give_info_portion("jup_b16_oasis_artefact_to_scientist")
db.actor:give_info_portion("mutant_hunter_achievement_gained")
db.actor:give_info_portion("pri_b301_save_zulus_complete")
db.actor:give_info_portion("jup_a10_vano_agree_go_und")
db.actor:give_info_portion("pri_a16_vano_was_alive_when_removed")
db.actor:give_info_portion("jup_b218_monolith_hired")
db.actor:give_info_portion("jup_b218_soldier_hired")
db.actor:give_info_portion("pri_a28_sokolov_left_alive")
db.actor:give_info_portion("balance_advocate_gained")
db.actor:give_info_portion("zat_b18_noah_met")
db.actor:give_info_portion("zat_b44_tech_buddies_both_told")
db.actor:give_info_portion("pri_a16_wanderer_was_alive_when_removed")
end

View file

@ -0,0 +1,222 @@
-- Preconditions for Outro of STALKER: Call Of Pripyat (see game_tutorials->outro_game)
-- 4a
function skadovsk_bad_cond()
return has_alife_info("kingpin_gained")
end
-- 4b
function skadovsk_good_cond()
return has_alife_info("one_of_the_lads_gained")
end
-- 4c
function skadovsk_neutral_cond()
return ( not has_alife_info("kingpin_gained") ) and ( not has_alife_info("one_of_the_lads_gained") )
end
-- 5a
function bloodsucker_live_cond()
return not has_alife_info("zat_b57_bloodsucker_lair_clear")
end
-- 5b
function bloodsucker_dead_cond()
return has_alife_info("zat_b57_bloodsucker_lair_clear")
end
-- 6a
function dolg_die_cond()
return has_alife_info("sim_freedom_help_harder")
end
-- 6b
function freedom_die_cond()
return has_alife_info("sim_duty_help_harder")
end
-- 6c
function dolg_n_freedom_cond()
return ( not has_alife_info("sim_freedom_help_harder") ) and ( not has_alife_info("sim_duty_help_harder") )
end
-- 7a
function scientist_good_cond()
return has_alife_info("research_man_gained")
end
-- 7b
function scientist_bad_cond()
return not has_alife_info("research_man_gained")
end
-- 8a
function garik_good_cond()
return has_alife_info("pri_a28_army_leaved_alive")
end
-- 8b
function garik_bad_cond()
return not has_alife_info("pri_a28_army_leaved_alive")
end
-- 9
function oasis_cond()
return has_alife_info("jup_b16_oasis_artefact_to_scientist")
end
-- 10
function mercenarys_cond()
return has_alife_info("pri_b35_task_running")
end
-- 11a
function yanov_good_cond()
return has_alife_info("mutant_hunter_achievement_gained")
end
-- 11b
function yanov_bad_cond()
return not has_alife_info("mutant_hunter_achievement_gained")
end
-- 12a
function zuluz_good_cond()
return has_alife_info("pri_b301_save_zulus_complete")
end
-- 12b
function zuluz_bad_cond()
return not has_alife_info("pri_b301_save_zulus_complete")
end
-- 13a
function vano_good_cond()
return has_alife_info("jup_a10_vano_agree_go_und") and has_alife_info("pri_a16_vano_was_alive_when_removed")
end
-- 13b
function vano_bad_cond()
return has_alife_info("jup_a10_vano_agree_go_und") and ( not has_alife_info("pri_a16_vano_was_alive_when_removed") )
end
-- 14a
function brodyaga_good_cond()
return has_alife_info("jup_b218_monolith_hired") and has_alife_info("pri_a16_wanderer_was_alive_when_removed")
end
-- 14b
function brodyaga_bad_cond()
return has_alife_info("jup_b218_monolith_hired") and ( not has_alife_info("pri_a16_wanderer_was_alive_when_removed") )
end
-- 15a
function sokolov_good_cond()
return has_alife_info("jup_b218_soldier_hired") and has_alife_info("pri_a28_sokolov_left_alive")
end
-- 15b
function sokolov_bad_cond()
return has_alife_info("jup_b218_soldier_hired") and ( not has_alife_info("pri_a28_sokolov_left_alive") )
end
-- 16
function sich_cond()
return has_alife_info("balance_advocate_gained")
end
-- 17
function noahs_ark_cond()
return has_alife_info("zat_b18_noah_met") and ( not has_alife_info("zat_b18_noah_dead") )
end
-- 18a
function kardan_good_cond()
return has_alife_info("zat_b44_tech_buddies_both_told")
end
-- 18b
function kardan_bad_cond()
return not has_alife_info("zat_b44_tech_buddies_both_told")
end
--19a
function strelok_live_cond()
return not has_alife_info("pri_a28_strelok_dead")
end
-- 19b
function strelok_die_cond()
return has_alife_info("pri_a28_strelok_dead")
end
-- 20a
function kovalski_live_cond()
return not has_alife_info("pri_a28_koval_dead")
end
-- 20b
function kovalski_die_cond()
return has_alife_info("pri_a28_koval_dead")
end
class "outro_sound"
function outro_sound:__init()
end
function outro_sound:start()
self.snd = sound_object("music\\outro")
self.snd:play (nil, 0.0, sound_object.s2d)
self:set_volume (1.0)
end
function outro_sound:stop()
self.snd:stop ()
end
function outro_sound:set_volume(vol)
self.snd.volume = vol
end
function start_bk_sound()
g_outro_sound = outro_sound()
g_outro_sound:start()
local hud = get_hud()
hud:AddCustomStatic("blackscreen", true)
xr_effects.disable_ui_only(db.actor, nil)
end
function stop_bk_sound()
if g_outro_sound ~= nil then
g_outro_sound:stop()
end
g_outro_sound = nil
xr_effects.game_disconnect()
xr_effects.game_credits()end
volume_max = 1.0
volume_min = 0.3
function calc_fade(factor, fade1_pos, fade2_pos, fade1_volume, fade2_volume)
local f = ((factor-fade1_pos)*(fade2_volume-fade1_volume))/(fade2_pos-fade1_pos) + fade1_volume
local min_vol = 0.0
local max_vol = 1.0
if fade1_volume > fade2_volume then
max_vol = fade1_volume
min_vol = fade2_volume
else
max_vol = fade2_volume
min_vol = fade1_volume
end
if f>max_vol then
f = max_vol
elseif f<min_vol then
f = min_vol
end
-- printf("%f - %f", factor, f)
return f
end
function update_bk_sound_fade_start(factor)
local start_pt = 0.6
local stop_pt = 1.0
f = calc_fade(factor, start_pt, stop_pt, volume_max, volume_min)
g_outro_sound:set_volume(f)
end
function update_bk_sound_fade_stop(factor)
local f = 1.0
if factor < 0.5 then
local start_pt = 0.0
local stop_pt = 0.12
f = calc_fade(factor, start_pt, stop_pt, volume_min, volume_max)
else
local start_pt2 = 0.7
local stop_pt2 = 0.95
f = calc_fade(factor, start_pt2, stop_pt2, volume_max, 0.0)
end
printf("%f - %f", factor, f)
g_outro_sound:set_volume(f)
end
function start_outro()
game.start_tutorial("outro_game")
end

View file

@ -0,0 +1,21 @@
function main ()
db.actor:give_info_portion("pri_a28_actor_in_zone_stay")
db.actor:give_info_portion("one_of_the_lads_gained")
db.actor:give_info_portion("zat_b57_bloodsucker_lair_clear")
db.actor:give_info_portion("sim_freedom_help_harder")
db.actor:give_info_portion("research_man_gained")
db.actor:give_info_portion("pri_a28_army_leaved_alive")
db.actor:give_info_portion("jup_b16_oasis_artefact_to_scientist")
db.actor:give_info_portion("mutant_hunter_achievement_gained")
db.actor:give_info_portion("pri_b301_save_zulus_complete")
db.actor:give_info_portion("jup_a10_vano_agree_go_und")
db.actor:give_info_portion("pri_a16_vano_was_alive_when_removed")
db.actor:give_info_portion("jup_b218_monolith_hired")
db.actor:give_info_portion("jup_b218_soldier_hired")
db.actor:give_info_portion("pri_a28_sokolov_left_alive")
db.actor:give_info_portion("balance_advocate_gained")
db.actor:give_info_portion("zat_b18_noah_met")
db.actor:give_info_portion("zat_b44_tech_buddies_both_told")
db.actor:give_info_portion("pri_a16_wanderer_was_alive_when_removed")
db.actor:give_info_portion("pri_b35_task_running")
end

450
gamedata/scripts/pda.script Normal file
View file

@ -0,0 +1,450 @@
-- вызывается 1 раз в 3 секунды
function fill_faction_state(state)
local board = sim_board.get_sim_board()
state.member_count = 0
state.resource = 0
state.power = 0
state.actor_goodwill = 3000
state.name = "ui_inGame2_hint_wnd_bar"
state.icon = "ui_inGame2_hint_wnd_bar"
state.icon_big = "logos_big_empty"
state.target = game.translate_string("ui_st_no_faction")
state.target_desc = "aaa"
state.location = "a"
state.war_state1 = "a"
state.war_state_hint1 = "1"
state.war_state2 = "3"
state.war_state_hint2 = "2"
state.war_state3 = "33"
state.war_state_hint3 = ""
state.war_state4 = "23"
state.war_state_hint4 = ""
state.war_state5 = "5"
state.war_state_hint5 = "5"
state.bonus = 0
end
--int get_max_member_count (); ------ 1 раз в 3 секунды
--float get_max_resource();
--float get_max_power();
function get_max_member_count()
return 10
end
function get_max_resource()
return 10
end
function get_max_power()
return 10
end
-- потом это нужно стереть
-- int mode:
-- 0 = Undefined = закрыто
-- 1 = Inventory
-- 2 = Trade
-- 3 = Upgrade
-- 4 = DeadBodySearch
-- 10 = Talk dialog show
-- 11 = Talk dialog hide
local last_mode = 0
dialog_closed = false
trade_closed = false
upgrade_closed = false
function actor_menu_mode(mode)
if(mode==0) then
if(last_mode==1) then
inventory_wnd_closed()
elseif(last_mode==2) then
trade_wnd_closed()
elseif(last_mode==3) then
upgrade_wnd_closed()
elseif(last_mode==4) then
dead_body_search_wnd_closed()
end
last_mode = 0
elseif(mode==1) then
last_mode = 1
inventory_wnd_opened()
elseif(mode==2) then
last_mode = 2
trade_wnd_opened()
elseif(mode==3) then
last_mode = 3
upgrade_wnd_opened()
elseif(mode==4) then
last_mode = 4
dead_body_search_wnd_opened()
elseif(mode==10) then
dialog_wnd_showed()
elseif(mode==11) then
dialog_wnd_closed()
end
end
function inventory_wnd_opened()
--printf("---:>Inventory opened")
end
function inventory_wnd_closed()
--printf("---:>Inventory closed")
end
function trade_wnd_opened()
dialog_closed = false
--printf("---:>Trade opened")
end
function trade_wnd_closed()
--printf("---:>Trade closed")
trade_closed = true
end
function upgrade_wnd_opened()
dialog_closed = false
--printf("---:>Upgrade opened")
end
function upgrade_wnd_closed()
--printf("---:>Upgrade closed")
upgrade_closed = true
end
function dead_body_search_wnd_opened()
--printf("---:>DeadBodySearch opened")
end
function dead_body_search_wnd_closed()
--printf("---:>DeadBodySearch closed")
end
function dialog_wnd_showed()
dialog_closed = false
for k,v in pairs(db.storage) do
local npc = v.object
if npc ~= nil then
local npc_id = npc:id()
if npc:is_talking() and npc_id ~= db.actor:id() then
local sound_theme = xr_sound.sound_table[npc_id]
if sound_theme and sound_theme.reset then
sound_theme:reset(npc_id)
end
break
end
end
end
--printf("---:>Talk Dialog show")
end
function dialog_wnd_closed()
--printf("---:>Talk Dialog hide")
dialog_closed = true
end
-- CoCray
function get_time_elapsed()
local s_time = level.get_start_time()
local seconds = tonumber(game.get_game_time():diffSec(s_time))
if (seconds < 60) then
return string.format("%d %s",seconds,game.translate_string("ui_st_secs"))
elseif (seconds < 3600) then
return string.format("%d %s",seconds/60,game.translate_string("ui_st_mins"))
elseif (seconds < 86400) then
return string.format("%d %s",seconds/60/60,game.translate_string("ui_st_hours"))
end
return string.format("%d %s",seconds/60/60/24,game.translate_string("ui_st_days"))
end
--//
function get_stat(index) -- index= int return string
if(index==0) then
return tostring(get_time_elapsed())
elseif(index==1) then
return tostring(xr_statistic.actor_statistic.surges)
elseif(index==2) then
return tostring(xr_statistic.actor_statistic.completed_quests)
elseif(index==3) then
return tostring(xr_statistic.actor_statistic.killed_monsters)
elseif(index==4) then
return tostring(xr_statistic.actor_statistic.killed_stalkers)
elseif(index==5) then
return tostring(xr_statistic.actor_statistic.artefacts_founded)
elseif(index==6) then
return tostring(xr_statistic.actor_statistic.founded_secrets)
end
return "Unknown"
end
killed_monsters_tbl =
{
bloodsucker_weak = {back = "ui_inGame2_Krovosos", icon = ""},
bloodsucker_normal = {back = "ui_inGame2_Krovosos_1", icon = ""},
bloodsucker_strong = {back = "ui_inGame2_Krovosos_2", icon = ""},
boar_weak = {back = "ui_inGame2_Kaban_1", icon = ""},
boar_strong = {back = "ui_inGame2_Kaban", icon = ""},
burer = {back = "ui_inGame2_Burer", icon = ""},
chimera = {back = "ui_inGame2_Himera", icon = ""},
controller = {back = "ui_inGame2_Controller", icon = ""},
dog = {back = "ui_inGame2_Blind_Dog", icon = ""},
flesh_weak = {back = "ui_inGame2_Flesh", icon = ""},
flesh_strong = {back = "ui_inGame2_Flesh_1", icon = ""},
gigant = {back = "ui_inGame2_Pseudo_Gigant", icon = ""},
poltergeist_tele = {back = "ui_inGame2_Poltergeyst", icon = ""},
poltergeist_flame = {back = "ui_inGame2_Poltergeist_1", icon = ""},
psy_dog_weak = {back = "ui_inGame2_PseudoDog_1", icon = ""},
psy_dog_strong = {back = "ui_inGame2_PseudoDog", icon = ""},
pseudodog_weak = {back = "ui_inGame2_PseudoDog_1", icon = ""},
pseudodog_strong = {back = "ui_inGame2_PseudoDog", icon = ""},
snork = {back = "ui_inGame2_Snork", icon = ""},
tushkano = {back = "ui_inGame2_Tushkan", icon = ""},
none = {back = "", icon = ""}
}
function get_monster_back()
if not(xr_statistic.actor_statistic.best_monster) or not(killed_monsters_tbl[xr_statistic.actor_statistic.best_monster]) then
return tostring(killed_monsters_tbl.none.back)
end
return tostring(killed_monsters_tbl[xr_statistic.actor_statistic.best_monster].back)
end
function get_monster_icon()
if not(xr_statistic.actor_statistic.best_monster) or not(killed_monsters_tbl[xr_statistic.actor_statistic.best_monster]) then
return tostring(killed_monsters_tbl.none.icon)
end
return tostring(killed_monsters_tbl[xr_statistic.actor_statistic.best_monster].icon)
end
function get_favorite_weapon()
if not(xr_statistic.actor_statistic.favorite_weapon_sect) then
return "wpn_knife"
end
return xr_statistic.actor_statistic.favorite_weapon_sect
end
local primary_objects_tbl =
{
{target="zat_b55_spot", hint="st_zat_b55_name"},
{target="zat_b100_spot", hint="st_zat_b100_name"},
{target="zat_b104_spot", hint="st_zat_b104_name"},
{target="zat_b38_spot", hint="st_zat_b38_name"},
{target="zat_b40_spot", hint="st_zat_b40_name"},
{target="zat_b56_spot", hint="st_zat_b56_name"},
{target="zat_b5_spot", hint="st_zat_b5_name"},
{target="zat_a2_spot", hint="st_zat_a2_name"},
{target="zat_b20_spot", hint="st_zat_b20_name"},
{target="zat_b53_spot", hint="st_zat_b53_name"},
{target="zat_b101_spot", hint="st_zat_b101_name"},
{target="zat_b106_spot", hint="st_zat_b106_name"},
{target="zat_b7_spot", hint="st_zat_b7_name"},
{target="zat_b14_spot", hint="st_zat_b14_name"},
{target="zat_b52_spot", hint="st_zat_b52_name"},
{target="zat_b39_spot", hint="st_zat_b39_name"},
{target="zat_b33_spot", hint="st_zat_b33_name"},
{target="zat_b18_spot", hint="st_zat_b18_name"},
{target="zat_b54_spot", hint="st_zat_b54_name"},
{target="zat_b12_spot", hint="st_zat_b12_name"},
{target="zat_b28_spot", hint="st_zat_b28_name"},
{target="zat_b103_spot", hint="st_zat_b103_name"},
{target="jup_b1_spot", hint="st_jup_b1_name"},
{target="jup_b46_spot", hint="st_jup_b46_name"},
{target="jup_b202_spot", hint="st_jup_b202_name"},
{target="jup_b211_spot", hint="st_jup_b211_name"},
{target="jup_b200_spot", hint="st_jup_b200_name"},
{target="jup_b19_spot", hint="st_jup_b19_name"},
{target="jup_a6_spot", hint="st_jup_a6_name"},
{target="jup_b25_spot", hint="st_jup_b25_name"},
{target="jup_b6_spot", hint="st_jup_b6_name"},
{target="jup_b205_spot", hint="st_jup_b205_name"},
{target="jup_b206_spot", hint="st_jup_b206_name"},
{target="jup_b32_spot", hint="st_jup_b32_name"},
{target="jup_a10_spot", hint="st_jup_a10_name"},
{target="jup_b209_spot", hint="st_jup_b209_name"},
{target="jup_b208_spot", hint="st_jup_b208_name"},
{target="jup_a12_spot", hint="st_jup_a12_name"},
{target="jup_b212_spot", hint="st_jup_b212_name"},
{target="jup_b9_spot", hint="st_jup_b9_name"},
{target="jup_b201_spot", hint="st_jup_b201_name"},
{target="jup_a9_spot", hint="st_jup_a9_name"},
{target="pri_a28_spot", hint="st_pri_a28_name"},
{target="pri_b36_spot", hint="st_pri_b36_name"},
{target="pri_b303_spot", hint="st_pri_b303_name"},
{target="pri_b301_spot", hint="st_pri_b301_name"},
{target="pri_a17_spot", hint="st_pri_a17_name"},
{target="pri_b306_spot", hint="st_pri_b306_name"},
{target="pri_a16_spot", hint="st_pri_a16_name"},
{target="pri_a25_spot", hint="st_pri_a25_name"},
{target="pri_b35_spot", hint="st_pri_b35_name"},
{target="pri_a21_spot", hint="st_pri_a21_name"},
{target="pri_b304_spot", hint="st_pri_b304_name"},
{target="pri_a18_spot", hint="st_pri_a18_name"}
}
local change_objects_tbl =
{
{target = "jup_b32_spot", hint = "st_jup_b32_name", zone = "jup_b32_anomal_zone", group = "jup_b32_scanner_1_placed", enabled = false},
{target = "jup_b201_spot", hint = "st_jup_b201_name", zone = "jup_b201_anomal_zone", group = "jup_b32_scanner_2_placed", enabled = false},
{target = "jup_b209_spot", hint = "st_jup_b209_name", zone = "jup_b209_anomal_zone", group = "jup_b32_scanner_3_placed", enabled = false},
{target = "jup_b211_spot", hint = "st_jup_b211_name", zone = "jup_b211_anomal_zone", group = "jup_b32_scanner_4_placed", enabled = false},
{target = "jup_b1_spot", hint = "st_jup_b1_name", zone = "jup_b10_anomal_zone", group = "jup_b32_scanner_5_placed", enabled = false},
}
local sleep_zones_tbl =
{
{target = "zat_a2_sr_sleep_id", hint = "st_ui_pda_sleep_place"},
{target = "jup_a6_sr_sleep_id", hint = "st_ui_pda_sleep_place"},
{target = "pri_a16_sr_sleep_id", hint = "st_ui_pda_sleep_place"},
}
function fill_primary_objects()
for k,v in pairs(primary_objects_tbl) do
local obj_id = get_story_object_id(v.target)
if(obj_id) then
level.map_add_object_spot(obj_id, "primary_object", v.hint)
end
end
change_anomalies_names()
fill_sleep_zones()
end
function fill_sleep_zones()
for k,v in pairs(sleep_zones_tbl) do
local obj_id = get_story_object_id(v.target)
if(obj_id and db.storage[obj_id] and db.storage[obj_id].object) then
if(db.storage[obj_id].object:position():distance_to(db.actor:position())<=150 and level.map_has_object_spot(obj_id, "ui_pda2_actor_sleep_location")==0) then
level.map_add_object_spot(obj_id, "ui_pda2_actor_sleep_location", v.hint)
elseif(db.storage[obj_id].object:position():distance_to(db.actor:position())>150 and level.map_has_object_spot(obj_id, "ui_pda2_actor_sleep_location")~=0) then
level.map_remove_object_spot(obj_id, "ui_pda2_actor_sleep_location")
end
end
end
end
function add_quick_slot_items_on_game_start()
local _ini = system_ini()
local str = utils.cfg_get_string(_ini, "actor", "quick_item_1", db.actor, false, "", "")
get_console():execute("slot_0 "..str)
local str = utils.cfg_get_string(_ini, "actor", "quick_item_2", db.actor, false, "", "")
get_console():execute("slot_1 "..str)
local str = utils.cfg_get_string(_ini, "actor", "quick_item_3", db.actor, false, "", "")
get_console():execute("slot_2 "..str)
local str = utils.cfg_get_string(_ini, "actor", "quick_item_4", db.actor, false, "", "")
get_console():execute("slot_3 "..str)
end
function change_anomalies_names()
if has_alife_info("jup_b32_scanner_reward") then
for k,v in pairs(change_objects_tbl) do
if has_alife_info(v.group) and not v.enabled then
v.enabled = true
end
end
end
if level.name() ~= "jupiter" then
return
end
for k,v in pairs(change_objects_tbl) do
if v.enabled then
local obj_id = get_story_object_id(v.target)
if (obj_id) and (level.map_has_object_spot(obj_id, "primary_object") ~= 0) then
level.map_remove_object_spot(obj_id, "primary_object")
end
local hint = game.translate_string(v.hint).."\\n".." \\n"
local has_af = false
local af_table = {}
has_af, af_table = xr_conditions.anomaly_has_artefact(db.actor, nil, {v.zone})
if has_af then
hint = hint..game.translate_string("st_jup_b32_has_af")
for k,v in pairs(af_table) do
hint = hint.."\\n"..game.translate_string("st_"..v.."_name")
end
else
hint = hint..game.translate_string("st_jup_b32_no_af")
end
if (obj_id) and level.map_has_object_spot(obj_id, "primary_object") == 0 then
level.map_add_object_spot(obj_id, "primary_object", hint)
end
end
end
end
-- CoCray
----------------------------------------------------------------------------
-- Engine->lua function calls
----------------------------------------------------------------------------
-- PDA Tabs
-- It's now possible to add new button tabs to pda*.xml.
-- You can use ActorMenu.get_pda_menu():GetActiveSection() to find out active pda tab
-- UI returned must be CUIScriptWnd
function set_active_subdialog(section)
--printf("section=%s",section)
if (section == "eptTasks") then
elseif (section == "eptRanking") then
elseif (section == "eptLogs") then
return nil
elseif (section == "eptRelations") then
--return ui_pda_relations_tab.get_ui()
elseif (section == "eptContacts") then
--return ui_pda_contacts_tab.get_ui()
elseif (section == "eptEncyclopedia") then
--return ui_pda_encyclopedia_tab.get_ui()
end
end
function property_box_clicked(property_ui)
-- See CoC for implmentation
end
function property_box_add_properties(property_ui,id,level_name,hint)
-- See CoC for implmentation
end
-- called from engine! It's how many character rankings to display! u8 (max 255)
function get_rankings_array_size()
return 1
end
-- called from engine! must return bool!
function coc_rankings_can_show(index)
return false
end
-- called from engine! must return string!
function coc_rankings_set_name(index)
return ""
end
-- called from engine! must return string!
function coc_rankings_set_hint(index)
return ""
end
-- called from engine! must return string!
function coc_rankings_set_description(index)
return ""
end
-- called from engine! must return string!
function coc_rankings_set_icon(index)
return ""
end
-- //

View file

@ -0,0 +1,76 @@
-- Ïðèëîæåíèå ñèëû ê ôèçè÷åñêîìó îáúåêòó
-- Created by Tunduk Vladimir aka Sidorovich
----------------
class "ph_force"
----------------
function ph_force:__init (obj, storage)
self.object = obj
self.st = storage
self.time = 0
self.process = false
end
----------------
function ph_force:reset_scheme ()
if self.st.delay ~= 0 then
self.time = time_global () + self.st.delay
end
self.process = false
end
----------------
function ph_force:update (delta)
if xr_logic.try_switch_to_another_section (self.object, self.st, db.actor) then
return
end
if self.process == true then
return
end
if self.st.delay ~= nil then
if time_global () - self.time < 0 then
return
end
end
local dir = self.st.point:sub (self.object:position ())
dir:normalize ()
self.object:set_const_force (dir, self.st.force, self.st.time)
self.process = true
end
----------------
function add_to_binder (npc, ini, scheme, section, storage)
local new_action = ph_force (npc, storage)
xr_logic.subscribe_action_for_events (npc, storage, new_action)
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.force = utils.cfg_get_number (ini, section, "force", npc, true, 0)
st.time = utils.cfg_get_number (ini, section, "time", npc, true, 0)
st.delay = utils.cfg_get_number (ini, section, "delay", npc, false, 0)
local path_name = utils.cfg_get_string(ini, section, "point", npc, true, "")
local index = utils.cfg_get_number (ini, section, "point_index", npc, false, 0)
if st.force == nil or st.force <= 0 then
abort ("PH_FORCE : invalid force !")
end
if st.time == nil or st.time <= 0 then
abort ("PH_FORCE : invalid time !")
end
if path_name == nil or path_name == "" then
abort ("PH_FORCE : invalid waypoint name !")
end
local path = patrol (path_name)
if index >= path:count () then
abort ("PH_FORCE : invalid waypoint index !")
end
st.point = path:point (index)
end

View file

@ -0,0 +1,96 @@
----------------------------------------------------------------------------------------------------
-- Button
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
----------------------------------------------------------------------------------------------------
class "ph_button"
function ph_button:__init(obj, storage)
self.object = obj
self.st = storage
end
function ph_button:reset_scheme()
self.object:play_cycle(self.st.anim, self.st.blending)
self.last_hit_tm = time_global()
end
function ph_button:update(delta)
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
end
function ph_button:try_switch()
local st = db.storage[self.object:id()]
if st.active_scheme and st.active_scheme == "ph_button" and self.st.on_press then
--if xr_logic.try_switch_to_another_section(obj, self.st, db.actor) then
if xr_logic.switch_to_section(self.object, self.st.ini,
xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.on_press.condlist)) then
return true
end
end
return false
end
function ph_button:hit_callback(obj, amount, local_direction, who, bone_index)
return
--[[ local who_name
if who then
who_name = who:name()
else
who_name = "nil"
end
printf("_bp: ph_button:hit_callback: obj='%s', amount=%d, who='%s'", obj:name(), amount, who_name)
if time_global() - self.last_hit_tm > 500 then
self.last_hit_tm = time_global()
if self:try_switch() then
return
end
end
]]
end
function ph_button:use_callback(victim, who)
printf("_bp: ph_button:use_callback: [%s] used by [%s]",
victim:name(), who:name())
if self:try_switch() then
return
end
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local new_action = ph_button(npc, storage)
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.on_press = xr_logic.cfg_get_condlist(ini, section, "on_press", npc)
st.tooltip = utils.cfg_get_string(ini, section, "tooltip", npc, false, "")
if st.tooltip then
npc:set_tip_text(st.tooltip)
else
npc:set_tip_text("")
end
st.anim = utils.cfg_get_string(ini, section, "anim", npc, true, "")
st.blending = utils.cfg_get_bool (ini, section, "anim_blend", npc, false, true)
if st.blending == nil then
st.blending = true
end
end

View file

@ -0,0 +1,86 @@
----------------------------------------------------------------------------------------------------
-- Code Pad
----------------------------------------------------------------------------------------------------
-- Author: Jim
-- Äîðàáîòêà: 2006 @ Oleg Kreptul (Haron) okreptul@yahoo.com
----------------------------------------------------------------------------------------------------
function printf() end
class "codepad"
function codepad:__init(obj, storage)
self.object = obj
self.st = storage
end
function codepad:reset_scheme()
self.object:set_nonscript_usable(false)
--self.object:set_callback(callback.use_object, self.use_callback, self)
end
function codepad:update(delta)
end
function codepad:use_callback(obj, who)
local numpad = ui_numpad.numpad(self)
numpad:ShowDialog(true)
end
function codepad:OnNumberReceive(text)
if self.st.code then
if tonumber(text) == self.st.code then
if self.st.on_code then
printf("ph_code <OnNumberReceive>: on_code [%s]", text)
xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.on_code.condlist)
end
end
else
local condlist = self.st.on_check_code[text]
if condlist then
printf("ph_code <OnNumberReceive>: on_check_code [%s]", text)
xr_logic.pick_section_from_condlist(db.actor, self.object, condlist)
end
end
end
function codepad:deactivate()
self.object:set_tip_text("")
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
local new_action = codepad(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
end
function set_scheme(npc, ini, scheme, section, gulag_name)
printf("ph_code <set_scheme>: START [%s]", npc: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.tips = utils.cfg_get_string(ini, section, "tips", npc, false, "", "st_codelock")
npc:set_tip_text(st.tips)
st.code = utils.cfg_get_number(ini, section, "code", npc, false)
if st.code then
st.on_code = xr_logic.cfg_get_condlist(ini, section, "on_code", npc)
printf("ph_code <set_scheme>: on_code [%d]", st.code)
else
st.on_check_code = {}
local i = 1
local cc = xr_logic.cfg_get_string_and_condlist(ini, section, "on_check_code" .. i, npc)
while cc do
st.on_check_code[cc.v1] = cc.condlist
printf("ph_code <set_scheme>: on_check_code [%s]", cc.v1)
i = i + 1
cc = xr_logic.cfg_get_string_and_condlist(ini, section, "on_check_code" .. i, npc)
end
end
printf("ph_code <set_scheme>: END [%s]", npc:name())
end

View file

@ -0,0 +1,46 @@
----------------------------------------------------------------------------------------------------
-- Physics death checker
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Tunduk Vladimir aka Sidorovich
----------------------------------------------------------------------------------------------------
class "ph_on_death"
function ph_on_death:__init(obj, storage)
self.object = obj
self.st = storage
end
function ph_on_death:reset_scheme()
end
function ph_on_death:update(delta)
end
function ph_on_death:death_callback (obj, who)
if db.storage[self.object:id()].active_scheme then
if xr_logic.try_switch_to_another_section (obj, self.st, db.actor) then
return
end
end
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local action = ph_on_death(npc, storage)
storage.action = action
xr_logic.subscribe_action_for_events (npc, storage, action)
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)
end
function disable_scheme(npc, scheme)
--- npc:set_callback(callback.death, nil)
end

View file

@ -0,0 +1,383 @@
----------------------------------------------------------------------------------------------------
-- Physic door control
----------------------------------------------------------------------------------------------------
-- Èñõîäíûé ñêðèïò: Evgeniy Negrobov (Jon) jon@gsc-game.kiev.ua
-- Ïåðåâîä íà xr_logic: Andrey Fidrya (Zmey) af@svitonline.com
-- Äîðàáîòêà: Oleg Kreptul (Haron) haronk@ukr.net
----------------------------------------------------------------------------------------------------
class "action_door"
function action_door:__init(obj, storage)
--printf ("action_door::action_door() called")
self.object = obj
self.st = storage
self.snd_obj = nil
storage.door_action = self
end
function action_door:reset_scheme(loading)
--printf("_bp: action_door:reset_scheme: self.object:name()='%s'", self.object:name())
self.st.signals = {}
self.initialized = false
local ph_shell = self.object:get_physics_shell()
if not ph_shell then
return
end
self.joint = ph_shell:get_joint_by_bone_name("door")
self.low_limits, self.hi_limits = 0, 0
self.low_limits, self.hi_limits = self.joint:get_limits(self.low_limits, self.hi_limits, 0)
self.block = false
self.soundless_block = false
self.show_tips = self.st.show_tips
local disable_snd
-- Çâóê íóæíî îòêëþ÷èòü, òîëüêî åñëè ñêðèïò äâåðè äëÿ ýòîãî îáúåêòà èñïîëüçóåòñÿ
-- âïåðâûå (ò.å. ïîñëå çàãðóçêè óðîâíÿ èëè ïîñëå çàãðóçêè ñîõðàíåííîé èãðû),
-- èíà÷å èãðîê óñëûøèò õëîïîê...
if not self.st.script_used_more_than_once then
disable_snd = true
self.st.script_used_more_than_once = true
end
if self.st.closed then
--' Åñëè äâåðü óæå çàêðûòà - òî íóæíî çàêðûòü áåç çâóêà
if self:is_closed() then
disable_snd = true
end
self:close_door(disable_snd)
else
self:open_door(disable_snd)
end
self.object:set_nonscript_usable(false)
self.initialized = true
end
function action_door:update(delta)
--printf("_bp: action_door:update()", delta)
if not self.initialized then
abort("object '%s': door failed to initialize", self.object:name())
end
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
end
function action_door:fastcall()
if not self.initialized then
return false
end
if self.block and self:is_closed() then
self:close_action()
self.object:on_door_is_closed()
return true
end
return false
end
function action_door:open_fastcall()
if not self.initialized then
return false
end
if self:is_open() then
local ph_obj = self.object:get_physics_object()
ph_obj:unset_door_ignore_dynamics() --'Èãíîðèðîâàíèå äèíàìèêè íà ìîìåíò îòêðûòèÿ/çàêðûòèÿ
self.object:on_door_is_open()
return true
end
return false
end
function action_door:close_action()
--printf("_bp: close_action(): %d", time_global())
-- Çàêðûëè äî ïðåäåëà, áóäåì áëîêèðîâàòü
if self.st.no_force == true then
self.joint:set_max_force_and_velocity(0, 0, 0)
else
self.joint:set_max_force_and_velocity(10000, 1, 0)
--!!! Ôèêñèðóåì êîñòü.
local ph_shell = self.object:get_physics_shell()
if ph_shell then
local ph_element = ph_shell:get_element_by_bone_name("door")
if not ph_element:is_fixed() then
--printf("FIX")
ph_element:fix()
end
end
end
local ph_obj = self.object:get_physics_object()
ph_obj:unset_door_ignore_dynamics() --'Èãíîðèðîâàíèå äèíàìèêè íà ìîìåíò îòêðûòèÿ/çàêðûòèÿ
self.block = false
-- Îòûãðàòü çâóê êîãäà äâåðü çàõëîïíóëàñü:
if not self.soundless_block and self.st.snd_close_stop then
xr_sound.set_sound_play(self.object:id(), self.st.snd_close_stop)
end
end
function action_door:open_door(disable_snd)
--printf("_bp: [%s] action_door:open_door()", self.object:name())
if not disable_snd then
if self.st.snd_open_start then
xr_sound.set_sound_play(self.object:id(), self.st.snd_open_start)
end
end
self.object:set_fastcall(self.open_fastcall,self)
--!!! Òóò íàäî ñíÿòü ôèêñàöèþ êîñòè
local ph_shell = self.object:get_physics_shell()
if ph_shell then
local ph_element = ph_shell:get_element_by_bone_name("door")
if ph_element:is_fixed() then
--printf("RELEASE")
ph_element:release_fixed()
local ph_obj = self.object:get_physics_object()
ph_obj:set_door_ignore_dynamics() --'Èãíîðèðîâàíèå äèíàìèêè íà ìîìåíò îòêðûòèÿ/çàêðûòèÿ
end
end
if self.st.no_force == true then
self.joint:set_max_force_and_velocity(0, 0, 0)
else
self.joint:set_max_force_and_velocity(2100, -3, 0)
end
self.block = false
if self.show_tips and self.st.tip_close then
self.object:set_tip_text(self.st.tip_close)
end
end
function action_door:is_closed()
local angle
if self.st.slider then
angle = -self.joint:get_axis_angle(0)
else
angle = self.joint:get_axis_angle(90)
end
--printf("_bp[%s]: action_door:update(): angle %f limits %f, %f",
-- self.object:name(), angle, self.low_limits, self.hi_limits)
if angle <= self.low_limits + 0.02 then
--printf("_bp: close_check(): true")
return true
end
return false
end
function action_door:is_open()
local angle
if self.st.slider then
angle = -self.joint:get_axis_angle(0)
else
angle = self.joint:get_axis_angle(90)
end
--printf("_bp[%s]: action_door:update(): angle %f limits %f, %f",
-- self.object:name(), angle, self.low_limits, self.hi_limits)
if angle >= self.hi_limits - 0.02 then
--printf("_bp: open_check(): true")
return true
end
return false
end
function action_door:close_door(disable_snd)
--printf("_bp: [%s] action_door:close_door()", self.object:name())
-- local disable_snd = self:is_closed()
if not disable_snd then
if self.st.snd_close_start then
xr_sound.set_sound_play(self.object:id(), self.st.snd_close_start)
end
end
-- Ñòàâèì êîëëáåê äëÿ îòëîâà îêîí÷àíèÿ çàêðûòèÿ äâåðè (÷òîáû çàáëîêèðîâàòü åå è ïðîèãðàòü çâóê, åñëè íóæíî):
self.object:set_fastcall(self.fastcall,self)
--printf("_bp: action_door:close_door()")
if self.st.no_force == true then
self.joint:set_max_force_and_velocity(0, 0, 0)
else
self.joint:set_max_force_and_velocity(200, 3, 0)
end
self.block = true -- Çàêðûâàåì è áëîêèðóåì
self.soundless_block = disable_snd
local ph_obj = self.object:get_physics_object()
ph_obj:set_door_ignore_dynamics() --'Èãíîðèðîâàíèå äèíàìèêè íà ìîìåíò îòêðûòèÿ/çàêðûòèÿ
if self.show_tips then
if self.st.locked == true and self.st.tip_unlock then
self.object:set_tip_text(self.st.tip_unlock)
return
end
if self.st.tip_open then
self.object:set_tip_text(self.st.tip_open)
end
end
end
function action_door:try_switch()
--printf("_bp: action_door: object '%s': try_switch", self.object:name())
if self.st.on_use then
if xr_logic.switch_to_section(self.object, self.st.ini,
xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.on_use.condlist)) then
return true
end
end
return false
end
function action_door:use_callback(door, actor)
if self.st.locked then
if self.st.snd_open_start then
xr_sound.set_sound_play(self.object:id(), self.st.snd_open_start)
end
end
if self:try_switch() then
return
end
-- local angle = self.joint:get_axis_angle(90)
-- if angle - self.low_limits > self.hi_limits - angle then
-- self:open_door(false)
-- else
-- self:close_door(false)
-- end
end
function action_door:hit_callback(obj, amount, local_direction, who, bone_index)
local who_name
if who then
who_name = who:name()
else
who_name = "nil"
end
--printf("DOOR: hit_callback: obj='%s', amount=%d, who='%s', bone='%s'", obj:name(), amount, who_name, bone_index)
print_table(self.st.hit_on_bone)
if self.st.hit_on_bone[bone_index] ~= nil then
local section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.hit_on_bone[bone_index].state)
xr_logic.switch_to_section(obj, self.st.ini, section)
return
end
end
function action_door:deactivate()
self.object:set_tip_text("")
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
--printf("DEBUG: add_to_binder: scheme='%s', section='%s'", scheme, section)
npc:register_door_for_npc ( )
local new_action = action_door(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.closed = utils.cfg_get_bool(ini, section, "closed", npc, false, true)
st.locked = utils.cfg_get_bool(ini, section, "locked", npc, false)
st.no_force = utils.cfg_get_bool(ini, section, "no_force", npc, false, false)
st.not_for_npc = utils.cfg_get_bool(ini, section, "not_for_npc", npc, false, false)
st.show_tips = utils.cfg_get_bool(ini, section, "show_tips", npc, false, true)
st.tip_open = utils.cfg_get_string(ini, section, "tip_open", npc, false, "", "tip_door_open")
st.tip_unlock = utils.cfg_get_string(ini, section, "tip_open", npc, false, "", "tip_door_locked")
st.tip_close = utils.cfg_get_string(ini, section, "tip_close", npc, false, "", "tip_door_close")
st.slider = utils.cfg_get_bool(ini, section, "slider", npc, false, false)
-- st.snd_init = utils.cfg_get_string(ini, section, "snd_init", npc, false, "")
st.snd_open_start = utils.cfg_get_string(ini, section, "snd_open_start", npc, false, "", "trader_door_open_start")
st.snd_close_start = utils.cfg_get_string(ini, section, "snd_close_start", npc, false, "", "trader_door_close_start")
st.snd_close_stop = utils.cfg_get_string(ini, section, "snd_close_stop", npc, false, "", "trader_door_close_stop")
st.on_use = xr_logic.cfg_get_condlist(ini, section, "on_use", npc)
if st.locked == true or st.not_for_npc == true then
if not npc:is_door_locked_for_npc() then
npc:lock_door_for_npc()
end
else
if npc:is_door_locked_for_npc() then
npc:unlock_door_for_npc()
end
end
st.hit_on_bone = utils.parse_data_1v(npc, utils.cfg_get_string(ini, section, "hit_on_bone", npc, false, ""))
end
-- Âûçûâàåòñÿ íà àïäåéòå ÍÏÑ
-- ïðîáåãàåòñÿ ïî âñåì äâåðÿì è ïûòàåòñÿ îòêðûòü òå, êîòîðûå íàõîäÿòñÿ ðÿäîì ñ ÍÏÑ
-- âîçâðàùàåò ñïèñîê äâåðåé, êîòîðóþ îòêðûë äàííûé ÍÏÑ
function try_to_open_door(npc)
if true then return {} end
local opened_doors = {}
local npc_position = npc:position()
for id,position in pairs(db.level_doors) do
if npc_position:distance_to_sqr(position) <= 9 then
if db.storage[id].ph_door ~= nil then
local action = db.storage[id].ph_door.door_action
if action.st.not_for_npc == false and action.st.closed == true then
--printf("OPEN DOOR")
action:use_callback()
opened_doors[id] = true
end
end
end
end
return opened_doors
end
function try_to_close_door(npc, doors)
if true then return {} end
local npc_position = npc:position()
local closed_doors = {}
for id, v in pairs(doors) do
if npc_position:distance_to_sqr(db.level_doors[id]) > 9 then
if db.storage[id].ph_door ~= nil then
local action = db.storage[id].ph_door.door_action
if action.st.not_for_npc == false and action.st.closed ~= true then
--printf("CLOSE DOOR")
action:use_callback()
closed_doors[id] = true
end
end
end
end
return closed_doors
end

View file

@ -0,0 +1,93 @@
----------------------------------------------------------------------------------------------------
-- Apply directional hit to the object
----------------------------------------------------------------------------------------------------
-- Èñõîäíûé ñêðèïò: Oleg Hryptul (Haron) haronk@ukr.net
----------------------------------------------------------------------------------------------------
class "action_hit"
----------------------------------------------------------------------------------------------------
-- Constructor
----------------------------------------------------------------------------------------------------
function action_hit:__init(obj, storage)
self.object = obj
self.st = storage
end
function action_hit:reset_scheme()
printf("_hr: action_hit:reset_scheme: self.object:name()='%s'", self.object:name())
local p1 = patrol(self.st.dir_path):point(0)
local p2 = self.object:position()
local h = hit()
h.power = self.st.power
h.impulse = self.st.impulse
h:bone(self.st.bone)
h.type = hit.strike
h.direction = utils.vector_copy_by_val(p1):sub(p2)
h.draftsman = self.object
self.object:hit(h)
--printf("_hr: action_hit:reset_scheme: p1=%f,%f,%f", p1.x, p1.y, p1.z)
--printf("_hr: action_hit:reset_scheme: p2=%f,%f,%f", p2.x, p2.y, p2.z)
--printf("_hr: action_hit:reset_scheme: bone = %d", h.bone)
printf("_hr: action_hit:reset_scheme: direction=%f,%f,%f", h.direction.x, h.direction.y, h.direction.z)
end
function action_hit:update(delta)
--printf("_hr: action_hit:update()")
--if not xr_logic.is_active(self.object, self.st) then
-- return
--end
local actor = level.actor()
if not actor then
return
end
if xr_logic.try_switch_to_another_section(self.object, self.st, actor) then
return
end
end
--[[
function action_hit:hit_callback(door, actor)
if self.st.locked then
if self.st.snd_open_start then
self:door_play_snd_from_set(self.st.snd_open_start)
end
return
end
local angle = self.joint:get_axis_angle(90)
if angle - self.low_limits > self.hi_limits - angle then
self:open_door()
else
self:close_door(false)
end
end
--]]
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: scheme='%s', section='%s'", scheme, section)
local new_action = action_hit(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.power = utils.cfg_get_number(ini, section, "power", npc, false, 0)
st.impulse = utils.cfg_get_number(ini, section, "impulse", npc, false, 1000)
st.bone = utils.cfg_get_string(ini, section, "bone", npc, true, "")
st.dir_path = utils.cfg_get_string(ini, section, "dir_path", npc, true, "")
end

View file

@ -0,0 +1,77 @@
----------------------------------------------------------------------------------------------------
-- Do nothing
----------------------------------------------------------------------------------------------------
-- Èñõîäíûé ñêðèïò: Oleg Hryptul (Haron) haronk@ukr.net
----------------------------------------------------------------------------------------------------
class "action_idle"
function action_idle:__init(obj, storage)
self.object = obj
self.st = storage
end
function action_idle:reset_scheme()
printf("_hr: action_idle:reset_scheme: self.object:name()='%s'", self.object:name())
self.object:set_nonscript_usable(self.st.nonscript_usable)
end
function action_idle:update(delta)
--printf("_hr: action_idle:update()")
--if not xr_logic.is_active(self.object, self.st) then
-- return
--end
local actor = db.actor
if xr_logic.try_switch_to_another_section(self.object, self.st, actor) then
return
end
end
function action_idle:hit_callback(obj, amount, local_direction, who, bone_index)
local who_name
if who then
who_name = who:name()
else
who_name = "nil"
end
printf("IDLE: hit_callback: obj='%s', amount=%d, who='%s', bone='%s'", obj:name(), amount, who_name, bone_index)
if self.st.hit_on_bone[bone_index] ~= nil then
local section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.hit_on_bone[bone_index].state)
xr_logic.switch_to_section(obj, self.st.ini, section)
return
end
end
function action_idle:use_callback(obj, actor)
if self.st.on_use then
if xr_logic.switch_to_section(self.object, self.st.ini,
xr_logic.pick_section_from_condlist(db.actor, self.object, self.st.on_use.condlist)) then
return true
end
end
end
function action_idle:deactivate()
self.object:set_tip_text("")
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf("DEBUG: add_to_binder: scheme='%s', section='%s'", scheme, section)
local new_action = action_idle(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.hit_on_bone = utils.parse_data_1v(npc, utils.cfg_get_string(ini, section, "hit_on_bone", npc, false, ""))
st.nonscript_usable = utils.cfg_get_bool(ini, section, "nonscript_usable", npc, false)
st.on_use = xr_logic.cfg_get_condlist(ini, section, "on_use", npc)
st.tips = utils.cfg_get_string(ini, section, "tips", npc, false, "", "")
npc:set_tip_text(st.tips)
end

View file

@ -0,0 +1,435 @@
function printf()
end
local pi_2 = math.pi / 3 -- 60 degree
local def_min_delta_per_sec = 0.2
local def_min_car_explode_time = 1000
local def_fire_angle = 120
local def_min_fire_time = 1.0
local def_fire_rep = 0.5
local def_fire_range = 50
local def_max_fc_upd_num = 1 -- default maximum fastcall updates num
local state_cannon_rotate = 1
local state_cannon_follow = 2
local state_cannon_delay = 3
local state_cannon_stop = 4
local state_shooting_on = 1
local state_none = 0
local state_firetarget_points = 1
local state_firetarget_enemy = 2
class "action_mgun"
function action_mgun:__init(obj, storage)
printf("mgun <state>: init.")
self.object = obj
self.mgun = self.object:get_car()
self.st = storage
self.start_direction = self.object:direction()
self.start_look_pos = vector():set(0,0,0)
self.start_look_pos.x = self.object:position().x + 5*math.sin(self.start_direction.x)
self.start_look_pos.z = self.object:position().z + 5*math.cos(self.start_direction.x)
self.start_look_pos.y = self.object:position().y
end
function action_mgun:reset_scheme(loading)
printf("car <state>: START INITIALIZING ======================================================")
printf("car <state>: action_mgun:reset_scheme: self.object:name()='%s'", self.object:name())
self.start_delaying_time = time_global()
self.start_shooting_time = time_global()
printf("pl mgun direction x:--- %s , z:--- %s", tostring(self.start_direction.x), tostring(self.start_direction.z))
self.fc_upd_num = 0 -- fastcall updates num
self.fc_upd_avg = 10 -- average time of the fastcall updates (in millisecond)
self.fc_last_upd_tm = -1 -- fastcall last update time
self.st.signals = {}
self.last_pos = nil
self.last_pos_time = 0
self.state_delaying = false
self.destroyed = false
self.object:set_nonscript_usable(false)
self.object:set_tip_text("")
if self.mgun:HasWeapon() then
printf("car <fire>: car has weapon.")
self.mgun:Action(CCar.eWpnActivate,1)
self.hasWeapon = true
else
printf("car <fire>: car hasn't weapon.")
self.hasWeapon = false
end
self.state_firetarget = state_none
self.state_cannon = state_none
self.state_shooting = state_none
self.target_fire_pt = nil
self.target_fire_pt_idx = 0
self.target_obj = nil
self.on_target_vis = nil
self.on_target_nvis = nil
if self.hasWeapon then
printf("car <fire>: target = %s", self.st.fire_target)
local n
if self.st.fire_target == "points" then
self.state_firetarget = state_firetarget_points
else
if self.st.fire_target == "actor" and db.actor:alive() then
self.target_obj = db.actor
self.state_firetarget = state_firetarget_enemy
else
n = self.st.fire_target
if n then
obj = get_story_object(n)
if obj and obj:alive() then
self.target_obj = obj
self.state_firetarget = state_firetarget_enemy
end
end
end
end
self.fire_track_target = self.st.fire_track_target
if self.st.on_target_vis then
vis = self.st.on_target_vis
if vis.v1 ~= nil then
obj = get_story_object(vis.v1)
if obj and obj:alive() then
vis.v1 = obj
self.on_target_vis = vis
printf("car <vis>: target %d", n)
end
end
end
if self.st.on_target_nvis then
nvis = self.st.on_target_nvis
if nvis.v1 ~= nil then
obj = get_story_object(nvis.v1)
if obj and obj:alive() then
nvis.v1 = obj
self.on_target_nvis = nvis
printf("car <nvis>: target %d", n)
end
end
end
self.path_fire = self.st.path_fire
self.path_fire_point = nil
--' Çàïîìèíàåì ïîçèöèþ êóäà ñòðåëÿòü.
if self.path_fire ~= nil then
if level.patrol_path_exists(self.path_fire) then
self.path_fire_point = patrol(self.path_fire):point(0)
else
abort("[ph_minigun] patrol path %s doesnt exist.", tostring(self.path_fire))
end
end
self.def_fire_time = self.st.fire_time
self.def_fire_rep = self.st.fire_rep
self.fire_rep = self.def_fire_rep
printf("car <fire>: def_rep = %d (%s)", self.fire_rep, utils.to_str(self.st.fire_rep))
self.fire_range_sqr = self.st.fire_range * self.st.fire_range
--' Ñòðåëüáà ïî ïàòðóëüíûì òî÷êàì.
if self.state_firetarget == state_firetarget_points and self.path_fire then
printf("car <state>: firetarget = points")
self.state_cannon = state_cannon_follow
self.state_shooting = state_none
elseif self.state_firetarget == state_firetarget_enemy then
printf("car <state>: firetarget = enemy")
self.state_shooting = state_none
self.state_cannon = state_cannon_follow
else
printf("car <state>: firetarget = none")
self.state_firetarget = state_none
self.state_cannon = state_none
self.state_shooting = state_none
end
end
self.object:set_fastcall(self.fastcall, self)
printf("car <state>: END INITIALIZING ========================================================\n")
end
function action_mgun:set_shooting(shooting)
self.mgun:Action(CCar.eWpnFire, shooting)
--'printf("car <fire>: action_car:set_shooting(%d)", shooting)
end
function action_mgun:check_fire_time()
if self.st.fire_rep == -1 then return end
if 1000*self.st.fire_time + self.start_shooting_time >= time_global() and self.state_delaying == false then
self.state_delaying = false
self.start_delaying_time = time_global() + math.random(-0.2, 0.2)*1000*self.st.fire_time
return
else
self.state_delaying = true
end
if self.start_delaying_time + 1000*self.st.fire_rep >= time_global() and self.state_delaying == true then
self.state_delaying = true
self.start_shooting_time = time_global()
else
self.state_delaying = false
end
end
function action_mgun:save()
end
function action_mgun:rot_to_firedir(direction)
if direction then
self.mgun:SetParam(CCar.eWpnDesiredPos, direction)
end
end
function action_mgun:rot_to_firepoint(pt)
if pt then
self.mgun:SetParam(CCar.eWpnDesiredPos, pt)
end
end
function action_mgun:set_signal(sig)
local stor = db.storage[self.object:id()]
stor[stor.active_scheme].signals[sig] = true
printf("car <sig>: %s", sig)
end
function action_mgun:fastcall()
if db.storage[self.object:id()].active_scheme ~= "ph_minigun" then
--' Åñëè àêòèâíàÿ ñõåìà - íå ìàøèíà, ñíÿòü áûñòðûé àïäåéò
self:set_shooting(0)
return true
end
return self:fast_update()
end
function action_mgun:update(delta)
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
return
end
if self.destroyed then
xr_logic.switch_to_section(self.object, self.st.ini, "nil")
return
end
self:check_fire_time()
end
function action_mgun:fast_update()
--printf("car <state>: START FAST UPDATE ======================================================")
if self.mgun:GetfHealth() <= 0 then
printf("car <state>: killed.")
self:destroy_car()
return true
end
local cur_time = time_global()
if self.fc_upd_num < def_max_fc_upd_num then
local last_upd = self.fc_last_upd_tm
if last_upd ~= -1 then
local n = self.fc_upd_num
if n < 3000 then
self.fc_upd_avg = (self.fc_upd_avg * n + (cur_time - last_upd))/(n + 1)
self.fc_upd_num = n + 1
else
self.fc_upd_num = 1
end
end
self.fc_last_upd_tm = cur_time
-- printf("car <state>: average update = %f, time(%f)", self.fc_upd_avg, cur_time)
end
if self.state_cannon == state_cannon_stop and
self.state_firetarget == state_none
then
if xr_logic.mob_captured(self.object) and not self.object:action() then
printf("car <state>: stopped")
self:destroy_car()
return true -- àïäåéòû áîëüøå íå íóæíû
end
return false
end
--printf("car <fire>: TEST")
if self.hasWeapon then
-- printf("car <fire>: target(%d)", self.state_firetarget)
if self.on_target_vis and self.on_target_vis.v1:alive() and self.mgun:IsObjectVisible(self.on_target_vis.v1) then
-- printf("car <vis>: try")
local new_section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.on_target_vis.condlist)
if new_section then
-- printf("car <vis>: switch to section [%s]", new_section)
xr_logic.switch_to_section(self.object, self.st.ini, new_section)
end
end
if self.on_target_nvis and self.on_target_nvis.v1:alive() and not self.mgun:IsObjectVisible(self.on_target_nvis.v1) then
--printf("car <nvis>: try")
local new_section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.on_target_nvis.condlist)
if new_section then
printf("car <nvis>: switch to section [%s]", new_section)
xr_logic.switch_to_section(self.object, self.st.ini, new_section)
end
end
if self.state_firetarget == state_firetarget_points then
--' Ñòðåëüáà ïî òî÷êàì
local fire_angle = angle_xz(self.object, self.path_fire_point, self.start_direction)
local can_rotate = fire_angle <= self.st.fire_angle*math.pi/360 and fire_angle >= -(self.st.fire_angle*math.pi/360)
if can_rotate then
self:rot_to_firepoint(self.path_fire_point)
if self.state_delaying then
if self.state_shooting ~= state_none and self.st.auto_fire == true then
self.state_shooting = state_none
self:set_shooting(self.state_shooting)
end
else
if self.state_shooting == state_none then
self.state_shooting = state_shooting_on
self:set_shooting(self.state_shooting)
end
end
end
elseif self.state_firetarget == state_firetarget_enemy then
local fire_angle = angle_xz(self.object, self.target_obj:position(), self.start_direction)
local can_rotate = fire_angle <= self.st.fire_angle*math.pi/360 and fire_angle >= -(self.st.fire_angle*math.pi/360)
local object_visible = self.mgun:IsObjectVisible(self.target_obj) or self.st.shoot_only_on_visible == false
--' printf("object visible:---------> %s can_rotate = %s fire_angle = %s", tostring(object_visible), tostring(can_rotate), tostring(fire_angle))
if self.target_obj:alive() and
self.object:position():distance_to_sqr(self.target_obj:position()) <= self.fire_range_sqr and
object_visible and can_rotate
then
if not self.state_delaying then
self.target_fire_pt = self.target_obj:position()
if self.target_obj:id() ~= db.actor:id() then
if self.target_obj:target_body_state() == move.crouch then
self.target_fire_pt.y = self.target_fire_pt.y + 0.5 --' FAKE
elseif not xr_wounded.is_heavy_wounded_by_id(self.target_obj:id()) then
self.target_fire_pt.y = self.target_fire_pt.y + 1.2 --' FAKE
else
self.target_fire_pt.y = self.target_fire_pt.y + 0.10 --' FAKE
end
else
self.target_fire_pt.y = self.target_fire_pt.y + 1.0 --' FAKE
end
self:rot_to_firepoint(self.target_fire_pt)
if self.mgun:CanHit() then
if self.state_shooting == state_none and self.st.auto_fire == true then
--'printf("car <fire>: shooting enemy (first).")
self.state_shooting = state_shooting_on
self:set_shooting(self.state_shooting)
end
else
if self.state_shooting ~= state_none then
--'printf("car <fire>: targeting enemy (first).")
self.state_shooting = state_none
self:set_shooting(self.state_shooting)
end
--'printf("car <fire>: targeting enemy.")
end
else
self.state_shooting = state_none
self:set_shooting(self.state_shooting)
end
else
if self.state_shooting ~= state_none or not can_rotate or self.state_delaying then
--' printf("car <fire>: enemy isn't visible (first).%s %s %s", tostring(self.object:direction().x), tostring(self.object:direction().y), tostring(self.object:direction().z))
self.state_shooting = state_none
self:set_shooting(self.state_shooting)
self:rot_to_firedir(self.start_look_pos)
end
--' printf("car <fire>: enemy isn't visible.")
if self.fire_track_target then
self.target_fire_pt = self.target_obj:position()
self.target_fire_pt.y = self.target_fire_pt.y + 1.0 -- FAKE
self:rot_to_firepoint(self.target_fire_pt)
--' printf("car <fire>: target tracking.")
end
end
end
end
return false
end
function action_mgun:destroy_car()
printf("car <destroy>: START ===============================")
self.state_cannon = state_none
self.state_firetarget = state_none
self.state_shooting = state_none
self.mgun:Action(CCar.eWpnAutoFire, 0)
self:set_shooting(self.state_shooting)
xr_logic.mob_release(self.object)
if self.st.on_death_info ~= nil then
db.actor:give_info_portion(self.st.on_death_info)
printf("car <destroy>: on_death_info [%s]", self.st.on_death_info)
end
self.destroyed = true
printf("car <destroy>: END =================================")
end
function angle_xz(npc , target_pos, start_direction)
local dir1 = start_direction
dir1.y = 0
local dir2 = vector():set(target_pos.x, target_pos.y, target_pos.z)
dir2 = dir2:sub(npc:position())
dir2.y = 0
return yaw(dir1, dir2)
end
--' ******************************************************************************************************************
--' * bind *
--' ******************************************************************************************************************
function add_to_binder(npc, ini, scheme, section, storage)
-- printf("DEBUG: add_to_binder: scheme='%s', section='%s'", scheme, section)
local new_action = action_mgun(npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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_fire = utils.cfg_get_string(ini, section, "path_fire", npc, false, gulag_name, nil)
st.auto_fire = utils.cfg_get_bool(ini, section, "auto_fire", npc, false, false) --' Ñòðåëÿòü èëè íåò.
st.fire_time = utils.cfg_get_number(ini, section, "fire_time", npc, false, def_min_fire_time) --' Âðåìÿ ñòðåëüáû
st.fire_rep = utils.cfg_get_number(ini, section, "fire_repeat", npc, false, def_fire_rep) --' Âðåìÿ çàäåðæêè
st.fire_range = utils.cfg_get_number(ini, section, "fire_range", npc, false, def_fire_range) --' Ðàññòîÿíèå ïðè êîòîðîé ñòðåëÿåì
st.fire_target = utils.cfg_get_string(ini, section, "target", npc, false, gulag_name, "points") --' Öåëü: actor|story_ids|points
st.fire_track_target= utils.cfg_get_bool(ini, section, "track_target", npc, false, false) --' Ïðåñëåäîâàòü öåëü.
st.fire_angle = utils.cfg_get_number(ini, section, "fire_angle", npc, false, def_fire_angle) --' Óãîë îáçîðà
st.shoot_only_on_visible = utils.cfg_get_bool(ini, section, "shoot_only_on_visible", npc, false, true)
st.on_target_vis = xr_logic.cfg_get_string_and_condlist(ini, section, "on_target_vis", npc) --' Óñëîâèå ïåðåõîäà
st.on_target_nvis = xr_logic.cfg_get_string_and_condlist(ini, section, "on_target_nvis", npc) --' Óñëîâèå ïåðåõîäà
end

View file

@ -0,0 +1,62 @@
----------------------------------------------------------------------------------------------------
-- Physics hit checker
----------------------------------------------------------------------------------------------------
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
----------------------------------------------------------------------------------------------------
class "ph_on_hit"
function ph_on_hit:__init(obj, storage)
self.object = obj
self.st = storage
end
function ph_on_hit:reset_scheme()
end
function ph_on_hit:update(delta)
end
function ph_on_hit:hit_callback(obj, amount, local_direction, who, bone_index)
local who_name
if who then
who_name = who:name()
else
who_name = "nil"
end
printf("_bp: ph_on_hit:hit_callback: obj='%s', amount=%d, who='%s', bone='%s'", obj:name(), amount, who_name, tostring(bone_index))
if db.storage[self.object:id()].active_scheme then
if xr_logic.try_switch_to_another_section(obj, self.st, db.actor) then
return
end
end
end
function ph_on_hit:deactivate()
printf("PH_ON_HIT: deactivate")
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
-- printf("DEBUG PH_ON_HIT: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local action = ph_on_hit(npc, storage)
storage.action = action
end
function set_scheme(npc, ini, scheme, section, gulag_name)
-- printf("DEBUG PH_ON_HIT: set_scheme: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
print_table(st.logic)
xr_logic.subscribe_action_for_events(npc, st, st.action)
end
function disable_scheme(npc, scheme)
-- printf("DEBUG PH_ON_HIT: disable_scheme: npc:name()='%s', scheme='%s'", npc:name(), scheme)
local st = db.storage[npc:id()][scheme]
if st then
xr_logic.unsubscribe_action_from_events(npc, st, st.action)
end
end

View file

@ -0,0 +1,81 @@
----------------------------------------------------------------------------------------------------
-- Oscillate object
----------------------------------------------------------------------------------------------------
-- Èñõîäíûé ñêðèïò: Tunduk Vladimir (Sidorovich)
-- Èäåÿ ñëåäóþùàÿ. Ìû ïðèêëàäûâàåì ê îáúåêòó ëèíåéíî íàðàñòàþùóþ ñèëó â òå÷åíèè îïðåäåëåííîãî âðåìåíè
-- Ïî èñòå÷åíèè âðåìåíè, ìû ïåðåäåðãèâàåì íàïðàâëåíèå ñèëû (íà ïðîòèâîïîëîæíîå èëè åùå êàê) è ñíîâà
-- ïðèêëàäûâàåì ê îáúåêòó (íå çàáûâàåì î ëèíåéíîì íàðàñòàíèè).
----------------------------------------------------------------------------------------------------
class "action_oscillator"
---------------------------------------------------------------------------------------------------------------------
function action_oscillator:__init (obj, storage)
self.object = obj
self.st = storage
self.time = 0
self.coefficient = 0
self.dir = vector ():set (math.random (), 0, math.random ()):normalize ()
self.joint = nil
self.pause = false
end
---------------------------------------------------------------------------------------------------------------------
function action_oscillator:reset_scheme ()
self.time = device():time_global()
self.dir = vector ():set (math.random (), 0, math.random ()):normalize ()
self.coefficient = self.st.force / self.st.period
self.joint = self.object:get_physics_shell ():get_joint_by_bone_name (self.st.joint)
self.time = time_global ()
self.pause = false
end
---------------------------------------------------------------------------------------------------------------------
function action_oscillator:update (delta)
-- ïîëó÷èì ãëîáàëüíîå âðåìÿ
local c_time = time_global ()
if self.pause == true then
if c_time - self.time < self.st.period * 0.5 then
return
end
self.time = c_time
self.pause = false
end
-- ïðîâåðèì íà íåîáõîäèìîñòü èçìåíåíèÿ íàïðàâëåíèÿ
if c_time - self.time >= self.st.period then
self.dir.x = -self.dir.x
self.dir.z = -self.dir.z
self.dir = vector_rotate_y (vector ():set (-self.dir.x, 0, -self.dir.z), self.st.angle)
self.time = c_time
self.pause = true
return
end
-- ðàññ÷èòàåì ñèëó
local force = (c_time - self.time) * self.coefficient
self.object:set_const_force (self.dir, force, 2)
end
---------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
printf ("DEBUG: add_to_binder: scheme='%s', section='%s'", scheme, section)
local new_action = action_oscillator (npc, storage)
xr_logic.subscribe_action_for_events (npc, storage, new_action)
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.joint = utils.cfg_get_string (ini, section, "joint", npc, true, gulag_name)
if st.joint == nil then
abort ("Invalid joint definition for object %s", npc:name ())
end
st.period = utils.cfg_get_number (ini, section, "period", npc, true, 0)
st.force = utils.cfg_get_number (ini, section, "force", npc, true, 0)
if st.period == nil or st.force == nil then
abort ("[ph_oscillate] Error : Force or period not defined")
end
st.angle = utils.cfg_get_number (ini, section, "correct_angle", npc, false, 0)
if st.angle == nil then
st.angle = 0
end
end
---------------------------------------------------------------------------------------------------------------------

View file

@ -0,0 +1,136 @@
class "snd_source"
function snd_source:__init (obj, storage)
self.object = obj
self.st = storage
self.destructed = false
end
function snd_source:reset_scheme(loading)
self.last_update = 0
self.st.signals = {}
self.played_sound = nil
self.first_sound = true
self.st.pause_time = 0
self.st.sound_set = true
if loading == false then
self.destructed = false
else
self.destructed = xr_logic.pstor_retrieve (self.object, "destr")
end
end
function snd_source:save ()
xr_logic.pstor_store (self.object, "destr", self.destructed)
end
function snd_source:hit_callback(obj, amount, local_direction, who, bone_index)
if self.st.no_hit == true then return end
printf ("SOUND SOURCE HAVE A HIT")
local who_name
if who then
who_name = who:name()
else
who_name = "nil"
end
printf("_bp: snd_source:hit_callback obj='%s', amount=%d, who='%s'", obj:name(), amount, who_name)
if self.played_sound ~= nil then
self.played_sound:stop ()
self.played_sound = nil
end
self.destructed = true
end
function snd_source:update(delta)
if self.destructed == true then return end
if xr_logic.try_switch_to_another_section (self.object, self.st, db.actor) then
return
end
if self.st.pause_time - device ():time_global () > 0 then
return
end
self.st.pause_time = 0
if self.st.sound_set == true then
self.st.sound_set = false
if self.st.random then
self.played_sound = xr_sound.get_sound_object(self.st.theme, "random")
elseif self.st.looped then
self.played_sound = xr_sound.get_sound_object(self.st.theme, "looped")
else
self.played_sound = xr_sound.get_sound_object(self.st.theme, "seq")
end
if self.played_sound ~= nil then
self.played_sound:play_at_pos (self.object, self.object:position ())
else
self.st.signals["theme_end"] = true
end
self.first_sound = false
end
if self.last_update == 0 then
self.last_update = device ():time_global ()
else
if device ():time_global () - self.last_update > 50 then
self.last_update = 0
else
return
end
end
if self.played_sound ~= nil then
if self.played_sound:playing () == false then
if self.first_sound == false then
self.st.signals["sound_end"] = true
end
self.st.sound_set = true
if self.st.pause_min ~= 0 or self.st.pause_max ~= 0 then
local time = math.random (self.st.pause_min, self.st.pause_max)
self.st.pause_time = device ():time_global () + time
end
self.first_sound = false
else
self.played_sound:set_position (self.object:position ())
end
end
end
function snd_source:deactivate ()
if self.played_sound ~= nil then
self.played_sound:stop ()
self.played_sound = nil
end
end
function add_to_binder (npc, ini, scheme, section, storage)
local new_action = snd_source (npc, storage)
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events(npc, storage, new_action)
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.theme = utils.cfg_get_string(ini, section, "snd", npc, false, "")
st.looped = utils.cfg_get_bool (ini, section, "looped", npc, false, false)
st.random = utils.cfg_get_bool (ini, section, "random", npc, false, true)
st.pause_min = utils.cfg_get_number (ini, section, "min_idle", npc, false, 0)
st.pause_max = utils.cfg_get_number (ini, section, "max_idle", npc, false, 0)
st.no_hit = utils.cfg_get_bool (ini, section, "no_hit", npc, false, true)
if st.pause_max < st.pause_min then
abort ("PH_SOUND - invalid time range !!!")
end
end

View file

@ -0,0 +1,33 @@
class "PhantomManager"
function PhantomManager:__init()
self.phantom_count = 0;
end
g_PhantomManager = PhantomManager();
function PhantomManager:add_phantom ()
self.phantom_count = self.phantom_count + 1;
end
function PhantomManager:remove_phantom ()
self.phantom_count = self.phantom_count - 1;
end
function PhantomManager:spawn_phantom (pos)
level.spawn_phantom (pos);
end
class "Phantom" (object_binder)
function Phantom:__init(obj) super(obj)
g_PhantomManager:add_phantom();
end
function Phantom:net_destroy()
g_PhantomManager:remove_phantom();
end
function bind(obj)
obj:bind_object (Phantom(obj))
end
function spawn_phantom (pos)
g_PhantomManager:spawn_phantom(pos);
end
function phantom_count ()
return g_PhantomManager.phantom_count;
end

View file

@ -0,0 +1,153 @@
class "evaluator_combat_enemy" (property_evaluator)
function evaluator_combat_enemy:__init(storage, name) super(nil, name)
self.st = storage
--' Òàéìåð îæèäàíèÿ âûõîäà èç áîÿ
self.st.timer = time_global()
end
function evaluator_combat_enemy:evaluate()
local best_enemy = self.object:best_enemy()
if best_enemy ~= nil and not xr_combat_ignore.is_enemy(self.object, best_enemy, db.storage[self.object:id()].combat_ignore, true) then
return false
end
if best_enemy ~= nil and self.st.timer ~= nil then
self.st.last_best_enemy_id = best_enemy:id()
self.st.last_best_enemy_name = best_enemy:name()
self.st.timer = nil
return true
end
if best_enemy == nil and self.st.timer == nil then
--printf("object name is [%s]", self.object:name())
local overrides = db.storage[self.object:id()].overrides
local min = (overrides and overrides.min_post_combat_time*1000) or 10000
local max = (overrides and overrides.max_post_combat_time*1000) or 15000
if self.st.last_best_enemy_id == db.actor:id() then
self.st.timer = time_global()
else
self.st.timer = time_global() + math.random(min, max)
end
end
if self.st.timer == nil then
return best_enemy ~= nil
end
if time_global() < self.st.timer then
return true
end
if self.st.animation == nil then
return false
end
self.st.animation:set_state(nil)
return self.st.animation.states.anim_marker ~= nil
end
----------------------------------------------------------------------------------------------------------------------
class "action_post_combat_wait" (action_base)
function action_post_combat_wait:__init(npc, storage, action_name) super(nil, action_name)
self.st = storage
end
function action_post_combat_wait:initialize()
action_base.initialize(self)
-- state_mgr.set_state(self.object, "hide")
self.object:set_item(object.idle, self.object:best_weapon())
self.object:set_mental_state(anim.danger)
self.object:set_body_state(move.crouch)
self.object:set_movement_type(move.stand)
self.object:set_sight(look.danger, nil, 0)
self.anim_st = { animstate = { states = {anim_marker = nil } } }
self.st.animation = state_mgr_animation.animation(self.object, self.anim_st, "state_mgr_animation_list")
self.anim_started = false
end
function action_post_combat_wait:execute()
action_base.execute(self)
if not self.object:in_smart_cover() then
if self.anim_started == false and
not weapon_locked(self.object)
then
self.anim_started = true
self.st.animation:set_state("hide")
self.st.animation:set_control()
end
end
xr_sound.set_sound_play(self.object:id(), "post_combat_wait")
end
function action_post_combat_wait:finalize()
xr_sound.set_sound_play(self.object:id(), "post_combat_relax")
if self.anim_started == true then
self.st.animation:set_state(nil, true)
end
self.st.animation = nil
action_base.finalize(self)
end
function weapon_locked(npc)
local weapon_strapped = npc:weapon_strapped()
local weapon_unstrapped = npc:weapon_unstrapped()
--log(string.format("%s [%s] [%s]", self.object:name(), tostring(weapon_strapped), tostring(weapon_unstrapped)))
if not (weapon_unstrapped or weapon_strapped) then
return true
end
local bestweapon = npc:best_weapon()
if bestweapon == nil then
return false
end
if npc:active_item() == nil then
return false
end
local weapon_going_to_be_strapped = npc:is_weapon_going_to_be_strapped(bestweapon)
if weapon_going_to_be_strapped and not weapon_strapped then
return true
end
if not weapon_going_to_be_strapped and not weapon_unstrapped then
return true
end
return false
end
function add_post_combat_idle(npc)
local manager = npc:motivation_action_manager()
local combat_action = manager:action(stalker_ids.action_combat_planner)
--combat_action:show("")
local combat_action_planner = cast_planner(combat_action)
db.storage[npc:id()].post_combat_wait = {}
local storage = db.storage[npc:id()].post_combat_wait
manager:remove_evaluator(stalker_ids.property_enemy)
manager:add_evaluator(stalker_ids.property_enemy, evaluator_combat_enemy(storage, "evaluator_combat_enemy"))
combat_action_planner:remove_evaluator(stalker_ids.property_enemy)
combat_action_planner:add_evaluator(stalker_ids.property_enemy, evaluator_combat_enemy(storage, "evaluator_combat_enemy"))
combat_action_planner:remove_action(stalker_ids.action_post_combat_wait)
local new_action = this.action_post_combat_wait(npc, storage, "action_post_combat_wait")
new_action:add_precondition(world_property(stalker_ids.property_enemy, true))
new_action:add_precondition(world_property(stalker_ids.property_pure_enemy, false))
new_action:add_precondition(world_property(stalker_ids.property_critically_wounded, false))
new_action:add_precondition(world_property(stalker_ids.property_danger_grenade, false))
new_action:add_effect(world_property(stalker_ids.property_enemy, false))
combat_action_planner:add_action(stalker_ids.action_post_combat_wait, new_action)
end

View file

@ -0,0 +1,218 @@
local function printf (fmt,...)
log (string.format(fmt,...))
end
local Counters = {}
local Names = {}
local timer = profile_timer()
local old_hook_func, old_hook_mask, old_hook_count
local started = false
local function getname (func)
local n = Names[func]
local loc = string.format("[%s]:%s", n.short_src, n.linedefined)
if "" ~= n.namewhat then
return (string.format("%s (%s)", loc, n.name))
else
return (string.format("%s", loc))
end
end
local function hook (context,line_number)
-- if nil ~= old_hook_func then
-- if old_hook_func ~= hook then
-- old_hook_func (context,line_number)
-- end
-- end
assert ("line" ~= context)
local f = debug.getinfo(2, "f").func
local caller = debug.getinfo(3, "f")
local g = nil
if caller ~= nil then
g = caller.func;
end
--[[
local f_name = nil
local g_name = nil
local old_g = Names[g]
if (Names[f] == nil) then
Names[f] = debug.getinfo(2,"Sn")
f_name = getname(f)
Names[f] = nil
else
f_name = getname(f)
end
if (g == nil) then
g_name = ""
else
if (Names[g] == nil) then
Names[g] = debug.getinfo(3,"Sn")
g_name = "from [" .. getname(g) .. "]"
Names[g] = nil
else
g_name = "from [" .. getname(g) .. "]"
end
end
printf ("%6s : [%s]%s",context,f_name,g_name)
]]
if ("return" == context) then
local object = Counters[f]
if (object ~= nil) then
object.timer:stop ()
object.child_timer:stop ()
if (g ~= nil) then
local object = Counters[g]
if (object ~= nil) then
object.timer:start ()
end
end
end
return
end
if ("tail return" == context) then
if (g ~= nil) then
local object = Counters[g]
if (object ~= nil) then
object.timer:start ()
end
end
return
end
assert ("call" == context)
if g ~= nil then
local object = Counters[g]
if (object ~= nil) then
object.timer:stop ()
end
end
if (Counters[f] == nil) then
Counters[f] = {count=1,timer=profile_timer(),child_timer=profile_timer()}
local object = Counters[f]
object.child_timer:start ()
object.timer:start ()
Names[f] = debug.getinfo(2,"Sn")
else
local object = Counters[f]
object.count = object.count + 1
object.child_timer:start ()
object.timer:start ()
end
end
function setup_hook (do_not_print_message)
if started == true then
return
end
timer:start ()
old_hook_func,
old_hook_mask,
old_hook_count = debug.gethook();
debug.sethook ()
debug.sethook (hook, "cr")
started = true
if (do_not_print_message ~= true) then
printf ("profiler is activated")
end
end
function clear_hook ()
if started == false then
printf ("profiler hook wasn't setup!")
return;
end
-- debug.sethook (old_hook_func,old_hook_mask,old_hook_count)
debug.sethook ()
timer:stop ()
started = false
end
function stats ()
if started == false then
printf ("profiler hook wasn't setup!")
return
end
clear_hook ()
printf ("profiler statistics")
local sort_stats = {}
for func, count in pairs(Counters) do
local n = getname(func)
if (nil == sort_stats[n]) then
sort_stats[n] = count
else
sort_stats[n].count = sort_stats[n].count + count.count
sort_stats[n].timer = sort_stats[n].timer + count.timer
sort_stats[n].child_timer = sort_stats[n].child_timer + count.child_timer
end
end
local script = profile_timer()
local count = 0
local out_stats = {}
for i,j in pairs(sort_stats) do
local k = i
if k == "[[C]]:-1" then
k = "#uncrecognized C/C++ stuff"
end
table.insert (out_stats,{name=k,count=j})
script = script + j.timer
count = count + j.count
end
table.sort (
out_stats,
function (a,b)
return (a.count.timer < b.count.timer)
end
)
printf ("total_time (pecent) child_time [total_call_count][average_call_time]")
for n,c in pairs(out_stats) do
printf ("%9.2fms (%5.2f%%) %9.2fms [%8d][%9.2fmks] : %s",c.count.timer:time()/1000,c.count.timer:time()*100/script:time(),c.count.child_timer:time()/1000,c.count.count, c.count.timer:time()/(c.count.count),c.name)
end
printf ("")
printf (" pure time : %%%% : children : count : function name")
printf ("")
printf ("profile time : %8.2fms",timer:time()/1000)
printf ("script time : %8.2fms (%5.2f%%)",script:time()/1000,script:time()*100/timer:time())
printf ("call count : %8d",count)
setup_hook (true)
end
function clear ()
if started == true then
clear_hook ()
end
Counters = {}
Names = {}
timer = profile_timer()
setup_hook (true)
end

View file

@ -0,0 +1,87 @@
--[[----------------------------------------------------------------------------
Õðàíèëèùå òåêñòîâûõ èíòåðïðåòàöèé ðàíãîâ è ôóíêöèè äëÿ ðàáîòû ñ íèì.
×óãàé Àëåêñàíäð
------------------------------------------------------------------------------]]
-- ðàíãè. ôîðìàò: {novice={0,30}, experienced={30,60}, ...}
local stalker_rank_intervals
local monster_rank_intervals
local stalker_max_rank_name
local monster_max_rank_name
local ranks_loaded = false
-- ïàðñèò çàäàííóþ ñòðîêó ðàíãîâ â çàäàííóþ òàáëèöó.
-- âîçâðàùàåò íàçâàíèå ìàêñèìàëüíîãî ðàíãà
function parse_ranks( s, tbl )
s = "0," .. s .. ",10000"
local t = parse_names( s )
local i = 2
while i < #t do
tbl[t[i]] = { tonumber(t[i-1]), tonumber(t[i+1]) }
i = i + 2
end
return t[i-2]
end
-- âû÷èòûâàåò ñòàëêåðñêèå è ìîíñòðÿ÷èå ðàíãè èç game_relations.ltx
function read_all_ranks()
stalker_rank_intervals = {}
monster_rank_intervals = {}
local ltx = system_ini()
stalker_max_rank_name = parse_ranks( ltx:r_string( "game_relations", "rating" ), stalker_rank_intervals )
monster_max_rank_name = parse_ranks( ltx:r_string( "game_relations", "monster_rating" ), monster_rank_intervals )
ranks_loaded = true
-- print_table( stalker_rank_intervals )
end
--
function get_rank_name( rank, tbl )
for name, interval in pairs( tbl ) do
if rank >= interval[1] and rank < interval[2] then
return name
end
end
return nil
end
-- âîçâðàùàåò íàçâàíèå ðàíãà çàäàííîãî game_object (ïåðñîíàæà)
function get_obj_rank_name( obj )
if not ranks_loaded then
read_all_ranks()
end
local obj_rank
-- HACK
if obj.m_story_id ~= nil then
obj_rank = obj:rank()
else
obj_rank = obj:character_rank()
end
if IsStalker(obj) then
return get_rank_name( obj_rank, stalker_rank_intervals ) or stalker_max_rank_name
else
return get_rank_name( obj_rank, monster_rank_intervals ) or monster_max_rank_name
end
end
-- âîçâðàùàåò òàáëè÷êó ñ èíòåðâàëîì ðàíãîâ äëÿ çàäàííîãî íàçâàíèÿ èíòåðâàëà
function get_rank_interval( name )
if not ranks_loaded then
read_all_ranks()
end
return stalker_rank_intervals[name] or monster_rank_intervals[name]
end

View file

@ -0,0 +1,180 @@
---------------------------------------------------------------------------------------------
--' Äëÿ òîãî, ÷òî áû ìèð íå áûë çàãðóæåí êó÷åé òðóïîâ,
--' áóäåì èõ ïîòèõîíüêó óäàëÿòü.
--' Made by Distemper ----------------------------------------------------------------
--' 11.02.08 ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
local IDLE_AFTER_DEATH = 40000
local function add_to_release_table(release_tbl, object_id)
printf("add to release_objects_table ["..object_id.."]")
local obj_params = {}
obj_params.id = object_id
obj_params.death_time = time_global()
table.insert(release_tbl, obj_params)
end
local function find_nearest_obj_to_release(release_tbl)
local max_distanse = 4900
local pos_in_table = nil
local actor = db.actor
local actor_pos = actor:position()
for k,v in pairs(release_tbl) do
printf("release_objects_table["..k.."] = "..v.id)
local object = alife():object(v.id)
if object then
printf("object_id = "..object.id)
printf("object_position x = "..vec_to_str(object.position))
local distance_to_body = actor_pos:distance_to_sqr(object.position)
printf("distanse = "..distance_to_body)
if distance_to_body > max_distanse and ((v.death_time == nil) or (time_global() > v.death_time + IDLE_AFTER_DEATH)) then
max_distanse = distance_to_body
pos_in_table = k
end
end
end
return pos_in_table
end
local RB_manager = nil
class "Crelease_body"
function Crelease_body:__init()
self.release_objects_table = {} -- òàáëèöà "ÑÒÅÊ" òðóïîâ
self.keep_items_table = {} -- òàáëèöà êâåñòîâûõ ïðåäìåòîâ
self.body_max_count = 15 -- êîëè÷åñòâî òåë êîòîðîå îäíîâðåìåííî ìîæåò íàõîäèòñÿ â èãðå
self.current_object_id = 0 -- id òîëüêî ÷òî óáèòîãî npc
--' Èòåðèðóåìñÿ ïî ñïèñêó êâåñòîâûõ èòåìîâ.
local snd_ini = ini_file("misc\\death_generic.ltx")
if not snd_ini:section_exist("keep_items") then
abort("There is no section [keep_items] in death_generic.ltx")
end
local n = snd_ini:line_count("keep_items")
local value = ""
for i = 0, n - 1 do
result, section, value = snd_ini:r_line("keep_items", i, "", "")
table.insert(self.keep_items_table, section)
end
end
function Crelease_body:moving_dead_body(obj)
printf("current body name ["..obj:name().."]")
printf("-------table-------")
print_table(self.release_objects_table)
printf("-----end table-----")
local object_id = obj:id()
if self:inspection_result(obj) then
printf("inspection_result return -> true")
if #self.release_objects_table <= self.body_max_count then
add_to_release_table(self.release_objects_table, object_id)
return
else
self:try_to_release()
end
add_to_release_table(self.release_objects_table, object_id)
end
end
function Crelease_body:try_to_release()
printf("dead body -> ["..self.body_max_count.."]")
local pos_in_table = nil
local overflow_count = #self.release_objects_table - self.body_max_count
for i = 1, overflow_count do
pos_in_table = find_nearest_obj_to_release(self.release_objects_table)
if pos_in_table == nil then
return
end
local release_object = alife():object(self.release_objects_table[pos_in_table].id)
if release_object then
printf("releasing object ["..release_object:name().."]")
if (IsStalker(release_object) or IsMonster(release_object)) and not release_object:alive() then
alife():release(release_object, true)
end
end
table.remove(self.release_objects_table, pos_in_table)
end
end
function Crelease_body:inspection_result(obj)
for k,v in pairs(self.keep_items_table) do
if obj:object(self.keep_items_table[k]) ~= nil then
printf("Object << "..obj:name().." >> presence_in_keep_items_table") -- â èíâåíòàðå åñòü êâåñòîâûé ïðåäìåò
return false
end
end
if get_object_story_id(obj:id()) ~= nil then
printf("Object << "..obj:name().." >> presence_in_story") -- ïîìå÷åí êàê ñþæåòíûé
return false
end
if self:check_for_known_info(obj) then
printf("Object << "..obj:name().." >> presence_in_known_info")
return false
end
return true
end
function Crelease_body:check_for_known_info(obj)
local char_ini = ""
local spawn_ini = obj:spawn_ini()
local filename = nil
if spawn_ini then
filename = utils.cfg_get_string(spawn_ini, "logic", "cfg", obj, false, "")
printf("filename is [%s]", tostring(filename))
end
if filename ~= nil then
if not getFS():exist("$game_config$", filename) then
abort("There is no configuration file [%s] in [%s]", filename, obj:name())
end
char_ini = ini_file(filename)
else
char_ini = obj:spawn_ini() or ini_file("scripts\\dummy.ltx")
end
local st = db.storage[obj:id()]
local known_info = utils.cfg_get_string(char_ini, st.section_logic, "known_info", obj, false, "", nil) or "known_info"
if char_ini:section_exist(known_info) then
return true
end
return false
end
function Crelease_body:save(packet)
set_save_marker(packet, "save", false, "Crelease_body")
local count = #self.release_objects_table
packet:w_u16(count)
for k,v in pairs(self.release_objects_table) do
packet:w_u16(v.id)
end
local level_id = game_graph():vertex(alife():actor().m_game_vertex_id):level_id()
packet:w_u16(level_id)
set_save_marker(packet, "save", true, "Crelease_body")
end
function Crelease_body:load(reader)
set_save_marker(reader, "load", false, "Crelease_body")
local count = reader:r_u16()
self.release_objects_table = {}
for i = 1, count do
local vid = reader:r_u16()
self.release_objects_table[i] = {}
self.release_objects_table[i].id = vid
end
local level_id = reader:r_u16()
if level_id ~= game_graph():vertex(alife():object(0).m_game_vertex_id):level_id() then
self.release_objects_table = {}
end
set_save_marker(reader, "load", true, "Crelease_body")
end
function get_release_body_manager()
if(RB_manager==nil) then
RB_manager = Crelease_body()
end
return RB_manager
end

View file

@ -0,0 +1,145 @@
class "Crestrictor_manager"
function Crestrictor_manager:__init(obj)
self.object = obj
self.base_out_restrictions = {}
self.base_in_restrictions = {}
self.out_restrictions = utils.parse_names(self.object:out_restrictions())
for k,v in pairs(self.out_restrictions) do
self.base_out_restrictions[v] = true
end
self.in_restrictions = utils.parse_names(self.object:in_restrictions())
for k,v in pairs(self.in_restrictions) do
self.base_in_restrictions[v] = true
end
end
----------------------------------------------------------------------------------------------------------------------
-- STALKER restrictions
----------------------------------------------------------------------------------------------------------------------
--' Äàííàÿ ôóíêöèÿ âû÷èòûâàåò èç ëîãèêè íàáîð ðåñòðèêòîðîâ, êîòîðûå íóæíî ïðîñòàâèòü ïåðñîíàæó.
function Crestrictor_manager:reset_restrictions(st, section)
--printf("reset restrictions obj=%s section=%s", self.object:name(), tostring(section))
local actual_ini = st.ini
local out_restr_string = get_param_string(utils.cfg_get_string(actual_ini, section, "out_restr", nil, false, "", ""), self.object)
--' Âû÷èòûâàåì íîâûå àóò ðåñòðèêòîðû
local new_out_restr = utils.parse_names(out_restr_string)
--' Óçíàåì ïðî ñóùåñòâóþùèå àóò ðåñòðèêòîðû
local old_out_restr = utils.parse_names(self.object:out_restrictions())
--[[
printf("old out_restrs table:")
print_table(old_out_restr)
printf("new out_restrs table:")
print_table(new_out_restr)
]]--
--' Ïðîâåðÿåì ïîÿâèëèñü ëè íîâûå ðåñòðèêòîðû.
local ins_restr = {} --' Òóò ïîìåñòèì ðåñòðèêòîðû, êîòîðûå íóæíî äîáàâèòü
local del_restr = {} --' Òóò ïîìåñòèì ðåñòðèêòîðû, êîòîðûå íóæíî óäàëèòü
for k,v in pairs(old_out_restr) do
local exist_rest = false
for kk,vv in pairs(new_out_restr) do
if v == vv then
exist_rest = true
break
end
end
if exist_rest == false and self.base_out_restrictions[v] ~= true then
table.insert(del_restr, v)
end
end
for k,v in pairs(new_out_restr) do
local exist_rest = false
for kk,vv in pairs(old_out_restr) do
if v == vv then
exist_rest = true
break
end
end
if exist_rest == false and v ~= "nil" then
table.insert(ins_restr, v)
end
end
--'Óäàëÿåì ñòàðûå àóò ðåñòðèêòîðû. àïïëàèì íîâûå.
for k,v in pairs(del_restr) do
--printf("old out_restr [%s] deleted", v)
self.object:remove_restrictions(v, "")
end
for k,v in pairs(ins_restr) do
--printf("new out_restr [%s] added", v)
self.object:add_restrictions(v, "")
end
--' Âû÷èòûâàåì íîâûå ÈÍ ðåñòðèêòîðû
local in_restr_string = get_param_string(utils.cfg_get_string(actual_ini, section, "in_restr", nil, false, "", ""), self.object)
--' Âû÷èòûâàåì íîâûå àóò ðåñòðèêòîðû
local new_in_restr = utils.parse_names(in_restr_string)
--' Óçíàåì ïðî ñóùåñòâóþùèå ÈÍ ðåñòðèêòîðû
local old_in_restr = utils.parse_names(self.object:in_restrictions())
--[[
printf("old in_restrs table:")
print_table(old_in_restr)
printf("new in_restrs table:")
print_table(new_in_restr)
]]--
--' Ïðîâåðÿåì ïîÿâèëèñü ëè íîâûå ðåñòðèêòîðû.
ins_restr = {} --' Òóò ïîìåñòèì ðåñòðèêòîðû, êîòîðûå íóæíî äîáàâèòü
del_restr = {} --' Òóò ïîìåñòèì ðåñòðèêòîðû, êîòîðûå íóæíî óäàëèòü
for k,v in pairs(old_in_restr) do
local exist_rest = false
for kk,vv in pairs(new_in_restr) do
if v == vv then
exist_rest = true
break
end
end
if exist_rest == false and self.base_in_restrictions[v] ~= true then
table.insert(del_restr, v)
end
end
for k,v in pairs(new_in_restr) do
local exist_rest = false
for kk,vv in pairs(old_in_restr) do
if v == vv then
exist_rest = true
break
end
end
if exist_rest == false and v ~= "nil" then
table.insert(ins_restr, v)
end
end
--'Óäàëÿåì ñòàðûå àóò ðåñòðèêòîðû. àïïëàèì íîâûå.
for k,v in pairs(del_restr) do
--printf("old in_restr [%s] deleted", v)
self.object:remove_restrictions("", v)
end
for k,v in pairs(ins_restr) do
--printf("new in_restr [%s] added", v)
self.object:add_restrictions("", v)
end
end
function get_restrictor_manager(npc)
if db.storage[npc:id()].restrictor_manager == nil then
db.storage[npc:id()].restrictor_manager = Crestrictor_manager(npc)
end
return db.storage[npc:id()].restrictor_manager
end

View file

@ -0,0 +1,162 @@
class "se_actor" (cse_alife_creature_actor)
--------------------
function se_actor:__init (section) super (section)
self.m_registred = false
self.start_position_filled = false
end
function se_actor:on_register()
cse_alife_creature_actor.on_register(self)
story_objects.get_story_objects_registry():register(self.id, "actor", true)
simulation_objects.get_sim_obj_registry():register(self)
self.m_registred = true
if not self.start_position_filled then
sim_board.get_sim_board():fill_start_position()
self.start_position_filled = true
end
end
function se_actor:on_unregister()
cse_alife_creature_actor.on_unregister(self)
unregister_story_object_by_id(self.id)
simulation_objects.get_sim_obj_registry():unregister(self)
end
--------------------
function se_actor:STATE_Write(packet)
cse_alife_creature_actor.STATE_Write(self, packet)
-- if self.m_registred ~= true then
-- return
-- end
set_save_marker(packet, "save", false, "se_actor")
packet:w_bool(self.start_position_filled)
-- story_objects.get_story_objects_registry():save(packet)
set_save_marker(packet, "save", true, "se_actor")
end
--------------------
function se_actor:STATE_Read(packet, size)
cse_alife_creature_actor.STATE_Read(self, packet, size)
-- ïîä LevelEditor íå ïûòàòüñÿ ÷èòàòü èç ïàêåòà íè÷åãî
if editor() then
return
end
-- if self.m_registred ~= true then
-- return
-- end
if db.actor == nil then
set_save_marker(packet, "load", false, "se_actor")
self.start_position_filled = packet:r_bool()
-- story_objects.get_story_objects_registry():load(packet)
set_save_marker(packet, "load", true, "se_actor")
end
end
--***********************************************************************************************
--* SIMULATION_TARGET_ACTOR *
--***********************************************************************************************
-- Ïîëó÷èòü ïîçèöèþ, ëåâåë âåðòåêñ, ãåéì âåðòåêñ îáüåêòà.
function se_actor:get_location()
return self.position, self.m_level_vertex_id, self.m_game_vertex_id
end
-- Äîñòèãíóò ëè ÿ îòðÿäîì âûáðàâøèì ìåíÿ êàê öåëü.
function se_actor:am_i_reached(squad)
return not level.object_by_id(self.id):alive()
end
-- Âûçûâàåòñÿ 1 ðàç ïîñëå äîñòèæåíèÿ ìåíÿ îòðÿäîì âûáðàâøèì ìåíÿ êàê öåëü.
function se_actor:on_after_reach(squad)
--squad.current_target_id = squad.smart_id
end
-- Âûçûâàåòñÿ 1 ðàç â ìîìåíò âûáîðà ìåíÿ êàê öåëè.
function se_actor:on_reach_target(squad)
squad:set_location_types()
for k in squad:squad_members() do
if db.offline_objects[k.id] ~= nil then
db.offline_objects[k.id] = {}
end
end
sim_board.get_sim_board():assign_squad_to_smart(squad, nil)
end
-- Âîçâðàùàåò CALifeSmartTerrainTask íà ìåíÿ, âûçûâàåòñÿ èç smart_terrain:task()
function se_actor:get_alife_task()
printf("Returning alife task for object [%s] game_vertex [%s] level_vertex [%s] position %s", self.id, self.m_game_vertex_id, self.m_level_vertex_id, vec_to_str(self.position))
return CALifeSmartTerrainTask(self.m_game_vertex_id, self.m_level_vertex_id)
end
local smarts_by_no_assault_zones = {
["zat_a2_sr_no_assault"] = "zat_stalker_base_smart",
["jup_a6_sr_no_assault"] = "jup_a6",
["jup_b41_sr_no_assault"] = "jup_b41"
}
function se_actor:sim_available()
-- Ïðîâåðèòü íå íàõîäèòñÿ ëè èãðîê áëèæå ÷åì 50 ìåòðîâ ê ñìàðòó çàêðûòîìó äëÿ ñèìóëÿöèè.
if smart_terrain.nearest_to_actor_smart.dist < 50
and simulation_objects.get_sim_obj_registry().objects[smart_terrain.nearest_to_actor_smart.id] == nil then
return false
end
for k,v in pairs (smarts_by_no_assault_zones) do
local zone = db.zone_by_name[k]
if zone and zone:inside(self.position) then
local smart = sim_board.get_sim_board():get_smart_by_name(v)
if smart and smart.base_on_actor_control ~= nil and smart.base_on_actor_control.status ~= smart_terrain_control.ALARM then
return false
end
end
end
-- Ïðîâåðèòü íå íàõîäèòñÿ ëè èãðîê â ñåéôðåñòðèêòîðå ñìàðòà âî âðåìÿ òðåâîãè.
if smart_terrain_control.current_smart_id == nil then
return true
end
local smart = alife():object(smart_terrain_control.current_smart_id)
if smart.base_on_actor_control ~= nil
and smart.base_on_actor_control.status == smart_terrain_control.NORMAL
and db.zone_by_name[smart.base_on_actor_control.noweap_zone]:inside(self.position) then
return false
end
return true
end
local is_squad_monster =
{
["monster_predatory_day"] = true,
["monster_predatory_night"] = true,
["monster_vegetarian"] = true,
["monster_zombied_day"] = true,
["monster_zombied_night"] = true,
["monster_special"] = true
}
-- Ìîé ïðåêîíäèøí.
function se_actor:target_precondition(squad)
local squad_params = sim_board.simulation_activities[squad.player_id]
if squad_params == nil or squad_params.actor == nil or squad_params.actor.prec(squad, self) == false then
return false
end
return true
--[[
if squad.player_id == "killer" then
return true
end
if is_squad_monster[squad.player_id] and in_time_interval(21, 8) and simulation_objects.sim_dist_to(squad, self) <= 900 then
return true
end
return false
]]
end
-- Ïîñ÷èòàòü ìîé ïðèîðèòåò äëÿ îòðÿäà.
function se_actor:evaluate_prior(squad)
return simulation_objects.evaluate_prior(self, squad)
end
--run_string xr_effects.teleport_squad(nil,nil,{"pri_a25_base_army_medic","pri_a16_pri_a25_medic_walk"})
--run_string give_info("pl")

View file

@ -0,0 +1,32 @@
class "se_artefact" (cse_alife_item_artefact)
function se_artefact:__init (section) super (section)
end
function se_artefact:on_register()
cse_alife_item_artefact.on_register(self)
-- Ïðîâåðÿåì êàñòîìäàòó îáüåêòà íà íàëè÷èå ñòîðè àéäè.
story_objects.check_spawn_ini_for_story_id(self)
end
function se_artefact:on_unregister()
unregister_story_object_by_id(self.id)
cse_alife_item_artefact.on_unregister(self)
end
--------------------
function se_artefact:can_switch_offline ()
-- printf("id [%s] can_switch_offline called, can it [%s]", tostring(self.id), tostring(cse_alife_item_artefact.can_switch_offline (self)))
if alife():actor() and (alife():actor().position:distance_to(self.position) <= 150) then
-- printf("af_id [%s] can not go offline, distance [%s]", tostring(self.id), tostring(db.actor:position():distance_to(self.position)))
return false
end
-- printf("af_id [%s] can go offline, distance [%s]", tostring(self.id), tostring(db.actor:position():distance_to(self.position)))
return cse_alife_item_artefact.can_switch_offline (self)
end
--------------------
function se_artefact:can_switch_online ()
-- printf("id [%s] can_switch_online called, can it [%s]", tostring(self.id), tostring(cse_alife_item_artefact.can_switch_online (self)))
return cse_alife_item_artefact.can_switch_online (self)
end
--------------------

Some files were not shown because too many files have changed in this diff Show more