470 lines
No EOL
16 KiB
Text
470 lines
No EOL
16 KiB
Text
--'******************************************************
|
|
--'* Áèíäåð îáúåêòà çîíû àíîìàëèé .
|
|
--'******************************************************
|
|
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 |