add game&rawdata
This commit is contained in:
parent
0133cd976c
commit
49b34b5546
45731 changed files with 709831 additions and 0 deletions
22
gamedata/scripts/.vscode/launch.json
vendored
Normal file
22
gamedata/scripts/.vscode/launch.json
vendored
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
5
gamedata/scripts/.vscode/settings.json
vendored
Normal file
5
gamedata/scripts/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Lua.diagnostics.disable": [
|
||||
"undefined-global"
|
||||
]
|
||||
}
|
||||
869
gamedata/scripts/_g.script
Normal file
869
gamedata/scripts/_g.script
Normal 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
|
||||
94
gamedata/scripts/actor_menu.script
Normal file
94
gamedata/scripts/actor_menu.script
Normal 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
|
||||
|
||||
73
gamedata/scripts/actor_proxy.script
Normal file
73
gamedata/scripts/actor_proxy.script
Normal 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
|
||||
218
gamedata/scripts/alife_storage_manager.script
Normal file
218
gamedata/scripts/alife_storage_manager.script
Normal 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
|
||||
39
gamedata/scripts/benchmark.script
Normal file
39
gamedata/scripts/benchmark.script
Normal 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
|
||||
61
gamedata/scripts/bind_anomaly_field.script
Normal file
61
gamedata/scripts/bind_anomaly_field.script
Normal 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
|
||||
470
gamedata/scripts/bind_anomaly_zone.script
Normal file
470
gamedata/scripts/bind_anomaly_zone.script
Normal 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
|
||||
68
gamedata/scripts/bind_artefact.script
Normal file
68
gamedata/scripts/bind_artefact.script
Normal 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
|
||||
66
gamedata/scripts/bind_camp.script
Normal file
66
gamedata/scripts/bind_camp.script
Normal 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
|
||||
78
gamedata/scripts/bind_campfire.script
Normal file
78
gamedata/scripts/bind_campfire.script
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
96
gamedata/scripts/bind_crow.script
Normal file
96
gamedata/scripts/bind_crow.script
Normal 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
|
||||
217
gamedata/scripts/bind_door_labx8.script
Normal file
217
gamedata/scripts/bind_door_labx8.script
Normal 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
|
||||
24
gamedata/scripts/bind_faction.script
Normal file
24
gamedata/scripts/bind_faction.script
Normal 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
|
||||
223
gamedata/scripts/bind_heli.script
Normal file
223
gamedata/scripts/bind_heli.script
Normal 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
|
||||
72
gamedata/scripts/bind_level_changer.script
Normal file
72
gamedata/scripts/bind_level_changer.script
Normal 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
|
||||
321
gamedata/scripts/bind_monster.script
Normal file
321
gamedata/scripts/bind_monster.script
Normal 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
|
||||
175
gamedata/scripts/bind_physic_object.script
Normal file
175
gamedata/scripts/bind_physic_object.script
Normal 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
|
||||
121
gamedata/scripts/bind_restrictor.script
Normal file
121
gamedata/scripts/bind_restrictor.script
Normal 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
|
||||
154
gamedata/scripts/bind_signal_light.script
Normal file
154
gamedata/scripts/bind_signal_light.script
Normal 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
|
||||
30
gamedata/scripts/bind_smart_cover.script
Normal file
30
gamedata/scripts/bind_smart_cover.script
Normal 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
|
||||
|
||||
70
gamedata/scripts/bind_smart_terrain.script
Normal file
70
gamedata/scripts/bind_smart_terrain.script
Normal 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
|
||||
597
gamedata/scripts/bind_stalker.script
Normal file
597
gamedata/scripts/bind_stalker.script
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
108
gamedata/scripts/cam_effector_sets.script
Normal file
108
gamedata/scripts/cam_effector_sets.script
Normal 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 = {
|
||||
}
|
||||
}
|
||||
10
gamedata/scripts/ce_new_attachable_item.script
Normal file
10
gamedata/scripts/ce_new_attachable_item.script
Normal 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
|
||||
|
||||
20
gamedata/scripts/ce_new_game_dm.script
Normal file
20
gamedata/scripts/ce_new_game_dm.script
Normal 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
|
||||
99
gamedata/scripts/ce_switcher.script
Normal file
99
gamedata/scripts/ce_switcher.script
Normal 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
|
||||
145
gamedata/scripts/check_logic_path.script
Normal file
145
gamedata/scripts/check_logic_path.script
Normal 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
|
||||
137
gamedata/scripts/class_registrator.script
Normal file
137
gamedata/scripts/class_registrator.script
Normal 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
|
||||
77
gamedata/scripts/combat_restrictor.script
Normal file
77
gamedata/scripts/combat_restrictor.script
Normal 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
|
||||
196
gamedata/scripts/cover_manager.script
Normal file
196
gamedata/scripts/cover_manager.script
Normal 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
104
gamedata/scripts/db.script
Normal 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
|
||||
271
gamedata/scripts/death_manager.script
Normal file
271
gamedata/scripts/death_manager.script
Normal 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
|
||||
1003
gamedata/scripts/dialog_manager.script
Normal file
1003
gamedata/scripts/dialog_manager.script
Normal file
File diff suppressed because it is too large
Load diff
987
gamedata/scripts/dialogs.script
Normal file
987
gamedata/scripts/dialogs.script
Normal 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
|
||||
1365
gamedata/scripts/dialogs_jupiter.script
Normal file
1365
gamedata/scripts/dialogs_jupiter.script
Normal file
File diff suppressed because it is too large
Load diff
244
gamedata/scripts/dialogs_pripyat.script
Normal file
244
gamedata/scripts/dialogs_pripyat.script
Normal 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
|
||||
1655
gamedata/scripts/dialogs_zaton.script
Normal file
1655
gamedata/scripts/dialogs_zaton.script
Normal file
File diff suppressed because it is too large
Load diff
41
gamedata/scripts/game_registrator.script
Normal file
41
gamedata/scripts/game_registrator.script
Normal 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
|
||||
344
gamedata/scripts/game_relations.script
Normal file
344
gamedata/scripts/game_relations.script
Normal 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
|
||||
134
gamedata/scripts/game_stats.script
Normal file
134
gamedata/scripts/game_stats.script
Normal 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
|
||||
----------------------------------------------------------
|
||||
26
gamedata/scripts/game_types.script
Normal file
26
gamedata/scripts/game_types.script
Normal 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)
|
||||
}
|
||||
|
||||
1023
gamedata/scripts/gulag_general.script
Normal file
1023
gamedata/scripts/gulag_general.script
Normal file
File diff suppressed because it is too large
Load diff
775
gamedata/scripts/heli_combat.script
Normal file
775
gamedata/scripts/heli_combat.script
Normal 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
|
||||
199
gamedata/scripts/heli_fire.script
Normal file
199
gamedata/scripts/heli_fire.script
Normal 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
|
||||
180
gamedata/scripts/heli_fly.script
Normal file
180
gamedata/scripts/heli_fly.script
Normal 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
|
||||
53
gamedata/scripts/heli_look.script
Normal file
53
gamedata/scripts/heli_look.script
Normal 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
|
||||
294
gamedata/scripts/heli_move.script
Normal file
294
gamedata/scripts/heli_move.script
Normal 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
|
||||
63
gamedata/scripts/heli_snd.script
Normal file
63
gamedata/scripts/heli_snd.script
Normal 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
|
||||
244
gamedata/scripts/inventory_upgrades.script
Normal file
244
gamedata/scripts/inventory_upgrades.script
Normal 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
|
||||
49
gamedata/scripts/ixray_global.script
Normal file
49
gamedata/scripts/ixray_global.script
Normal 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
|
||||
47
gamedata/scripts/ixray_system/dynamic_callbacks.lua
Normal file
47
gamedata/scripts/ixray_system/dynamic_callbacks.lua
Normal 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
|
||||
34
gamedata/scripts/ixray_system/global.lua
Normal file
34
gamedata/scripts/ixray_system/global.lua
Normal 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
|
||||
3626
gamedata/scripts/ixray_system/luapanda.lua
Normal file
3626
gamedata/scripts/ixray_system/luapanda.lua
Normal file
File diff suppressed because it is too large
Load diff
149
gamedata/scripts/ixray_system/socket.lua
Normal file
149
gamedata/scripts/ixray_system/socket.lua
Normal 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
|
||||
35
gamedata/scripts/jump_level.script
Normal file
35
gamedata/scripts/jump_level.script
Normal 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
|
||||
4
gamedata/scripts/lain_test_bl.script
Normal file
4
gamedata/scripts/lain_test_bl.script
Normal 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
|
||||
180
gamedata/scripts/level_psy_antenna.script
Normal file
180
gamedata/scripts/level_psy_antenna.script
Normal 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
|
||||
240
gamedata/scripts/level_weathers.script
Normal file
240
gamedata/scripts/level_weathers.script
Normal 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
|
||||
196
gamedata/scripts/loadscreen.script
Normal file
196
gamedata/scripts/loadscreen.script
Normal 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
|
||||
12010
gamedata/scripts/lua_help.script
Normal file
12010
gamedata/scripts/lua_help.script
Normal file
File diff suppressed because it is too large
Load diff
117
gamedata/scripts/luaxml.script
Normal file
117
gamedata/scripts/luaxml.script
Normal 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
|
||||
9
gamedata/scripts/memusage.script
Normal file
9
gamedata/scripts/memusage.script
Normal 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
|
||||
344
gamedata/scripts/mob_camp.script
Normal file
344
gamedata/scripts/mob_camp.script
Normal 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
|
||||
|
||||
47
gamedata/scripts/mob_combat.script
Normal file
47
gamedata/scripts/mob_combat.script
Normal 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
|
||||
|
||||
44
gamedata/scripts/mob_death.script
Normal file
44
gamedata/scripts/mob_death.script
Normal 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
|
||||
130
gamedata/scripts/mob_home.script
Normal file
130
gamedata/scripts/mob_home.script
Normal 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
|
||||
|
||||
121
gamedata/scripts/mob_jump.script
Normal file
121
gamedata/scripts/mob_jump.script
Normal 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
|
||||
|
||||
176
gamedata/scripts/mob_remark.script
Normal file
176
gamedata/scripts/mob_remark.script
Normal 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
|
||||
35
gamedata/scripts/mob_state_mgr.script
Normal file
35
gamedata/scripts/mob_state_mgr.script
Normal 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
|
||||
|
||||
290
gamedata/scripts/mob_walker.script
Normal file
290
gamedata/scripts/mob_walker.script
Normal 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
|
||||
|
||||
85
gamedata/scripts/modules.script
Normal file
85
gamedata/scripts/modules.script
Normal 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)
|
||||
574
gamedata/scripts/move_mgr.script
Normal file
574
gamedata/scripts/move_mgr.script
Normal 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
|
||||
297
gamedata/scripts/news_manager.script
Normal file
297
gamedata/scripts/news_manager.script
Normal 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
|
||||
110
gamedata/scripts/object_collection.script
Normal file
110
gamedata/scripts/object_collection.script
Normal 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
|
||||
|
||||
10
gamedata/scripts/outro_bad.script
Normal file
10
gamedata/scripts/outro_bad.script
Normal 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
|
||||
18
gamedata/scripts/outro_balanced_good.script
Normal file
18
gamedata/scripts/outro_balanced_good.script
Normal 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
|
||||
222
gamedata/scripts/outro_cond.script
Normal file
222
gamedata/scripts/outro_cond.script
Normal 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
|
||||
21
gamedata/scripts/outro_good.script
Normal file
21
gamedata/scripts/outro_good.script
Normal 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
450
gamedata/scripts/pda.script
Normal 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
|
||||
-- //
|
||||
76
gamedata/scripts/ph_appforce.script
Normal file
76
gamedata/scripts/ph_appforce.script
Normal 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
|
||||
96
gamedata/scripts/ph_button.script
Normal file
96
gamedata/scripts/ph_button.script
Normal 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
|
||||
|
||||
86
gamedata/scripts/ph_code.script
Normal file
86
gamedata/scripts/ph_code.script
Normal 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
|
||||
46
gamedata/scripts/ph_death.script
Normal file
46
gamedata/scripts/ph_death.script
Normal 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
|
||||
|
||||
|
||||
383
gamedata/scripts/ph_door.script
Normal file
383
gamedata/scripts/ph_door.script
Normal 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
|
||||
93
gamedata/scripts/ph_hit.script
Normal file
93
gamedata/scripts/ph_hit.script
Normal 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
|
||||
77
gamedata/scripts/ph_idle.script
Normal file
77
gamedata/scripts/ph_idle.script
Normal 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
|
||||
435
gamedata/scripts/ph_minigun.script
Normal file
435
gamedata/scripts/ph_minigun.script
Normal 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
|
||||
62
gamedata/scripts/ph_on_hit.script
Normal file
62
gamedata/scripts/ph_on_hit.script
Normal 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
|
||||
81
gamedata/scripts/ph_oscillate.script
Normal file
81
gamedata/scripts/ph_oscillate.script
Normal 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
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
136
gamedata/scripts/ph_sound.script
Normal file
136
gamedata/scripts/ph_sound.script
Normal 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
|
||||
|
||||
33
gamedata/scripts/phantom_manager.script
Normal file
33
gamedata/scripts/phantom_manager.script
Normal 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
|
||||
153
gamedata/scripts/post_combat_idle.script
Normal file
153
gamedata/scripts/post_combat_idle.script
Normal 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
|
||||
218
gamedata/scripts/profiler.script
Normal file
218
gamedata/scripts/profiler.script
Normal 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
|
||||
87
gamedata/scripts/ranks.script
Normal file
87
gamedata/scripts/ranks.script
Normal 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
|
||||
|
||||
180
gamedata/scripts/release_body_manager.script
Normal file
180
gamedata/scripts/release_body_manager.script
Normal 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
|
||||
145
gamedata/scripts/restrictor_manager.script
Normal file
145
gamedata/scripts/restrictor_manager.script
Normal 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
|
||||
162
gamedata/scripts/se_actor.script
Normal file
162
gamedata/scripts/se_actor.script
Normal 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")
|
||||
32
gamedata/scripts/se_artefact.script
Normal file
32
gamedata/scripts/se_artefact.script
Normal 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
Loading…
Add table
Add a link
Reference in a new issue