Various Changes; Updated and Added Mods

This commit is contained in:
2024-03-27 00:55:00 -04:00
parent 8abddf23c7
commit 46265b6fcc
2193 changed files with 23397 additions and 56583 deletions
@@ -0,0 +1,880 @@
--------------------------------
----- Written by Darryl123 -----
--------------------------------
-------------------------
----- Miscellaneous -----
-------------------------
-- Check if achievements can be unlocked.
function can_unlock()
return (db.actor and db.actor.afterFirstUpdate)
end
-- Counts how many achievements exist.
local achievements_count = nil
function get_achievements_count()
-- Check if a count has already been made.
if (achievements_count) then
return achievements_count
end
-- Scan the achievements section for achievements.
achievements_count = 0
local line_count = ini_sys:line_count("achievements") or 0
for i = 0, line_count - 1 do
-- Check whether the achievement requires story mode.
local junk1, section, junk2 = ini_sys:r_line("achievements", i, "", "")
local ignore = ini_sys:r_bool_ex(section, "ignore", false)
local story = ini_sys:r_bool_ex(section, "story", false)
local ironman = ini_sys:r_bool_ex(section, "ironman", false)
local warfare = ini_sys:r_bool_ex(section, "warfare", false)
local is_story = (story and not has_alife_info("story_mode_disabled"))
local is_ironman = (ironman and IsHardcoreMode())
local is_warfare = (warfare and _G.WARFARE)
if (not (story or ironman or warfare)) -- if achievement has no restricted mode
or (is_story and not ironman) -- if achievement for story mode only
or (is_story and is_ironman)
or (is_warfare)
then
if (not ignore) then
achievements_count = achievements_count + 1
end
end
end
return achievements_count
end
-- Counts how many achievements are locked.
function get_achievements_locked_count()
return get_achievements_count() - get_achievements_unlocked_count()
end
-- Counts how many achievements are unlocked.
function get_achievements_unlocked_count()
return game_statistics.get_actor_achievements_count()
end
-- Checks whether an achievement is unlocked.
function has_achievement(achievement)
return game_statistics.has_actor_achievement(achievement)
end
--------------------
----- Functors -----
--------------------
-- Bookworm Food
function bookworm_food_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("bookworm_food")) then
return true
end
-- Unlock the achievement.
if (bookworm_food_requirements()) then
bookworm_food_rewards()
return true
end
end
-- Completionist.
function completionist_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("completionist")) then
return true
end
-- Unlock the achievement.
if (completionist_requirements()) then
completionist_rewards()
return true
end
end
-- Down to Earth.
function down_to_earth_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("down_to_earth")) then
return true
end
-- Unlock the achievement.
if (down_to_earth_requirements()) then
down_to_earth_rewards()
return true
end
end
-- Duga Free.
function duga_free_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("duga_free")) then
return true
end
-- Unlock the achievement.
if (duga_free_requirements()) then
duga_free_rewards()
return true
end
end
-- Geologist.
function geologist_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("geologist")) then
return true
end
-- Unlock the achievement.
if (geologist_requirements()) then
geologist_rewards()
return true
end
end
-- Heavy Pockets.
function heavy_pockets_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("heavy_pockets")) then
return true
end
-- Unlock the achievement.
if (heavy_pockets_requirements()) then
heavy_pockets_rewards()
return true
end
end
-- Infopreneur.
function infopreneur_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("infopreneur")) then
return true
end
-- Unlock the achievement.
if (infopreneur_requirements()) then
infopreneur_rewards()
return true
end
end
-- Mechanized Warfare.
function mechanized_warfare_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("mechanized_warfare")) then
return true
end
-- Unlock the achievement.
if (mechanized_warfare_requirements()) then
mechanized_warfare_rewards()
return true
end
end
-- Patriarch.
function patriarch_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("patriarch")) then
return true
end
-- Unlock the achievement.
if (patriarch_requirements()) then
patriarch_rewards()
return true
end
end
-- Radiotherapy.
function radiotherapy_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("radiotherapy")) then
return true
end
-- Unlock the achievement.
if (radiotherapy_requirements()) then
radiotherapy_rewards()
return true
end
end
-- Rag and Bone.
function rag_and_bone_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("rag_and_bone")) then
return true
end
-- Unlock the achievement.
if (rag_and_bone_requirements()) then
rag_and_bone_rewards()
return true
end
end
-- Silver or Lead.
function silver_or_lead_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("silver_or_lead")) then
return true
end
-- Unlock the achievement.
if (silver_or_lead_requirements()) then
silver_or_lead_rewards()
return true
end
end
-- Tourist.
function tourist_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("tourist")) then
return true
end
-- Unlock the achievement.
if (has_alife_info("tourist_achievement_delay")) then
tourist_rewards()
return true
end
-- An infoportion delays the achievement.
-- Without this it often unlocks during level transition.
if (tourist_requirements()) then
db.actor:give_info_portion("tourist_achievement_delay")
return false
end
end
-- Well Dressed.
function well_dressed_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("well_dressed")) then
return true
end
-- Unlock the achievement.
if (well_dressed_requirements()) then
well_dressed_rewards()
return true
end
end
-- Wishful Thinking.
function wishful_thinking_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("wishful_thinking")) then
return true
end
-- Unlock the achievement.
if (wishful_thinking_requirements()) then
wishful_thinking_rewards()
return true
end
end
-- Infantile Pleasure.
function infantile_pleasure_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("infantile_pleasure")) then
return true
end
-- Unlock the achievement.
if (infantile_pleasure_requirements()) then
infantile_pleasure_rewards()
return true
end
end
-- Recycler.
function recycler_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("recycler")) then
return true
end
-- Unlock the achievement.
if (recycler_requirements()) then
recycler_rewards()
return true
end
end
-- Artificer Eagerness.
function artificer_eagerness_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("artificer_eagerness")) then
return true
end
-- Unlock the achievement.
if (artificer_eagerness_requirements()) then
artificer_eagerness_rewards()
return true
end
end
-- Unforeseen Guest.
function unforeseen_guest_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("unforeseen_guest")) then
return true
end
-- Unlock the achievement.
if (unforeseen_guest_requirements()) then
unforeseen_guest_rewards()
return true
end
end
-- Absolver.
function absolver_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("absolver")) then
return true
end
-- Unlock the achievement.
if (absolver_requirements()) then
absolver_rewards()
return true
end
end
-- Collaborator.
function collaborator_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("collaborator")) then
return true
end
-- Unlock the achievement.
if (collaborator_requirements()) then
collaborator_rewards()
return true
end
end
-- Iron Curtain.
function iron_curtain_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("iron_curtain")) then
return true
end
-- Unlock the achievement.
if (iron_curtain_requirements()) then
iron_curtain_rewards()
return true
end
end
-- Murky Spirit.
function murky_spirit_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("murky_spirit")) then
return true
end
-- Unlock the achievement.
if (murky_spirit_requirements()) then
murky_spirit_rewards()
return true
end
end
-- Invictus.
function invictus_functor()
-- Check if it can be unlocked.
if (not can_unlock()) then
return false
end
-- Check if it is already unlocked.
if (has_achievement("invictus")) then
return true
end
-- Unlock the achievement.
if (invictus_requirements()) then
invictus_rewards()
return true
end
end
------------------------
----- Requirements -----
------------------------
-- Bookworm Food
-- Requires all encyclopedia articles be unlocked.
function bookworm_food_requirements()
return (
(ui_pda_encyclopedia_tab.get_articles_locked_count() == 0)
)
end
-- Completionist.
-- Requires all available achievements to be unlocked.
function completionist_requirements()
return (
(get_achievements_locked_count() <= 1)
)
end
-- Down to Earth.
-- Requires 3 helicopters killed, or just one with an RPG-7.
function down_to_earth_requirements()
return (
(game_statistics.get_statistic_count("helicopters_downed") >= 3)
or (game_statistics.get_statistic_count("helicopters_downed2") >= 1)
)
end
-- Duga Free.
-- Requires story mode, and that the Miracle Machine and Brain Scorcher are disabled.
function duga_free_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("yan_labx16_switcher_primary_off"))
and (has_alife_info("bar_deactivate_radar_done"))
)
end
-- Geologist.
-- Requires 50 artefacts be detected by the player.
function geologist_requirements()
return (
(game_statistics.get_statistic_count("artefacts_detected") >= 50)
)
end
-- Heavy Pockets.
-- Requires player to possess 1,000,000 RU.
function heavy_pockets_requirements()
return (
(db.actor:money() >= 1000000)
)
end
-- Infopreneur.
-- Requires player to deliver 50 PDAs.
function infopreneur_requirements()
return (
(game_statistics.get_statistic_count("pdas_delivered") >= 50)
)
end
-- Mechanized Warfare.
-- Requires a mechanic to own all tools.
function mechanized_warfare_requirements()
return (
(has_alife_info("agr_smart_terrain_1_6_army_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("army_south_mechan_mlr_upgrade_tier_3"))
or (has_alife_info("bar_visitors_stalker_mechanic_upgrade_tier_3"))
or (has_alife_info("cit_killers_merc_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("dasc_tech_mlr_upgrade_tier_3"))
or (has_alife_info("val_smart_terrain_7_3_bandit_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("esc_smart_terrain_5_7_loner_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("jup_b217_stalker_tech_upgrade_tier_3"))
or (has_alife_info("jup_cont_mech_bandit_upgrade_tier_3"))
or (has_alife_info("mar_base_stalker_tech_upgrade_tier_3"))
or (has_alife_info("mil_smart_terrain_7_7_freedom_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("mechanic_monolith_jup_depo_upgrade_tier_3"))
or (has_alife_info("mechanic_monolith_kbo_upgrade_tier_3"))
or (has_alife_info("pri_monolith_monolith_mechanic_stalker_upgrade_tier_3"))
or (has_alife_info("merc_pri_a18_mech_mlr_upgrade_tier_3"))
or (has_alife_info("trucks_cemetery_bandit_mechanic_upgrade_tier_3"))
or (has_alife_info("yan_ecolog_kruglov_upgrade_tier_3"))
or (has_alife_info("zat_a2_stalker_mechanic_upgrade_tier_3"))
or (has_alife_info("zat_stancia_mech_merc_upgrade_tier_3"))
or (has_alife_info("mechanic_army_yan_mlr_upgrade_tier_3"))
or (has_alife_info("jup_depo_isg_tech_upgrade_tier_3"))
or (has_alife_info("sim_default_army_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_bandit_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_csky_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_dolg_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_ecolog_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_freedom_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_killer_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_monolith_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_stalker_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_renegade_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_greh_mechanic_upgrade_tier_3"))
or (has_alife_info("sim_default_isg_mechanic_upgrade_tier_3"))
)
end
-- Patriarch.
-- Requires rank of 'Legend' be reached.
function patriarch_requirements()
return (
(db.actor:character_rank() >= 50000)
)
end
-- Radiotherapy.
-- Requires 25 emissions and 25 psi-storms to be survived.
function radiotherapy_requirements()
return (
(game_statistics.get_statistic_count("emissions") >= 25)
and (game_statistics.get_statistic_count("psi_storms") >= 25)
)
end
-- Rag and Bone.
-- Requires 100 stashes be found and looted.
function rag_and_bone_requirements()
return (
(game_statistics.get_statistic_count("stashes_found") >= 100)
)
end
-- Silver or Lead.
-- Requires player to kill 500 stalkers or have 50 surrender to you.
function silver_or_lead_requirements()
return (
(game_statistics.get_statistic_count("killed_stalkers") >= 500)
or (game_statistics.get_statistic_count("enemies_surrendered") >= 50)
)
end
-- Tourist.
-- Requires player to visit all levels.
function tourist_requirements()
return (
(game_statistics.has_actor_visitied_all_levels())
)
end
-- Well Dressed.
-- Requires player to kill 500 mutants or field dress 250 mutant parts.
function well_dressed_requirements()
return (
(game_statistics.get_statistic_count("killed_monsters") >= 500)
or (game_statistics.get_statistic_count("field_dressings") >= 250)
)
end
-- Wishful Thinking.
-- Requires story mode, and for the player to finish Living Legend questlines.
function wishful_thinking_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("living_legend_done"))
)
end
-- Infantile Pleasure
-- Requires player to smash 200 boxes
function infantile_pleasure_requirements()
return ((game_statistics.get_statistic_count("boxes_smashed") >= 200))
end
-- Recycler
-- Requires player to disassemble 200 items
function recycler_requirements()
return ((game_statistics.get_statistic_count("items_disassembled") >= 200))
end
-- Artificer Eagerness
-- Requires player to craft 50 items
function artificer_eagerness_requirements()
return ((game_statistics.get_statistic_count("items_crafted") >= 50))
end
-- Unforeseen Guest
-- Requires player to stay disguised for 5 hours under stalkers watch
function unforeseen_guest_requirements()
return ((game_statistics.get_statistic_count("minutes_disguised") >= 5*60))
end
-- Absolver.
-- Requires story mode, and for the player to finish Mortal Sin questlines.
function absolver_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("mortal_sin_zone_hero"))
)
end
-- Collaborator.
-- Requires story mode, and for the player to finish Operation Afterglow questlines.
function collaborator_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("operation_afterglow_complete"))
)
end
-- Iron Curtain.
-- Requires Warfare mode, and for the player's faction to take over the levels.
function iron_curtain_requirements()
return (
IsWarfare() and (has_alife_info("warfare_actor_faction_domination"))
)
end
-- Murky Spirit.
-- Requires story mode, and for the player to finish Lost to the Zone questlines.
function murky_spirit_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("operation_afterglow_complete"))
and IsHardcoreMode()
and not (has_alife_info("ironman_flag_off"))
)
end
-- Invictus.
-- Requires story mode, and for the player to finish Living Legend questlines.
function invictus_requirements()
return (
not (has_alife_info("story_mode_disabled"))
and (has_alife_info("operation_afterglow_complete"))
and IsHardcoreMode()
and not (has_alife_info("ironman_flag_off"))
and not (has_alife_info("ironman_flag_died"))
and (game_difficulties.get_game_factor("type") == 3)
and (game_difficulties.get_eco_factor("type") == 3)
and not (has_alife_info("diff_gameplay_flag_change"))
and not (has_alife_info("diff_economy_flag_change"))
and not (has_alife_info("debug_mode_flag_on"))
)
end
-------------------
----- Rewards -----
-------------------
-- Bookworm Food.
-- Future memory sticks become rare PDAs.
function bookworm_food_rewards()
SendScriptCallback("actor_on_achievement_earned","bookworm_food","st_achievement_15_unlock")
end
-- Completionist.
function completionist_rewards()
SendScriptCallback("actor_on_achievement_earned","completionist","st_achievement_10_unlock")
end
-- Down to Earth.
-- Weaker helicopters are respawned.
function down_to_earth_rewards()
SendScriptCallback("actor_on_achievement_earned","down_to_earth","st_achievement_12_unlock")
end
-- Duga Free.
-- Yantar & Radar psi-fields disabled.
function duga_free_rewards()
SendScriptCallback("actor_on_achievement_earned","duga_free","st_achievement_4_unlock")
end
-- Geologist.
-- Increased spawn chance of artefacts.
function geologist_rewards()
SendScriptCallback("actor_on_achievement_earned","geologist","st_achievement_13_unlock")
end
-- Heavy Pockets.
-- Traders sell cheaper and rarer goods.
function heavy_pockets_rewards()
SendScriptCallback("actor_on_achievement_earned","heavy_pockets","st_achievement_1_unlock")
end
-- Infopreneur.
-- Money received for delivering PDAs increased.
function infopreneur_rewards()
SendScriptCallback("actor_on_achievement_earned","infopreneur","st_achievement_3_unlock")
end
-- Mechanized Warfare.
-- A mechanic can now fully upgrade equipment.
function mechanized_warfare_rewards()
SendScriptCallback("actor_on_achievement_earned","mechanized_warfare","st_achievement_7_unlock")
end
-- Patriarch.
-- Larger sized squads can be recruited.
function patriarch_rewards()
SendScriptCallback("actor_on_achievement_earned","patriarch","st_achievement_14_unlock")
end
-- Radiotherapy.
-- 25% chance of surviving emissions and psi-vortices.
function radiotherapy_rewards()
SendScriptCallback("actor_on_achievement_earned","radiotherapy","st_achievement_2_unlock")
end
-- Rag and Bone.
-- Random chance of better loot in task reward stashes.
function rag_and_bone_rewards()
SendScriptCallback("actor_on_achievement_earned","rag_and_bone","st_achievement_9_unlock")
end
-- Silver or Lead.
-- 33% chance of a second stash from surrendering stalkers.
function silver_or_lead_rewards()
SendScriptCallback("actor_on_achievement_earned","silver_or_lead","st_achievement_6_unlock")
end
-- Tourist.
-- 3 "Tourist's stashes" are revealed.
function tourist_rewards()
for i=1,3 do
treasure_manager.create_random_stash(nil, "Curious stash", nil)
end
db.actor:disable_info_portion("tourist_achievement_delay")
SendScriptCallback("actor_on_achievement_earned","tourist","st_achievement_8_unlock")
end
-- Well Dressed.
-- 20% chance of extra parts when field dressing mutants.
function well_dressed_rewards()
SendScriptCallback("actor_on_achievement_earned","well_dressed","st_achievement_5_unlock")
end
-- Wishful Thinking.
-- Unlock "Renegades" faction
function wishful_thinking_rewards()
axr_main.config:w_value("unlocked_factions","renegade",true)
axr_main.config:save()
SendScriptCallback("actor_on_achievement_earned","wishful_thinking","st_achievement_11_unlock")
end
-- Infantile Pleasure.
-- 25% chance of extra items found in boxes.
function infantile_pleasure_rewards()
SendScriptCallback("actor_on_achievement_earned","infantile_pleasure","st_achievement_16_unlock")
end
-- Recycler.
-- 33% chance of extra part obtained from disassembling.
function recycler_rewards()
SendScriptCallback("actor_on_achievement_earned","recycler","st_achievement_17_unlock")
end
-- Artificer Eagerness.
-- 1 less part used for crafting.
function artificer_eagerness_rewards()
SendScriptCallback("actor_on_achievement_earned","artificer_eagerness","st_achievement_18_unlock")
end
-- Unforeseen Guest.
-- less suspicious spikes upon sudden actions.
function unforeseen_guest_rewards()
SendScriptCallback("actor_on_achievement_earned","unforeseen_guest","st_achievement_19_unlock")
end
-- Absolver.
-- Unlock "Sin" faction
function absolver_rewards()
axr_main.config:w_value("unlocked_factions","greh",true)
axr_main.config:save()
SendScriptCallback("actor_on_achievement_earned","absolver","st_achievement_20_unlock")
end
-- Collaborator.
-- Unlock "ISG" faction
function collaborator_rewards()
axr_main.config:w_value("unlocked_factions","isg",true)
axr_main.config:save()
SendScriptCallback("actor_on_achievement_earned","collaborator","st_achievement_21_unlock")
end
-- Iron Curtain.
-- Reward 40,000 RU
function iron_curtain_rewards()
db.actor:give_money(40000)
SendScriptCallback("actor_on_achievement_earned","iron_curtain","st_achievement_22_unlock")
end
-- Murky Spirit.
function murky_spirit_rewards()
SendScriptCallback("actor_on_achievement_earned","murky_spirit","st_achievement_23_unlock")
end
-- Invictus.
function invictus_rewards()
SendScriptCallback("actor_on_achievement_earned","invictus","st_achievement_24_unlock")
end
@@ -0,0 +1,587 @@
--------------------------------
----- Written by Darryl123 -----
--------------------------------
--[[
- Modified by Tronex
- 2019/4/29
- NPC rank and rep progression by different stats
--]]
------------------
----- Tables -----
------------------
-- Achievements unlocked.
actor_achievements = {
["bookworm_food"] = { unlocked = false, rank = 1000, rept = 0 },
["completionist"] = { unlocked = false, rank = 1000, rept = 0 },
["down_to_earth"] = { unlocked = false, rank = 1000, rept = 0 },
["duga_free"] = { unlocked = false, rank = 1000, rept = 0 },
["geologist"] = { unlocked = false, rank = 1000, rept = 0 },
["heavy_pockets"] = { unlocked = false, rank = 1000, rept = 0 },
["infopreneur"] = { unlocked = false, rank = 1000, rept = 0 },
["mechanized_warfare"] = { unlocked = false, rank = 1000, rept = 0 },
["patriarch"] = { unlocked = false, rank = 1000, rept = 0 },
["radiotherapy"] = { unlocked = false, rank = 1000, rept = 0 },
["rag_and_bone"] = { unlocked = false, rank = 1000, rept = 0 },
["silver_or_lead"] = { unlocked = false, rank = 1000, rept = 0 },
["tourist"] = { unlocked = false, rank = 1000, rept = 0 },
["well_dressed"] = { unlocked = false, rank = 1000, rept = 0 },
["wishful_thinking"] = { unlocked = false, rank = 1000, rept = 0 },
["infantile_pleasure"] = { unlocked = false, rank = 1000, rept = 0 },
["recycler"] = { unlocked = false, rank = 1000, rept = 0 },
["artificer_eagerness"] = { unlocked = false, rank = 1000, rept = 0 },
["unforeseen_guest"] = { unlocked = false, rank = 1000, rept = 0 },
["absolver"] = { unlocked = false, rank = 1000, rept = 0 },
["collaborator"] = { unlocked = false, rank = 1000, rept = 0 },
["iron_curtain"] = { unlocked = false, rank = 1000, rept = 0 },
["murky_spirit"] = { unlocked = false, rank = 1000, rept = 0 },
["invictus"] = { unlocked = false, rank = 1000, rept = 0 },
}
-- Artefacts found and detected.
-- Should be empty by default.
actor_artefacts = {
}
-- Unlocked Anomaly maps. Should be empty by default.
actor_anomaly_maps = {
}
-- Miscellaneous data that requires recording.
actor_miscellaneous = {
["actual_rank"] = 0,
["actual_rept"] = 0,
}
-- Levels visited.
actor_visited_levels = {
["jupiter"] = false,
["jupiter_underground"] = false,
["k00_marsh"] = false,
["k01_darkscape"] = false,
["k02_trucks_cemetery"] = false,
["l01_escape"] = false,
["l02_garbage"] = false,
["l03_agroprom"] = false,
["l03u_agr_underground"] = false,
["l04_darkvalley"] = false,
["l04u_labx18"] = false,
["l05_bar"] = false,
["l06_rostok"] = false,
["l07_military"] = false,
["l08_yantar"] = false,
["l08u_brainlab"] = false,
["l09_deadcity"] = false,
["l10_limansk"] = false,
["l10_radar"] = false,
["l10_red_forest"] = false,
["l10u_bunker"] = false,
["l11_hospital"] = false,
["l11_pripyat"] = false,
["l12_stancia"] = false,
["l12_stancia_2"] = false,
["l12u_control_monolith"] = false,
["l12u_sarcofag"] = false,
["l13_generators"] = false,
["l13u_warlab"] = false,
["labx8"] = false,
["pripyat"] = false,
["zaton"] = false,
["y04_pole"] = false,
}
-- Smart terrains visited.
-- Should be empty by default.
actor_visited_smarts = {
}
-- Tracked player statistics and their rank and reputation rewards.
actor_statistics = {
["arena_battles"] = { count = 0, rank = 7, rept = 8 },
["artefacts_detected"] = { count = 0, rank = 4, rept = 0 },
["artefacts_found"] = { count = 0, rank = 2, rept = 0 },
["articles"] = { count = 0, rank = 2, rept = 0 }, -- Counter is incremented but isn't used.
["boxes_smashed"] = { count = 0, rank = 1, rept = 0 },
["deaths"] = { count = 0, rank = 0, rept = 0 },
["donations"] = { count = 0, rank = 3, rept = 1 }, -- Actual points given depends on item condition.
["emissions"] = { count = 0, rank = 14, rept = 0 },
["enemies_surrendered"] = { count = 0, rank = 4, rept = 0 },
["field_dressings"] = { count = 0, rank = 1, rept = 0 },
["helicopters_downed"] = { count = 0, rank = 100, rept = 25 },
["helicopters_downed2"] = { count = 0, rank = 50, rept = 0 }, -- Bonus points for using explosives.
["killed_companions"] = { count = 0, rank = 0, rept = -75 },
["killed_monsters"] = { count = 0, rank = 2, rept = 0 },
["killed_prisoners"] = { count = 0, rank = 0, rept = -25 },
["killed_stalkers"] = { count = 0, rank = 0, rept = 0 }, -- Unused; see below and the "rank_kill_points" config section.
["killed_stalkers_e"] = { count = 0, rank = 0, rept = 2 }, -- Enemy relations.
["killed_stalkers_f"] = { count = 0, rank = 0, rept = -100 }, -- Friendly relations.
["killed_stalkers_n"] = { count = 0, rank = 0, rept = -75 }, -- Neutral relations.
["level_changes"] = { count = 0, rank = 0, rept = 0 },
["pdas_delivered"] = { count = 0, rank = 3, rept = 2 },
["psi_storms"] = { count = 0, rank = 7, rept = 0 },
["stashes_found"] = { count = 0, rank = 2, rept = 0 },
["tasks_cancelled"] = { count = 0, rank = 0, rept = -25 },
["tasks_completed"] = { count = 0, rank = 10, rept = 8 },
["tasks_failed"] = { count = 0, rank = 0, rept = -25 },
["wounded_helped"] = { count = 0, rank = 5, rept = 8 },
-- new
["items_crafted"] = { count = 0, rank = 1, rept = 0 },
["items_disassembled"] = { count = 0, rank = 1, rept = 0 },
["self_repairs"] = { count = 0, rank = 1, rept = 0 },
["minutes_disguised"] = { count = 0, rank = 1, rept = 0 },
}
-- Saved NPC statistics and their rank and reputation rewards.
npc_statistics = {
["artefacts_found"] = { save = true, rank = 150, rept = 0 },
["boxes_smashed"] = { save = false, rank = 10, rept = 0 },
["field_dressings"] = { save = false, rank = 25, rept = 0 },
["helicopters_downed"] = { save = false, rank = 2500, rept = 50 },
["helicopters_downed2"] = { save = false, rank = 1000, rept = 50 },
["killed_monsters"] = { save = true, rank = 100, rept = 0 },
["killed_stalkers"] = { save = true, rank = 0, rept = 0 }, -- All
["killed_stalkers_e"] = { save = false, rank = 100, rept = 10 }, -- Enemy relations.
["killed_stalkers_f"] = { save = false, rank = 0, rept = -100 }, -- Friendly relations.
["killed_stalkers_n"] = { save = false, rank = 0, rept = -75 }, -- Neutral relations.
["corpse_looted"] = { save = true, rank = 10, rept = 0 },
["wounded_helped"] = { save = true, rank = 50, rept = 100 },
["items_sold"] = { save = true, rank = 10, rept = 0 },
}
---------------------
----- Callbacks -----
---------------------
-- Called when actor takes an item.
function actor_on_item_take(item)
if not (item and IsArtefact(item)) then return end
-- Hack to prevent player from exploting Artefacts Containers (gaining rank by recieving artefacts)
if _G.ARTY_FROM_CONT then
_G.ARTY_FROM_CONT = nil
return
end
local artefact = item:get_artefact()
local anomaly = bind_anomaly_zone.parent_zones_by_artefact_id[item:id()]
-- Artefacts found counter incrementation.
-- Checks to make sure artefact id hasn't already been logged.
if (artefact) then
artefact:FollowByPath("NULL", 0, vector():set(500,500,500))
if not (actor_artefacts[item:id()]) then
actor_artefacts[item:id()] = true
increment_statistic("artefacts_found")
else
return
end
end
-- Artefacts detected counter incrementation.
-- Requires the artefact be associated with an anomaly.
if (artefact and anomaly) then
anomaly:on_artefact_take(item)
increment_statistic("artefacts_detected")
else
bind_anomaly_zone.artefact_ways_by_id[item:id()] = nil
end
end
-- Called when an NPC is killed.
function npc_on_death_callback(victim, killer)
-- Return if the actor is not the killer.
if not (killer and victim) then return end
local id = killer:id()
local killer_faction = character_community(killer)
local victim_faction = character_community(victim)
--if not (killer:id() == AC_ID) then return end
-- Increment statistics based on faction relations.
local stat
if (xr_conditions.is_factions_friends(nil, nil, { killer_faction, victim_faction })) then
stat = "killed_stalkers_f"
elseif (xr_conditions.is_factions_enemies(nil, nil, { killer_faction, victim_faction })) then
stat = "killed_stalkers_e"
else
stat = "killed_stalkers_n"
end
if (id == AC_ID) then
increment_statistic("killed_stalkers")
increment_statistic(stat)
else
increment_npc_statistic(killer,"killed_stalkers")
increment_npc_statistic(killer,stat)
end
end
-- Called when an achievement is earned.
function actor_on_achievement_earned(achievement, message)
if (achievement and message) then
news_manager.send_tip(db.actor, message, nil, achievement, nil, nil)
if actor_achievements[achievement] then
actor_achievements[achievement].unlocked = true
if actor_achievements[achievement].rank then
increment_rank( actor_achievements[achievement].rank )
end
if actor_achievements[achievement].rept then
increment_reputation( actor_achievements[achievement].rept )
end
else
actor_achievements[achievement] = {}
actor_achievements[achievement].unlocked = true
end
end
end
-- Called when the game is loaded.
function on_game_load()
if (not IsTestMode()) then
actor_visited_levels[level.name()] = true
end
if DEV_DEBUG and (not has_alife_info("debug_mode_flag_on")) then
give_info("debug_mode_flag_on")
printf("~ Player used debug mode!")
end
end
-- Called when the game starts.
function on_game_start()
RegisterScriptCallback("actor_on_item_take", actor_on_item_take)
RegisterScriptCallback("npc_on_death_callback", npc_on_death_callback)
RegisterScriptCallback("actor_on_achievement_earned", actor_on_achievement_earned)
RegisterScriptCallback("on_game_load", on_game_load)
RegisterScriptCallback("on_level_changing", on_level_changing)
RegisterScriptCallback("actor_on_interaction", actor_on_interaction)
create_relations_tables()
end
-- Called when changing levels.
function on_level_changing()
if (not IsTestMode()) then
increment_statistic("level_changes")
end
end
-----------------------
----- Incrementors ----
-----------------------
-- Increments actor rank value.
-- Impose restrictions at double the minimum and maximum ranks' values.
function increment_rank(value)
db.actor:change_character_rank(value or 0)
if (db.actor:character_rank() < 0) then db.actor:set_character_rank(0) end
if (db.actor:character_rank() > 1000000000) then db.actor:set_character_rank(1000000000) end
check_for_rank_change()
end
function increment_npc_rank(npc, value)
if (not npc) then return end
--npc:change_character_rank(value or 0)
npc:set_character_rank(npc:character_rank() + (value or 0))
if (npc:character_rank() < 0) then npc:set_character_rank(0) end
if (npc:character_rank() > 1000000000) then npc:set_character_rank(1000000000) end
--printf("/ NPC stats | +Rank = %s | id: %s - name: %s", npc:character_rank(), npc:id(), npc:character_name())
end
-- Increments actor reputation value.
-- Impose restrictions at double the minimum and maximum reputations' values.
function increment_reputation(value)
-- Fix for arena causing reputation changes
if has_alife_info("bar_arena_fight") then
return
end
db.actor:change_character_reputation(value or 0)
if (db.actor:character_reputation() < -4000) then db.actor:set_character_reputation(-4000) end
if (db.actor:character_reputation() > 4000) then db.actor:set_character_reputation(4000) end
check_for_reputation_change()
end
function increment_npc_reputation(npc,value)
if (not npc) then return end
--npc:change_character_reputation(value or 0)
npc:set_character_reputation(npc:character_reputation() + (value or 0))
if (npc:character_reputation() < -4000) then npc:set_character_reputation(-4000) end
if (npc:character_reputation() > 4000) then npc:set_character_reputation(4000) end
--printf("/ NPC stats | +Rep = %s | id: %s - name: %s", npc:character_reputation(), npc:id(), npc:character_name())
end
-- Increments a statistic counter.
-- Also updates actor rank and reputation values.
function increment_statistic(value, custom_rank, custom_rept)
local statistic = value and actor_statistics[value] or nil
if (statistic and statistic.count and statistic.rank and statistic.rept) then
statistic.count = statistic.count + 1
increment_rank(custom_rank or statistic.rank)
increment_reputation(custom_rept or statistic.rept)
end
end
function increment_npc_statistic(npc, value, custom_rank, custom_rept)
local statistic = value and npc_statistics[value] or nil
if (npc and IsStalker(npc) and npc:alive() and statistic and statistic.rank and statistic.rept) then
if statistic.save then
local se_npc = alife_object(npc:id())
if se_npc then
local m_data = alife_storage_manager.get_se_obj_state(se_npc,true)
if (m_data) then
m_data[value] = m_data[value] and m_data[value] + 1 or 1
end
end
end
increment_npc_rank(npc, custom_rank or statistic.rank)
increment_npc_reputation(npc, custom_rept or statistic.rept)
end
end
-------------------------
----- Miscellaneous -----
-------------------------
-- Gets the count for unlocked achievements.
function get_actor_achievements_count()
local count = 0
for k, v in pairs(actor_achievements) do
if (v.unlocked == true) then
count = count + 1
end
end
return count
end
-- Gets the count for visited levels.
function get_actor_visited_levels_count()
local count = 0
for k, v in pairs(actor_visited_levels) do
if (v == true) then
count = count + 1
end
end
return count
end
-- Gets the count for visited smarts.
function get_actor_visited_smarts_count()
local count = 0
for k, v in pairs(actor_visited_smarts) do
if (v == true) then
count = count + 1
end
end
return count
end
-- Gets the count value for a statistic.
function get_statistic_count(value)
local statistic = value and actor_statistics[value] or nil
return (statistic and statistic.count) and statistic.count or 0
end
-- Gets whether the actor has an achievement unlocked.
function has_actor_achievement(value)
local achievement = value and actor_achievements[value]
return achievement and achievement.unlocked or false
end
-- Gets whether the actor has visited all levels.
function has_actor_visitied_all_levels()
for k, v in pairs (actor_visited_levels) do
if (v == false) then
return false
end
end
return true
end
-- Gets whether the actor has visited a specific level.
function has_actor_visited_level(value)
return value and actor_visited_levels[value] or false
end
-- Gets whether the actor has visited a specific smart.
function has_actor_visited_smart(value)
return value and actor_visited_smarts[value] or false
end
-- Called when a smart terrain is visited.
function actor_on_interaction(typ, obj, name)
if (typ ~= "smarts") then
return
end
actor_visited_smarts[name] = true
end
-----------------------------
----- Rank & Reputation -----
-----------------------------
-- Creates the rank and reputation tables.
local rank_table, rept_table
function create_relations_tables()
-- Check if the rank and reputation tables are initialised.
if not (rank_table and rept_table) then
-- Matches each rank and reputation to a value.
local function parse_string(value)
local result = {}
for name in string.gmatch(value, "([%w_%-.\\]+)[%,%s]*") do
result[#result + 1] = name
end
return result
end
-- Retrieve the rank and reputation values from configs.
local ini = ini_file("creatures\\game_relations.ltx")
local rank_table_temp = parse_string(ini:r_string_ex("game_relations", "rating"))
local rept_table_temp = parse_string(ini:r_string_ex("game_relations", "reputation"))
-- Fill the contents of the rank table.
rank_table = {}
for index = 2, #rank_table_temp, 2 do
rank_table[#rank_table + 1] = tonumber(rank_table_temp[index])
end
-- Fill the contents of the reputation table.
rept_table = {}
for index = 2, #rept_table_temp, 2 do
rept_table[#rept_table + 1] = tonumber(rept_table_temp[index])
end
end
end
-- Checks for changes the actor's rank.
function check_for_rank_change(suppress)
local current_rank = db.actor:character_rank()
local new_rank, old_rank = 0, 0
for index = 1, #rank_table do
if (current_rank <= rank_table[index]) then
break
end
new_rank = new_rank + 1
end
for index = 1, #rank_table do
if (actor_miscellaneous.actual_rank <= rank_table[index]) then
break
end
old_rank = old_rank + 1
end
if (not suppress) then
if (old_rank > new_rank) then
news_manager.send_tip(db.actor, "st_rank_decreased", nil, "rank_change", nil, nil)
elseif (new_rank > old_rank) then
news_manager.send_tip(db.actor, "st_rank_increased", nil, "rank_change", nil, nil)
end
end
actor_miscellaneous.actual_rank = current_rank
end
-- Checks for changes to the actor's reputation.
function check_for_reputation_change(suppress)
local current_rept = db.actor:character_reputation()
local new_rept, old_rept = 0, 0
for index = 1, #rept_table do
if (current_rept <= rept_table[index]) then
break
end
new_rept = new_rept + 1
end
for index = 1, #rept_table do
if (actor_miscellaneous.actual_rept <= rept_table[index]) then
break
end
old_rept = old_rept + 1
end
if (not suppress) then
if (old_rept > new_rept) then
news_manager.send_tip(db.actor, "st_reputation_decreased", nil, "rep_change", nil, nil)
elseif (new_rept > old_rept) then
news_manager.send_tip(db.actor, "st_reputation_increased", nil, "rep_change", nil, nil)
end
end
actor_miscellaneous.actual_rept = current_rept
end
----------------------------
----- Saving & Loading -----
----------------------------
-- Loads the contents of the tables the regular way.
-- Unimplemented as Call of Chernobyl doesn't use this.
function load(packet)
if (USE_MARSHAL) then
return
end
end
-- Loads the contents of the tables using MARSHAL.
function load_state(data)
-- If no saved data exists then return.
if not (data.game_statistics) then
return
end
-- See the comments in the save_state method as to how this works.
actor_artefacts = data.game_statistics.actor_artefacts or actor_artefacts
actor_anomaly_maps = data.game_statistics.actor_anomaly_maps or actor_anomaly_maps
actor_miscellaneous = data.game_statistics.actor_miscellaneous or actor_miscellaneous
actor_visited_levels = data.game_statistics.actor_visited_levels or actor_visited_levels
actor_visited_smarts = data.game_statistics.actor_visited_smarts or actor_visited_smarts
if (data.game_statistics.actor_achievements) then
for k, v in pairs(data.game_statistics.actor_achievements) do
if (actor_achievements[k]) then
actor_achievements[k].unlocked = v
end
end
end
if (data.game_statistics.actor_statistics) then
for k, v in pairs(data.game_statistics.actor_statistics) do
if (actor_statistics[k]) then
actor_statistics[k].count = v
end
end
end
end
-- Saves the contents of the tables the regular way.
-- Unimplemented as Call of Chernobyl doesn't use this.
function save(packet)
if (USE_MARSHAL) then
return
end
end
-- Saves the contents of the tables using MARSHAL.
function save_state(data)
-- Create a table to store saved data.
if (not data.game_statistics) then
data.game_statistics = {}
end
-- Save tables as they are if they only record true/false values.
data.game_statistics.actor_artefacts = actor_artefacts
data.game_statistics.actor_anomaly_maps = actor_anomaly_maps
data.game_statistics.actor_miscellaneous = actor_miscellaneous
data.game_statistics.actor_visited_levels = actor_visited_levels
data.game_statistics.actor_visited_smarts = actor_visited_smarts
-- Couple of things to be noted here.
-- Rank and reputation values are stored in these tables as well, and we really don't want to save those.
-- If we did, it would mean any changes to their values in this script file would be ignored by existing saves.
-- However, saving the data this way also prevents any potential nil value crashes if new statistics and such are added.
data.game_statistics.actor_achievements = {}
for k, v in pairs(actor_achievements) do
data.game_statistics.actor_achievements[k] = v.unlocked
end
data.game_statistics.actor_statistics = {}
for k, v in pairs(actor_statistics) do
data.game_statistics.actor_statistics[k] = v.count
end
end
@@ -3,7 +3,7 @@ function on_xml_read()
local xml_to_change = [[gameplay\character_desc_marsh.xml]]
if xml_file_name == xml_to_change then
local renegade_trader_profile = [[
<specific_character id="mar_renegade_trader" team_default="1">
<specific_character id="mar_renegade_trader" team_default="1">
<name>mar_renegade_trader_name</name>
<icon>ui_inGame2_bandit_1</icon>
<map_icon x="1" y="0"></map_icon>
@@ -26,7 +26,7 @@ function on_xml_read()
#include "gameplay\character_criticals.xml"
<terrain_sect>stalker_terrain</terrain_sect>
<snd_config>characters_voice\human\bandit_1\</snd_config>
<visual>actors\stalker_renegade\stalker_renegade_trader</visual>
<visual>actors\stalker_renegade\stalker_renegade_1a_face_3</visual>
<start_dialog>val_smart_terrain_7_4_bandit_trader_stalker_start_dialog</start_dialog>
<actor_dialog>dm_init_trader</actor_dialog>
@@ -38,7 +38,7 @@ function on_xml_read()
<actor_dialog>debt_register</actor_dialog>
<actor_dialog>debt_pay_off</actor_dialog>
<actor_dialog>actor_break_dialog</actor_dialog>
</specific_character>
</specific_character>
<specific_character id="mar_renegade_mechanic" team_default="1">
<name>mar_renegade_mechanic_name</name>
@@ -64,7 +64,7 @@ function on_xml_read()
<terrain_sect>stalker_terrain</terrain_sect>
<mechanic_mode>1</mechanic_mode>
<snd_config>characters_voice\human\bandit_1\</snd_config>
<visual>actors\stalker_renegade\stalker_renegade_mechanic</visual>
<visual>actors\stalker_renegade\stalker_renegade_leader</visual>
<start_dialog>val_smart_terrain_7_3_bandit_mechanic_stalker_start_dialog</start_dialog>
<actor_dialog>dm_init_trader</actor_dialog>
@@ -75,7 +75,7 @@ function on_xml_read()
<actor_dialog>dm_tech_repair</actor_dialog>
<actor_dialog>dm_encrypted_pda</actor_dialog>
<actor_dialog>actor_break_dialog</actor_dialog>
</specific_character>
</specific_character>
]]
xml_obj:insertFromXMLString(renegade_trader_profile)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["agr_endless_night_spawn_01"] = {
pos = vector():set(28.622802734375, 4.2881875038147, -124.99558258057),
smart = "agr_smart_terrain_4_6",
},
["agr_endless_night_spawn_02"] = {
pos = vector():set(52.704040527344, 16.574716567993, 123.60317993164),
smart = "agr_smart_terrain_5_2",
},
["agr_endless_night_spawn_03"] = {
pos = vector():set(-97.329170227051, 12.251251220703, 158.92121887207),
smart = "agr_smart_terrain_2_2",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["bar_endless_night_spawn_01"] = {
pos = vector():set(197.84326171875, 2.120393037796, -84.757629394531),
smart = "bar_zastava_dogs_lair",
},
["bar_endless_night_spawn_02"] = {
pos = vector():set(42.580982208252, -0.0022871494293213, 207.98942565918),
smart = "bar_zastava_dogs_lair_2",
},
["bar_endless_night_spawn_03"] = {
pos = vector():set(147.11489868164, -0.003469854593277, 64.117401123047),
smart = "bar_visitors",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["cit_endless_night_spawn_01"] = {
pos = vector():set(-134.28648376465, -1.4032030105591, -330.41253662109),
smart = "zombie_smart_ds_mlr_1",
},
["cit_endless_night_spawn_02"] = {
pos = vector():set(51.318702697754, 3.5220413208008, 68.45654296875),
smart = "zombie_smart_ds_mlr_2",
},
["cit_endless_night_spawn_03"] = {
pos = vector():set(-221.71157836914, 9.9104175567627, -180.50151062012),
smart = "cit_kanaliz1",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["ds_endless_night_spawn_01"] = {
pos = vector():set(-13.702819824219, -0.45751050114632, -327.75891113281),
smart = "ds2_st_dogs",
},
["ds_endless_night_spawn_02"] = {
pos = vector():set(248.58453369141, -0.55253577232361, -86.308952331543),
smart = "ds_boars_nest",
},
["ds_endless_night_spawn_03"] = {
pos = vector():set(207.64343261719, -2.2147569656372, 552.82995605469),
smart = "ds_kem3",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["esc_endless_night_spawn_01"] = {
pos = vector():set(-86.41145324707, -4.1926307678223, -78.133041381836),
smart = "esc_smart_terrain_4_11",
},
["esc_endless_night_spawn_02"] = {
pos = vector():set(312.53915405273, 3.3987352848053, 126.92022705078),
smart = "esc_smart_terrain_8_9",
},
["esc_endless_night_spawn_03"] = {
pos = vector():set(129.46849060059, -0.71068423986435, 322.65246582031),
smart = "esc_smart_terrain_6_6",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["gar_endless_night_spawn_01"] = {
pos = vector():set(-210.73924255371, 0.29106289148331, -34.128147125244),
smart = "gar_smart_terrain_1_5",
},
["gar_endless_night_spawn_02"] = {
pos = vector():set(197.09075927734, 1.3092757463455, -109.58041381836),
smart = "gar_smart_terrain_6_6",
},
["gar_endless_night_spawn_03"] = {
pos = vector():set(270.46417236328, 0.50552141666412, 177.38319396973),
smart = "gar_smart_terrain_8_3",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["mar_endless_night_spawn_01"] = {
pos = vector():set(-152.15197753906, 0.80081522464752, 86.731491088867),
smart = "mar_smart_terrain_3_7",
},
["mar_endless_night_spawn_02"] = {
pos = vector():set(272.58688354492, 4.4342155456543, 55.053783416748),
smart = "mar_smart_terrain_8_8",
},
["mar_endless_night_spawn_03"] = {
pos = vector():set(364.51748657227, 2.1262073516846, 115.86725616455),
smart = "mar_smart_terrain_10_7",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["mil_endless_night_spawn_01"] = {
pos = vector():set(238.30529785156, 1.3474156856537, 437.15505981445),
smart = "mil_smart_terrain_2_1",
},
["mil_endless_night_spawn_02"] = {
pos = vector():set(38.137920379639, -13.218147277832, 333.01922607422),
smart = "mil_smart_terrain_2_6",
},
["mil_endless_night_spawn_03"] = {
pos = vector():set(-364.98373413086, -15.18780040741, 203.99565124512),
smart = "mil_smart_terrain_4_2",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["ros_endless_night_spawn_01"] = {
pos = vector():set(-221.39151000977, 0.098205626010895, 115.52049255371),
smart = "ros_smart_poltergeist2",
},
["ros_endless_night_spawn_02"] = {
pos = vector():set(-288.29718017578, -0.0036440342664719, 195.13694763184),
smart = "ros_smart_monster4",
},
["ros_endless_night_spawn_03"] = {
pos = vector():set(-285.64953613281, 0.54708015918732, 115.35409545898),
smart = "ros_smart_monster5",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["trc_endless_night_spawn_01"] = {
pos = vector():set(138.85020446777, 3.9266076087952, -124.36943054199),
smart = "trc_sim_5",
},
["trc_endless_night_spawn_02"] = {
pos = vector():set(198.9889831543, 10.085237503052, 163.07121276855),
smart = "trc_sim_11",
},
["trc_endless_night_spawn_03"] = {
pos = vector():set(-52.121494293213, 13.674411773682, 285.16284179688),
smart = "trc_sim_17",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["val_endless_night_spawn_01"] = {
pos = vector():set(-58.37699508667, -0.39553779363632, -374.03778076172),
smart = "val_smart_terrain_3_0",
},
["val_endless_night_spawn_02"] = {
pos = vector():set(-134.28462219238, -1.4056015014648, -330.41253662109),
smart = "val_smart_terrain_5_8",
},
["val_endless_night_spawn_03"] = {
pos = vector():set(-47.002891540527, -3.0274252891541, -145.11131286621),
smart = "val_smart_terrain_6_5",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,30 @@
function actor_on_first_update()
local pool = {
["yan_endless_night_spawn_01"] = {
pos = vector():set(161.0279083252, -0.71909606456757, 65.10375213623),
smart = "yan_smart_terrain_1_6",
},
["yan_endless_night_spawn_02"] = {
pos = vector():set(-209.48184204102, 6.8956809043884, -161.16413879395),
smart = "yan_smart_terrain_4_2",
},
["yan_endless_night_spawn_03"] = {
pos = vector():set(-161.47422790527, 6.5996909141541, -308.79528808594),
smart = "yan_smart_terrain_6_2",
}
}
for sec,v in pairs(pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,309 @@
function actor_on_first_update()
local lc_pool = {
["lc_ros01_ros02"] = {
pos = vector():set(-136.3947,-0.0025,122.3627),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros01_ros02.1"] = {
pos = vector():set(-135.5676,-0.000,122.1426),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros01_ros02.2"] = {
pos = vector():set(-137.3257,-0.0067,121.5680),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros01_ros02.3"] = {
pos = vector():set(-136.9949,-0.0018,122.1856),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01"] = {
pos = vector():set(-136.9901,0.0062,124.2836),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01.1"] = {
pos = vector():set(-136.9537,0.0044,125.0893),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01.2"] = {
pos = vector():set(-138.3931,0.0078,124.3509),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01.3"] = {
pos = vector():set(-138.4250,0.0095,124.6852),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01.4"] = {
pos = vector():set(-138.6385,0.0060,124.1129),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros02_ros01.5"] = {
pos = vector():set(-137.5683,0.0036,123.8512),
smart = "ros_smart_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros03_ros04"] = {
pos = vector():set(-196.8538,3.0381,68.4065),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros05_ros06"] = {
pos = vector():set(-211.6216,-0.0015,9.8376),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros05_ros06.1"] = {
pos = vector():set(-210.3275,-0.0004,9.9314),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros05_ros06.2"] = {
pos = vector():set(-211.0420,-0.0011,10.7245),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros06_ros05"] = {
pos = vector():set(-212.0351,8.8153,9.2077),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros06_ros05.1"] = {
pos = vector():set(-212.5222,8.6005,8.4991),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros06_ros05.2"] = {
pos = vector():set(-212.6854,8.8162,9.5271),
smart = "ros_smart_stalker_killers1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros07_ros08"] = {
pos = vector():set(-172.6166,-0.0011,60.7795),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros07_ros08.1"] = {
pos = vector():set(-171.1199,-0.0027,61.0932),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros07_ros08.2"] = {
pos = vector():set(-172.9888,-0.0005,62.2433),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros07_ros08.3"] = {
pos = vector():set(-171.8293,-3.9115,62.2001),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros08_ros07"] = {
pos = vector():set(-188.0054,17.6997,75.3117),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros08_ros07.1"] = {
pos = vector():set(-188.5492,17.6990,75.2511),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
},
["lc_ros08_ros07.2"] = {
pos = vector():set(-186.6996,17.6995,74.1847),
smart = "ros_smart_snork1",
spot = "level_changer_spot_mini",
hint = "space_restrictor_to_rostok_desc",
}
}
for sec,v in pairs(lc_pool) do
local se = get_story_se_item(sec)
if not (se) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
se = alife():create(sec,pos,vid,gid)
end
if (se.position:distance_to_sqr(v.pos) > 0.1) then
local pos = v.pos
local vid = level.vertex_id(pos)
local gid = SIMBOARD.smarts_by_names[v.smart].m_game_vertex_id
TeleportObject(se.id,pos,vid,gid)
end
if (level.map_has_object_spot(se.id,v.spot) == 0) then
level.map_add_object_spot_ser(se.id,v.spot,game.translate_string(v.hint))
end
end
end
function check_name(actor,obj,p)
return p and p[1] and obj and string.find(obj:name(),p[1]) and true
end
function teleport_actor(actor,obj)
local p = {
["lc_ros01_ros02"] = {
pos = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
w_p = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
smart = "ros_smart_killers1",
},
["lc_ros01_ros02.1"] = {
pos = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
w_p = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
smart = "ros_smart_killers1",
},
["lc_ros01_ros02.2"] = {
pos = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
w_p = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
smart = "ros_smart_killers1",
},
["lc_ros01_ros02.3"] = {
pos = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
w_p = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01.1"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01.2"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01.3"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01.4"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros02_ros01.5"] = {
pos = vector():set(-137.00665283203, 0.0017983913421631, 124.59739685059),
w_p = vector():set(-136.99494934082, -0.0014290809631348, 122.18569946289),
smart = "ros_smart_killers1",
},
["lc_ros03_ros04"] = {
pos = vector():set(-196.85385131836, 3.0381197929382, 68.406555175781),
w_p = vector():set(-196.1629486084, 0.062152981758118, 69.714248657227),
smart = "ros_smart_snork1",
},
["lc_ros05_ros06"] = {
pos = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
w_p = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
smart = "ros_smart_stalker_killers1",
},
["lc_ros05_ros06.1"] = {
pos = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
w_p = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
smart = "ros_smart_stalker_killers1",
},
["lc_ros05_ros06.2"] = {
pos = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
w_p = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
smart = "ros_smart_stalker_killers1",
},
["lc_ros06_ros05"] = {
pos = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
w_p = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
smart = "ros_smart_stalker_killers1",
},
["lc_ros06_ros05.1"] = {
pos = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
w_p = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
smart = "ros_smart_stalker_killers1",
},
["lc_ros06_ros05.2"] = {
pos = vector():set(-212.22702026367, 8.8150157928467, 8.7844772338867),
w_p = vector():set(-211.20606994629, -0.0010014176368713, 10.295828819275),
smart = "ros_smart_stalker_killers1",
},
["lc_ros07_ros08"] = {
pos = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
w_p = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
smart = "ros_smart_snork1",
},
["lc_ros07_ros08.1"] = {
pos = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
w_p = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
smart = "ros_smart_snork1",
},
["lc_ros07_ros08.2"] = {
pos = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
w_p = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
smart = "ros_smart_snork1",
},
["lc_ros07_ros08.3"] = {
pos = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
w_p = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
smart = "ros_smart_snork1",
},
["lc_ros08_ros07"] = {
pos = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
w_p = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
smart = "ros_smart_snork1",
},
["lc_ros08_ros07.1"] = {
pos = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
w_p = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
smart = "ros_smart_snork1",
},
["lc_ros08_ros07.2"] = {
pos = vector():set(-188.33070373535, 17.697116851807, 74.735275268555),
w_p = vector():set(-172.27548217773, -0.00015679001808167, 61.4404296875),
smart = "ros_smart_snork1",
},
}
local sec = obj and obj:section()
local v = sec and p[sec]
if (v and v.w_p and v.pos and v.smart) then
db.actor:set_actor_position(v.w_p)
end
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
@@ -0,0 +1,119 @@
local dynamic_object_storage = {}
function dynamic_object(actor,obj,p)
local ini = p and p[1] and ini_file(p[1])
local smart_name = ini and ini:r_string_ex("dynamic_object_configs","smart")
local smart = smart_name and SIMBOARD.smarts_by_names[smart_name]
if not (smart) then
return
end
if not (dynamic_object_storage[smart_name]) then
dynamic_object_storage[smart_name] = {}
end
local lst = dynamic_object_storage[smart_name]
local n = ini:line_count("exclusive")
for k=0,n-1 do
local r,i,v = ini:r_line("exclusive",k)
local s = get_object_config(v)
if (i and s) then
local idx = lst[i]
local sec = s.sec
local pos = s.pos
local ang = s.ang
local con = s.con and ini:r_string_to_condlist("dynamic_object_configs",s.con,"true")
if (xr_logic.pick_section_from_condlist(db.actor,obj,con) == "true") then
local se = idx and tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and string.find(se:name(),sec)) then
-- Correct. Update object.
se.position = vector():set(pos)
se.angle = vector():set(ang)
else
-- Wrong object or doesn't exit. Try to delete the old object and create a new one.
if (se and idx.sec and string.find(se:name(),idx.sec)) then
alife_release(se)
end
local new_se = alife():create(sec,pos,smart.m_level_vertex_id,smart.m_game_vertex_id)
if (new_se) then
new_se.angle = vector():set(ang)
lst[i] = {id = tonumber(new_se.id),sec = tostring(sec)}
--printf("GhenTuong: dynamic_object create %s [%s]",new_se.id,new_se:name())
end
end
else
if (idx) then
local se = tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and idx.sec and string.find(se:name(),idx.sec)) then
--printf("GhenTuong: dynamic_object delete %s [%s]",se.id,se:name())
alife_release(se)
end
lst[i] = nil
end
end
end
end
for i,idx in pairs(lst) do
if (i and idx) then
if not (ini:line_exist("exclusive",i)) then
local se = idx and tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and idx.sec and string.find(se:name(),idx.sec)) then
--printf("GhenTuong: dynamic_object delete %s [%s]",se.id,se:name())
alife_release(se)
end
lst[i] = nil
end
else
lst[i] = nil
end
end
end
--[[
if not (ini:section_exist("exclusive") and ini:line_exist("exclusive",i)) then
return
end
local v = ini:r_string_ex("exclusive",i)
--]]
function get_object_config(v)
local str = v and str_explode(v,"|")
local sec = str[1] and (str[1] ~= "") and (str[1] ~= "nil") and tostring(str[1])
local tp = str[2] and str_explode(str[2],",") or nil
local td = str[3] and str_explode(str[3],",") or nil
local pox = tp and tonumber(tp[1])
local poy = tp and tonumber(tp[2])
local poz = tp and tonumber(tp[3])
local rox = td and tonumber(td[1]) and math.rad(tonumber(td[1]))
local roy = td and tonumber(td[2]) and math.rad(tonumber(td[2]))
local roz = td and tonumber(td[3]) and math.rad(tonumber(td[3]))
local con = str[4] or "nil"
if not (pox and poy and poz and rox and roy and roz and con) then
return
end
return {sec = sec, pos = vector():set(pox,poy,poz), ang = vector():set(rox,roy,roz), con = con}
end
function get_object(smart_name,index)
local idx = dynamic_object_storage_loaded and dynamic_object_storage[smart_name] and dynamic_object_storage[smart_name][index]
return idx and {id = tonumber(idx.id),sec = tostring(idx.sec)}
end
function save_state(m_data)
m_data.xr_dynamic_object_storage = dynamic_object_storage
end
function load_state(m_data)
dynamic_object_storage = m_data.xr_dynamic_object_storage or {}
end
function on_game_start()
RegisterScriptCallback("save_state",save_state)
RegisterScriptCallback("load_state",load_state)
end