640 lines
18 KiB
Plaintext
640 lines
18 KiB
Plaintext
|
|
||
|
--[[
|
||
|
|
||
|
Tronex
|
||
|
|
||
|
set enable_debug to true, for debugging and map markers
|
||
|
|
||
|
----------------------------------------------------------
|
||
|
|
||
|
- Dynamic Anomalies
|
||
|
2019/6/14
|
||
|
used ini:
|
||
|
plugins\dynamic_anomalies.ltx
|
||
|
|
||
|
1. Script will read the list of anomalies and their position/types from the config (you can recorded custom pos for your anomalies)
|
||
|
2. Then spawn all anomalies on new game, then disable a random number of them.
|
||
|
3. When an enmission happen, anomalies will shuffle between off/on state (the dynamic factor)
|
||
|
|
||
|
----------------------------------------------------------
|
||
|
|
||
|
- The Pulse
|
||
|
A concept of electro-psy anomaly that forms in the sky and discharge into the ground like a thunderbolt, killing any stalkers nearby
|
||
|
|
||
|
--]]
|
||
|
|
||
|
|
||
|
local enable_debug = false
|
||
|
function print_debug(...)
|
||
|
if enable_debug then
|
||
|
printf(...)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
-- Dynamic anomalies
|
||
|
-------------------------------
|
||
|
local ini_ano
|
||
|
local dyn_ano_init = false
|
||
|
local current_level
|
||
|
|
||
|
local dyn_ano_chance = 35 -- [0 - 100] chance of activating a dynamic anomaly
|
||
|
local dyn_ano_safe_dist = 15 -- [m] don't activate anomalies within the safe distance to player
|
||
|
local dyn_ano_type = {} -- [type] = {}
|
||
|
local dyn_ano_info = {} -- [level][name] = info
|
||
|
|
||
|
local dyn_anomalies_dbg = {} -- [id] = name
|
||
|
dyn_anomalies = {} -- [level][id] = name
|
||
|
|
||
|
-- ZCP
|
||
|
if smr_amain_mcm.get_config("smr_enabled") then
|
||
|
dyn_ano_chance = smr_anomalies_mcm.get_config("dyn_ano_chance")
|
||
|
end
|
||
|
-- ZCP END
|
||
|
|
||
|
-- Prepare
|
||
|
function ini_settings()
|
||
|
|
||
|
if (dyn_ano_init) then return end
|
||
|
dyn_ano_init = true
|
||
|
|
||
|
ini_ano = ini_file("plugins\\dynamic_anomalies.ltx")
|
||
|
|
||
|
local n,m = 0,0
|
||
|
local result, id, value = "","",""
|
||
|
local name, info = "","",""
|
||
|
|
||
|
-- Gather anomaly types
|
||
|
n = ini_ano:line_count("categories") or 0
|
||
|
for i=0,n-1 do
|
||
|
result, id, value = ini_ano:r_line_ex("categories",i,"","")
|
||
|
-- ZCP
|
||
|
if smr_amain_mcm.get_config("smr_enabled") and (smr_anomalies_mcm.get_config(id) == false) then
|
||
|
smr_debug.get_log().info("anomalies/types", "skipping disabled anomaly type %s", id)
|
||
|
goto continue
|
||
|
end
|
||
|
-- ZCP END
|
||
|
dyn_ano_type[id] = {}
|
||
|
|
||
|
m = ini_ano:line_count(id) or 0
|
||
|
for ii=0,m-1 do
|
||
|
result, name, info = ini_ano:r_line_ex(id,ii,"","")
|
||
|
if name and info then
|
||
|
for j=1,tonumber(info) do
|
||
|
local size = #dyn_ano_type[id] + 1
|
||
|
dyn_ano_type[id][size] = name
|
||
|
print_debug("- Dynamic Anomalies | dyn_ano_type[%s][%s] = %s", id, size, name)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
::continue::
|
||
|
end
|
||
|
|
||
|
-- Gather anomaly coordinates in all levels
|
||
|
n = ini_ano:line_count("levels") or 0
|
||
|
for i=0,n-1 do
|
||
|
result, id, value = ini_ano:r_line_ex("levels",i,"","")
|
||
|
m = ini_ano:line_count(id) or 0
|
||
|
|
||
|
dyn_ano_info[id] = {}
|
||
|
|
||
|
for ii=0,m-1 do
|
||
|
result, name, info = ini_ano:r_line_ex(id,ii,"","")
|
||
|
if name and info then
|
||
|
local t = str_explode(info,",")
|
||
|
if (#t == 6) and (t[1] ~= "NA") then
|
||
|
dyn_ano_info[id][name] = {
|
||
|
typ = t[1],
|
||
|
x = tonumber(t[2]),
|
||
|
y = tonumber(t[3]),
|
||
|
z = tonumber(t[4]),
|
||
|
lvl_id = tonumber(t[5]),
|
||
|
gm_id = tonumber(t[6]),
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local marker_by_type = {
|
||
|
["electric"] = "anomaly_electric",
|
||
|
["chemical"] = "anomaly_chemical",
|
||
|
["thermal"] = "anomaly_thermal",
|
||
|
["gravitational"] = "anomaly_gravitational",
|
||
|
["radioactive"] = "anomaly_radioactive",
|
||
|
["disabled"] = "anomaly_disabled",
|
||
|
}
|
||
|
function add_marker(lvl, section, id, state)
|
||
|
|
||
|
if enable_debug then
|
||
|
ini_settings()
|
||
|
|
||
|
if lvl and dyn_ano_info[lvl] then
|
||
|
local name = dyn_anomalies_dbg[id]
|
||
|
if name then
|
||
|
|
||
|
local info = dyn_ano_info[lvl][name]
|
||
|
if info then
|
||
|
for k,v in pairs(marker_by_type) do
|
||
|
if (level.map_has_object_spot(id, v) ~= 0) then
|
||
|
level.map_remove_object_spot(id, v)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local typ = info.typ
|
||
|
local spot = marker_by_type[typ] or marker_by_type["gravitational"]
|
||
|
if (state == false) then
|
||
|
spot = marker_by_type["disabled"]
|
||
|
end
|
||
|
level.map_add_object_spot_ser(id, spot, "Name: " .. name .. " \\nType: " .. typ .. " \\nSection: " .. section)
|
||
|
else
|
||
|
print_debug("! Dynamic Anomalies | Marker - no info is found for name {%s}", name)
|
||
|
end
|
||
|
else
|
||
|
print_debug("! Dynamic Anomalies | Marker - no name is found for id (%s)", id)
|
||
|
end
|
||
|
else
|
||
|
print_debug("! Dynamic Anomalies | Marker - level %s is not stored in dyn_ano_info table", lvl)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Operation
|
||
|
function dyn_anomalies_spawn()
|
||
|
|
||
|
-- Iterate through all anomalies info for all levels
|
||
|
|
||
|
for lvl,v in pairs(dyn_ano_info) do
|
||
|
dyn_anomalies[lvl] = {}
|
||
|
|
||
|
for name,info in pairs(v) do
|
||
|
|
||
|
-- Get random anomaly section
|
||
|
local anom_type = dyn_ano_type[info.typ]
|
||
|
local section = anom_type and anom_type[math.random(#anom_type)]
|
||
|
if (not section) then
|
||
|
print_debug("! Dynamic Anomalies | Anomaly section not found for type: %s", info.typ)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- Info check
|
||
|
if not (info.x and info.y and info.z and info.lvl_id and info.gm_id and true) then
|
||
|
print_debug("! Dynamic Anomalies | Anomaly {%s} has wrong or incomplete info", name)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- Spawn
|
||
|
local se_obj = alife_create( section, vector():set(info.x , info.y , info.z), info.lvl_id, info.gm_id )
|
||
|
if ( not se_obj ) then
|
||
|
print_debug("! Dynamic Anomalies | Unable to spawn dynamic anomaly")
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- Set anomaly properties:
|
||
|
local data = utils_stpk.get_anom_zone_data( se_obj )
|
||
|
if ( not data ) then
|
||
|
print_debug("! Dynamic Anomalies | Unable to set dynamic anomaly properties" )
|
||
|
return
|
||
|
end
|
||
|
data.shapes[1] = {}
|
||
|
data.shapes[1].shtype = 0
|
||
|
data.shapes[1].offset = vector():set( 0, 0, 0 ) -- Leave for compatibility with CoC 1.4.22, delete later
|
||
|
data.shapes[1].center = vector():set( 0, 0, 0 )
|
||
|
data.shapes[1].radius = 3
|
||
|
utils_stpk.set_anom_zone_data( data, se_obj )
|
||
|
|
||
|
-- Save data
|
||
|
dyn_anomalies[lvl][se_obj.id] = true
|
||
|
|
||
|
if enable_debug then
|
||
|
dyn_anomalies_dbg[se_obj.id] = name
|
||
|
end
|
||
|
|
||
|
print_debug("- Dynamic Anomalies | %s | Spawned anomaly [%s](%s){%s}", lvl, section, se_obj.id, name)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function dyn_anomalies_suffle()
|
||
|
for lvl,v in pairs(dyn_anomalies) do
|
||
|
for id, state in pairs(v) do
|
||
|
if (math.random(100) < dyn_ano_chance) then
|
||
|
dyn_anomalies[lvl][id] = true
|
||
|
print_debug("/ Dynamic Anomalies | Shuffle - dyn_anomalies[%s][%s] = %s", lvl, id, true)
|
||
|
else
|
||
|
dyn_anomalies[lvl][id] = false
|
||
|
print_debug("/ Dynamic Anomalies | Shuffle - dyn_anomalies[%s][%s] = %s", lvl, id, false)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function dyn_anomalies_update()
|
||
|
if (not dyn_anomalies[current_level]) then
|
||
|
print_debug("! Dynamic Anomalies | Can't update anomalies because current level (%s) has no anomalies recorded", current_level)
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local actor_pos = db.actor:position()
|
||
|
for id,state in pairs(dyn_anomalies[current_level]) do
|
||
|
local obj = level.object_by_id(id)
|
||
|
if obj then
|
||
|
if (actor_pos:distance_to(obj:position()) > dyn_ano_safe_dist) then
|
||
|
obj:enable_anomaly()
|
||
|
|
||
|
if (state == false) then
|
||
|
obj:disable_anomaly()
|
||
|
end
|
||
|
|
||
|
add_marker(current_level, obj:section(), id, state)
|
||
|
print_debug("- Dynamic Anomalies | %s | Anomaly (%s) is set to state: %s", current_level, id, state)
|
||
|
else
|
||
|
print_debug("! Dynamic Anomalies | %s | Anomaly (%s) is close to player, no process", current_level, id)
|
||
|
end
|
||
|
|
||
|
else
|
||
|
print_debug("! Dynamic Anomalies | %s | Couldn't get online object for id (%s)", current_level, id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
function dyn_anomalies_refresh(force)
|
||
|
|
||
|
-- Prepare anomalies for the first time
|
||
|
if (not has_alife_info("dynamic_anomalies_spawned")) and is_empty(dyn_anomalies) then
|
||
|
give_info("dynamic_anomalies_spawned")
|
||
|
|
||
|
ini_settings()
|
||
|
|
||
|
dyn_anomalies_spawn()
|
||
|
dyn_anomalies_suffle()
|
||
|
|
||
|
-- shuffle state of all anomalies after emission
|
||
|
elseif force then
|
||
|
dyn_anomalies_suffle()
|
||
|
end
|
||
|
|
||
|
-- enable/disable online anomalies
|
||
|
-- NOTE: it's important to use timer because online objects don't register instantly after creating the server objects, so we need to wait for a bit.
|
||
|
-- Guess there's a delay in engine to set things up completely
|
||
|
local n = has_alife_info("dynamic_anomalies_spawned") and 1 or 10
|
||
|
CreateTimeEvent(0, "update_dynamic_anomalies", n, dyn_anomalies_update)
|
||
|
end
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
-- Pulse anomalies
|
||
|
-------------------------------
|
||
|
local pAno_first = true
|
||
|
local pAno_tg = time_global()
|
||
|
local pAno_light = nil
|
||
|
local pAno_pfx = particles_object("generator\\generator_accum_thunderbolt")
|
||
|
local pAno_snd_close = sound_object("anomaly\\emi_blowout")
|
||
|
local pAno_snd_far = sound_object("anomaly\\emi_blowout_01")
|
||
|
local pAno_snd_distance = 150 -- [m] (max distance between player and anomaly where close sound effect can be heard)
|
||
|
local pAno_snd_delay = 5.5 -- [sec] (time delay between anomaly's spawn and sound effect)
|
||
|
local pAno_p_hit_distance = 10 -- [m] (max distance between player and anomaly to recieve psy damage)
|
||
|
local pAno_e_hit_distance = 20 -- [m] (max distance between player and anomaly to recieve shock damage)
|
||
|
local pAno_hit_delay = 11.5 -- [sec] (time delay between anomaly's spawn and player hit)
|
||
|
local pAno_article_distance = 50 -- [m] (max distance between player and anomaly to trigger related article )
|
||
|
local pAno_max_distance = 150 -- [m] (max distance between player and anomaly's spawn)
|
||
|
local pAno_delay = 2 * 60 * 1000 -- [millie sec] (smallest time delay between pulse anomalies to spawn)
|
||
|
local pAno_chance = {
|
||
|
["clear"] = 0,
|
||
|
["partly"] = 0,
|
||
|
["cloudy"] = 10,
|
||
|
["rain"] = 15,
|
||
|
["storm"] = 25,
|
||
|
["foggy"] = 0,
|
||
|
}
|
||
|
local pAno_maps = {
|
||
|
["k00_marsh"] = 0.5,
|
||
|
["k01_darkscape"] = 1,
|
||
|
["k02_trucks_cemetery"] = 1,
|
||
|
["l01_escape"] = 0.2,
|
||
|
["l02_garbage"] = 0.7,
|
||
|
["l03_agroprom"] = 0.5,
|
||
|
["l04_darkvalley"] = 0.5,
|
||
|
["l06_rostok"] = 1,
|
||
|
["l07_military"] = 0.5,
|
||
|
["l08_yantar"] = 0.7,
|
||
|
["l09_deadcity"] = 0.5,
|
||
|
["l10_red_forest"] = 1,
|
||
|
["jupiter"] = 1,
|
||
|
["pripyat"] = 1,
|
||
|
["zaton"] = 1,
|
||
|
["l13_generators"] = 1.5,
|
||
|
["l12_stancia_2"] = 1.5,
|
||
|
["l12_stancia"] = 1.5,
|
||
|
["l11_pripyat"] = 0.2,
|
||
|
["l10_radar"] = 1,
|
||
|
["y04_pole"] = 0.7,
|
||
|
}
|
||
|
|
||
|
local function pulse_anomaly_sound(sound_pos)
|
||
|
local distance = distance_2d(db.actor:position(), sound_pos)
|
||
|
local pAno_snd = (distance > pAno_snd_distance) and pAno_snd_far or pAno_snd_close
|
||
|
|
||
|
if pAno_snd and pAno_snd:playing() then
|
||
|
pAno_snd:stop()
|
||
|
end
|
||
|
if pAno_snd ~= nil then
|
||
|
pAno_snd:play_at_pos(db.actor, sound_pos)
|
||
|
pAno_snd.volume = 1
|
||
|
end
|
||
|
|
||
|
pAno_light:set_position(sound_pos)
|
||
|
pAno_light.enabled = true
|
||
|
pAno_light:update()
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local function pulse_anomaly_hit(particle_pos)
|
||
|
pAno_light.lanim_brightness = 0.2
|
||
|
pAno_light.volumetric_distance = 1
|
||
|
pAno_light.volumetric_intensity = 0.1
|
||
|
|
||
|
if GetEvent("current_safe_cover") then
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local hit_power = 0
|
||
|
local distance = distance_2d(db.actor:position(), particle_pos)
|
||
|
|
||
|
-- Article
|
||
|
if distance < pAno_article_distance then
|
||
|
SendScriptCallback("actor_on_interaction", "anomalies", nil, "pulse")
|
||
|
end
|
||
|
|
||
|
-- Psi hit
|
||
|
if distance < pAno_p_hit_distance then
|
||
|
hit_power = math.cos(distance * math.pi / pAno_p_hit_distance) + 1
|
||
|
local h = hit()
|
||
|
h.type = hit.telepatic
|
||
|
if (level_environment.is_actor_immune() or dialogs_yantar.actor_has_psi_helmet()) then
|
||
|
h.power = 0
|
||
|
else
|
||
|
h.power = surge_manager.SurgeManager:hit_power(hit_power, h.type)
|
||
|
end
|
||
|
h.impulse = 0
|
||
|
h.direction = VEC_Z
|
||
|
h.draftsman = db.actor
|
||
|
|
||
|
db.actor:hit(h)
|
||
|
|
||
|
level.remove_pp_effector(666)
|
||
|
level.add_pp_effector("psi_fade.ppe", 666, false)
|
||
|
level.set_pp_effector_factor(666,h.power)
|
||
|
end
|
||
|
|
||
|
-- Electric hit
|
||
|
if distance < pAno_e_hit_distance then
|
||
|
hit_power = math.cos(distance * math.pi / pAno_e_hit_distance) + 1
|
||
|
local h = hit()
|
||
|
h.type = hit.shock
|
||
|
if (level_environment.is_actor_immune()) then
|
||
|
h.power = 0
|
||
|
else
|
||
|
h.power = surge_manager.SurgeManager:hit_power(hit_power, h.type)
|
||
|
end
|
||
|
h.impulse = 0
|
||
|
h.direction = VEC_Z
|
||
|
h.draftsman = db.actor
|
||
|
db.actor:hit(h)
|
||
|
level.remove_pp_effector(667)
|
||
|
level.add_pp_effector("electro_fade.ppe", 667, false)
|
||
|
level.set_pp_effector_factor(667,h.power)
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local function pulse_anomaly_light()
|
||
|
pAno_light.lanim_brightness = 0.025
|
||
|
pAno_light.volumetric_distance = 0.25
|
||
|
pAno_light.volumetric_intensity = 0.05
|
||
|
pAno_light.enabled = false
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
function pulse_anomaly_update()
|
||
|
local tg = time_global()
|
||
|
if pAno_first then
|
||
|
pAno_tg = tg + pAno_delay
|
||
|
pAno_first = false
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if (pAno_light and pAno_light.enabled) then
|
||
|
pAno_light:update()
|
||
|
end
|
||
|
|
||
|
if bLevelUnderground or (tg < pAno_tg) then
|
||
|
return
|
||
|
end
|
||
|
pAno_tg = tg + pAno_delay
|
||
|
|
||
|
local lvl_factor = pAno_maps[level.name()] or 0
|
||
|
local wthr = level_weathers.get_weather_manager():get_curr_weather()
|
||
|
local weather_chance = pAno_chance[wthr] or 1
|
||
|
if (math.random(100) > (weather_chance * lvl_factor)) then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local pos = db.actor:position()
|
||
|
local angle_dec = math.random(0,359)
|
||
|
local angle_rad = math.rad(angle_dec)
|
||
|
local ano_distance = math.random(0,pAno_max_distance)
|
||
|
local pos_x = math.cos(angle_rad)*ano_distance
|
||
|
local pos_z = math.sin(angle_rad)*ano_distance
|
||
|
local particle_pos = vector():set(pos.x+pos_x, pos.y+60, pos.z+pos_z)
|
||
|
|
||
|
pAno_pfx:play_at_pos(particle_pos)
|
||
|
|
||
|
if (not pAno_light) then
|
||
|
--local color = fcolor()
|
||
|
--color:set(0,0,100,50)
|
||
|
|
||
|
pAno_light = script_light()
|
||
|
pAno_light.range = 100
|
||
|
--pAno_light.type = 0 --light_type.Direct)
|
||
|
--pAno_light:set_direction(vector():set(0,-1.5,0))
|
||
|
--pAno_light.shadow = true
|
||
|
pAno_light.lanim = "koster_01_electra"
|
||
|
pAno_light.lanim_brightness = 0.025
|
||
|
pAno_light.volumetric = true
|
||
|
pAno_light.volumetric_quality = 1
|
||
|
pAno_light.volumetric_distance = 0.25
|
||
|
pAno_light.volumetric_intensity = 0.05
|
||
|
--pAno_light.color = color
|
||
|
end
|
||
|
|
||
|
CreateTimeEvent(0, "pulse_anomaly_sound", pAno_snd_delay, pulse_anomaly_sound, particle_pos)
|
||
|
|
||
|
CreateTimeEvent(0, "pulse_anomaly_hit", pAno_hit_delay, pulse_anomaly_hit, particle_pos)
|
||
|
|
||
|
CreateTimeEvent(0, "pulse_anomaly_light", pAno_hit_delay + 0.5, pulse_anomaly_light)
|
||
|
end
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
-- Callbacks
|
||
|
-------------------------------
|
||
|
local function actor_on_first_update()
|
||
|
current_level = level.name()
|
||
|
local enabled = ui_options.get("alife/general/dynamic_anomalies")
|
||
|
if enabled and (not IsTestMode()) then
|
||
|
dyn_anomalies_refresh()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function actor_on_update()
|
||
|
-- ZCP
|
||
|
if smr_anomalies_mcm.get_config("pulse") then
|
||
|
pulse_anomaly_update()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function actor_on_interaction(typ, obj, name)
|
||
|
if (typ == "anomalies") and (name == "emission_end") and ui_options.get("alife/general/dynamic_anomalies") then
|
||
|
dyn_anomalies_refresh(true)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function save_state(m_data)
|
||
|
m_data.dyn_anomalies = dyn_anomalies
|
||
|
if enable_debug then
|
||
|
m_data.dyn_anomalies_dbg = dyn_anomalies_dbg
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function load_state(m_data)
|
||
|
dyn_anomalies = m_data.dyn_anomalies or {}
|
||
|
if enable_debug then
|
||
|
dyn_anomalies_dbg = m_data.dyn_anomalies_dbg or {}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function anomaly_on_before_activate(zone, obj, flags)
|
||
|
|
||
|
if (not obj or not zone) then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if (IsStalker(obj) or IsMonster(obj)) then
|
||
|
if (not obj:alive()) then
|
||
|
flags.ret_value = false
|
||
|
end
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if not (obj:clsid() == clsid.obj_bolt) then
|
||
|
flags.ret_value = false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
|
||
|
RegisterScriptCallback("actor_on_update",actor_on_update)
|
||
|
RegisterScriptCallback("actor_on_interaction",actor_on_interaction)
|
||
|
RegisterScriptCallback("anomaly_on_before_activate",anomaly_on_before_activate)
|
||
|
RegisterScriptCallback("save_state",save_state)
|
||
|
RegisterScriptCallback("load_state",load_state)
|
||
|
end
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
-- Anomaly field binder
|
||
|
-------------------------------
|
||
|
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)
|
||
|
|
||
|
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(se_abstract)
|
||
|
if not object_binder.net_spawn(self, se_abstract) then
|
||
|
return false
|
||
|
end
|
||
|
db.add_zone(self.object)
|
||
|
db.add_obj(self.object)
|
||
|
fields_by_names[self.object:name()] = self
|
||
|
|
||
|
--[[
|
||
|
eDefaultRestrictorTypeNone = u8(0),
|
||
|
eDefaultRestrictorTypeOut = u8(1),
|
||
|
eDefaultRestrictorTypeIn = u8(2),
|
||
|
eRestrictorTypeNone = u8(3),
|
||
|
eRestrictorTypeIn = u8(4),
|
||
|
eRestrictorTypeOut = u8(5),
|
||
|
--]]
|
||
|
-- don't enable unless you realize that engine AI schemes to deal with anomalies is stupid and will not be supported
|
||
|
-- MAY CAUSE HUGE FPS DROP ON COP MAPS
|
||
|
--[[
|
||
|
if (get_console_cmd(1,"ai_die_in_anomaly") == true) then
|
||
|
-- It causes HUGE fps drop on COP maps which is why it was probably cut
|
||
|
local ignore = {
|
||
|
["zaton"] = true,
|
||
|
["jupiter"] = true,
|
||
|
["pripyat"] = true
|
||
|
}
|
||
|
if not (ignore[level.name()]) then
|
||
|
self.object:set_restrictor_type(3)
|
||
|
end
|
||
|
end
|
||
|
--]]
|
||
|
|
||
|
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)
|
||
|
--[[ testing
|
||
|
local itr = function(id)
|
||
|
local obj = id and alife_object(id)
|
||
|
printf("%s touch_feel id=%s obj=%s",self.object:name(),id,obj and obj:name())
|
||
|
end
|
||
|
self.object:iterate_feel_touch(itr)
|
||
|
--]]
|
||
|
end
|
||
|
|
||
|
-- Standart function for save
|
||
|
function anomaly_field_binder:net_save_relevant()
|
||
|
return true
|
||
|
end
|