Various Changes; Updated and Added Mods
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
[lc_extra_level_transition_base]
|
||||
GroupControlSection = spawn_group
|
||||
$spawn = "physics\object"
|
||||
$prefetch = 8
|
||||
class = O_PHYSIC
|
||||
remove_time = 60
|
||||
visual = dynamics\light\light_signal.ogf
|
||||
fixed_bones = link
|
||||
script_binding = bind_physic_object.init
|
||||
custom_data = scripts\lc_extra_level_transitions.ltx
|
||||
|
||||
; Extra items can be included by naming them items_extra_level_transitions_*
|
||||
; For example,items_extra_level_transitions_cordon.ltx
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
[lc_cordon_south_darkscape_collapsed_tunnel]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ; mandatory field
|
||||
story_id = lc_cordon_south_darkscape_collapsed_tunnel ; story_id, without it the item wont be added
|
||||
pos = -59,-30,-477 ; position of item
|
||||
gvid = 449 ; Gvid of item
|
||||
spot = level_changer_right ; texture to use for spot on the map
|
||||
hint = esc_space_restrictor_to_darkscape_descr ; string id for hint description, defined in xml files
|
||||
to_pos = 513.7,-1.5,-420.8 ; position where to teleport actor
|
||||
to_gvid = 1119 ; Gvid where to teleport actor
|
||||
; dir = 0,60,0 ;; actor facing
|
||||
; trigger_radius = 1.2 ;; Radius to trigger transition (default is 6)
|
||||
|
||||
[lc_darkscape_collapsed_tunnel_cordon_south]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ; mandatory field
|
||||
story_id = lc_darkscape_collapsed_tunnel_cordon_south
|
||||
pos = 520.17,-1.35,-429.54
|
||||
gvid = 1119
|
||||
spot = level_changer_down
|
||||
hint = ds_space_restrictor_to_escape_descr
|
||||
to_pos = -64,-29,-457
|
||||
to_gvid = 449
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
[lc_limansk_river_jupiter_bandit_base]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ; mandatory field
|
||||
story_id = lc_limansk_river_jupiter_bandit_base ; story_id, without it the item wont be added
|
||||
pos = 68.83,-7,-15.85 ; position of item
|
||||
gvid = 2440 ; Gvid of item
|
||||
spot = level_changer_up_right ; texture to use for spot on the map
|
||||
hint = space_restrictor_to_jupiter_desc ; string id for hint description, defined in xml files
|
||||
to_pos = -446,0,-345.2 ; position where to teleport actor
|
||||
to_gvid = 4818 ; Gvid where to teleport actor
|
||||
|
||||
[lc_jupiter_bandit_base_limansk_river]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ; mandatory field
|
||||
story_id = lc_jupiter_bandit_base_limansk_river
|
||||
pos = -455.8,0,-345.9
|
||||
gvid = 4818
|
||||
spot = level_changer_down_left
|
||||
hint = space_restrictor_to_limansk_desc
|
||||
to_pos = 60.1,-7,-5.51
|
||||
to_gvid = 2440
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
; Yantar <-> Dead City
|
||||
[lc_yantar_west_dead_city_west]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ;; mandatory field
|
||||
story_id = lc_yantar_west_dead_city_west ;; story_id, without it the item wont be added
|
||||
pos = -219.6,6.7,-48.95 ;; position of item
|
||||
gvid = 2307 ;; Gvid of item
|
||||
spot = level_changer_up ;; texture to use for spot on the map
|
||||
hint = space_restrictor_to_deadcity_desc ;; string id for hint description, defined in xml files
|
||||
to_pos = -226,10.01,-181.52 ;; position where to teleport actor
|
||||
to_gvid = 2318 ;; Gvid where to teleport actor
|
||||
|
||||
[lc_dead_city_west_yantar_west]:lc_extra_level_transition_base
|
||||
lc_extra_level_transition = true ;; mandatory field
|
||||
story_id = lc_yantar_west_dead_city_west ;; story_id, without it the item wont be added
|
||||
pos = -234.17,9.86,-190.01 ;; position of item
|
||||
gvid = 2318 ;; Gvid of item
|
||||
spot = level_changer_down ;; texture to use for spot on the map
|
||||
hint = space_restrictor_to_yantar_desc ;; string id for hint description, defined in xml files
|
||||
to_pos = -222.64,7.48,-62.54 ;; position where to teleport actor
|
||||
dir = 0,60,0 ;; actor facing
|
||||
to_gvid = 2307 ;; Gvid where to teleport actor
|
||||
@@ -0,0 +1,8 @@
|
||||
[logic]
|
||||
active = ph_idle@idle
|
||||
|
||||
[ph_idle@idle]
|
||||
on_info = {=is_actor_inside_lc} %=script(lc_extra_transitions:handle_nearby_actor)% ph_idle@wait
|
||||
|
||||
[ph_idle@wait]
|
||||
on_timer = 5000| ph_idle@idle
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
|
||||
<string_table>
|
||||
|
||||
<string id="ui_mcm_extra_level_transitions_title">
|
||||
<text>Extra Level Transitions</text>
|
||||
</string>
|
||||
<string id="ui_mcm_menu_extra_level_transitions">
|
||||
<text>Level Transitions</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_enable_time_advance">
|
||||
<text>Enable Time Advance</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_enable_time_advance_desc">
|
||||
<text>Time will be advanced on level transitions</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_delete_level_transitions">
|
||||
<text>Delete Level Transitions</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_delete_level_transitions_desc">
|
||||
<text>Extra level transitions will be deleted from the game. The option is intended for safe removal of the mod</text>
|
||||
</string>
|
||||
|
||||
</string_table>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
|
||||
<string_table>
|
||||
|
||||
<string id="ui_mcm_extra_level_transitions_title">
|
||||
<text>Äîïîëíèòåëüíûå ïåðåõîäû óðîâíåé</text>
|
||||
</string>
|
||||
<string id="ui_mcm_menu_extra_level_transitions">
|
||||
<text>Ïåðåõîäû óðîâíåé</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_enable_time_advance">
|
||||
<text>Âêëþ÷èòü çàòðàòó âðåìåíè</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_enable_time_advance_desc">
|
||||
<text>Ïðè èñïîëüçîâàíèè íîâûõ ïåðåõîäîâ áóäåò òðàòèòüñÿ âðåìÿ íà ïåðåìåùåíèå</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_delete_level_transitions">
|
||||
<text>Óäàëèòü ïåðåõîäû óðîâíåé</text>
|
||||
</string>
|
||||
<string id="ui_mcm_extra_level_transitions_delete_level_transitions_desc">
|
||||
<text>Äîïîëíèòåëüíûå ïåðåõîäû óðîâíåé áóäóò óäàëåíû èç èãðû. Îïöèÿ ïðåäíàçíà÷åíà äëÿ áåçîïàñíîãî óäàëåíèÿ ìîäà</text>
|
||||
</string>
|
||||
|
||||
</string_table>
|
||||
@@ -0,0 +1,245 @@
|
||||
-- UTILS
|
||||
-- Load the defaults
|
||||
local function load_defaults()
|
||||
local t = {}
|
||||
local op = lc_extra_transitions_mcm.op
|
||||
for i, v in ipairs(op.gr) do
|
||||
if v.def ~= nil then
|
||||
t[v.id] = v.def
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
local settings = load_defaults()
|
||||
|
||||
local function on_option_change()
|
||||
settings = load_defaults()
|
||||
if ui_mcm then
|
||||
for k, v in pairs(settings) do
|
||||
settings[k] = ui_mcm.get("extra_level_transitions/" .. k)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function str_coords_to_vector(str)
|
||||
local t = str_explode(str, ",")
|
||||
if #t < 3 then
|
||||
error("str_coords_to_vector, missing %s coords", 3 - #t)
|
||||
end
|
||||
return vector():set(tonumber(t[1]), tonumber(t[2]), tonumber(t[3]))
|
||||
end
|
||||
|
||||
-- Transitions
|
||||
lc_pool = (function()
|
||||
local res = {}
|
||||
ini_sys:section_for_each(function(section)
|
||||
if SYS_GetParam(1, section, "lc_extra_level_transition", false) and SYS_GetParam(0, section, "story_id") then
|
||||
local n = ini_sys:section_exist(section) and ini_sys:line_count(section) or 0
|
||||
if (n > 0) then
|
||||
res[section] = {}
|
||||
for i = 0,n-1 do
|
||||
local _,id,val = ini_sys:r_line(section,i,"","")
|
||||
res[section][id] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
return res
|
||||
end)()
|
||||
|
||||
local saved_spots = {}
|
||||
local change_triggered = false
|
||||
|
||||
local function find_save_spot(vid, gid)
|
||||
for k, v in pairs(saved_spots) do
|
||||
if v.vid == vid and
|
||||
v.gid == gid
|
||||
then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function xr_conditions.is_actor_inside_lc(actor, npc, p)
|
||||
local lc = actor:id() == AC_ID and npc or actor
|
||||
local d = SYS_GetParam(2, lc:section(), "trigger_radius", 6)
|
||||
d = d * d
|
||||
return npc:position():distance_to_sqr(actor:position()) <= d
|
||||
end
|
||||
|
||||
function actor_on_first_update()
|
||||
on_option_change()
|
||||
if ui_mcm and ui_mcm.get("extra_level_transitions/delete_level_transitions") then
|
||||
ui_mcm.set("extra_level_transitions/delete_level_transitions", false)
|
||||
end
|
||||
|
||||
for sec,v in pairs(lc_pool) do
|
||||
local se = get_story_se_item(sec)
|
||||
local pos = str_coords_to_vector(v.pos)
|
||||
local vid = level.vertex_id(pos)
|
||||
local gid = tonumber(v.gvid)
|
||||
|
||||
if not (se) then
|
||||
se = alife():create(sec,pos,vid,gid)
|
||||
end
|
||||
|
||||
if (se.position:distance_to_sqr(pos) > 0.1) then
|
||||
TeleportObject(se.id,pos,vid,gid)
|
||||
end
|
||||
|
||||
if saved_spots[se.id] and saved_spots[se.id].spot and level.map_has_object_spot(se.id,saved_spots[se.id].spot) ~= 0 then
|
||||
level.map_remove_object_spot(se.id, saved_spots[se.id].spot)
|
||||
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
|
||||
saved_spots[se.id] = {
|
||||
spot = v.spot,
|
||||
sec = sec,
|
||||
id = se.id,
|
||||
vid = vid,
|
||||
gid = gid,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function delete_level_transitions()
|
||||
if ui_mcm and ui_mcm.get("extra_level_transitions/delete_level_transitions") then
|
||||
ui_mcm.set("extra_level_transitions/delete_level_transitions", false)
|
||||
local sim = alife()
|
||||
for i = 1, 65534 do
|
||||
local obj = sim:object(i)
|
||||
if obj then
|
||||
local sec = obj:section_name()
|
||||
if lc_pool[sec] then
|
||||
sim:release(obj)
|
||||
if level.map_has_object_spot(obj.id,saved_spots[obj.id].spot) ~= 0 then
|
||||
level.map_remove_object_spot(obj.id, saved_spots[obj.id].spot)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
empty_table(saved_spots)
|
||||
end
|
||||
end
|
||||
|
||||
--global distance calculation
|
||||
function get_travel_cost(se_obj)
|
||||
if not se_obj then return end
|
||||
|
||||
local sim = alife()
|
||||
local actor = db.actor
|
||||
local closest_smart_id
|
||||
for name,smart in pairs( SIMBOARD.smarts_by_names ) do
|
||||
if simulation_objects.is_on_the_same_level(sim:actor(), smart) then
|
||||
local dist = smart.position:distance_to(actor:position())
|
||||
local smrt = SIMBOARD.smarts[smart.id]
|
||||
if (smrt) and (not closest_smart_id or (dist < closest_smart_id[1])) then
|
||||
closest_smart_id = { dist, smart.id }
|
||||
end
|
||||
end
|
||||
end
|
||||
local closest_smart = alife_object(closest_smart_id[2])
|
||||
local dist = math.sqrt(warfare.distance_to_xz_sqr(global_position.from(closest_smart), global_position.from(se_obj)))
|
||||
return dist
|
||||
end
|
||||
|
||||
function is_gvid_on_the_actor_level(gvid)
|
||||
return game_graph():vertex(alife():actor().m_game_vertex_id):level_id() == game_graph():vertex(gvid):level_id()
|
||||
end
|
||||
|
||||
function teleport_actor(actor,obj)
|
||||
local sec = obj and obj:section()
|
||||
local v = sec and lc_pool[sec]
|
||||
|
||||
if (v and v.to_pos and v.to_gvid and not change_triggered) then
|
||||
local pos = str_coords_to_vector(v.to_pos)
|
||||
local dir = v.dir and str_coords_to_vector(v.dir) or VEC_ZERO
|
||||
local vid = level.vertex_id(pos)
|
||||
local gid = tonumber(v.to_gvid)
|
||||
|
||||
if settings.enable_time_advance then
|
||||
-- local saved_spot = find_save_spot(vid, gid)
|
||||
-- local d = saved_spot and get_travel_cost(alife_object(saved_spot.id)) or 1000
|
||||
local d = math.random(800, 1600)
|
||||
local dist = math.floor(d / SYS_GetParam(2, "actor", "walk_accel", 11.5) * random_float(0.75, 1.25))
|
||||
local hours = math.floor(dist / 60)
|
||||
local minutes = dist % 60
|
||||
|
||||
printf("advance time by %s, %s, distance %s, speed %s", hours, minutes, d, dist)
|
||||
level.change_game_time(0, hours, minutes)
|
||||
surge_manager.get_surge_manager().time_forwarded = true
|
||||
psi_storm_manager.get_psi_storm_manager().time_forwarded = true
|
||||
level_weathers.get_weather_manager():forced_weather_change()
|
||||
end
|
||||
|
||||
change_triggered = true
|
||||
|
||||
if v.snd then
|
||||
utils_obj.play_sound(v.snd)
|
||||
end
|
||||
|
||||
if v.on_teleport then
|
||||
local condlist = xr_logic.parse_condlist(obj, obj:section(), "on_teleport", v.on_teleport)
|
||||
xr_logic.pick_section_from_condlist(actor, obj, condlist)
|
||||
end
|
||||
|
||||
if is_gvid_on_the_actor_level(gid) then
|
||||
level.add_pp_effector("sleep_fade.ppe", 1313, false)
|
||||
|
||||
CreateTimeEvent(0,"delay_travel",3,function()
|
||||
db.actor:set_actor_position(pos)
|
||||
db.actor:set_actor_direction((dir.y * 180) / math.pi)
|
||||
change_triggered = false
|
||||
return true
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
ChangeLevel(pos,vid,gid,dir,true)
|
||||
-- level.disable_input()
|
||||
end
|
||||
end
|
||||
|
||||
function handle_nearby_actor(actor, obj)
|
||||
local sec = obj and obj:section()
|
||||
local v = sec and lc_pool[sec]
|
||||
|
||||
if not v then return end
|
||||
if change_triggered then return end
|
||||
|
||||
-- Evaluate precondition before enabling transition
|
||||
if (v.precondition and v.precondition ~= "") then
|
||||
local precond_list = xr_logic.parse_condlist(obj, nil, "precondition", v.precondition)
|
||||
if (precond_list == "false") then
|
||||
return
|
||||
end
|
||||
if (actor and xr_logic.pick_section_from_condlist(actor, obj, precond_list) == "false") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if v.disable_dialog then
|
||||
teleport_actor(actor, npc)
|
||||
else
|
||||
local dialog = lc_extra_transitions_ui.create_dialog()
|
||||
dialog:SetObj(obj)
|
||||
dialog:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function save_state(m_data)
|
||||
m_data.lc_extra_transitions_saved_spots = saved_spots
|
||||
end
|
||||
|
||||
function load_state(m_data)
|
||||
saved_spots = m_data.lc_extra_transitions_saved_spots or {}
|
||||
end
|
||||
|
||||
function on_game_start()
|
||||
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
|
||||
RegisterScriptCallback("on_option_change", on_option_change)
|
||||
RegisterScriptCallback("on_option_change", delete_level_transitions)
|
||||
RegisterScriptCallback("save_state",save_state)
|
||||
RegisterScriptCallback("load_state",load_state)
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
op = {
|
||||
id = "extra_level_transitions", sh = true, gr = {
|
||||
{id = "banner", type = "slide", text = "ui_mcm_extra_level_transitions_title", size = {512, 50}, spacing = 20},
|
||||
{id = "enable_time_advance", type = "check", val = 1, def = false},
|
||||
{id = "delete_level_transitions", type = "check", val = 1, def = false},
|
||||
}
|
||||
}
|
||||
|
||||
function on_mcm_load()
|
||||
return op
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
-- basic dynamic msg_box
|
||||
-- alundaio
|
||||
|
||||
class "msg_box_ui" (CUIScriptWnd)
|
||||
function msg_box_ui:__init() super()
|
||||
self:SetWndRect(Frect():set(0,0,1024,768))
|
||||
self:SetAutoDelete(true)
|
||||
|
||||
self:InitCallBacks()
|
||||
self:OnMsgCancel()
|
||||
|
||||
self.message_box = CUIMessageBoxEx()
|
||||
self:Register(self.message_box, "msg_box")
|
||||
|
||||
self:InitCallBacks()
|
||||
self:InitControls()
|
||||
end
|
||||
|
||||
function msg_box_ui:Reset()
|
||||
self.obj = nil
|
||||
end
|
||||
|
||||
---@param obj game_object
|
||||
function msg_box_ui:SetObj(obj)
|
||||
-- Track nearby teleport space restrictor
|
||||
self.obj_id = obj:id()
|
||||
|
||||
-- Update text to indicate destination
|
||||
local next_level = game.translate_string(lc_extra_transitions.lc_pool[obj:section()].hint or "")
|
||||
local msg_str = game.translate_string("st_level_changer_descr")
|
||||
local str = strformat(msg_str, next_level)
|
||||
self.message_box:SetText(str)
|
||||
end
|
||||
|
||||
function msg_box_ui:Show()
|
||||
self.message_box:ShowDialog(true)
|
||||
end
|
||||
|
||||
function msg_box_ui:__finalize()
|
||||
end
|
||||
|
||||
function msg_box_ui:InitCallBacks()
|
||||
self:AddCallback("msg_box", ui_events.MESSAGE_BOX_OK_CLICKED, self.OnMsgOk, self)
|
||||
self:AddCallback("msg_box", ui_events.MESSAGE_BOX_CANCEL_CLICKED, self.OnMsgCancel, self)
|
||||
self:AddCallback("msg_box", ui_events.MESSAGE_BOX_YES_CLICKED, self.OnMsgOk, self)
|
||||
self:AddCallback("msg_box", ui_events.MESSAGE_BOX_NO_CLICKED, self.OnMsgCancel, self)
|
||||
end
|
||||
|
||||
function msg_box_ui:OnMsgOk()
|
||||
local obj = level.object_by_id(self.obj_id)
|
||||
if not obj then return end
|
||||
|
||||
lc_extra_transitions.teleport_actor(db.actor, obj)
|
||||
end
|
||||
|
||||
function msg_box_ui:OnMsgCancel()
|
||||
-- Teleport player away from space restrictor?
|
||||
-- Require grabbing some 'reject' position from config
|
||||
-- See ui_sr_teleport.script
|
||||
end
|
||||
|
||||
function msg_box_ui:InitControls()
|
||||
self.message_box:InitMessageBox("message_box_yes_no")
|
||||
end
|
||||
|
||||
function create_dialog()
|
||||
local ui = msg_box_ui()
|
||||
ui:Reset()
|
||||
return ui
|
||||
end
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
[General]
|
||||
gameName=stalkeranomaly
|
||||
modid=0
|
||||
version=d2024.3.25.0
|
||||
newestVersion=
|
||||
category="-1,"
|
||||
nexusFileStatus=1
|
||||
installationFile=Extra_Level_Transitions.4.zip
|
||||
repository=Nexus
|
||||
ignoredVersion=
|
||||
comments=
|
||||
notes=
|
||||
nexusDescription=
|
||||
url=
|
||||
hasCustomURL=false
|
||||
lastNexusQuery=
|
||||
lastNexusUpdate=
|
||||
nexusLastModified=2024-03-25T08:27:06Z
|
||||
nexusCategory=0
|
||||
converted=false
|
||||
validated=false
|
||||
color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0)
|
||||
tracked=0
|
||||
|
||||
[installedFiles]
|
||||
1\modid=0
|
||||
1\fileid=0
|
||||
size=1
|
||||
Reference in New Issue
Block a user