Added New Mods and Profiles Folders

This is a complete rebuild of the modpack, with all new mods and updates for 1.5.3 of Anomaly.
This commit is contained in:
2025-01-14 05:07:53 -05:00
parent 85c665b107
commit 376b4b9689
21217 changed files with 546254 additions and 0 deletions
@@ -0,0 +1,202 @@
; unchanged categories like drinks, medicine, weapons etc are added fully from vanilla
; things that we categorize manually are in this ltx
; Mutant Parts
[mut_1]
mutant_part_boar_leg
mutant_part_tushkano_head
mutant_part_tusk_boar
mutant_part_flesh_eye
mutant_part_fang_psevdodog
mutant_part_snork_leg
mutant_part_cat_thyroid
mutant_part_cat_claw
mutant_part_dog_liver
mutant_part_dog_heart
mutant_part_dog_tail
mutant_part_zombi_hand
[mut_2]
mutant_part_chimera_kogot
mutant_part_chimera_claw
mutant_part_psevdodog_tail
mutant_part_snork_mask
mutant_part_burer_hand
mutant_part_cat_tail
mutant_part_fracture_hand
mutant_part_lurker_tail
mutant_part_lurker_eye
mutant_part_psysucker_hand
mutant_part_heart_bloodsucker
[mut_3]
mutant_part_controller_glass
mutant_part_controller_hand
mutant_part_pseudogigant_hand
mutant_part_pseudogigant_eye
mutant_part_heart_chimera
mutant_part_krovosos_jaw
mutant_part_brain_burer
; Mutant Meat
[meat_1]
mutant_part_flesh_meat
mutant_part_boar_chop
mutant_part_dog_meat
mutant_part_psevdodog_meat
mutant_part_snork_hand
mutant_part_tushkano_meat
[meat_2]
mutant_part_chimera_meat
mutant_part_lurker_meat
mutant_part_krovosos_meat
mutant_part_psysucker_meat
; Mutant Hides
[hide_1]
hide_flesh
hide_pseudodog
hide_boar
hide_psy_dog
hide_lurker
[hide_2]
hide_bloodsucker
hide_psysucker
hide_chimera
hide_pseudogiant
hide_controller
hide_burer
; supplies additional (to exclude meat)
[xt_supplies]
sausage
breadold
device_pda_1
tomato
bread
beans
ration_ukr
ration_ru
mre
chili
chocolate
chocolate_p
conserva
corn
items_anm_dummy
kolbasa
mint
nuts
protein
tushonka
salmon
raisins
; junk artefacts
[arts_1]
af_black
af_dragon_eye
af_fire_loop
af_ball
af_fonar
af_tapeworm
af_moh
af_serofim
af_elektron
af_kogot
af_generator
af_black_angel
af_grapes
af_skull_miser
af_star_phantom
af_medallion
af_peas
af_kislushka
af_zhelch
af_sandstone
af_fountain
af_spaika
af_signet
af_repei
af_bat
af_sun
af_ear
af_chelust
af_atom
af_lighthouse
af_cell
af_cocoon
; tier 2 artefacts
[arts_2]
af_itcher
af_pin
af_blood
af_mincer_meat
af_electra_sparkler
af_sponge
af_cristall_flower
af_lobster_eyes
af_medusa
af_night_star
af_dummy_glassbeads
af_dummy_battery
af_soul
; tier 3 artefacts
[arts_3]
af_cristall
af_bracelet
af_ring
af_electra_moonlight
af_vyvert
af_empty
af_gravi
af_eye
af_dummy_dummy
af_fuzz_kolobok
; tier 4 and 5 artefacts
[arts_4]
af_fireball
af_baloon
af_electra_flash
af_black_spray
af_full_empty
af_gold_fish
af_fire
af_ice
af_glass
af_death_lamp
af_vaselisk
af_geliy
af_gimlet
;t5
af_compass
af_oasis_heart
af_monolith
; attachments
[attachs]
af_surge
af_frames
af_grid
af_freon
af_cooler
af_kevlar
af_plates
af_camelbak
af_surge_up
af_frames_up
af_grid_up
af_freon_up
af_cooler_up
af_kevlar_up
af_plates_up
af_camelbak_up
@@ -0,0 +1,54 @@
;-- don't know zaton/jupiter npcs so didnt include them
[trader]
m_trader ;; cordon sidorovich
esc_main_base_trader_mlr ;; cordon loris
esc_3_16_military_trader ;; cordon army
baraholka_trader ;; garbage stalker
baraholka_trader_night ;; garbage stalker
dasc_trade_mlr ;; darkscape stalker
bar_visitors_barman_stalker_trader ;; bar barkeep
bar_dolg_general_petrenko_stalker ;; bar duty
agr_smart_terrain_1_6_army_trader_stalker ;; agroprom army
val_smart_terrain_7_4_bandit_trader_stalker ;; dark valley bandit
trucks_cemetery_bandit_trader ;; truck cemetery bandit
mil_smart_terrain_7_10_freedom_trader_stalker ;; warehouses freedom
cit_killers_merc_trader_stalker ;; dead city merc
pri_monolith_monolith_trader_stalker ;; pripyat monolith
trader_monolith_kbo ;; monolith dont know who this is
trader_pri_a15_mlr ;; outskirts monolith
pri_special_trader_mlr ;; outskirts merc
monolith_bridge_trader_mlr ;; red forest monolith?
red_greh_trader ;; red forest sin
[mechanic]
esc_smart_terrain_5_7_loner_mechanic_stalker
army_south_mechan_mlr
dasc_tech_mlr
mar_base_stalker_tech
agr_smart_terrain_1_6_army_mechanic_stalker
bar_visitors_stalker_mechanic
val_smart_terrain_7_3_bandit_mechanic_stalker
trucks_cemetery_bandit_mechanic
mechanic_army_yan_mlr
mil_smart_terrain_7_7_freedom_mechanic_stalker
cit_killers_merc_mechanic_stalker
merc_pri_a18_mech_mlr_squad
pri_a16_mech_mlr
mechanic_monolith_kbo
pri_monolith_monolith_mechanic_stalker
red_greh_tech
[medic]
mar_smart_terrain_base_doctor
agr_1_6_medic_army_mlr
bar_dolg_medic
bandit_main_base_medic_mlr
mil_freedom_medic
cit_killers_merc_medic_stalker
[barman]
mar_base_stalker_barmen
agr_1_6_barman_army_mlr
yan_povar_army_mlr
mil_freedom_barman_mlr
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<!-- Categories -->
<string id="xcvb_trade_mut_1">
<text>Mutant parts (common)</text>
</string>
<string id="xcvb_trade_mut_2">
<text>Mutant parts (uncommon)</text>
</string>
<string id="xcvb_trade_mut_3">
<text>Mutant parts (rare)</text>
</string>
<string id="xcvb_trade_meat_1">
<text>Meat (common)</text>
</string>
<string id="xcvb_trade_meat_2">
<text>Meat (rare)</text>
</string>
<string id="xcvb_trade_hide_1">
<text>Hides (common)</text>
</string>
<string id="xcvb_trade_hide_2">
<text>Hides (rare)</text>
</string>
<string id="xcvb_trade_arts_1">
<text>Artefacts (junk)</text>
</string>
<string id="xcvb_trade_arts_2">
<text>Artefacts (common)</text>
</string>
<string id="xcvb_trade_arts_3">
<text>Artefacts (uncommon)</text>
</string>
<string id="xcvb_trade_arts_4">
<text>Artefacts (rare)</text>
</string>
<string id="xcvb_trade_xt_weapons">
<text>Weapon</text>
</string>
<string id="xcvb_trade_xt_armors">
<text>Armor</text>
</string>
<string id="xcvb_trade_xt_repair">
<text>Repair</text>
</string>
<string id="xcvb_trade_xt_supplies">
<text>Supplies</text>
</string>
<string id="xcvb_trade_xt_med">
<text>Medicine</text>
</string>
<string id="xcvb_trade_attachs">
<text>Attachments</text>
</string>
<!-- for HUD -->
<string id="xcvb_trade_discount">
<text>Discount</text>
</string>
<string id="xcvb_trade_sell_to">
<text>Sell to trader</text>
</string>
<string id="xcvb_trade_buy_from">
<text>Buy from trader</text>
</string>
<string id="xcvb_trade_group">
<text>group:</text>
</string>
<string id="xcvb_trade_buy_krug">
<text></text>
</string>
<!-- message -->
<string id="xcvb_trade_trade">
<text>(Trade)</text>
</string>
<string id="xcvb_trade_hi">
<text>Stalkers, I've got new discounts:</text>
</string>
<string id="xcvb_trade_stay">
<text>those will stay for the next</text>
</string>
<string id="xcvb_trade_day">
<text>day.</text>
</string>
<string id="xcvb_trade_days">
<text>days.</text>
</string>
<string id="xcvb_trade_buy_msg">
<text>Selling</text>
</string>
<string id="xcvb_trade_sell_msg">
<text>Buying</text>
</string>
</string_table>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="windows-1251"?>
<!--
MCM
-->
<string_table>
<string id="ui_mcm_xcvb_trade_title">
<text>Dynamic discounts</text>
</string>
<string id="ui_mcm_menu_xcvb_trade">
<text>Dynamic discounts</text>
</string>
<!-- Main -->
<string id="ui_mcm_xcvb_trade_min_event_time">
<text>Min event duration (days)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_event_time">
<text>Max event duration (days)</text>
</string>
<string id="ui_mcm_xcvb_trade_min_event_disc">
<text>Min event discount (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_event_disc">
<text>Max event discount (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_disc_amount">
<text>Max amount of discounts per event</text>
</string>
<string id="ui_mcm_xcvb_trade_max_disc_amount_desc">
<text>Max amount of groups that can get dynamic discount when the event fires.</text>
</string>
<string id="ui_mcm_xcvb_trade_msg_threshold">
<text>Event message threshold (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_msg_threshold_desc">
<text>You will be notified of new discount only if it will be higher than this threshold (or lower than negative threshold).</text>
</string>
<string id="ui_mcm_xcvb_trade_dbgx">
<text>debug</text>
</string>
</string_table>
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<!-- Categories -->
<string id="xcvb_trade_mut_1">
<text>×àñòè ìóòàíòîâ (îáû÷íûå)</text>
</string>
<string id="xcvb_trade_mut_2">
<text>×àñòè ìóòàíòîâ (íåîáû÷íûå)</text>
</string>
<string id="xcvb_trade_mut_3">
<text>×àñòè ìóòàíòîâ (ðåäêèå)</text>
</string>
<string id="xcvb_trade_meat_1">
<text>Ìÿñî (îáû÷íîå)</text>
</string>
<string id="xcvb_trade_meat_2">
<text>Ìÿñî (ðåäêîå)</text>
</string>
<string id="xcvb_trade_hide_1">
<text>Øêóðû (îáû÷íûå)</text>
</string>
<string id="xcvb_trade_hide_2">
<text>Øêóðû (ðåäêèå)</text>
</string>
<string id="xcvb_trade_arts_1">
<text>Àðòåôàêòû (ìóñîðíûå)</text>
</string>
<string id="xcvb_trade_arts_2">
<text>Àðòåôàêòû (îáû÷íûå)</text>
</string>
<string id="xcvb_trade_arts_3">
<text>Àðòåôàêòû (íåîáû÷íûå)</text>
</string>
<string id="xcvb_trade_arts_4">
<text>Àðòåôàêòû (ðåäêèå)</text>
</string>
<string id="xcvb_trade_xt_weapons">
<text>Îðóæèå</text>
</string>
<string id="xcvb_trade_xt_armors">
<text>Áðîíÿ</text>
</string>
<string id="xcvb_trade_xt_repair">
<text>Ðåìîíò</text>
</string>
<string id="xcvb_trade_xt_supplies">
<text>Ïðèïàñû</text>
</string>
<string id="xcvb_trade_xt_med">
<text>Ìåäèöèíà</text>
</string>
<string id="xcvb_trade_attachs">
<text>Êðåïëåíèÿ</text>
</string>
<!-- for HUD -->
<string id="xcvb_trade_discount">
<text>Ñêèäêè</text>
</string>
<string id="xcvb_trade_sell_to">
<text>Ïðîäàæà òîðãîâöó</text>
</string>
<string id="xcvb_trade_buy_from">
<text>Ïîêóïêà ó òîðãîâöà</text>
</string>
<string id="xcvb_trade_group">
<text>ãðóïïà:</text>
</string>
<string id="xcvb_trade_buy_krug">
<text></text>
</string>
<!-- message -->
<string id="xcvb_trade_trade">
<text>(Òîðãîâëÿ)</text>
</string>
<string id="xcvb_trade_hi">
<text>Ñòàëêåðû, ó ìåíÿ íîâûå ñêèäêè:</text>
</string>
<string id="xcvb_trade_stay">
<text>îíè îñòàíóòñÿ íà</text>
</string>
<string id="xcvb_trade_day">
<text>äåíü.</text>
</string>
<string id="xcvb_trade_days">
<text>äíåé.</text>
</string>
<string id="xcvb_trade_buy_msg">
<text>Ïðîäàþ</text>
</string>
<string id="xcvb_trade_sell_msg">
<text>Ïîêóïàþ</text>
</string>
</string_table>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="windows-1251"?>
<!--
MCM
-->
<string_table>
<string id="ui_mcm_xcvb_trade_title">
<text>Äèíàìè÷åñêèå ñêèäêè</text>
</string>
<string id="ui_mcm_menu_xcvb_trade">
<text>Äèíàìè÷åñêèå ñêèäêè</text>
</string>
<!-- Main -->
<string id="ui_mcm_xcvb_trade_min_event_time">
<text>Ìèí. äëèòåëüíîñòü ýâåíòà (äíè)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_event_time">
<text>Ìàêñ. äëèòåëüíîñòü ýâåíòà (äíè)</text>
</string>
<string id="ui_mcm_xcvb_trade_min_event_disc">
<text>Ìèí. ñêèäêà ýâåíòà (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_event_disc">
<text>Ìàêñ. ñêèäêà ýâåíòà (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_max_disc_amount">
<text>Ìàêñ. êîëè÷åñòâî ñêèäîê ýâåíòà</text>
</string>
<string id="ui_mcm_xcvb_trade_max_disc_amount_desc">
<text>Ìàêñèìàëüíîå êîëè÷åñòâî ãðóïï, êîòîðûå ìîãóò ïîëó÷èòü äèíàìè÷åñêóþ ñêèäêó ïðè ýâåíòå.</text>
</string>
<string id="ui_mcm_xcvb_trade_msg_threshold">
<text>Ïîðîã ñîîáùåíèÿ ýâåíòà (%)</text>
</string>
<string id="ui_mcm_xcvb_trade_msg_threshold_desc">
<text>Âû áóäåòå óâåäîìëåíû î íîâîé ñêèäêå òîëüêî â òîì ñëó÷àå, åñëè îíà áóäåò âûøå ýòîãî ïîðîãà (èëè íèæå îòðèöàòåëüíîãî ïîðîãà).</text>
</string>
<string id="ui_mcm_xcvb_trade_dbgx">
<text>äåáàã</text>
</string>
</string_table>
@@ -0,0 +1 @@
#include "ui\ui_xcvb_trade_16.xml"
@@ -0,0 +1,31 @@
<w>
<!-- Hover -->
<hover_discount x="75" y="30" width="50" height="25" check_mode="0">
<text x="0" y="0" complex_mode="1" align="l" font="graffiti22">xcvb_trade_discount</text>
<texture r="190" g="0" b="0" a="0">none.dds</texture>
</hover_discount>
<buy_bg x="210" y="25" width="300" height="400" stretch="1">
<text x="0" y="0" complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture r="10" g="10" b="10" a="230">none.dds</texture>
<buy_header x="0" y="25" width="300" height="25" stretch="1">
<text x="0" y="0" complex_mode="1" align="c" font="graffiti22">xcvb_trade_buy_from</text>
<texture r="50" g="50" b="50" a="190">none.dds</texture>
</buy_header>
</buy_bg>
<sell_bg x="515" y="25" width="300" height="400" stretch="1">
<text x="0" y="0" complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture r="10" g="10" b="10" a="230">none.dds</texture>
<sell_header x="0" y="25" width="300" height="25" stretch="1">
<text x="0" y="0" complex_mode="1" align="c" font="graffiti22">xcvb_trade_sell_to</text>
<texture r="50" g="50" b="50" a="190">none.dds</texture>
</sell_header>
</sell_bg>
</w>
@@ -0,0 +1,541 @@
local cur_npc
local met_traders = {}
local items_list = {}
local min_event_duration = xcvb_trade_mcm.get_config("min_event_time")
local max_event_duration = xcvb_trade_mcm.get_config("max_event_time")
local min_event_discount = xcvb_trade_mcm.get_config("min_event_disc")
local max_event_discount = xcvb_trade_mcm.get_config("max_event_disc")
local max_discounts_amount = xcvb_trade_mcm.get_config("max_disc_amount")
local message_threshold = xcvb_trade_mcm.get_config("msg_threshold")
local gt = game.translate_string
local ctime_to_t = utils_data.CTime_to_table
local t_to_ctime = utils_data.CTime_from_table
local debugx = xcvb_trade_mcm.get_config("dbgx")
--[[
item types:
mutant_parts (common, uncommon, rare): mut_1, mut_2, mut_3
meat (common, rare): meat_1, meat_2
hides (common, rare): hide_1, hide_2
artefacts (junk, t2 common, t3 uncommon, t4+ rare): arts_1, arts_2, arts_3, arts_4
weapons (+ammo): xt_weapons
armors (+helmets): xt_armors
repair/details: xt_repair
supplies/food/drinks: xt_supplies
medicine: xt_med
attachments: attachs
--]]
-- npc with section in table will use their own values
-- if npc section isnt in table - they will use shared group from "xcvb_trader_groups.ltx" (trader, mechanic etc) if they are found in it
-- sell = sell to npc, buy = buy from npc, discount values in %
-- value here is base discount for these items, value of 0 means no base discount but still possible to get an event discount
-- mut_1, mut_2, mut_3, meat_1, meat_2, hide_1, hide_2, arts_1, arts_2, arts_3, arts_4, xt_weapons, xt_armors, xt_repair, xt_supplies, xt_med
local traders_t = {
------- unspecified traders/mechs/medics/barmans -------
["trader"] = {
sell = { mut_1 = 15, mut_2 = 15, hide_1 = 15, arts_1 = 15, arts_2 = 15, attachs = 0 },
buy = { xt_supplies = -15, xt_weapons = 0, xt_armors = 0, attachs = 0 },
},
["mechanic"] = {
sell = { xt_weapons = -10, xt_armors = -10, xt_repair = -10 },
buy = { xt_repair = -15 },
},
["medic"] = {
sell = { xt_med = -10 },
buy = { xt_med = -15 },
},
["barman"] = {
sell = { meat_1 = 30 },
buy = { xt_supplies = -25 },
},
------- specified traders -------
-- Sidorovich cordon
["m_trader"] = {
sell = { mut_1 = 15, mut_2 = 15, hide_1 = 15, arts_1 = 15, arts_2 = 15 },
buy = { xt_supplies = -15, xt_weapons = 0, xt_armors = 0 },
},
-- Loris cordon
["esc_main_base_trader_mlr"] = {
sell = { mut_1 = 15, mut_2 = 15, hide_1 = 15, arts_1 = 15, arts_2 = 15 },
buy = { xt_supplies = -15, xt_weapons = 0, xt_armors = 0 },
},
-- Butcher garbage
["hunter_gar_trader"] = {
sell = { mut_1 = 30, mut_2 = 30, meat_1 = 30, hide_1 = 30 },
buy = { xt_supplies = -25, xt_weapons = 0, xt_armors = 0 },
},
-- Spore swamp
["mar_base_owl_stalker_trader"] = {
sell = { mut_1 = 15, mut_2 = 15, hide_1 = 20, arts_1 = 0, arts_2 = 20, arts_3 = 20, attachs = 0 },
buy = { xt_supplies = -15, xt_weapons = 0, xt_armors = 0, attachs = 0 },
},
-- Barman bar
["bar_visitors_barman_stalker_trader"] = {
sell = { mut_1 = 15, mut_2 = 15, meat_1 = 15, hide_1 = 15, arts_1 = 15, arts_2 = 15 },
buy = { xt_supplies = -15, xt_weapons = 0, xt_armors = 0 },
},
-- Sakharov yantar
["yan_stalker_sakharov"] = {
sell = { mut_3 = 30, hide_2 = 30, arts_3 = 30, arts_4 = 30 },
buy = { xt_med = -25, xt_armors = 0, attachs = -15 },
},
}
---------------- cost change ----------------
function on_get_item_cost(kind, obj, profile, vanilla_cost, ret)
if not (cur_npc and met_traders[cur_npc] and met_traders[cur_npc].base and met_traders[cur_npc].event) then return end
if not (met_traders[cur_npc].base.sell and met_traders[cur_npc].event.sell) then return end
if not (met_traders[cur_npc].base.buy and met_traders[cur_npc].event.buy) then return end
-- find item group
local item_group
for group, t in pairs(items_list) do
if item_group then break end
for i = 1, #t do
if obj:section() == t[i] then
item_group = group
break
end
end
end
if not item_group then return end
-- sell to npc
local base_sell = met_traders[cur_npc].base.sell[item_group]
local event_sell = met_traders[cur_npc].event.sell[item_group] or 0
if profile.mode == 1 and base_sell then
local discount = (base_sell + event_sell) / 100
ret.new_cost = (ret.new_cost or vanilla_cost) * (1 + discount)
pr("sell %s, vanilla cost: %s || new_cost: %s", obj:section(), vanilla_cost, ret.new_cost)
end
-- buy from npc
local base_buy = met_traders[cur_npc].base.buy[item_group]
local event_buy = met_traders[cur_npc].event.buy[item_group] or 0
if profile.mode == 2 and base_buy then
local discount = (base_buy + event_buy) / 100
ret.new_cost = (ret.new_cost or vanilla_cost) * (1 + discount)
pr("buy %s, vanilla cost: %s || new_cost: %s", obj:section(), vanilla_cost, ret.new_cost)
end
end
---------------- open/close trade and manage traders ----------------
function open_trade(mode)
if mode ~= 2 then return end
local npc = mob_trade.GetTalkingNpc()
local is_trader = npc and trade_manager.get_trade_profile(npc:id(), "cfg_ltx")
if not is_trader then return end -- if not trader
local sec = npc:section()
if not get_trader_discount_table(sec) then printf("xcvb discounts trader sec: [%s] not found", sec) return end -- if npc section not found in discount table
-- add faction check if not enemy
local npc_comm = alife_object(npc:id()) and get_real_community(alife_object(npc:id()), "stalker")
if (not npc_comm) or (game_relations.is_factions_enemies(get_actor_true_community(), npc_comm)) then return end
-- if meet trader for first time
local cur_time = game.get_game_time()
if not met_traders[npc:id()] then
met_traders[npc:id()] = {}
met_traders[npc:id()].event = { sell = {}, buy = {} }
met_traders[npc:id()].event_start_time = ctime_to_t(cur_time)
met_traders[npc:id()].event_duration = 86400 -- set first event to appear after 1 day
local se_npc = alife_object(npc:id())
if se_npc then
met_traders[npc:id()].trader_name = se_npc:character_name()
met_traders[npc:id()].trader_icon = se_npc:character_icon()
end
end
-- update base table in case it was changed
met_traders[npc:id()].base = get_trader_discount_table(sec)
-- set local var
cur_npc = npc:id()
-- load all item sections that match group from traders_t (buy and sell) into new table IF its gonna lag too much
-- start HUD
CreateTimeEvent("delay_trade_hud_e", "delay_trade_hud_a", 0.2, function()
if not cur_npc then -- if was closed before this function
return true
end
activate_hud()
return true
end)
end
function close_trade(mode)
if cur_npc and mode ~= 2 then
cur_npc = nil
deactivate_hud()
end
end
local tmr = 0
function actor_on_update()
local tg = time_global()
if tg < tmr then return end
tmr = tg + 30000
-- do only when trading isnt opened
if cur_npc then return end
local cur_time = game.get_game_time()
for npc_id, t1 in pairs(met_traders) do
-- if its time to get new event
if cur_time:diffSec(t_to_ctime(t1.event_start_time)) > t1.event_duration then
-- reset current event
met_traders[npc_id].event = { sell = {}, buy = {} }
-- pick a few random keys (item groups) from "base" and set their new "event" values (thanks Longreed)
local change_count = max_discounts_amount
for i = 1, change_count do
local key = random_key_table(t1.base)
if key and (not is_empty(t1.base[key])) then
local val = random_key_table(t1.base[key])
met_traders[npc_id].event[key][val] = math.random(min_event_discount, max_event_discount)
end
end
-- set new event time and duration
met_traders[npc_id].event_start_time = ctime_to_t(cur_time)
local days_duration = math.random(min_event_duration, max_event_duration)
met_traders[npc_id].event_duration = 86400 * days_duration
-- compare vals from same "base" + "event" keys with message threshold and send message
local str = get_message_str(t1)
local trader_name = t1.trader_name
local trader_icon = t1.trader_icon
if str ~= "" then
local w_clr = utils_xml.get_color("pda_white")
local p_clr = utils_xml.get_color("d_purple")
local msg = p_clr .. gt("xcvb_trade_trade") .. " " .. w_clr .. gt("xcvb_trade_hi") .. " \\n" .. str .. " " .. w_clr .. gt("xcvb_trade_stay") .. " " .. days_duration .. " " .. gt("xcvb_trade_day" .. (days_duration > 1 and "s" or ""))
dynamic_news_helper.send_tip(msg, trader_name, nil, 20, trader_icon, "danger", "npc")
end
end
end
end
---------------- item footer ----------------
BuildFooter = ui_item.build_desc_footer
function ui_item.build_desc_footer(obj, sec, str)
str = str or gt(ini_sys:r_string_ex(sec, "description"))
if (not str) then return "" end
local item_group
for group, t in pairs(items_list) do
if item_group then break end
for i = 1, #t do
if sec == t[i] then
item_group = group
break
end
end
end
local p_clr = utils_xml.get_color("d_purple")
local w_clr = utils_xml.get_color("pda_white")
local def_clr = utils_xml.get_color("ui_gray_1")
if item_group then
local group_str = p_clr .. " " .. gt("xcvb_trade_buy_krug") .. " " .. def_clr .. gt("xcvb_trade_group") .. " " .. w_clr .. gt("xcvb_trade_" .. item_group) .. "\\n \\n" .. def_clr
return BuildFooter(obj, sec, str) .. group_str
end
return BuildFooter(obj, sec, str)
end
---------------- utils ----------------
function get_trader_discount_table(npc_sec)
if not npc_sec then return end
if traders_t[npc_sec] then
return traders_t[npc_sec]
end
local ret_t
local ltx = ini_file("plugins\\xcvb_trader_groups.ltx")
ltx:section_for_each(function(sec)
local n = ltx:line_count(sec)
for i = 0, n - 1 do
result, id, value = ltx:r_line_ex(sec, i, "", "")
if npc_sec == id and traders_t[sec] then
ret_t = traders_t[sec]
break
end
end
end)
return ret_t
end
local furniture = {
["esc_m_trader"] = true,
["red_m_lesnik"] = true
}
local blacklisted_comms = {
["trader"] = true,
["monster"] = true
}
function get_real_community(se_obj, default)
if se_obj.name and se_obj:name() and furniture[se_obj:name()] then
return default
end
local community = se_obj.community and se_obj:community()
if (not community) then return default end
if not blacklisted_comms[community] then
return community
end
local squad_community = get_object_squad(se_obj) and get_object_squad(se_obj):get_squad_community()
if not blacklisted_comms[squad_community] then
return squad_community
else
return default
end
end
function categorize_items()
local categories = {
["Items (Drink)"] = "xt_supplies",
["Items (Tool)"] = "xt_supplies",
["Items (Medical)"] = "xt_med",
["Items (Repair)"] = "xt_repair",
["Items (Parts)"] = "xt_repair",
["Weapons (Ammo)"] = "xt_weapons",
["Weapons (Melee)"] = "xt_weapons",
["Weapons (Pistol)"] = "xt_weapons",
["Weapons (Shotgun)"] = "xt_weapons",
["Weapons (SMG)"] = "xt_weapons",
["Weapons (Rifle)"] = "xt_weapons",
["Weapons (Sniper)"] = "xt_weapons",
["Helmets"] = "xt_armors",
["Outfits (Light)"] = "xt_armors",
["Outfits (Medium)"] = "xt_armors",
["Outfits (Heavy)"] = "xt_armors",
}
-- save vanilla sections
for dbg_name, name in pairs(categories) do
local dbg_ar = ui_debug_main.get_spawn_table(dbg_name)
if dbg_ar and #dbg_ar > 0 then
items_list[name] = items_list[name] or {}
for j = 1, #dbg_ar do -- debug array with items
items_list[name][#items_list[name] + 1] = dbg_ar[j]
end
end
end
-- save additional sections
local ltx = ini_file("plugins\\xcvb_item_groups.ltx")
ltx:section_for_each(function(sec)
items_list[sec] = items_list[sec] or {}
local n = ltx:line_count(sec)
for i = 0, n - 1 do
result, id, value = ltx:r_line_ex(sec, i, "", "")
-- if ini_sys:section_exist(id) then
items_list[sec][#items_list[sec] + 1] = id
end
end)
-- test
--[[
for name, ar in pairs(items_list) do
pr("-----CATEGORY: %s", name)
for i = 1, #ar do pr(ar[i]) end
end
--]]
end
function get_message_str(t1)
local str = ""
for mode, mode_t in pairs(t1.event) do -- mode = sell/buy
for event_k, event_v in pairs(mode_t) do -- event_k = item group, event_v = value
if t1.base[mode] and t1.base[mode][event_k] then
local g_clr = utils_xml.get_color("d_green")
local r_clr = utils_xml.get_color("d_red")
local w_clr = utils_xml.get_color("pda_white")
local sum = event_v + t1.base[mode][event_k]
local sign = sum > 0 and "+" or ""
local sell_clr = (sum >= message_threshold and g_clr) or (sum <= -message_threshold and r_clr)
local buy_clr = (sum >= message_threshold and r_clr) or (sum <= -message_threshold and g_clr)
local mode_clr = (mode == "sell" and sell_clr) or (mode == "buy" and buy_clr)
if mode_clr then
str = str .. w_clr .. gt("xcvb_trade_" .. mode .. "_msg") .. " " .. gt("xcvb_trade_" .. event_k) .. " " .. mode_clr .. sign .. sum .. "%" .. w_clr .. "; \\n"
end
end
end
end
return str
end
function sort_alphabetically(t)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a)
return a
end
function pr(...)
if not debugx then return end
printf(...)
end
---------------- HUD ----------------
HUD = nil
function activate_hud()
if HUD == nil then
HUD = xcvb_trade_tooltip()
get_hud():AddDialogToRender(HUD)
end
HUD:Update(true)
end
function deactivate_hud()
if HUD ~= nil then
get_hud():RemoveDialogToRender(HUD)
HUD = nil
end
end
class "xcvb_trade_tooltip" (CUIScriptWnd)
function xcvb_trade_tooltip:__init() super()
self:InitControls()
end
function xcvb_trade_tooltip:InitControls()
self:SetWndRect(Frect():set(0,0,1024,768))
self:SetAutoDelete(true)
self.xml = CScriptXmlInit()
local xml = self.xml
xml:ParseFile("ui_xcvb_trade.xml")
-- build elements
self.hover = xml:InitStatic("hover_discount", self)
self.buy_bg = xml:InitStatic("buy_bg", self)
self.buy_header = xml:InitStatic("buy_bg:buy_header", self.buy_bg)
self.sell_bg = xml:InitStatic("sell_bg", self)
self.sell_header = xml:InitStatic("sell_bg:sell_header", self.sell_bg)
self.buy_bg:Show(false)
self.sell_bg:Show(false)
-- fill with text from npc id table
local function get_str(mode)
local str = ""
local t = cur_npc and met_traders[cur_npc] and met_traders[cur_npc].base and met_traders[cur_npc].base[mode]
if not (t) then
return str
end
local sorted_ar = sort_alphabetically(t)
for _, base_k in ipairs(sorted_ar) do
local base_v = t[base_k]
local event_v = met_traders[cur_npc].event and met_traders[cur_npc].event[mode] and met_traders[cur_npc].event[mode][base_k]
local g_clr = utils_xml.get_color("d_green")
local r_clr = utils_xml.get_color("d_red")
local w_clr = utils_xml.get_color("pda_white")
local clr_pick
local function sign_pick(val) return val > 0 and "+" or "" end
local sum = base_v + (event_v or 0)
if mode == "sell" then
clr_pick = (sum > 0 and g_clr) or (sum < 0 and r_clr) or w_clr
else
clr_pick = (sum < 0 and g_clr) or (sum > 0 and r_clr) or w_clr
end
str = str .. clr_pick .. gt("xcvb_trade_" .. base_k) .. " " .. sign_pick(base_v) .. base_v .. "% " .. (event_v and ("(" .. sign_pick(event_v) .. event_v .. "%)") or "") .. " \\n"
end
return str
end
self.sell_bg:TextControl():SetText(get_str("sell"))
self.buy_bg:TextControl():SetText(get_str("buy"))
end
function xcvb_trade_tooltip:Update()
CUIScriptWnd.Update(self)
local pos = GetCursorPosition()
local e_p, e_w, e_h = self.hover:GetWndPos(), self.hover:GetWidth(), self.hover:GetHeight()
local pos_true = pos.x > e_p.x and pos.y > e_p.y and pos.x < (e_p.x + e_w) and pos.y < (e_p.y + e_h)
self.sell_bg:Show(pos_true)
self.buy_bg:Show(pos_true)
end
function xcvb_trade_tooltip:__finalize()
end
--------------------------------------
function on_option_change()
min_event_duration = xcvb_trade_mcm.get_config("min_event_time")
max_event_duration = xcvb_trade_mcm.get_config("max_event_time")
min_event_discount = xcvb_trade_mcm.get_config("min_event_disc")
max_event_discount = xcvb_trade_mcm.get_config("max_event_disc")
max_discounts_amount = xcvb_trade_mcm.get_config("max_disc_amount")
message_threshold = xcvb_trade_mcm.get_config("msg_threshold")
debugx = xcvb_trade_mcm.get_config("dbgx")
end
function save_state(m_data)
m_data.met_traders = met_traders
end
function load_state(m_data)
met_traders = m_data.met_traders or {}
end
function on_game_start()
RegisterScriptCallback("on_get_item_cost", on_get_item_cost)
RegisterScriptCallback("ActorMenu_on_mode_changed", open_trade)
RegisterScriptCallback("ActorMenu_on_mode_changed", close_trade)
RegisterScriptCallback("actor_on_update", actor_on_update)
RegisterScriptCallback("actor_on_first_update", categorize_items)
RegisterScriptCallback("on_option_change", on_option_change)
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
end
@@ -0,0 +1,34 @@
-- If you don't use MCM, change your defaults from here.
local defaults = {
["min_event_time"] = 1,
["max_event_time"] = 4,
["min_event_disc"] = -20,
["max_event_disc"] = 20,
["max_disc_amount"] = 5,
["msg_threshold"] = 35,
["dbgx"] = false,
}
function get_config(key)
if ui_mcm then return ui_mcm.get("xcvb_trade/"..key) else return defaults[key] end
end
function on_mcm_load()
op = { id= "xcvb_trade",sh=true ,gr={
{ id= "title",type= "slide",link= "ui_options_slider_player",text="ui_mcm_xcvb_trade_title",size= {512,50},spacing= 20 },
{id = "min_event_time", type = "track", val = 2, min=1,max=4,step=1, def = 1},
{id = "max_event_time", type = "track", val = 2, min=4,max=10,step=1, def = 4},
{id = "min_event_disc", type = "track", val = 2, min=-50,max=-5,step=5, def = -20},
{id = "max_event_disc", type = "track", val = 2, min=5,max=50,step=5, def = 20},
{id = "max_disc_amount", type = "track", val = 2, min=1,max=10,step=1, def = 5},
{id = "msg_threshold", type = "track", val = 2, min=5,max=50,step=5, def = 35},
{id= "divider", type = "line" },
{id = "dbgx", type = "check", val = 1, def = false},
}
}
return op
end