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,28 @@
[partskit_tool]:tch_repair
visual = dynamics\repair\ramrod_tool.ogf
description = st_partskit_descr
inv_name = st_partskit
inv_name_short = st_partskit
inv_grid_x = 6
inv_grid_y = 53
inv_grid_width = 2
inv_grid_height = 1
cost = 28269
inv_weight = 3.0
empty_weight = 0.1
max_uses = 4
attach_angle_offset = -0.287979, 1.560923, 1.544060
attach_position_offset = 0.096910, -0.013594, 0.107925
attach_bone_name = bip01_r_hand
auto_attach = false
repair_min_condition = 0.10
repair_max_condition = 0.99
repair_add_condition = 0.99
repair_part_bonus = 0.99
repair_use_parts = true
repair_only = barrel, gas_tube, bolt, bolt_carrier, trigger_components, spring
repair_parts_sections = explo_jerrycan_fuel, kerosene, gun_oil_ru_d, solvent
repair_parts_multi = 4
repair_use_actor_effects = true
tier = 3
@@ -0,0 +1,16 @@
; lmgs should have custom overheat base values
[custom_overheat]
wpn_rpk = 75
wpn_rpk74 = 75
wpn_rpd = 100
wpn_pkm = 100
wpn_pkm_zulus = 100
wpn_m249 = 100
[overheat]
base_threshold = 50
suppressed_mult = 0.5
heat_1 = 1.2 ; damage mult above 1x heat threshold (50-99)
heat_2 = 2.5 ;(100-149)
heat_3 = 4 ;(150-160)
@@ -0,0 +1,153 @@
[wpo_part_prices]
prt_w_barrel_1 = 3000
prt_w_barrel_2 = 3000
prt_w_barrel_3 = 4125
prt_w_barrel_4 = 6375
prt_w_barrel_5 = 6000
prt_w_barrel_6 = 6375
prt_w_barrel_7 = 5250
prt_w_barrel_8 = 3750 ;5.45 barrel
prt_w_barrel_9 = 4125
prt_w_barrel_10 = 8250
prt_w_barrel_11 = 4875
prt_w_barrel_12 = 2625
prt_w_barrel_13 = 6750
prt_w_trigger_components_1 = 5175
prt_w_trigger_components_2 = 5625
prt_w_trigger_components_3 = 7125
prt_w_trigger_components_4 = 4500
prt_w_trigger_components_5 = 7125
prt_w_trigger_components_6 = 3900
prt_w_bolt_carrier_1 = 4875
prt_w_bolt_carrier_2 = 6375
prt_w_bolt_carrier_3 = 5625
prt_w_bolt_carrier_4 = 5250
prt_w_bolt_carrier_5 = 4875
prt_w_bolt_carrier_6 = 6375
prt_w_bolt_carrier_7 = 4875
prt_w_bolt_carrier_8 = 3750
prt_w_bolt_carrier_9 = 3750
prt_w_bolt_carrier_10 = 6750
prt_w_bolt_carrier_11 = 4500
prt_w_bolt_1 = 4875
prt_w_bolt_2 = 7125
prt_w_bolt_3 = 7125
prt_w_bolt_4 = 5250
prt_w_bolt_5 = 6000
prt_w_bolt_6 = 4875
prt_w_bolt_7 = 6375
prt_w_bolt_8 = 6375
prt_w_bolt_9 = 5250
prt_w_bolt_10 = 7875
prt_w_bolt_11 = 4125
prt_w_bolt_12 = 4125
prt_w_bolt_13 = 6750
prt_w_bolt_14 = 4875
prt_w_bolt_15 = 4125
prt_w_bolt_16 = 5625
prt_w_bolt_17 = 4125
prt_w_gas_tube_1 = 6375
prt_w_gas_tube_2 = 4875
prt_w_gas_tube_3 = 4500
prt_w_gas_tube_4 = 4500
prt_w_gas_tube_5 = 5250
prt_w_gas_tube_6 = 5625
prt_w_gas_tube_7 = 7875
prt_w_gas_tube_8 = 6375
prt_w_gas_tube_9 = 4125
prt_w_gas_tube_10 = 4125
prt_w_gas_tube_11 = 5250
prt_w_p_barrel_1 = 2775
prt_w_p_barrel_2 = 3000
prt_w_p_barrel_3 = 3375
prt_w_p_barrel_4 = 6375
prt_w_p_barrel_5 = 2775
prt_w_p_barrel_6 = 2775
prt_w_p_barrel_7 = 4500
prt_w_p_trigger_1 = 2775
prt_w_p_trigger_2 = 3000
prt_w_p_trigger_3 = 3375
prt_w_p_trigger_4 = 4500
prt_w_p_spring_1 = 2625
prt_w_p_spring_2 = 3000
prt_w_p_spring_3 = 3750
prt_w_p_spring_4 = 3375
prt_w_p_spring_5 = 1875
prt_w_p_spring_6 = 4125
[wpo_part_weights]
prt_w_barrel_1 = 1
prt_w_barrel_2 = 1
prt_w_barrel_3 = 1
prt_w_barrel_4 = 1
prt_w_barrel_5 = 1
prt_w_barrel_6 = 1
prt_w_barrel_7 = 1
prt_w_barrel_8 = 1 ;5.45 barrel
prt_w_barrel_9 = 1
prt_w_barrel_10 = 1
prt_w_barrel_11 = 1
prt_w_barrel_12 = 1
prt_w_barrel_13 = 1
prt_w_trigger_components_1 = 1
prt_w_trigger_components_2 = 1
prt_w_trigger_components_3 = 1
prt_w_trigger_components_4 = 1
prt_w_trigger_components_5 = 1
prt_w_trigger_components_6 = 1
prt_w_bolt_carrier_1 = 1
prt_w_bolt_carrier_2 = 1
prt_w_bolt_carrier_3 = 1
prt_w_bolt_carrier_4 = 1
prt_w_bolt_carrier_5 = 1
prt_w_bolt_carrier_6 = 1
prt_w_bolt_carrier_7 = 1
prt_w_bolt_carrier_8 = 1
prt_w_bolt_carrier_9 = 1
prt_w_bolt_carrier_10 = 1
prt_w_bolt_carrier_11 = 1
prt_w_bolt_1 = 1
prt_w_bolt_2 = 1
prt_w_bolt_3 = 1
prt_w_bolt_4 = 1
prt_w_bolt_5 = 1
prt_w_bolt_6 = 1
prt_w_bolt_7 = 1
prt_w_bolt_8 = 1
prt_w_bolt_9 = 1
prt_w_bolt_10 = 1
prt_w_bolt_11 = 1
prt_w_bolt_12 = 1
prt_w_bolt_13 = 1
prt_w_bolt_14 = 1
prt_w_bolt_15 = 1
prt_w_bolt_16 = 1
prt_w_bolt_17 = 1
prt_w_gas_tube_1 = 1
prt_w_gas_tube_2 = 1
prt_w_gas_tube_3 = 1
prt_w_gas_tube_4 = 1
prt_w_gas_tube_5 = 1
prt_w_gas_tube_6 = 1
prt_w_gas_tube_7 = 1
prt_w_gas_tube_8 = 1
prt_w_gas_tube_9 = 1
prt_w_gas_tube_10 = 1
prt_w_gas_tube_11 = 1
prt_w_p_barrel_1 = 1
prt_w_p_barrel_2 = 1
prt_w_p_barrel_3 = 1
prt_w_p_barrel_4 = 1
prt_w_p_barrel_5 = 1
prt_w_p_barrel_6 = 1
prt_w_p_barrel_7 = 1
prt_w_p_trigger_1 = 1
prt_w_p_trigger_2 = 1
prt_w_p_trigger_3 = 1
prt_w_p_trigger_4 = 1
prt_w_p_spring_1 = 1
prt_w_p_spring_2 = 1
prt_w_p_spring_3 = 1
prt_w_p_spring_4 = 1
prt_w_p_spring_5 = 1
prt_w_p_spring_6 = 1
@@ -0,0 +1,28 @@
; this effectively replaces weapon drop conditions in death_generic
; i am taking these from Asshall
[weapons]
novice = 5, 25
trainee = 30, 50; 0.40, 0.55
experienced = 30, 55; 0.40, 0.60
professional = 30, 60; 0.45, 0.60
veteran = 30, 60; 0.45, 0.65
expert = 30, 65; 0.50, 0.65
master = 30, 70; 0.50, 0.70
legend = 30, 75; 0.55, 0.70
[weapons_larp]
novice = 5, 35, 60 : 5, 85, 99
trainee = 30, 50, 65 : 10, 81, 99
experienced = 30, 50, 65 : 15, 76, 98
professional = 30, 50, 60, 70 : 20, 71, 97, 99
veteran = 30, 50, 60, 70 : 20, 68, 96, 99
expert = 30, 50, 60, 70 : 20, 64, 95, 97
master = 30, 50, 60, 75 : 20, 62, 95, 95
legend = 30, 50, 60, 75 : 20, 57, 94, 90
; there are two we wish to use here,
[weapon_parts]
; 0-59 weights
below = 1, 20, 40, 59 : 0, 50, 30, 90
; 60-100 weights
above = 60, 80, 100 : 10, 40, 95
@@ -0,0 +1,2 @@
[articles_wpo]
article_wpo = encyclopedia_addons
@@ -0,0 +1 @@
#include "articles_*.ltx"
@@ -0,0 +1,2 @@
; prefix section with 'categories_' to specify section with new categories
#include "categories_*.ltx"
@@ -0,0 +1 @@
#include "repair_*.ltx"
@@ -0,0 +1,36 @@
[gun_oil] ;1830
repair_min_condition = 0.25
repair_add_condition = 0.12
repair_threshold = 0.5
[gun_oil_ru_d] ;1675
repair_min_condition = 0.25
repair_add_condition = 0.14
repair_threshold = 0.7
[gun_oil_ru] ;1300
repair_min_condition = 0.25
repair_add_condition = 0.06
repair_threshold = 0.6
[solvent] ;1754
repair_min_condition = 0.25
repair_add_condition = 0.1
repair_threshold = 0.4
[cleaning_kit_p]
repair_min_condition = 0.2
repair_add_condition = 0.15
[cleaning_kit_s]:cleaning_kit_p
[cleaning_kit_r5]:cleaning_kit_p
[cleaning_kit_r7]:cleaning_kit_p
[cleaning_kit_u]:cleaning_kit_p
[toolkit_p]
repair_min_condition = 0.01
repair_add_condition = 0.2
[toolkit_s]:toolkit_p
[toolkit_r5]:toolkit_p
[toolkit_r7]:toolkit_p
[rasp_tool]
repair_min_condition = 0.6
repair_add_condition = 0.25
[ramrod_tool]:rasp_tool
[leatherman_tool]:rasp_tool
@@ -0,0 +1,14 @@
<string_table>
<string id="ui_mcm_menu_clear_jam">
<text>Unjam Keybind</text>
</string>
<string id="ui_mcm_clear_jam_keybind">
<text>Unjam Key</text>
</string>
<string id="ui_mcm_clear_jam_keybind_desc">
<text>Changes the key used for Unjam. Default key is Z. Behaviour of the key can be changed in related MCM tab.</text>
</string>
<string id="ui_mcm_clear_jam_mcm">
<text>Update MCM to see this feature. Key defaults to Z</text>
</string>
</string_table>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<string id="st_dot">
<text></text>
</string>
</string_table>
@@ -0,0 +1,6 @@
<string_table>
<string id="encyclopedia_addons">
<text>Addons</text>
</string>
</string_table>
@@ -0,0 +1,422 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<!-- Jammin -->
<string id="kb_unjam">
<text>Unjam weapon</text>
</string>
<string id="ui_st_misfire">
<text>Weapon misfired!</text>
</string>
<string id="ui_st_jam">
<text>Weapon jammed!</text>
</string>
<string id="ui_st_superjam">
<text>Weapon severely jammed!</text>
</string>
<string id="ui_st_nothing">
<text>Nothing to unjam</text>
</string>
<string id="ui_st_unjam">
<text>Weapon unjammed successfully</text>
</string>
<string id="ui_st_functional">
<text>Weapon functional</text>
</string>
<string id="ui_st_oldjam">
<text>You are using Anomaly Magazines. Do not unjam your weapon. Reload your weapon.</text>
</string>
<string id="ui_st_unjam_fail">
<text>That didn't seem to work - it must be really jammed in there...</text>
</string>
<string id="ui_st_parts_damage">
<text>Weapon has suffered internal component damage.</text>
</string>
<string id="st_news_parts_alreadygood">
<text>Part does not need to be replaced.</text>
</string>
<string id="ui_st_heat1">
<text>, but warm.</text>
</string>
<string id="ui_st_heat2">
<text>, but hot!</text>
</string>
<string id="ui_st_heat3">
<text>, but very hot!</text>
</string>
<string id="st_unjam">
<text>unjam</text>
</string>
<!-- Messages -->
<string id="st_news_parts_success">
<text>Successfully replaced part: </text>
</string>
<string id="st_news_parts_repair_success">
<text>Successfully repaired part: </text>
</string>
<string id="st_news_parts_fail">
<text>%c[d_red]Weapon already has higher condition part.</text>
</string>
<string id="st_news_parts_incompatible">
<text>%c[d_red]Part is not compatible with weapon.</text>
</string>
<string id="st_news_parts_barrel">
<text>%c[d_red]Barrels cannot be replaced in the field.</text>
</string>
<string id="st_news_parts_trigger">
<text>%c[d_red]Triggers cannot be replaced in the field.</text>
</string>
<string id="st_news_parts_rusty">
<text>%c[d_red]Weapon is too rusty to take apart in the field.</text>
</string>
<string id="st_news_dis_items">
<text>%c[d_red]A proper disassembling tool is required.</text>
</string>
<string id="st_news_fieldstrip">
<text>Removed parts:</text>
</string>
<string id="st_news_cleaned">
<text>Cleaned part:</text>
</string>
<!-- MCM -->
<string id="ui_mcm_menu_wpo">
<text>WPO</text>
</string>
<string id="ui_mcm_wpo_title">
<text>Weapon Parts Overhaul</text>
</string>
<string id="ui_mcm_wpo_wpojam">
<text>Weapon Jam Options</text>
</string>
<string id="ui_mcm_wpo_wpoecon">
<text>Economy Options</text>
</string>
<string id="ui_mcm_wpo_wpomisc">
<text>Misc Options</text>
</string>
<string id="ui_mcm_menu_wpojam">
<text>WPO Jam</text>
</string>
<string id="ui_mcm_menu_wpoecon">
<text>WPO Econ</text>
</string>
<string id="ui_mcm_menu_wpomisc">
<text>WPO Misc</text>
</string>
<string id="ui_mcm_wpo_wpojam_keybind">
<text>Unjam key</text>
</string>
<string id="ui_mcm_wpo_wpojam_jamchance">
<text>Jam Chance multiplier</text>
</string>
<string id="ui_mcm_wpo_wpojam_jamchance_desc">
<text>Multiplier for your weapons to jam in the new way. Drag down if you </text>
</string>
<string id="ui_mcm_wpo_wpojam_superjam">
<text>Enable super jams</text>
</string>
<string id="ui_mcm_wpo_wpojam_superjam_desc">
<text>Enables (or disables) those pesky super-jams. Super-jams are jams that require removing the loaded ammunition to clear properly.</text>
</string>
<string id="ui_mcm_wpo_wpojam_simplejam">
<text>Drop mag if superjammed</text>
</string>
<string id="ui_mcm_wpo_wpojam_simplejam_desc">
<text>If enabled, on pressing reload with a superjammed weapon, the magazine will be ejected for you. No more inventory fumbling!</text>
</string>
<string id="ui_mcm_wpo_wpojam_heat">
<text>Enable weapon overheating</text>
</string>
<string id="ui_mcm_wpo_wpojam_heat_desc">
<text>Weapons will become hotter when firing, which will affect degradation, jam chance, and part damage.</text>
</string>
<string id="ui_mcm_wpo_wpojam_oldammo">
<text>Old Ammo Affects Degradation</text>
</string>
<string id="ui_mcm_wpo_wpojam_oldammo_desc">
<text>Old ammo will increase rate of barrel wear and chance of jams.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_degradation">
<text>Degradation in rain</text>
</string>
<string id="ui_mcm_wpo_wpoecon_degradation_desc">
<text>Rate at which your weapon degrades faster in rainy weather.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_threshold">
<text>Part damage condition threshold</text>
</string>
<string id="ui_mcm_wpo_wpoecon_threshold_desc">
<text>Weapon condition under which usage has a chance to damage parts. The lower, the less overall parts will be damaged.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_repairkit">
<text>Repair kits replace parts</text>
</string>
<string id="ui_mcm_wpo_wpoecon_repairkit_desc">
<text>Has repair kits replace parts (restore to 100). If not enabled, repair kits only add 25%. Stretches out the difficulty if disabled.</text>
</string>
<!-- <string id="ui_mcm_wpo_wpoecon_fullservice">
<text>Technician Service Level</text>
</string>
<string id="ui_mcm_wpo_wpoecon_fullservice_desc">
<text>Determines the level of service that technicians provide.
\n\n Clean Weapon Only: Only restores base weapon condition.
\n\n Clean Parts: Restores base weapon condition and cleans parts, if applicable.
\n\n Full service: Restores base condition, fixes parts, replaces parts.
</text>
</string> -->
<string id="st_wpn_service_cost">
<text>Cost of service:</text>
</string>
<string id="st_wpn_service_hint">
<text>Maintain parts</text>
</string>
<string id="st_wpn_service_dropdown">
<text>Open the part maintenance menu</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altroll">
<text>Weighted weapon conditions</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altroll_desc">
<text>Roll weapon conditions based on Lagrange interpolation. Reduces drop quality overall, good if you like to scavenge, and goes well with the next item.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altpartroll">
<text>Weighted part conditions</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altpartroll_desc">
<text>Use new formula for weapon part drops, where condition of weapon determines if parts are rolled in good or bad condition. Improves drop quality at low tiers and reduces drop quality at high tiers.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_saletype">
<text>Weapon Sale Logic</text>
</string>
<string id="ui_mcm_wpo_wpoecon_saletype_desc">
<text>Determine how weapon selling works. \n \n
- Vanilla: Weapons sell for a price commensurate with their condition (not recommended for balance)\n
- Relaxed: Weapon sell price scales with part condition, based on damaged/not damaged (60% threshold). Recommended.\n
- Strict: Weapons must have all parts not damaged (>60%) in order to be eligible for sale.\n
Note that any missing part invalidates a weapon for sale, regardless of the conditions above.
</text>
</string>
<string id="ui_mcm_lst_vanilla">
<text>Vanilla</text>
</string>
<string id="ui_mcm_lst_easy">
<text>Relaxed</text>
</string>
<string id="ui_mcm_lst_hard">
<text>Strict</text>
</string>
<string id="ui_mcm_wpo_wpoecon_easybarrel">
<text>Replace barrels without workbench</text>
</string>
<string id="ui_mcm_wpo_wpoecon_easytrigger">
<text>Replace triggers without workbench</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity">
<text>Profanity on weapon jam</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_desc">
<text>Enables colorful dialogue on a malfunction.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_timeout">
<text>Disable profanity spam</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_timeout_desc">
<text>Adds a timeout to jam profanity if true. Use if you hate fun.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_display">
<text>Display part condition</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_language">
<text>Profanity language</text>
</string>
<string id="ui_mcm_lst_eng">
<text>English</text>
</string>
<string id="ui_mcm_lst_rus">
<text>Russian</text>
</string>
<string id="ui_mcm_wpo_wpomisc_verbosity">
<text>Enable jam messaging</text>
</string>
<string id="ui_mcm_wpo_wpomisc_verbosity_desc">
<text>Controls whether or not information is displayed to user on jams and internal part damage.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_fun">
<text>Fun level</text>
</string>
<string id="ui_mcm_lst_no">
<text>Duty</text>
</string>
<string id="ui_mcm_lst_yes">
<text>Loner</text>
</string>
<string id="ui_mcm_lst_ofc">
<text>Freedom</text>
</string>
<string id="ui_mcm_wpo_wpomisc_debug">
<text>Debug logging</text>
</string>
<string id="ui_mcm_wpo_wpomisc_debug_desc">
<text>Debug logging, enables a whole bunch of additional information in console log.</text>
</string>
<string id="st_field_strip">
<text>field strip</text>
</string>
<string id="st_field_strip_fail">
<text>This weapon has no parts to remove.</text>
</string>
<string id="ui_st_missing">
<text>This weapon is missing parts or has a destroyed part.</text>
</string>
<string id="article_wpo">
<text>Weapon Maintenance</text>
</string>
<string id="article_wpo_text">
<text>
%c[pda_green]QUICK FAQS%c[ui_gray_1]\n \n
\n1. Why is my gun jamming at 100%?
\nA. Your parts are damaged. Check the condition.
\n2. How do I unjam?
\nA. Double-tap USE. Or right-click weapon in inventory to bring up unjam command.
\n3. Why am I losing condition when I replace parts?
\nA. You need to relubricate the weapon. This does not happen below 60%. Use a Leatherman to reduce the amount, or a workbench to eliminate it entirely.
\n4. Why don't technicians fix my parts?
\nA. Parts must be scavenged. You can buy parts at the technician, or use a weapon repair kit. This is the core longevity behind WPO. \n \n
Weapon Parts Overhaul drastically changes how weapon maintenance works in Anomaly. Read this guide carefully to understand everything.\n \n
%c[pda_green]I. Parts and Maintenance%c[ui_gray_1]\n
\n• Your weapon overall condition (the condition bar you are normally used to) is now easier to maintain. The mechanic will restore this for 60% less cost. All the weapon repair items are far more powerful.
\n• Weapon parts need maintenance. You can see the condition of weapon parts at-a-glance on mouse over.
\n • Color of the text indicates status.
\n%c[d_red] • Missing
\n%c[d_orange] • Damaged and cannot be cleaned
\n%c[pda_yellow] • Dirty and can be cleaned%c[ui_gray_1]
\n• Weapon parts can be removed by field-stripping the weapon. This removes every component that is not a barrel or trigger.
\n• Weapon parts can also be ad-hoc replaced with drag and drop. %c[d_red]NOTE THAT THIS DEPLETES WEAPON CONDITION IF ABOVE 60%. Have a Leatherman present to reduce this impact. %c[ui_gray_1].
\n• Weapon parts can also be replaced at workbench for free if the correct repair kit is owned. %c[pda_yellow]This is one of two ways to replace barrels or triggers.
\n \n
%c[pda_green]II. Jamming and Part Damage%c[ui_gray_1]\n
\n• Parts have five levels of damage: %c[d_red]broken%c[ui_gray_1], %c[d_red]damaged%c[ui_gray_1], %c[d_orange]worn%c[ui_gray_1], %c[0,250,250,0]dirty%c[ui_gray_1], %c[d_green]functional%c[ui_gray_1]
\n• The more damaged the parts, the higher a chance to suffer a malfunction.
\n• There are three types of malfunction: misfire, jam, and severe jam.
\n• Misfire and jam can be cleared simply by unjamming.
\n• Severe jam requires ejection of magazine before clearing the jam.
\n• Barrels do not contribute to jam chance. However, dirty and below barrels reduce weapon damage up to 50%.
\n• Firing a weapon below 85% condition(default, change %c[pda_yellow]MCM: Part damage condition threshold%c[ui_gray_1]) has a chance to deal damage to weapon parts.
\n• Firing a weapon in heavy rain will degrade the weapon faster.
\n• (TEMP REMOVED) Firing a weapon for too long causes overheating, leading to more jams and faster degradation.
%c[pda_green]III. Economy changes%c[ui_gray_1]\n
\n• Having a cleaning kit will allow you to clean "dirty" weapon parts (above 60% condition). This also restores 10% condition.
\n• Having a repair kit will allow you to repair parts through a right-click menu. This uses a charge and restores 25% condition to the part, as well as 10% condition to the weapon.%c[pda_yellow]This is the other way to fix barrels/triggers.%c[ui_gray_1]
\n• Technicians will randomly sell weapon parts at a serious markup.
\n• Weapon parts above 60% can be repaired with files, ramrods or multitools.
\n• Weapon parts above 10% can be repaired with a very expensive toolkit available at traders.
\n \n For all other issues, ping arti#3278 on Discord. I am way too lazy to read Moddb comments.
</text>
</string>
<string id="st_partskit">
<text>Part repair kit</text>
</string>
<string id="st_partskit_descr">
<text>Highly advanced toolset including micro-files, cold weld metal epoxy, electrolysis bath setup, and tons of lubricants, petrol distillates and other solvents. The tools here can restore a Lada engine into a Ferrari, to say nothing of what it can do to machine components. Only the most destroyed pieces of scrap metal won't be able to be restored by this kit. However, this kit is extremely hard to put together and is thus sold in very small quantities by Zone technicians.\n\n</text>
</string>
<!-- Info -->
<string id="st_dot">
<text></text>
</string>
<string id="st_clean_half">
<text>halved cleaning effectiveness below threshold: </text>
</string>
<string id="st_damage_missing">
<text>missing</text>
</string>
<string id="st_damage_0">
<text>broken</text>
</string>
<string id="st_damage_1">
<text>damaged</text>
</string>
<string id="st_damage_2">
<text>worn</text>
</string>
<string id="st_damage_3">
<text>dirty</text>
</string>
<string id="st_damage_4">
<text>functional</text>
</string>
<string id="st_damage_5">
<text>functional</text>
</string>
<string id="st_wpo_replace_parts">
<text>maintain parts</text>
</string>
<string id="st_wpo_repair">
<text>repair 25% condition to </text>
</string>
<string id="st_wpo_replace">
<text>replace </text>
</string>
<string id="st_wpo_clean">
<text>clean</text>
</string>
<string id="st_wpo_remove">
<text>remove</text>
</string>
<string id="st_name_trigger">
<text>trigger mechanism</text>
</string>
<string id="st_name_spring">
<text>recoil spring</text>
</string>
<string id="st_name_barrel">
<text>barrel</text>
</string>
<string id="st_name_bolt_carrier">
<text>bolt carrier</text>
</string>
<string id="st_name_bolt">
<text>bolt</text>
</string>
<string id="st_name_gas_tube">
<text>gas system</text>
</string>
<string id="st_name_extractor">
<text>extractor</text>
</string>
<string id="st_name_ejector">
<text>ejector</text>
</string>
<string id="st_name_pump">
<text>pump</text>
</string>
<string id="st_name_hammers">
<text>hammers</text>
</string>
<string id="st_name_chock">
<text>chock</text>
</string>
<string id="st_name_all">
<text>all</text>
</string>
<string id="st_name_issues">
<text>STATUS:</text>
</string>
</string_table>
@@ -0,0 +1,14 @@
<string_table>
<string id="ui_mcm_menu_clear_jam">
<text>Áèíä äëÿ ðàñêëèíà</text>
</string>
<string id="ui_mcm_clear_jam_keybind">
<text>Ðàñêëèí</text>
</string>
<string id="ui_mcm_clear_jam_desc">
<text>Èçìåíÿåò êëàâèøó èñïîëüçóåìóþ äëÿ ðàñêëèíà îðóæèÿ. Ñòàíäàðòíàÿ êëàâèøà - Z. Ïîâåäåíèå êëàâèøè ìîæíî èçìåíèòü â ñîîòâ. âêëàäêå MCM.</text>
</string>
<string id="ui_mcm_clear_jam_mcm">
<text>Îáíîâèòå MCM ÷òîáû óâèäåòü ýòó ôóíêöèþ. Ñòàíäàðòíàÿ êëàâèøà - Z.</text>
</string>
</string_table>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<string id="st_dot">
<text></text>
</string>
</string_table>
@@ -0,0 +1,402 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<!-- Jammin -->
<string id="kb_unjam">
<text>Óáðàòü êëèí</text>
</string>
<string id="ui_st_misfire">
<text>Îðóæèå äàëî îñå÷êó!</text>
</string>
<string id="ui_st_jam">
<text>Îðóæèå çàêëèíèëî!</text>
</string>
<string id="ui_st_superjam">
<text>Îðóæèå ñèëüíî çàêëèíèëî!</text>
</string>
<string id="ui_st_nothing">
<text>Â ðóêàõ íåò ñòðåëêîâîãî îðóæèÿ.</text>
</string>
<string id="ui_st_unjam">
<text>Êëèí îðóæèÿ óñòðàí¸í.</text>
</string>
<string id="ui_st_functional">
<text>Îðóæèå ãîòîâî ê ñòðåëüáå</text>
</string>
<string id="ui_st_oldjam">
<text>Èç-çà ïëîõîãî ñîñòîÿíèÿ îðóæèå çàêëèíèëî. Íóæíà ïåðåçàðÿäêà.</text>
</string>
<string id="ui_st_unjam_fail">
<text>Îðóæèå ñèëüíî çàêëèíèëî - ñíà÷àëà ðàçðÿäè ìàãàçèí, à çàòåì ïåðåä¸ðíè çàòâîð.</text>
</string>
<string id="ui_st_parts_damage">
<text>Âíóòðåííèå êîìïîíåíòû îðóæèÿ ïîâðåæäåíû.</text>
</string>
<string id="st_news_parts_alreadygood">
<text>Ýòà äåòàëü íå òðåáóåò çàìåíû.</text>
</string>
<string id="ui_st_heat1">
<text>, íî òåïëîå.</text>
</string>
<string id="ui_st_heat2">
<text>, íî ãîðÿ÷åå!</text>
</string>
<string id="ui_st_heat3">
<text>, íî î÷åíü ãîðÿ÷åå!</text>
</string>
<string id="st_unjam">
<text>óáðàòü êëèí</text>
</string>
<!-- Messages -->
<string id="st_news_parts_success">
<text>%c[d_green]Äåòàëü óñïåøíî çàìåíåíà.</text>
</string>
<string id="st_news_parts_repair_success">
<text>Óñïåøíî îòðåìîíòèðîâàíî: </text>
</string>
<string id="st_news_parts_fail">
<text>%c[d_red]Íà îðóæèè óæå óñòàíîâëåíà äåòàëü ëó÷øåãî êà÷åñòâà.</text>
</string>
<string id="st_news_parts_incompatible">
<text>%c[d_red]Ýòà äåòàëü íåñîâìåñòèìà ñ äàííûì îðóæèåì.</text>
</string>
<string id="st_news_parts_barrel">
<text>%c[d_red]Ñòâîë íåëüçÿ çàìåíèòü â ïîëåâûõ óñëîâèÿõ.</text>
</string>
<string id="st_news_parts_trigger">
<text>%c[d_red]Ñïóñêîâîé ìåõàíèçì íåëüçÿ çàìåíèòü â ïîëåâûõ óñëîâèÿõ.</text>
</string>
<string id="st_news_parts_rusty">
<text>%c[d_red]Íåâîçìîæíî ðàçîáðàòü ýòî îðóæèå â ïîëåâûõ óñëîâèÿõ, òàê êàê îíî ñëèøêîì ðæàâîå.</text>
</string>
<string id="st_news_dis_items">
<text>%c[d_red]Äëÿ ðàçáîðêè òðåáóåòñÿ ïîäõîäÿùèé èíñòðóìåíò.</text>
</string>
<string id="st_news_fieldstrip">
<text>Óäàëåííûå äåòàëè:</text>
</string>
<string id="st_news_cleaned">
<text>Î÷èùåííûå äåòàëè:</text>
</string>
<!-- MCM -->
<string id="ui_mcm_menu_wpo">
<text>WPO</text>
</string>
<string id="ui_mcm_wpo_title">
<text>Íàñòðîéêà Weapon Parts Overhaul</text>
</string>
<string id="ui_mcm_wpo_wpojam">
<text>Íàñòðîéêè êëèíà îðóæèÿ</text>
</string>
<string id="ui_mcm_wpo_wpoecon">
<text>Íàñòðîéêè ýêîíîìèêè</text>
</string>
<string id="ui_mcm_wpo_wpomisc">
<text>Ïðî÷èå íàñòðîéêè</text>
</string>
<string id="ui_mcm_menu_wpojam">
<text>WPO êëèí</text>
</string>
<string id="ui_mcm_menu_wpoecon">
<text>WPO ýêîíîìèêà</text>
</string>
<string id="ui_mcm_menu_wpomisc">
<text>WPO ïðî÷åå</text>
</string>
<string id="ui_mcm_wpo_wpojam_jamchance">
<text>Ìíîæèòåëü øàíñà êëèíà</text>
</string>
<string id="ui_mcm_wpo_wpojam_jamchance_desc">
<text>Ìíîæèòåëü øàíñà íîâîé ìåõàíèêè êëèíà îðóæèÿ.</text>
</string>
<string id="ui_mcm_wpo_wpojam_superjam">
<text>Ðàçðåøèòü ñóïåð-êëèí</text>
</string>
<string id="ui_mcm_wpo_wpojam_superjam_desc">
<text>Âêëþ÷àåò (èëè îòêëþ÷àåò) òàê íàçûâàåìûé "ñóïåð-êëèí". Ïðè "ñóïåð-êëèíå" íóæíî ïîëíîñòüþ ðàçðÿäèòü îðóæèå.</text>
</string>
<string id="ui_mcm_wpo_wpojam_simplejam">
<text>Âûáðîñ ìàãàçèíà ïðè ñóïåð-êëèíå</text>
</string>
<string id="ui_mcm_wpo_wpojam_simplejam_desc">
<text>Åñëè âêëþ÷åíî, ïðè íàæàòèè ïåðåçàðÿäêè (ïî ñòàíäàðòó R) ñ ñèëüíî çàêëèíèâøåì îðóæèåì, ìàãàçèí áóäåò èçâëå÷åí. Áîëüøå íå ïðèäåòñÿ âîçèòüñÿ ñ èíâåíòàðåì.</text>
</string>
<string id="ui_mcm_wpo_wpojam_heat">
<text>Âêëþ÷èòü ïåðåãðåâ îðóæèÿ</text>
</string>
<string id="ui_mcm_wpo_wpojam_heat_desc">
<text>Îðóæèå áóäåò ñòàíîâèòüñÿ ãîðÿ÷åå ïðè âåäåíèè îãíÿ, ÷òî ïîâëèÿåò íà ñêîðîñòü äåãðàäàöèè, øàíñ êëèíà è ïîâðåæäåíèÿ âíóòðåííèõ êîìïîíåíòîâ.</text>
</string>
<string id="ui_mcm_wpo_wpojam_oldammo">
<text>Ñòàðûå áîåïðèïàñû âëèÿþò íà äåãðàäàöèþ</text>
</string>
<string id="ui_mcm_wpo_wpojam_oldammo_desc">
<text>Ñòàðûå áîåïðèïàñû óâåëè÷èâàþò èçíîñ ñòâîëà è ïîâûøàþò øàíñ êëèíà.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_degradation">
<text>Êîýôôèöèåíò äåãðàäàöèè ïîä äîæä¸ì</text>
</string>
<string id="ui_mcm_wpo_wpoecon_degradation_desc">
<text>Ìíîæèòåëü äåãðàäàöèè îðóæèÿ, êîãäà îíî èñïîëüçóåòñÿ âî âðåìÿ äîæäÿ.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_threshold">
<text>Ïîðîã ñîñòîÿíèÿ ïîâðåæäåíèÿ äåòàëè</text>
</string>
<string id="ui_mcm_wpo_wpoecon_threshold_desc">
<text>Ñîñòîÿíèå îðóæèÿ ïðè êîòîðîì åñòü øàíñ ïîâðåäèòü äåòàëè. ×åì ìåíüøå, òåì îðóæèå äîëæíî áûòü áîëüøå ïîâðåæäåíî ÷òîáû äåòàëè íà÷àëè ïîâðåæäàòüñÿ.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_repairkit">
<text>Ðåìíàáîðû âîññòàíàâëèâàþò êîìïîíåíòû</text>
</string>
<string id="ui_mcm_wpo_wpoecon_repairkit_desc">
<text>Ðåìîíòíûå íàáîðû áóäóò âîññòàíàâëèâàòü êîìïîíåíòû îðóæèÿ (äî 100%). Åñëè íå âêëþ÷åíî, ëèøü äîáàâëÿåò 25% ê ñîñòîÿíèþ. Óâåëè÷èâàåò ñëîæíîñòü â âûêëþ÷åííîì ñîñòîÿíèè.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altroll">
<text>Ðàñïðåäåë¸ííûé âåñ ñîñòîÿíèÿ îðóæèÿ</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altroll_desc">
<text>Ðàñïðåäåëåíèå ñîñòîÿíèÿ îðóæèÿ â ìèðå íà îñíîâå èíòåðïîëÿöèè Ëàãðàíæà. Ñíèæàåò êà÷åñòâî äðîïà â öåëîì è ïîîùðÿåò ñîáèðàòåëüñòâî. Õîðîøî ñî÷åòàåòñÿ ñî ñëåäóþùèì ïóíêòîì.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altpartroll">
<text>Ðàñïðåäåë¸ííûé âåñ ñîñòîÿíèÿ êîìïîíåíòîâ</text>
</string>
<string id="ui_mcm_wpo_wpoecon_altpartroll_desc">
<text>Èñïîëüçîâàíèå íîâîé ôîðìóëû äëÿ äðîïà îðóæåéíûõ êîìïîíåíòîâ, â êîòîðîé ñîñòîÿíèå îðóæèÿ îïðåäåëÿåò òî, áóäóò ëè èçâëå÷åíû êîìïîíåíòû â õîðîøåì èëè ïëîõîì êà÷åñòâå. Íà íèçêèõ çíà÷åíèÿõ óâåëè÷èâàåò êà÷åñòâî äðîïà, íà âûñîêèõ óìåíüøàåò.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_minpart">
<text>Ìèíèìàëüíîå ñîñòîÿíèå êîìïîíåíòîâ äëÿ ïðîäàæè</text>
</string>
<string id="ui_mcm_wpo_wpoecon_minpart_desc">
<text>Ìèíèìàëüíîå ñîñòîÿíèå äëÿ ÂÑÅÕ îðóæåéíûõ êîìïîíåíòîâ, ÷òîáû èõ ïðèíèìàëè òîðãîâöû. Åñëè â îðóæèè åñòü õîòÿ áû ÎÄÈÍ êîìïîíåíò íèæå ýòîãî çíà÷åíèÿ, îðóæèå ó âàñ íå êóïÿò. Çíà÷åíèå 0 îòêëþ÷àåò äàííóþ ïðîâåðêó.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_easybarrel">
<text>Çàìåíà ñòâîëîâ áåç âåðñòàêà.</text>
</string>
<string id="ui_mcm_wpo_wpoecon_easytrigger">
<text>Çàìåíà ñïóñêîâûõ ìåõàíèçìîâ áåç âåðñòàêà.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity">
<text>Ìàò ïðè êëèíå îðóæèÿ</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_desc">
<text>Âêëþ÷àåò êðàñî÷íûå âûðàæåíèÿ ïðè êëèíå îðóæèÿ.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_timeout">
<text>Óìåíüøèòü ÷àñòîòó ðóãàòåëüñòâ</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_timeout_desc">
<text>Äîáàâëÿåò çàäåðæêó ïðè âêëþ÷¸ííîé îïöèè "ìàò ïðè êëèíå îðóæèÿ". Èñïîëüçóéòå, åñëè âàì ñëèøêîì âåñåëî.</text>
</string>
<string id="ui_mcm_wpo_wpomisc_profanity_language">
<text>ßçûê ðóãàòåëüñòâ</text>
</string>
<string id="ui_mcm_lst_eng">
<text>Àíãëèéñêèé</text>
</string>
<string id="ui_mcm_lst_rus">
<text>Ðóññêèé</text>
</string>
<string id="ui_mcm_wpo_wpomisc_verbosity">
<text>Òåêñòîâîå ñîîáùåíèå î êëèíå</text>
</string>
<string id="ui_mcm_wpo_wpomisc_verbosity_desc">
<text>Âûâîä ñîîáùåíèé î êëèíå â èíòåðôåéñ. Âñåãî òðè óðîâíÿ:\nÍåò: òîëüêî êëèí ïî îáùåìó ñîñòîÿíèþ îðóæèÿ (èíà÷å ñîâñåì çàïóòàíî áóäåò).\nÑòàíäàðò (ðåêîìåíäóåòñÿ): óâåäîìëåíèå î êëèíå è îá óñïåøíîì ðàñêëèíå.\nÂñ¸: Êàê è ïðåäûäóùèé ïóíêò, íî â äîáàâîê áóäåò âûäàíî óâåäîìëåíèå î ñóïåð-êëèíå, à òàê æå èíôîðìàöèÿ î ïîâðåæäåíèè êîìïîíåíòîâ, åñëè îíî ïðîèñõîäèò.</text>
</string>
<string id="ui_mcm_lst_verbosity_none">
<text>Íåò</text>
</string>
<string id="ui_mcm_lst_verbosity_normal">
<text>Ñòàíäàðò</text>
</string>
<string id="ui_mcm_lst_verbosity_full">
<text>Âñ¸</text>
</string>
<string id="ui_mcm_wpo_wpomisc_fun">
<text>Óðîâåíü âåñåëüÿ</text>
</string>
<string id="ui_mcm_lst_no">
<text>Äîëã</text>
</string>
<string id="ui_mcm_lst_yes">
<text>Îäèíî÷êè</text>
</string>
<string id="ui_mcm_lst_ofc">
<text>Ñâîáîäà</text>
</string>
<string id="ui_mcm_wpo_wpomisc_debug">
<text>Îòëàäî÷íûé æóðíàë</text>
</string>
<string id="ui_mcm_wpo_wpomisc_debug_desc">
<text>Äîïîëíèòåëüíàÿ îòëàäî÷íàÿ èíôîðìàöèÿ, êîòîðàÿ áóäåò çàïèñàíà â ëîã-ôàéë èãðû.</text>
</string>
<string id="ui_mcm_wpo_babymode">
<text>Ðåæèì äëÿ äåòåé (áåç êëèíà) </text>
</string>
<string id="ui_mcm_wpo_babymode_desc">
<text>È çà÷åì?</text>
</string>
<string id="ui_st_mockery_1">
<text>Ó òåáÿ áû âñ¸ çàêëèíèëî, íî ïîõîæå, òåáå ýòî êàæåòñÿ ÷ðåçìåðíûì.</text>
</string>
<string id="ui_st_mockery_2">
<text>Íðàâÿòñÿ ïðîñòåíüêèå ðåìîíòû?</text>
</string>
<string id="ui_st_mockery_3">
<text>Êñòàòè, ïî÷åìó áû çàîäíî ïåðåíîñèìûé âåñ äî 600 íå ïîäíÿòü, ðàç òàêîå äåëî?</text>
</string>
<string id="ui_st_mockery_4">
<text>Òû ìåíÿ ðàçî÷àðîâûâàåøü.</text>
</string>
<string id="st_field_strip">
<text>Èçâëå÷ü êîìïîíåíòû</text>
</string>
<string id="st_field_strip_fail">
<text>Èç ýòîãî îðóæèÿ áîëüøå íå÷åãî èçâëåêàòü.</text>
</string>
<string id="ui_st_missing">
<text>Â îðóæèè îòñóòñòâóþò êîìïîíåíòû.</text>
</string>
<string id="article_wpo">
<text>Îáñëóæèâàíèå îðóæèÿ</text>
</string>
<string id="article_wpo_text">
<text>
%c[pda_green]Âîïðîñ - Îòâåò %c[ui_gray_1]\n \n
\n1. Ïî÷åìó ìîå îðóæèå çàêëèíèâàåò íà 100%?
\nA. Ñêîðåå âñåãî êàêèå-òî ÷àñòè îðóæèÿ ïîâðåæäåíû. Ïðîâåðüòå ñîñòîÿíèå.
\n2. Êàê óáðàòü êëèí?
\nA. Íàæìèòå äâà ðàçà íà êíîïêó èñïîëüçîâàíèÿ, ïî ñòàíäàðòó F. Èëè ïðàâîé êíîïêîé ìûøè ïî îðóæèþ â èíâåíòàðå è âûáåðèòå êîìàíäó "Óáðàòü Êëèí".
\n3. Ïî÷åìó ÿ òåðÿþ ïðî÷íîñòü îðóæèÿ çàìåíÿÿ ÷àñòè?
\nA. Âàì íóæíî çàíîãî ñìàçàòü îðóæèå. Çàìåíîé äåòàëåé ïðî÷íîñòü îðóæèÿ íå ìîæåò óïàñòü ìåíüøå 60%. Èñïîëüçóéòå ìóëüòèòóë Leatherman ÷òîáû óìåíüøèòü ýòî, èëè âåðñòàê ÷òîáû ïîëíîñòüþ èçáàâèòüñÿ îò ýòîãî.
\n4. Ïî÷åìó òåõíèêè íå ÷èíÿò îðóæåéíûå ÷àñòè?
\nA. ×àñòè äîëæíû áûòü èñïðàâëåíû ñàìîñòîÿòåëüíî. Âû ìîæåòå êóïèòü ÷àñòè ó òåõíèêîâ, èëè èñïîëüçîâàòü îðóæåéíûå íàáîðû. Ýòî îñíîâíîé ñìûñë Weapon Part Overhaul. \n \n
Êàïèòàëüíûå ðåìîíò ÷àñòåé îðóæèÿ ðàäèêàëüíî ìåíÿåò òî, êàê ðàáîòàåò òåõíè÷åñêîå îáñëóæèâàíèå â Àíîìàëè. Âíèìàòåëüíî ÷èòàéòå ýòî ðóêîâîäñòâî ÷òîáû ïîíÿòü âñå ïðàâèëüíî.\n \n
%c[pda_green]I. Îðóæåéíûå ÷àñòè è èõ îáñëóæèâàíèå%c[ui_gray_1]\n
\n• Îáùåå ñîñòîÿíèå âàøåãî îðóæèÿ (øêàëà ñîñòîÿíèÿ ê êîòîðîé âû ïðèâûêëè) òåïåðü ëåã÷å ïîääåðæèâàòü. Ìåõàííèê âîñòàíîâèò ïðî÷íîñòü íà 60% äåøåâëå. Âñå ïðåäìåòû äëÿ ðåìîíòà îðóæèÿ íàìíîãî ìîùíåå.
\n• Îðóæåéíûì ÷àñòÿì íóæíî îáñëóæèâàíèå. Âû ìîæåòå óâèäåòü ñîñòîÿíèå îðóæåéíûõ ÷àñòåé íàâåäÿ êóðñîð ìûøè.
\n ? Öâåò òåêñòà îáîçíà÷àåò îáùåå ñîñòîÿíèå.
\n%c[d_red] ? Îòñóòñòâóåò
\n%c[d_orange] ? Ïîâðåæäåíî è íå ìîæåò áûòü îáñëóæåíî
\n%c[pda_yellow] ? Çàãðÿçíåíî è ìîæåò áûòü î÷èùåíî%c[ui_gray_1]
\n• Îðóæåéíûå ÷àñòè ìîãóò áûòü ñíÿòû ðàçîáðàâ ñàìî îðóæèå. Ýòî âûòàùèò âñå îðóæåéíûå ÷àñòè ïîìèìî ñòâîëà.
\n• Îðóæåéíûå ÷àñòè ìîãóò áûòü çàìåíåíû ïåðåòàñêèâàíèåì. %c[d_red]Ó×ÒÈÒÅ ÝÒÎ ÓÌÅÍÜØÀÅÒ ÑÎÑÒÎßÍÈÅ ÂÀØÅÃÎ ÎÐÓÆÈß ÅÑËÈ ÎÍÎ ÂÛØÅ 60%. Èìåéòå ñ ñîáîé ìóëüòèòóë Leatherman ÷òîáû óìåíüøèòü óðîí ïî îðóæèþ ïðè çàìåíå ÷àñòåé. %c[ui_gray_1]
\n• Äåòàëè îðóæèÿ òàê-æå ìîæíî áåñïëàòíî çàìåíèòü íà âåðñòàêå, èìåÿ ïðè ýòîì íóæíûé ðåìîíòíûé êîìëåêò. %c[pda_yellow]Ýòî îäèí èç äâóõ ñïîñîáîâ çàìåíû ñòâîëà.
\n \n
%c[pda_green]II. Óðîí ïî îðóæåéíûì ÷àñòÿì è Êëèíû%c[ui_gray_1]\n
\n• ×àñòè èìåþò 5 ñòóïåíåé ïîëîìêè: %c[d_red]ñëîìàí%c[ui_gray_1], %c[d_red]ïîâðåæäåí%c[ui_gray_1], %c[d_orange]èçíîøåí%c[ui_gray_1], %c[0,250,250,0]çàãðÿçíåí%c[ui_gray_1], %c[d_green]ðàáîòîñïîñîáåí%c[ui_gray_1]
\n• ×åì áîëüøå ïîâðåæäåíû äåòàëè, òåì âûøå øàíñ ïîëîìêè.
\n• Åñòü òðè òèïà ïîëîìêè: îñå÷êà, êëèí, è ñèëüíûé êëèí.
\n• Îñå÷êà è êëèí ìîãóò áûòü èñïðàâëåíû ïðîñòûì èñïðàâëåíèåì êëèíà.
\n• Ñèëüíûé êëèí òðåáóåò óäàëåíèåì ìàãàçèíà èç îðóæèÿ ïåðåä èñïðàâëåíèåì êëèíà.
\n• Ñòâîëû íå óâåëè÷èâàþò âåðîÿòíîñòü êëèíà. Îäíàêî, ãðÿçíîå èëè ñòåïåíü ïîëîìêè íèæå óìåíüøàþò óðîí îðóæèÿ äî 50%
\n• Ñòðåëüáà èç îðóæèÿ ìåíüøå 85% ïðî÷íîñòè(ïî óìîë÷àíèþ, ìîæíî èçìåíèòü â %c[pda_yellow]MCM: Ïîðîã ñîñòîÿíèÿ ïîâðåæäåíèÿ äåòàëè%c[ui_gray_1]) èìååò øàíñ íàíåñòè óðîí ïî ïðî÷íîñòè îðóæèÿ.
\n• Ñòðåëüáà èç îðóæèÿ âî âðåìÿ ñèëüíîãî äîæäÿ áóäåò óõóäøàòü ïðî÷íîñòü îðóæèÿ ãîðàçäî áûñòðåå.
\n• Ñòðåëüáà äëèííûìè î÷åðåäÿìè âûçûâàåò ïåðåãðåâ, êîòîðûé ïðèâîäèò ê êëèíàì è áîëåå áûñòðîìó óõóäøåíèþ ïðî÷íîñòè îðóæèÿ.
%c[pda_green]III. Èçìåíåíèÿ ýêîíîìèêè%c[ui_gray_1]\n
\n• Èñïîëüçóÿ ÷èñòÿùèé íàáîð î÷èñòèò "ãðÿçíûå" îðóæåéíûå ÷àñòè (âûøå 60% ïðî÷íîñòè)
\n• Ðåìîíòíûé íàáîð çàìåíèò õóäøóþ ïî ïðî÷íîñòè ÷àñòü.%c[pda_yellow]Ýòî äðóãîé ñïîñîá çàìåíèòü ñòâîë.%c[ui_gray_1]
\n• Òåõíèêè áóäóò ñëó÷àéíûì îáðàçîì ïðîäàâàòü îðóæåéíûå ÷àñòè ïî ñåðüåçíîé íàöåíêå.
\n• Îðóæåéíûå ÷àñòè ïî ïðî÷íîñòè âûøå 60% ìîãóò áûòü îòðåìîíòèðîâàíû íàïèëüíèêîì, øîìïîëîì èëè ìóëüòèòóëîì.
\n• Îðóæåéíûå ÷àñòè ïî ïðî÷íîñòè âûøå 10% ìîãóò áûòü îòðåìîíòèðîâàíû î÷åíü äîðîãèìè ðåì-êîìïëåêòàìè äîñòóïíûìè ó òðåéäåðîâ.
\n \n Ïî âñåì îñòàëüíûì âîïðîñàì, ïèøèòå arti#3278 â Discord (ðàçóìååòñÿ, íà àíãëèéñêîì). ß ñëèøêîì ëåíèâ ÷òîáû ÷èòàòü êîììåíòàðèè íà Moddb.
</text>
</string>
<string id="st_partskit">
<text>Êîìïëåêò äëÿ ðåìîíòà îðóæåéíûõ äåòàëåé</text>
</string>
<string id="st_partskit_descr">
<text>Âûñîêîòåõíîëîãè÷íûé íàáîð èíñòðóìåíòîâ âêëþ÷àÿ ìèêðî-íàïèëüíèêè, ìåòàëëè÷åñêóþ ýïîêñèäíóþ ñìîëó äëÿ õîëîäíîé ñâàðêè, óñòàíîâêó ýëåêòðîëèçíîé âàííû, è òîííû ñìàçî÷íûõ ìàòåðèàëîâ, áåíçèíîâûå äåñòèëëÿíòû è äðóãèå ðàñòâîðèòåëè. Ýòè èíñòðóìåíòû ìîãóò ïðåâðàòèòü äâèãàòåëü Ëàäû â Ôåððàðè, íå ãîâîðÿ î òîì ÷òî îí ìîæåò ñäåëàòü ñ äðóãèìè êîìïîíåíòàìè ìàøèíû. Òîëüêî ñàìûå ðàçðóøåííûå êóñêè ìåòàëëîëîìà íå ìîãóò áûòü âîññòàíîâëåíû ýòèì êîìïëåêòîì. Îäíàêî, ýòîò êîìïëåêò î÷åíü ñëîæíî ñîáðàòü â Çîíå, ïîýòîìó òåõíèêè ïðîäàþò åãî â î÷åíü íåáîëüøèõ êîëè÷åñòâàõ.\n\n</text>
</string>
<!-- Info -->
<string id="st_dot">
<text></text>
</string>
<string id="st_damage_missing">
<text>îòñóòñòâóåò:</text>
</string>
<string id="st_damage_0">
<text>ñëîìàíî:</text>
</string>
<string id="st_damage_1">
<text>ïîâðåæäåíî:</text>
</string>
<string id="st_damage_2">
<text>èçíîøåíî:</text>
</string>
<string id="st_damage_3">
<text>çàãðÿçíåíî:</text>
</string>
<string id="st_damage_4">
<text>ôóíêöèîíàëüíî:</text>
</string>
<string id="st_damage_5">
<text>èñïðàâíî:</text>
</string>
<string id="st_wpo_replace_parts">
<text>îáñëóæèâàíèå</text>
</string>
<string id="st_wpo_repair">
<text>âîññòàíîâèòü 25% ñîñòîÿíèÿ: </text>
</string>
<string id="st_wpo_replace">
<text>çàìåíèòü</text>
</string>
<string id="st_wpo_clean">
<text>î÷èñòèòü</text>
</string>
<string id="st_wpo_remove">
<text>äåìîíòèðîâàòü</text>
</string>
<string id="st_name_trigger">
<text>óäàðíî-ñïóñêîâîé ìåõàíèçì</text>
</string>
<string id="st_name_spring">
<text>âîçâðàòíûé ìåõàíèçì</text>
</string>
<string id="st_name_barrel">
<text>ñòâîë</text>
</string>
<string id="st_name_bolt_carrier">
<text>ïðîäîëüíî-ñêîëüçÿùèé çàòâîð</text>
</string>
<string id="st_name_bolt">
<text>óäàðíèê</text>
</string>
<string id="st_name_gas_tube">
<text>ãàç-áëîê</text>
</string>
<string id="st_name_extractor">
<text>ýêñòðàêòîð</text>
</string>
<string id="st_name_ejector">
<text>ýæåêòîð</text>
</string>
<string id="st_name_pump">
<text>ïîìïîâûé ìåõàíèçì</text>
</string>
<string id="st_name_hammers">
<text>ìîëîòîê</text>
</string>
<string id="st_name_chock">
<text>ïîäïîð</text>
</string>
<string id="st_name_all">
<text>âñå</text>
</string>
<string id="st_name_issues">
<text>ÑÎÑÒÎßÍÈÅ:</text>
</string>
</string_table>
@@ -0,0 +1,5 @@
<w>
<file name="ui\guide\article_wpo_image">
<texture id="article_wpo_image" x="0" y="0" width="700" height="271"/>
</file>
</w>
@@ -0,0 +1,17 @@
<w>
<background x="34" y="354" width="130" height="162" stretch="1">
<texture>ui_inGame2_workshop_craft_recipes</texture>
</background>
<button x="145" y="0" width="28" height="29" hint="st_wpn_service_dropdown" stretch="1">
<texture>ui_inGame2_btn_sort_weapon</texture>
</button>
<button2 x="145" y="0" width="28" height="29" stretch="1">
<texture>ui_inGame2_btn_sort_utility</texture>
</button2>
<txt_box x="302" y="742" width="68" height="29">
<text align="l" font="letterica16" color="ui_3"/>
</txt_box>
</w>
@@ -0,0 +1,2 @@
#include "weapon_*.ltx"
@@ -0,0 +1,73 @@
[base]
jam_chance = 0.001, 0.03, 0.07, 0.25, 0.5
max_jam_chance = 0.75
misfire_chance = 0, 0.01, 0.02, 0.04, 0.08
superjam_mult = 1
damage_chance_mult = 1
barrel_wear = 0.01
unjam_sound = handgun_unjam
jam_sound = PistolSmall_Malf
damage_sound = Weapon_Break
[base_pistol]:base
jam_chance = 0.001, 0.01, 0.02, 0.04, 0.08
; revolvers can only misfire
[base_revolver]:base
jam_chance = 0, 0, 0, 0, 0
superjam_mult = 0
jam_sound = ManuallyActivated_Malf
[base_smg]:base
unjam_sound = ar_unjam
jam_sound = PlasticReceiver_Malf
[base_shotgun_db]:base
unjam_sound = shotgun_unjam
barrel_wear = 0.1
jam_chance = 0, 0, 0.01, 0.03, 0.1
max_jam_chance = 0.2
superjam_mult = 0
misfire_chance = 0, 0.02, 0.04, 0.08, 0.16
jam_sound = ManuallyActivated_Malf
[base_shotgun_pump]:base
unjam_sound = shotgun_unjam
barrel_wear = 0.07
jam_chance = 0, 0.01, 0.05, 0.10, 0.15
superjam_mult = 0.5
jam_sound = Shotgun_Malf
[base_shotgun_semi]:base
unjam_sound = ak_unjam
barrel_wear = 0.05
jam_sound = Shotgun_Malf
[base_ak]:base
jam_chance = 0.001, 0.02, 0.05, 0.15, 0.30
unjam_sound = ak_unjam
jam_sound = AR_Malf
[base_ar]:base
unjam_sound = ar_unjam
jam_sound = AR_Malf
; lr300, l85
[base_ar_shitty]:base_ar
jam_chance = 0.001, 0.05, 0.10, 0.25, 0.5
superjam_mult = 2
[base_sniper_bolt]:base
unjam_sound = bolt_unjam
superjam_mult = 0
jam_sound = ManuallyActivated_Malf
[base_sniper_semi]:base
unjam_sound = ak_unjam
jam_sound = AR_Malf
[base_sniper_svt]:base
jam_chance = 0.001, 0.05, 0.15, 0.35, 0.75
damage_chance_mult = 2
superjam_mult = 2
jam_sound = AR_Malf
@@ -0,0 +1,280 @@
;Category: Weapons (Pistol)
[wpn_aps_bas]:base_pistol
[wpn_aps_bas_apsabigo]:base_pistol
[wpn_colt1911_n]:base_pistol
[wpn_glock17]:base_pistol
[wpn_glock17_m1]:base_pistol
[wpn_korth]:base_pistol
[wpn_korth_custom]:base_pistol
[wpn_pb_bas]:base_pistol
[wpn_pb_bas_custom]:base_pistol
[wpn_pl15]:base_pistol
[wpn_pl15_pl15_scolaz]:base_pistol
[wpn_pl15_tan]:base_pistol
[wpn_pl15_tan_pl15_scolaz]:base_pistol
[wpn_pm_bas]:base_pistol
[wpn_pm_bas_actor]:base_pistol
[wpn_pm_bas_custom]:base_pistol
[wpn_pmm_bas]:base_pistol
[wpn_sig220_n]:base_pistol
[wpn_sig220_n_u2p2g0r]:base_pistol
[wpn_sig220_n_upg220]:base_pistol
[wpn_sig226]:base_pistol
[wpn_sig226_226sig_kit]:base_pistol
[wpn_sr1m]:base_pistol
[wpn_sr1m_gurza_up]:base_pistol
[wpn_sr1m_sr1upgr1]:base_pistol
[wpn_usp_tac]:base_pistol
[wpn_walther_p99]:base_pistol
[wpn_walther_p99_mod9]:base_pistol
[wpn_fn57_bas]:base_pistol
;-------------------------------------------------------------------
;Category: Weapons (Shotgun)
[wpn_ks23]:base_shotgun_pump
[wpn_ks23_23_up]:base_shotgun_pump
[wpn_ks23_ecolog]:base_shotgun_pump
[wpn_ks23_kaban]:base_shotgun_pump
[wpn_ks23_kaban_kab_up]:base_shotgun_pump
[wpn_mp153_m1]:base_shotgun_pump
[wpn_saiga12s_isg]:base_shotgun_semi
[wpn_saiga12s_m1]:base_shotgun_semi
[wpn_saiga12s_m2]:base_shotgun_semi
[wpn_toz106]:base_sniper_bolt
[wpn_toz106_m1]:base_sniper_bolt
;-------------------------------------------------------------------
;Category: Weapons (SMG)
[wpn_sr2_m1]:base_smg
[wpn_sr2_veresk]:base_smg
[wpn_sr2_veresk_sr2_upkit]:base_smg
[wpn_sr2_m2]:wpn_sr2_veresk
[wpn_kiparis_m1]:base_smg
[wpn_kiparis_m2]:base_smg
[wpn_kiparis_m3]:base_smg
[wpn_kiparis_s]:base_smg
[wpn_vz61_scorpion_m1]:base_smg
[wpn_vz61_scorpion_m2]:base_smg
[wpn_ppsh_bas]:base_smg
;-------------------------------------------------------------------
;Category: Weapons (Rifle)
[wpn_abakan_n]:base_ak
[wpn_ak104_alfa]:base_ak
[wpn_ak105_shakal]:base_ak
[wpn_ak105_sp]:base_ak
[wpn_ak105_swamp]:base_ak
[wpn_ak12_bas]:base_ak
[wpn_ak12_custom]:base_ak
[wpn_ak12_custom_mono_kit]:base_ak
[wpn_ak12_mono_com]:base_ak
[wpn_ak12_m1]:base_ak
[wpn_ak5c_bas]:base_ak
[wpn_ak5c_bas_5c_tik]:base_ak
[wpn_ak5c_isg]:base_ak
[wpn_ak74_isg]:base_ak
[wpn_ak74_n]:base_ak
[wpn_ak74_pmc]:base_ak
[wpn_ak74m_beard]:base_ak
[wpn_ak74m_n]:base_ak
[wpn_ak74u_isg]:base_ak
[wpn_ak74u_m1_isg]:base_ak
[wpn_ak74u_n1]:base_ak
[wpn_ak74u_tac]:base_ak
[wpn_ak105_bas]:base_ak
[wpn_akm_alfa]:base_ak
[wpn_akm_bas]:base_ak
[wpn_akm_isg]:base_ak
[wpn_akms_bas]:base_ak
[wpn_ar15_freedom]:base_ar
[wpn_aug_a1_bas]:base_ar
[wpn_aug_a1_custom_bas]:base_ar
[wpn_aug_a3_bas]:base_ar
[wpn_aug_a3_custom_bas]:base_ar
[wpn_fal_aus]:base_ar
[wpn_fal_sa58_osw]:base_ar
[wpn_howa20]:base_ar
[wpn_l85_m1]:base_ar
[wpn_l85_m2]:base_ar
[wpn_l85_m3]:base_ar
[wpn_m4_butcher]:base_ar
[wpn_m4_ru556]:base_ar
[wpn_m4_tac]:base_ar
[wpn_m4a1_siber]:base_ar
[wpn_adar2_15]:wpn_m4_ru556
[wpn_m4_skryaga]:wpn_m4_ru556
[wpn_scar_l_tac]:wpn_m4_ru556
[wpn_rpk74_16]:base_ak
[wpn_sig550_siber]:base_ar
[wpn_sig550_tac_siber]:wpn_sig550_siber
[wpn_sig552_isg_siber]:wpn_sig550_siber
[wpn_sig552_siber]:wpn_sig550_siber
[wpn_sig552_tac_siber]:wpn_sig550_siber
[wpn_scar_siber]:base_ar
[wpn_scar_siber_black]:base_ar
[wpn_scar_siber_m1]:base_ar
[wpn_scar_siber_m1_black]:base_ar
[wpn_scar_siber_m2]:base_ar
[wpn_scar_siber_m2_custom]:base_ar
[wpn_g28]:base_ar
[wpn_val_tac]:base_ak
[wpn_vintorez_isg]:base_ak
[wpn_vintorez_m1]:base_ak
[wpn_vintorez_m2]:base_ak
[wpn_vintorez_n1]:base_ak
[wpn_pk_siber]:base_ak
[wpn_pkm_siber]:wpn_pk_siber
[wpn_pkm_zenit_shorty]:wpn_pk_siber
[wpn_pkm_zenit_siber]:wpn_pk_siber
[wpn_pkp_siber]:wpn_pk_siber
[wpn_pkp_tac_siber]:wpn_pk_siber
;-------------------------------------------------------------------
;Category: Weapons (Sniper)
[wpn_dvl10]:base_sniper_bolt
[wpn_dvl10_m1]:base_sniper_bolt
[wpn_k98_mod]:base_sniper_bolt
[wpn_k98_mod_silen98]:base_sniper_bolt
[wpn_remington700_bas]:base_sniper_bolt
[wpn_remington700_archangel]:base_sniper_bolt
[wpn_remington700_lapua700]:base_sniper_bolt
[wpn_rem700_aics]:wpn_remington700_lapua700
[wpn_rem700_mcmillan]:wpn_remington700_lapua700
[wpn_remington700_magpul_pro]:base_sniper_bolt
[wpn_remington700_mod_x_gen3]:base_sniper_bolt
[wpn_sks_b]:base_sniper_semi
[wpn_sks_molot]:base_sniper_semi
[wpn_sks_tac]:base_sniper_semi
[wpn_svd_m1]:base_sniper_semi
[wpn_svds]:base_sniper_semi
[wpn_svds_pmc]:base_sniper_semi
;-------------------------------------------------------------------
@@ -0,0 +1,80 @@
[wpn_aps]:base_pistol
jam_sound = Pistol_Malf
[wpn_pm]:base_pistol
[wpn_pm_custom]:base_pistol
[wpn_pmm]:base_pistol
[wpn_pb]:base_pistol
[wpn_pb_custom]:base_pistol
[wpn_tt33]:base_pistol
[wpn_tt33_modern]:base_pistol
[wpn_cz52]:base_pistol
[wpn_fort]:base_pistol
[wpn_fort_snag]:base_pistol
[wpn_mp443]:base_pistol
[wpn_gsh18]:base_pistol
[wpn_gsh18_custom]:base_pistol
[wpn_oc33]:base_pistol
jam_sound = Pistol_Malf
[wpn_cz75]:base_pistol
[wpn_cz75_auto]:base_pistol
[wpn_beretta]:wpn_oc33
[wpn_beretta_camo]:wpn_oc33
[wpn_beretta_modern]:wpn_oc33
[wpn_beretta_alt]:wpn_oc33
[wpn_hpsa]:base_pistol
[wpn_hpsa_alt]:base_pistol
[wpn_colt1911]:wpn_oc33
[wpn_colt1911_duty]:wpn_oc33
[wpn_colt1911_merc]:wpn_oc33
[wpn_colt1911_camo]:wpn_oc33
[wpn_colt1911_custom]:wpn_oc33
[wpn_colt1911_modern]:wpn_oc33
[wpn_colt1911_alt]:wpn_oc33
[wpn_colt1911_new]:wpn_oc33
[wpn_colt_kimber]:wpn_oc33
[wpn_sig220]:wpn_oc33
[wpn_sig220_custom]:wpn_oc33
[wpn_sig220_nimble]:wpn_oc33
[wpn_fn57]:base_pistol
[wpn_fnp45]:wpn_oc33
[wpn_fnp45_custom]:wpn_oc33
[wpn_fnx45]:wpn_oc33
[wpn_fnx45_custom]:wpn_oc33
[wpn_fnx45_alt]:wpn_oc33
[wpn_glock]:wpn_oc33
[wpn_glock_custom]:wpn_oc33
[wpn_glock_modern]:wpn_oc33
[wpn_usp]:wpn_oc33
[wpn_usp_custom]:wpn_oc33
[wpn_usp_match]:wpn_oc33
[wpn_usp_nimble]:wpn_oc33
[wpn_walther]:base_pistol
[wpn_walther_custom]:base_pistol
[wpn_desert_eagle]:wpn_oc33
[wpn_desert_eagle_custom]:wpn_oc33
[wpn_desert_eagle_modern]:wpn_oc33
[wpn_desert_eagle_nimble]:wpn_oc33
[wpn_mp412]:wpn_oc33
[wpn_mp5]:base_smg
[wpn_mp5_custom]:base_smg
[wpn_mp5_alt]:base_smg
[wpn_mp5sd]:base_smg
[wpn_mp5sd_custom]:base_smg
[wpn_mp5sd_new]:base_smg
[wpn_mp5_nimble]:base_smg
[wpn_mp7]:base_smg
[wpn_pp2000]:base_smg
[wpn_vityaz]:base_smg
[wpn_vz61]:base_smg
[wpn_vz61_freedom]:base_smg
[wpn_vz61_camo]:base_smg
[wpn_vz61_alt]:base_smg
[wpn_bizon]:base_smg
[wpn_kiparis]:base_smg
[wpn_ump45]:base_smg
[wpn_ump45_custom]:base_smg
[wpn_ppsh41]:base_smg
[wpn_ppsh41_woodnew]:base_smg
[wpn_ppsh41_rednew]:base_smg
@@ -0,0 +1,119 @@
[wpn_ak]:base_ak
[wpn_ash12]:base_ak
[wpn_9a91]:base_ak
[wpn_abakan]:base_ak
[wpn_abakan_camo]:base_ak
[wpn_ace21]:base_ak
[wpn_aek]:base_ak
[wpn_aek_camo]:base_ak
[wpn_aek_duty]:base_ak
[wpn_ak101]:base_ak
[wpn_ak101_camo]:base_ak
[wpn_ak102]:base_ak
[wpn_ak103]:base_ak
[wpn_ak103_camo]:base_ak
[wpn_ak104]:base_ak
[wpn_ak105]:base_ak
[wpn_ak12]:base_ak
[wpn_ak74]:base_ak
[wpn_ak74m]:base_ak
[wpn_ak74m_alt]:base_ak
[wpn_ak74m_camo]:base_ak
[wpn_ak74m_custom]:base_ak
[wpn_ak74m_duty]:base_ak
[wpn_ak74m_pka]:base_ak
[wpn_ak74u]:base_ak
[wpn_ak74u_camo]:base_ak
[wpn_ak74u_custom]:base_ak
[wpn_ak74u_old]:base_ak
[wpn_ak74u_snag]:base_ak
[wpn_ak74_alt]:base_ak
[wpn_ak74_custom]:base_ak
[wpn_ak74_modern]:base_ak
[wpn_ak74_old]:base_ak
[wpn_ak74_rpk]:base_ak
[wpn_akm]:base_ak
[wpn_akms]:base_ak
[wpn_akms_alt]:base_ak
[wpn_aks]:base_ak
[wpn_aks74]:base_ak
[wpn_aks74_new]:base_ak
[wpn_g43]:base_ak
[wpn_galil]:base_ak
[wpn_galil_custom]:base_ak
[wpn_galil_modern]:base_ak
[wpn_groza]:base_ak
[wpn_groza_nimble]:base_ak
[wpn_pkm]:base_ak
[wpn_pkm_zulus]:base_ak
[wpn_pkp]:base_ak
[wpn_rpk]:base_ak
[wpn_rpk74]:base_ak
[wpn_sks]:base_ak
[wpn_sks_modern]:base_ak
[wpn_sr25]:base_ak
[wpn_type63]:base_ak
[wpn_val]:base_ak
[wpn_val_modern]:base_ak
[wpn_vihr]:base_ak
[wpn_vintorez]:base_ak
[wpn_vintorez_1pn93]:base_ak
[wpn_vintorez_alt]:base_ak
[wpn_vintorez_nimble]:base_ak
[wpn_vsk94]:base_ak
[wpn_fal]:base_ak
[wpn_m60]:base_ak
[wpn_aug]:base_ar
jam_sound = PlasticReceiver_Malf
[wpn_aug_custom]:wpn_aug
[wpn_aug_freedom]:wpn_aug
[wpn_aug_merc]:wpn_aug
[wpn_aug_modern]:wpn_aug
[wpn_fn2000]:wpn_aug
[wpn_fn2000_camo]:wpn_aug
[wpn_fn2000_custom]:wpn_aug
[wpn_fn2000_nimble]:wpn_aug
[wpn_g3]:base_ar
[wpn_g36]:wpn_aug
[wpn_g36k]:wpn_aug
[wpn_g36_camo]:wpn_aug
[wpn_g36_nimble]:wpn_aug
[wpn_g3sg1]:base_ar
[wpn_fnc]:base_ar
[wpn_hk417]:base_ar
[wpn_aug_a3]:wpn_aug
[wpn_mk14]:base_ar
[wpn_scar]:base_ar
[wpn_scar_custom]:base_ar
[wpn_scar_new]:base_ar
[wpn_sig550]:base_ar
[wpn_sig550_camo]:base_ar
[wpn_sig550_custom]:base_ar
[wpn_sig550_luckygun]:base_ar
[wpn_sig550_sniper]:base_ar
[wpn_sig552]:base_ar
[wpn_hk416]:base_ar
[wpn_m16]:base_ar
[wpn_m16a2]:base_ar
[wpn_m249]:base_ar
[wpn_m4]:base_ar
[wpn_m4a1]:base_ar
[wpn_m4a1_camo]:base_ar
[wpn_m4a1_custom]:base_ar
[wpn_m4a1_freedom]:base_ar
[wpn_famas3]:base_ar
[wpn_l85]:base_ar_shitty
[wpn_l85a2]:wpn_l85
[wpn_l85a2_alt]:wpn_l85
[wpn_l85a2_custom]:wpn_l85
[wpn_l85a2_modern]:wpn_l85
[wpn_l85_alt]:wpn_l85
[wpn_l85_custom]:wpn_l85
[wpn_l85_modern]:wpn_l85
[wpn_lr300]:wpn_l85
[wpn_lr300_camo]:wpn_l85
[wpn_lr300_custom]:wpn_l85
@@ -0,0 +1,28 @@
[wpn_bm16]:base_shotgun_db
[wpn_bm16_alt]:base_shotgun_db
[wpn_bm16_full]:base_shotgun_db
[wpn_bm16_full_alt]:base_shotgun_db
[wpn_toz34]:base_shotgun_db
[wpn_toz34_custom]:base_shotgun_db
[wpn_toz34_decor]:base_shotgun_db
[wpn_toz34_mark4]:base_shotgun_db
[wpn_toz34_obrez]:base_shotgun_db
[wpn_toz34_obrez_custom]:base_shotgun_db
[wpn_toz34_obrez_decor]:base_shotgun_db
[wpn_toz34_bull]:base_shotgun_db
[wpn_mossberg590]:base_shotgun_pump
[wpn_mp133]:base_shotgun_pump
[wpn_fort500]:base_shotgun_pump
[wpn_mp153]:base_shotgun_pump
[wpn_spas12]:base_shotgun_pump
[wpn_spas12_custom]:base_shotgun_pump
[wpn_spas12_nimble]:base_shotgun_pump
[wpn_wincheaster1300]:base_shotgun_pump
[wpn_wincheaster1300_trapper]:base_shotgun_pump
[wpn_remington870]:base_shotgun_pump
[wpn_vepr]:base_shotgun_semi
[wpn_usas12]:base_shotgun_semi
[wpn_saiga12s]:base_shotgun_semi
@@ -0,0 +1,23 @@
[wpn_k98]:base_sniper_bolt
[wpn_l96a1]:base_sniper_bolt
[wpn_l96a1m]:base_sniper_bolt
[wpn_m24]:base_sniper_bolt
[wpn_mosin]:base_sniper_bolt
[wpn_remington700]:base_sniper_bolt
[wpn_sv98]:base_sniper_bolt
[wpn_sv98_custom]:base_sniper_bolt
[wpn_trg]:base_sniper_bolt
[wpn_m98b]:base_sniper_bolt
[wpn_svd]:base_sniper_semi
[wpn_svd_custom]:base_sniper_semi
[wpn_svd_nimble]:base_sniper_semi
[wpn_svt40]:base_sniper_svt
[wpn_svt40_modern]:base_sniper_semi
[wpn_svu]:base_sniper_semi
[wpn_svu_alt]:base_sniper_semi
[wpn_svu_nimble]:base_sniper_semi
[wpn_wa2000]:base_sniper_semi
[wpn_m82]:base_sniper_semi
[wpn_vssk]:base_sniper_semi
@@ -0,0 +1,182 @@
-- If you don't use MCM, change your defaults from here.
local defaults = {
["jamchance"] = 1,
["superjam"] = true,
["simplejam"] = false,
-- ["heat"] = false,
["oldammo"] = true,
["degradation"] = 1.4,
["threshold"] = 85,
["repairkit"] = true,
["altroll"] = false,
["altpartroll"] = false,
["saletype"] = 1,
-- ["fullservice"] = 2,
["easybarrel"] = false,
["easytrigger"] = true,
["profanity"] = true,
["profanity_timeout"] = true,
["profanity_language"] = "rus",
["verbosity"] = true,
["debug"] = false,
["fun"] = 0
}
local mcm_map = {
["jamchance"] = "wpojam",
["superjam"] = "wpojam",
["simplejam"] = "wpojam",
-- ["heat"] = "wpojam",
["oldammo"] = "wpojam",
["degradation"] = "wpoecon",
["threshold"] = "wpoecon",
["repairkit"] = "wpoecon",
["altroll"] = "wpoecon",
["altpartroll"] = "wpoecon",
["saletype"] = "wpoecon",
-- ["fullservice"] = "wpoecon",
["easybarrel"] = "wpoecon",
["easytrigger"] = "wpoecon",
["profanity"] = "wpomisc",
["profanity_timeout"] = "wpomisc",
["profanity_language"] = "wpomisc",
["verbosity"] = "wpomisc",
["debug"] = "wpomisc",
["fun"] = "wpomisc",
["display"] = "wpomisc"
}
local last_click = nil
local mcm_key = DIK_keys.DIK_F -- your default key
local key_function = "key_func" -- this too if you renamed the function
function key_func()
arti_jamming.unjam()
end
local mcm_id = "clear_jam"
local mcm_keybinds = ui_mcm and ui_mcm.key_hold
local modifier = 0
local second_key = 0
function get_config(key)
if ui_mcm then return ui_mcm.get("wpo/"..mcm_map[key].."/"..key) else return defaults[key] end
end
function on_mcm_load()
op = { id= "wpo" ,gr={
{
id="wpojam",sh=true,gr={
{id= "jamtitle",type= "slide",text="ui_mcm_wpo_wpojam",link= "ui_options_slider_player",size= {512,50},spacing= 20},
{id = "jamchance", type = "track", val = 2, min=0.5,max=2,step=0.01, def = 1},
{id = "superjam", type = "check", val = 1, def = true},
{id = "simplejam", type = "check", val = 1, def = false},
{id = "oldammo", type = "check", val = 1, def = true},
{ id = "keybind", type = "key_bind" , val = 2, def = mcm_key },
{ id = "modifier", type = ui_mcm.kb_mod_radio , val = 2, def = 1, hint = "mcm_kb_mode" ,
content = {
{ 0, "mcm_kb_mode_press"},
{ 1, "mcm_kb_mode_dtap"},
{ 2, "mcm_kb_mode_hold"}
}
},
{ id = "second_key", type = ui_mcm.kb_mod_radio, val = 2, def = 0, hint = "mcm_kb_modifier" ,
content = {
{0,"mcm_kb_mod_none"} ,
{1,"mcm_kb_mod_shift"} ,
{2,"mcm_kb_mod_ctrl"},
{3,"mcm_kb_mod_alt"}
}},
{ id = "desc_mcm", type = "desc", text = "ui_mcm_unjam_mcm", clr = {255, 175 ,0 ,0}, precondition = {function() return not mcm_keybinds end} }
}
},
{
id="wpoecon",sh=true,gr={
{id= "econtitle",type= "slide",text="ui_mcm_wpo_wpoecon",link="ui_options_slider_player",size= {512,50},spacing= 20},
{id = "degradation", type = "track", val = 2, min=1,max=3,step=0.1, def = 1.4},
{id = "threshold", type = "track", val = 2, min=60,max=99,step=1, def = 85},
{id = "repairkit", type = "check", val = 1, def = true},
{id = "altroll", type = "check", val = 1, def = false},
{id = "altpartroll", type = "check", val = 1, def = false},
-- {id = "fullservice", type = "radio_h", content={ {0, "clean"} , {1, "parts"}, {2, "full"}} ,val = 2, def = 2},
{id = "saletype", type = "list", val = 2, content={ {0,"vanilla"} , {1,"easy"}, {2,"hard"}}, def=1},
{id = "easybarrel", type = "check", val = 1, def = false},
{id = "easytrigger", type = "check", val = 1, def = true},
}
},
{
id="wpomisc",sh=true,gr={
{id= "misctitle",type= "slide",text="ui_mcm_wpo_wpomisc",link= "ui_options_slider_player",size= {512,50},link="",spacing= 20},
{id = "debug", type = "check", val = 1, def=false},
{id = "profanity", type = "check", val = 1, def = true},
{id = "profanity_timeout", type = "check", val = 1, def = true},
{id = "profanity_language", type = "radio_h", content={ {"eng","eng"} , {"rus","rus"}} ,val = 0, def ="rus"},
{id = "display", type = "check", val = 1, def = true},
{id = "verbosity", type = "check", val = 1, def = true},
{id = "fun", type = "list", val = 2, content={ {0,"no"} , {1,"yes"}, {2,"ofc"}}, def=0},
}
}
}
}
return op
end
local modes = {
[0] = { ["call"] = {"on_key_press", "on_key_hold"}, ["function"] = function(key) ui_mcm.simple_press(mcm_id, key, key_function) end },
[1] = { ["call"] = {"on_key_press", "on_key_hold"}, ["function"] = function(key) if ui_mcm.double_tap(mcm_id, key) then key_function() end end },
[2] = { ["call"] = {"on_key_hold", "on_key_press"}, ["function"] = function(key) if ui_mcm.key_hold(mcm_id, key) then key_function() end end }
}
function on_key_press(key)
if not ui_mcm then
local bind = dik_to_bind(key)
local tg = time_global()
if bind == key_bindings.kUSE then
if not last_click then last_click = tg
else
if tg < last_click + 400 then
key_func()
end
last_click = nil
end
end
end
if key ~= mcm_key then return end
if not mcm_keybinds then
key_function()
return
end
if ui_mcm.get_mod_key(second_key) then
modes[modifier]["function"](key)
end
end
function on_key_hold(key)
if key ~= mcm_key then return end
if ui_mcm.get_mod_key(second_key) then
modes[modifier]["function"](key)
end
end
function on_option_change(mcm)
if mcm then
mcm_key = ui_mcm.get("wpo/wpojam/keybind")
modifier = ui_mcm.get("wpo/wpojam/modifier")
second_key = ui_mcm.get("wpo/wpojam/second_key")
RegisterScriptCallback(modes[modifier]["call"][1], this[modes[modifier]["call"][1]])
UnregisterScriptCallback(modes[modifier]["call"][2], this[modes[modifier]["call"][2]])
end
end
function on_game_start()
RegisterScriptCallback("on_option_change", on_option_change)
RegisterScriptCallback("on_key_press", on_key_press)
key_function = this[key_function]
on_option_change(mcm_keybinds)
end
@@ -0,0 +1,178 @@
local ini_custom_repair = ini_file("repair\\importer.ltx")
-- Simple injector to replace min condition, add condition repair type and repair only, so we don't need to conflict over LTX files
function get_prop(section, prop, type)
type = type or 0
local ini_to_check = ini_custom_repair:section_exist(section) and ini_custom_repair or ini_sys
if type == 0 then
return ini_to_check:r_string_ex(section, prop) or ini_sys:r_string_ex(section, prop, "")
elseif type == 1 then
return ini_to_check:r_bool_ex(section, prop) or ini_sys:r_bool_ex(section, prop, false)
else
return ini_to_check:r_float_ex(section, prop) or ini_sys:r_float_ex(section, prop, 0)
end
end
-- Override props from LTX
function item_repair.UIRepair:Reset(obj,section)
self.section = section
self.obj = obj
-- Settings
self.repair_frame = ini_sys:r_string_ex(section,"repair_ui") or "ui_itm_repair_1"
self.use_condition = ini_sys:r_bool_ex(section,"use_condition") or false
self.min_condition = get_prop(section,"repair_min_condition", 2) or 0
self.max_condition = ini_sys:r_float_ex(section,"repair_max_condition") or 0
self.add_condition = get_prop(section,"repair_add_condition", 2) or 0
self.part_bonus = get_prop(section,"repair_part_bonus", 2) or 0
self.use_parts = ini_sys:r_bool_ex(section,"repair_use_parts") or false
self.repair_type = ini_sys:r_string_ex(section,"repair_type") or "all"
self.repair_only = parse_list(ini_sys,section,"repair_only",true)
self.parts_multi = ini_sys:r_float_ex(section,"repair_parts_multi") or 1
self.parts_sections = parse_list(ini_sys,section,"repair_parts_sections",true)
self.parts_match = get_prop(section,"repair_parts_match",1)
self.use_actor_effects = ini_sys:r_bool_ex(section,"repair_use_actor_effects",false)
self.con_val = {}
-- Elements
self.CC[2]:Reset()
self.con_txt[1]:SetText("")
self.con_txt[2]:SetText("")
self.text_item[1]:SetText("")
self.text_item[2]:SetText("")
self.cell_item[1]:Reset()
self.cell_item[2]:Reset()
self.con_txt_base:SetText("")
self.con_txt_new:SetText("")
self.btn_repair:Enable(false)
local to_show = self.use_parts and true or false
self.cap[2]:Show(to_show)
self.b_inv[2]:Show(to_show)
self.b_item[2]:Show(to_show)
self.text_item[2]:Show(to_show)
self.con_txt[2]:Show(to_show)
self.CC[2]:Show(to_show)
-- Set Repair kit icon
utils_xml.set_upgr_icon(self.obj, self.section, self.box_item_main, self.box_item_main_temp)
-- Set Repair kit name
self.cap_menu:SetText(ui_item.get_sec_name(self.section))
-- Show damaged items
self:InitInventory(1)
-- Hide active item
actor_effects.toggle_active_slot(0)
-- Play sound
if (self.repair_frame == "ui_itm_repair_1") or (self.repair_frame == "ui_itm_repair_2") then
utils_obj.play_sound("interface\\inv_zipper_open")
else
utils_obj.play_sound("interface\\inv_briefcase_light_open")
end
end
local str_tbl = {}
gc = game.translate_string
function refresh_strings()
str_tbl.workshop_tool = gc("st_itm_desc_workshop_tool")
str_tbl.repair_bonus = gc("st_itm_desc_outfit_repair_bonus")
str_tbl.repair_base_con = gc("st_itm_desc_repair_base_con")
str_tbl.repair_min_con = gc("st_itm_desc_repair_min_con")
str_tbl.require_tool = gc("st_itm_desc_outfit_required_tool")
str_tbl.repair_match = gc("st_itm_desc_repair_match")
end
math_ceil = math.ceil
local clr_o = utils_xml.get_color("d_orange")
local clr_1 = utils_xml.get_color("ui_gray_2")
local clr_2 = utils_xml.get_color("ui_gray_1")
local clr_p = utils_xml.get_color("d_purple")
local clr_b = utils_xml.get_color("d_cyan")
BuildFooter = ui_item.build_desc_footer
-- Override from UI
function ui_item.build_desc_footer(obj, sec, str)
if not ini_custom_repair:section_exist(sec) then return BuildFooter(obj, sec, str) end
str = str or gc(ini_sys:r_string_ex(sec,"description"))
if (not str) then return "" end
local _str = ""
if is_empty(str_tbl) then
refresh_strings()
end
-- Repair base condition
local repair_base = get_prop(sec,"repair_add_condition", 2)
if repair_base then
_str = _str .. clr_o .. " ".. gc("st_dot") .." " .. clr_1 .. " " .. str_tbl.repair_base_con .. ": " .. clr_2 .. " +" .. tostring(math_ceil(repair_base*100)) .. "% \\n"
end
-- Repair min condition
local repair_min = get_prop(sec,"repair_min_condition", 2)
if repair_min then
_str = _str .. clr_o .. " ".. gc("st_dot") .." " .. clr_1 .. " " .. str_tbl.repair_min_con .. ": " .. clr_2 .. " " .. tostring(math_ceil(repair_min*100)) .. "% \\n"
end
-- Repair bonus part
local repair_bonus = get_prop(sec,"repair_part_bonus", 2)
if repair_bonus then
_str = _str .. clr_o .. " ".. gc("st_dot") .." " .. clr_1 .. " " .. str_tbl.repair_bonus .. ": " .. clr_2 .. " +" .. tostring(math_ceil(repair_bonus*100)) .. "% \\n"
end
-- Repair match parts
local is_part_match = get_prop(sec,"repair_parts_match", 1)
if is_part_match then
_str = _str .. clr_b .. " ".. gc("st_dot") .." " .. clr_1 .. " " .. str_tbl.repair_match .. " \\n"
end
-- Workshop tool
local is_workshop_tool = get_prop(sec,"workshop_tool", 1)
if is_workshop_tool then
_str = _str .. clr_p .. " ".. gc("st_dot") .." " .. clr_1 .. " " .. str_tbl.workshop_tool .. " \\n"
end
str = str .. _str .. " \\n"
return str
end
ParseList = _G.parse_list
local override_secs = {
repair_parts_sections = true,
repair_only = true,
repair_parts_sections = true
}
function _G.parse_list(ini, key, val, convert)
--printf("Parsing key %s, val %s", key, val)
local ini_to_use = (override_secs[val] and ini_custom_repair:section_exist(key) and ini_custom_repair:r_string_ex(key, val)) and ini_custom_repair or ini
return ParseList(ini_to_use, key, val, convert)
end
-- mother fuck
GetList = _G.GetItemList
function _G.GetItemList(typ)
list = GetList(typ)
if typ == "repair" then
for k,v in pairs(list) do
if ini_custom_repair:section_exist(k) and ini_custom_repair:r_string_ex(k, "repair_only") then
list[k] = parse_list(ini_custom_repair, k, "repair_only", true)
end
end
end
return list
end
function on_game_start()
refresh_strings()
RegisterScriptCallback("on_localization_change",refresh_strings)
end
@@ -0,0 +1,57 @@
parts_list = {}
local ini_parts = itms_manager.ini_parts
-- GetCost = utils_item.get_item_cost
-- -- for mechanics, part prices are very high to buy
-- function utils_item.get_item_cost(obj, profile)
-- if not (obj and profile) or utils_item.on_get_item_cost then
-- return GetCost(obj, profile)
-- end
-- local sec = obj:section()
-- -- printf("profile cfg = %s, sec = %s, parent id %s", profile.cfg, sec, obj:parent() and obj:parent():id() or 0)
-- if profile.cfg == "items\\trade\\trade_generic_mechanic.ltx" and parts_list[sec] and obj:parent() and obj:parent():id() ~= 0 then
-- local discount = profile.discount
-- local cost_final = discount * parts_list[sec]
-- -- printf("Set sale cost of %s to be %s", sec, cost_final)
-- return cost_final
-- else
-- return GetCost(obj, profile)
-- end
-- end
GetStatus = utils_item.get_item_trade_status
function utils_item.get_item_trade_status(obj, profile)
if not (obj and profile) or profile.mode == 2 then
return GetStatus(obj, profile)
end
if not (IsWeapon(obj) and (not IsItem("fake_ammo_wpn",obj:section()))) or (obj:parent() and obj:parent():id() ~= 0) then return GetStatus(obj, profile) end
local parts = se_load_var(obj:id(), obj:name(), "parts")
-- printf("Checking parts for %s", obj:section())
if not parts then return GetStatus(obj, profile) end
local has_broken, has_missing = false, false
for k,v in pairs(parts) do
if parts_list[k] and v < 60 then
-- printf("weapon %s has busted part %s", obj:section(), k)
has_broken = true
if v == -1 then has_missing = true end
end
end
if has_missing or ( a_arti_jamming_mcm.get_config("saletype") == 2 and has_broken) then
return 2
else
return GetStatus(obj, profile)
end
end
function on_game_start()
local prices = ini_file("items\\settings\\part_prices.ltx")
local part_section = utils_data.collect_section(prices, "wpo_part_prices")
local n = prices:line_count("wpo_part_prices") or 0
for i=0, n-1 do
local result, sec, value = prices:r_line("wpo_part_prices" , i , "", "")
parts_list[sec] = value
end
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,62 @@
-- Currently unimplemented.
-- Project heat bar and automatically jam gun when it fills.
local time_quant
local decrease_quant
local heat_per_shot = 10
-- return overheat base amount (factor in section and suppressor)
function get_overheat_base(weapon)
if not weapon then return end
local sec_p = parent_section(weapon:section())
local overheat_base = ini_overheat:r_float_ex("custom_overheat", sec_p) or overheat_data.base
if weapon:weapon_is_silencer() then overheat_base = overheat_base * overheat_data.suppressor_mult end
return overheat_base
end
function get_heat()
return cgd.heat.level
end
function actor_on_update()
-- overheat checks
if db.actor:active_item() and cgd.has_parts then
manage_overheat(db.actor:active_item())
end
end
-- this should only be invoked if the weapon can be overheated
function manage_overheat(wpn)
-- ignore if not current (somehow)
if not wpn or wpn:id() ~= cgd.id then return end
if cgd.heat.level < cgd.heat.overheat_threshold then
decrease_quant = 0.15
else
decrease_quant = 0.05
end
local sec = wpn:section()
if not wpn then return end
if (string.match(tostring(sec),"knife") or string.match(tostring(sec),"axe")) then return end
if IsWeapon(wpn) and cgd.heat.level > 0 and data.weapon_state ~= 5 then
-- decrease quantity over time when not shooting
cgd.heat.level = clamp(cgd.heat.level - decrease_quant, 0, cgd.heat.overheat_max)
end
end
-- return overheat damage modifier for current weapon, weapon itself is passed to get some convenience things
-- if you are not passing current, return just 1
-- eval returns multiplier, pass false gives just level
function get_overheat_modifier(weapon, eval)
if true--not get_config("heat")
then return eval and 1 or 0 end
local id = weapon:id()
if eval == nil then eval = true end
if id ~= cgd.id then return 1 end
local overheat_base = cgd.heat.overheat_base
local heat_severity = math.floor(cgd.heat.level/overheat_base)
if heat_severity > 0 then
return eval and overheat_data.damage[heat_severity] or heat_severity
else return eval and 1 or 0 end
end
@@ -0,0 +1,24 @@
-- Placeholder for older versions
-- local last_click = nil
-- local function on_key_press(key)
-- local bind = dik_to_bind(key)
-- local tg = time_global()
-- if bind == key_bindings.kUSE then
-- if not last_click then last_click = tg
-- else
-- if tg < last_click + 400 then
-- arti_jamming.unjam()
-- end
-- last_click = nil
-- end
-- end
-- end
-- function on_game_start()
-- RegisterScriptCallback("on_key_press",on_key_press)
-- end
@@ -0,0 +1,538 @@
--[[
Custom Dynamic Functors, written by demonized
Allows to add/remove item functors dynamically from script
Can override ltx-defined functors and can remove the override to return back to ltx functor
To use in your script look at example below
---------------------------------------------------------------------------------------------------------------------
local function name_condition_function(obj, bag, mode)
if obj then
return true
end
end
local function name_function(obj, bag, mode)
return "st_my_functor_string_in_xml"
end
local function action_condition_function(obj, bag, mode)
if obj then
return true
end
end
local function action_function(obj, bag, mode)
alife_create_item(obj:section(), db.actor)
end
local add_functor = custom_functor_autoinject.add_functor
add_functor("my_name_of_functor", name_condition_function, name_function, action_condition_function, action_function, override_bags<true, false>)
---------------------------------------------------------------------------------------------------------------------
to add your functor you use add_functor function which requires these arguments in order:
name: string, your name of your functor, can be any string.
If the name of functor already exists this function will overwrite functions for it
name_condition_function: function, the condition at which you will get your right-click option for item
name_function: function, the name itself, must return string ID defined in XML files for your option.
if set to return nil, the option won't appear
action_condition_function: function, the condition at which the action will be performed, usually its the same as name_condition_function
you can put nil into argument to use the same function as name_condition_function
action_function: function, the action itself to perform
override_bags: boolean. If its true, then you can override bags and modes to check for condition, otherwise it will use defaults (mode == "inventory" and bag == "actor_bag" or bag == "actor_equ" or bag == "actor_belt")
functions themselves accept obj, bag and mode arguments
obj: current object you right-clicked
bag: current bag, list of possible bags: {"actor_equ","actor_belt","actor_bag","actor_trade_bag","actor_trade","npc_bag","npc_trade","npc_trade_bag"}
mode: current mode, list of possible modes: {"inventory" , "loot" , "trade" , "repair"}
bag and mode is not enabled unless you set override_bags flag to true
removal of functor is done by calling this
--------------------------------------------------------------------------------------
local remove_functor = custom_functor_autoinject.remove_functor
remove_functor("my_name_of_functor")
--------------------------------------------------------------------------------------
you can also override existing functors defined in item's ltx by using this
---------------------------------------------------------------------------------------------------------------------
local override_functor = custom_functor_autoinject.override_functor
override_functor(slot, name_condition_function, name_function, action_condition_function, action_function, override_bags<true, false>)
---------------------------------------------------------------------------------------------------------------------
arguments are same, except you have to provide the slot (first argument) for your override. The slots are 1-10
for example if item's ltx have use1_functor and use1_action_functor then
if you want to override it you have to provide slot 1
be aware that if your name_condition_function or action_condition_function may return false
then old functor will be fired
if you don't want that behaviour, you can define generic "return true" function for those
and check condition for firing in name_function and action_function
removal of override is done by calling this
--------------------------------------------------------------------------------------
local remove_override = custom_functor_autoinject.remove_override
remove_override(slot)
--------------------------------------------------------------------------------------
--]]
local function func_index(t,a,b)
return (t[a].index) < (t[b].index)
end
local function func_index_reverse(t,a,b)
return (t[a].index) > (t[b].index)
end
local function func_value(t, a, b)
return t[a] < t[b]
end
local spairs = spairs
local string_find = string.find
local string_gsub = string.gsub
local table_remove = table.remove
local tonumber = tonumber
local unpack = unpack
--Recursive print of tables similar to PHP print_r function
local function print_r(t)
local print_r_cache={}
local function sub_print_r(t,indent)
if (print_r_cache[tostring(t)]) then
printf(indent.."*"..tostring(t))
else
print_r_cache[tostring(t)]=true
if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
printf(indent.."["..pos.."] => "..tostring(t).." {")
sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
printf(indent..string.rep(" ",string.len(pos)+6).."}")
else
printf(indent.."["..pos.."] => "..tostring(val))
end
end
else
printf(indent..tostring(t))
end
end
end
sub_print_r(t," ")
end
local function print_table(table, subs)
local sub
if subs ~= nil then
sub = subs
else
sub = ""
end
for k,v in pairs(table) do
if type(v) == "table" then
print_table(v, sub.."["..k.."]----->")
elseif type(v) == "function" then
printf(sub.."%s = function",k)
elseif type(v) == "userdata" then
if (v.x) then
printf(sub.."%s = %s",k,utils_data.vector_to_string(v))
else
printf(sub.."%s = userdata", k)
end
elseif type(v) == "boolean" then
if v == true then
if(type(k)~="userdata") then
printf(sub.."%s = true",k)
else
printf(sub.."userdata = true")
end
else
if(type(k)~="userdata") then
printf(sub.."%s = false", k)
else
printf(sub.."userdata = false")
end
end
else
if v ~= nil then
printf(sub.."%s = %s", k,v)
else
printf(sub.."%s = nil", k,v)
end
end
end
end
-- Removing element from table and shifting down both key and value
-- Modes: 0 - index, 1 - value, 2 - key, 3 - key-index
local function table_remove_shift(t, val, mode)
local removed = false
local res
if mode == 0 then
for k, v in spairs(t, func_index) do
if removed then
t[k - 1] = v
if t[k - 1].index then
t[k - 1].index = t[k - 1].index - 1
end
if t[k - 1].properties_index then
t[k - 1].properties_index = t[k - 1].properties_index - 1
end
t[k] = nil
elseif v.index and v.index == val then
res = t[k]
t[k] = nil
removed = true
end
end
elseif mode == 1 then
for k, v in spairs(t, func_value) do
if removed then
t[k - 1] = v - 1
t[k] = nil
elseif v == val then
res = t[k]
t[k] = nil
removed = true
end
end
elseif mode == 2 then
for k, v in spairs(t, func_value) do
if removed then
t[k] = v - 1
elseif v == val then
res = t[k]
t[k] = nil
removed = true
end
end
elseif mode == 3 then
for k, v in spairs(t, func_index) do
if removed then
if t[k].index then
t[k].index = t[k].index - 1
end
elseif v.index and v.index == val then
res = t[k]
t[k] = nil
removed = true
end
end
end
return res
end
local ui_inventory_init = ui_inventory.UIInventory.__init
ui_inventory.UIInventory.__init = function(self)
ui_inventory_init(self)
self.custom_functor = {}
self.custom_functor_names = {}
end
local NameCustom = ui_inventory.UIInventory.Name_Custom
function ui_inventory.UIInventory:Name_Custom(obj, bag, temp, i)
obj = self:CheckItem(obj,"Name_Custom " .. i)
if self.custom_functor[i] and self.custom_functor[i].cond_name(obj, bag, self.mode) then
return self.custom_functor[i].func_name(obj, bag, self.mode)
else
return NameCustom(self, obj, bag, temp, i)
end
end
local ActionCustom = ui_inventory.UIInventory.Action_Custom
function ui_inventory.UIInventory:Action_Custom(obj, bag, temp, i)
obj = self:CheckItem(obj,"Action_Custom " .. i)
if self.custom_functor[i] and self.custom_functor[i].cond_action(obj, bag, self.mode) then
return self.custom_functor[i].func_action(obj, bag, self.mode)
else
return ActionCustom(self, obj, bag, temp, i)
end
end
ui_inventory.UIInventory.get_max_custom_functor = function(self)
local max = 0
local max_custom = {}
local max_index = 0
for k, v in pairs(self.properties) do
if string_find(k, "custom_.*") then
if v.index > max_index then
max_index = v.index
end
local x = tonumber(string_gsub(k, "custom_(.*)", "%1"), nil)
if x > max then
max = x
max_custom = v
end
end
end
return max, max_custom, max_index
end
local modes = {
["inventory"] = true,
["loot"] = true,
["trade"] = true,
["repair"] = true
}
local bags = {
["actor_equ"] = true,
["actor_belt"] = true,
["actor_bag"] = true,
["actor_trade_bag"] = true,
["actor_trade"] = true,
["npc_bag"] = true,
["npc_trade"] = true,
["npc_trade_bag"] = true
}
ui_inventory.UIInventory.Mode_Custom_Functor = function(self, obj, bag, temp, i)
return modes[self.mode]
end
ui_inventory.UIInventory.Cont_Custom_Functor = function(self, obj, bag, temp, i)
return bags[bag]
end
ui_inventory.UIInventory.add_custom_functor = function(self, name, cond_name, func_name, cond_action, func_action, override_bags)
local custom_functor_slot
if self.custom_functor_names[name] then
custom_functor_slot = self.custom_functor_names[name]
self.custom_functor[custom_functor_slot].cond_name = cond_name
self.custom_functor[custom_functor_slot].func_name = func_name
self.custom_functor[custom_functor_slot].cond_action = cond_action
self.custom_functor[custom_functor_slot].func_action = func_action
self.properties["custom_" .. custom_functor_slot].mode_func[1] = override_bags and "Mode_Custom_Functor" or "Mode_Custom"
self.properties["custom_" .. custom_functor_slot].cont_func[1] = override_bags and "Cont_Custom_Functor" or "Cont_Custom"
else
local max, max_custom, max_index = self:get_max_custom_functor()
local custom_num = max + 1
local properties_num = max_index + 1
for k, v in spairs(self.properties, func_index_reverse) do
if v.index > max_index then
printf("%s, %s", k, v.index)
v.index = v.index + 1
else
printf("%s, %s, max custom_functor reached", k, v.index)
break
end
end
self.properties["custom_" .. custom_num] = {
index = properties_num,
name_func = {"Name_Custom", max_custom["name_func"][2] + 1},
mode_func = {override_bags and "Mode_Custom_Functor" or "Mode_Custom", max_custom["mode_func"][2] + 1},
cont_func = {override_bags and "Cont_Custom_Functor" or "Cont_Custom", max_custom["cont_func"][2] + 1},
precondition1 = {"Name_Custom", max_custom["precondition1"][2] + 1},
action = {"Action_Custom", max_custom["action"][2] + 1}
}
custom_functor_slot = custom_num
self.custom_functor[custom_functor_slot] = {
index = custom_functor_slot,
properties_index = properties_num,
name = name,
cond_name = cond_name,
func_name = func_name,
cond_action = cond_action,
func_action = func_action
}
self.custom_functor_names[name] = custom_functor_slot
end
end
ui_inventory.UIInventory.remove_custom_functor = function(self, name)
if not self.custom_functor_names[name] then return end
local index = table_remove_shift(self.custom_functor_names, self.custom_functor_names[name], 2)
if not index then return end
local custom_functor = table_remove_shift(self.custom_functor, index, 0)
if not custom_functor then return end
local removed = false
for k, v in spairs(self.properties, func_index) do
if string_find(k, "custom_.*") then
if removed then
local x = tonumber(string_gsub(k, "custom_(.*)", "%1"), nil) - 1
self.properties["custom_" .. x] = self.properties[k]
self.properties["custom_" .. x].index = self.properties["custom_" .. x].index - 1
self.properties["custom_" .. x].name_func[2] = self.properties["custom_" .. x].name_func[2] - 1
self.properties["custom_" .. x].mode_func[2] = self.properties["custom_" .. x].mode_func[2] - 1
self.properties["custom_" .. x].cont_func[2] = self.properties["custom_" .. x].cont_func[2] - 1
self.properties["custom_" .. x].precondition1[2] = self.properties["custom_" .. x].precondition1[2] - 1
self.properties["custom_" .. x].action[2] = self.properties["custom_" .. x].action[2] - 1
self.properties[k] = nil
elseif v.index == custom_functor.properties_index then
self.properties[k] = nil
removed = true
end
elseif removed then
v.index = v.index - 1
end
end
end
ui_inventory.UIInventory.override_functor = function(self, slot, cond_name, func_name, cond_action, func_action, override_bags)
self.custom_functor[slot] = {
cond_name = cond_name,
func_name = func_name,
cond_action = cond_action,
func_action = func_action
}
self.properties["custom_" .. slot].mode_func[1] = override_bags and "Mode_Custom_Functor" or "Mode_Custom"
self.properties["custom_" .. slot].cont_func[1] = override_bags and "Cont_Custom_Functor" or "Cont_Custom"
end
ui_inventory.UIInventory.remove_override = function(self, slot)
self.custom_functor[slot] = nil
self.properties["custom_" .. slot].mode_func[1] = "Mode_Custom"
self.properties["custom_" .. slot].cont_func[1] = "Cont_Custom"
end
ui_inventory.UIInventory.get_functor_at_slot = function(self, slot)
return self.custom_functor[slot]
end
ui_inventory.UIInventory.get_functor_by_name = function(self, name)
if self.custom_functor_names[name] then
return self.custom_functor[self.custom_functor_names[name]], self.custom_functor_names[name]
end
end
-- Adding
local first_update_pending = true
local functor_queue = {}
local function add_to_queue(type, ...)
functor_queue[#functor_queue + 1] = {
type = type,
data = {...}
}
end
local function process_queue()
if not ui_inventory.GUI then
ui_inventory.GUI = ui_inventory.UIInventory()
end
printf("Custom functors, processing queue")
for i, v in ipairs(functor_queue) do
printf("Custom functors, type %s", v.type)
ui_inventory.GUI[v.type](ui_inventory.GUI, unpack(v.data))
end
functor_queue = {}
first_update_pending = false
end
local function actor_on_first_update()
process_queue()
end
function add_functor(name, cond_name, func_name, cond_action, func_action, override_bags)
if not name then return end
local cond_action = cond_action or cond_name
if first_update_pending then
add_to_queue("add_custom_functor", name, cond_name, func_name, cond_action, func_action, override_bags)
return
end
ui_inventory.GUI:add_custom_functor(name, cond_name, func_name, cond_action, func_action, override_bags)
end
function remove_functor(name)
if not name then return end
if first_update_pending then
add_to_queue("remove_custom_functor", name)
return
end
ui_inventory.GUI:remove_custom_functor(name)
end
function override_functor(slot, cond_name, func_name, cond_action, func_action, override_bags)
if slot < 1 or slot > 10 then
printf("functor slot is not valid, min 1, max 10, your slot: %s", slot)
return
end
local cond_action = cond_action or cond_name
if first_update_pending then
add_to_queue("override_functor", slot, cond_name, func_name, cond_action, func_action, override_bags)
return
end
ui_inventory.GUI:override_functor(slot, cond_name, func_name, cond_action, func_action, override_bags)
end
function remove_override(slot)
if slot < 1 or slot > 10 then
printf("functor slot is not valid min 1, max 10, your slot: %s", slot)
return
end
if first_update_pending then
add_to_queue("remove_override", slot)
return
end
ui_inventory.GUI:remove_override(slot)
end
function get_functor_at_slot(slot)
if first_update_pending then
add_to_queue("get_functor_at_slot", slot)
return
end
return ui_inventory.GUI:get_functor_at_slot(slot)
end
function get_functor_by_name(name)
if first_update_pending then
add_to_queue("get_functor_by_name", name)
return
end
return ui_inventory.GUI:get_functor_by_name(name)
end
function print_properties()
if not ui_inventory.GUI then
ui_inventory.GUI = ui_inventory.UIInventory()
end
for k, v in spairs(ui_inventory.GUI.properties, func_index) do
printf("[" .. k .. "] => ")
print_r(v)
end
end
function print_custom_functor()
if not ui_inventory.GUI then
ui_inventory.GUI = ui_inventory.UIInventory()
end
print_r(ui_inventory.GUI.custom_functor)
end
function print_custom_functor_names()
if not ui_inventory.GUI then
ui_inventory.GUI = ui_inventory.UIInventory()
end
print_r(ui_inventory.GUI.custom_functor_names)
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
end
@@ -0,0 +1,6 @@
GetEcoFactor = game_difficulties.get_eco_factor
function game_difficulties.get_eco_factor(str)
if (str == "percentage_parts") then return true
else return GetEcoFactor(str) end
end
@@ -0,0 +1,107 @@
-- monkeypatchable inv upgrades to effect repair cost
-- inv upgrades
ini_parts = itms_manager.ini_parts
function section_has_parts(sec)
local psec = ini_sys:r_string_ex(sec,"parent_section") or sec
local parts = ini_parts:r_string_ex("con_parts_list", psec)
return parts ~= nil
end
-- mp meeeee
function how_much_repair( item_name, item_condition )
local cost = ini_sys:r_u32(item_name, "cost")
local class = ini_sys:r_string_ex(item_name, "class")
local cof = game_difficulties.get_eco_factor("repair") or 1.67
--return math.floor( cost * factor * math.pow(1 - item_condition , 1.63) )
return math.floor( cost * (1 - item_condition) * cof ) -- CoP formula
end
function inventory_upgrades.can_afford_repair_item( item_name, item_condition )
local price = how_much_repair( item_name, item_condition )
if db.actor:money() < price then
return false
end
return true
end
function inventory_upgrades.question_repair_item( item_name, item_condition, can, mechanic ) --( string, float, bool, string )
if(item_name=="pri_a17_gauss_rifle") then
return game.translate_string("st_gauss_cannot_be_repaired")
end
if can then
local price = how_much_repair( item_name, item_condition )
if db.actor:money() < price then
return game.translate_string("st_upgr_cost")..": "..price.." RU\\n"..game.translate_string("ui_inv_not_enought_money")..": "..price-db.actor:money().." RU"
end
return game.translate_string("st_upgr_cost").." "..price.." RU. "..game.translate_string("ui_st_inv_repair").."?"
end
return nil
end
function inventory_upgrades.effect_repair_item( item_name, item_condition)
local price = how_much_repair( item_name, item_condition )
db.actor:give_money(-price)
if (ui_options.get("gameplay/general/mechanic_feature") ~= true) then
return
end
local item
local function itr(actor,itm)
if (itm and itm:section() == item_name and itm:condition() == item_condition) then
item = itm
return true
end
return false
end
db.actor:iterate_inventory(itr,db.actor)
if (item) then
local cls = item:clsid()
if (cls == "WP_BINOC") then
return
end
local victim = get_speaker()
if (victim) then
local damage_factor = 1.0 - clamp(item_condition, 0.0, 1.0)
inventory_upgrades.lend_item_for_repair(item,victim:section(),6000*damage_factor)
end
end
end
local repair_id
OnRepair = ui_inventory.UIInventory.RMode_OnRepair
function ui_inventory.UIInventory:RMode_OnRepair()
self:Print(nil, "RMode_OnRepair")
if (not self.upgr.id) then
return
end
local obj = level.object_by_id(self.upgr.id)
if (not obj) then
return
end
repair_id = self.upgr.id
OnRepair(self)
end
RepairYes = ui_inventory.UIInventory.RMode_RepairYes
function ui_inventory.UIInventory:RMode_RepairYes()
RepairYes(self)
repair_id = nil
end
function get_repair_id()
return repair_id
end
@@ -0,0 +1,125 @@
-- LAgrange inteRPolation library
-- algorithm by peete-q
-- Migrated to Anomaly by Asshall
-- Modified and modularized by arti
-- To calculate non linear probability I used a type of interpolation called "Lagrange interpolation".
-- The basic premise is that you input coordinates for x and y, for the exemple of loot x is the condition of the item to drop and y is the probability to drop such condition
-- For exemple if I input :
-- x | y
-- 2 | 0
-- 25 | 85
-- The probability of getting an item between 2 and 25 % condition is distributed between 0% proba and 85%
-- So in theory there is a 0 percent chance to get a 2% condition drop
-- and a 85% chance to get a 25% condition item with the probalities smoothly distributed between those two
-- This is an overly simplified explication because it's the best I can do, but the gist is that by interpolating n point in a curve you can get an approximation of the y value for all x
-- In this case x represents the condition and y the number to beat to drop.
-- Here is a table exemple
-- [weapon_coords]
-- novice = 2, 25, 50 : 5, 85, 99
-- trainee = 2, 25, 50 : 10, 81 ,99
-- experienced = 2, 25, 50 : 15, 76 ,98
-- professional = 2, 25, 50, 65 : 20 ,71 ,97, 99
-- veteran = 2, 25, 50, 65 : 20 ,68 ,96, 99
-- expert = 2, 25, 50, 65 : 20 ,64 ,95, 99
-- master = 2, 25, 50, 65 : 20 ,62 ,95, 98
-- legend = 2, 25, 50, 65 : 20 ,57 ,94, 98
-- I did not implement that, peete-q did : https://github.com/peete-q/assets/blob/master/lua-modules/lib/interpolate.lua All credits goes to them
function lagrange(data, xi)
local x = data["x"]
local y = data["y"]
xi = tonumber(xi)
local n = #x
-- Need the same number of points otherwise exit out
if n ~= #y then return end
-- Brilliant optimisation by peete-q
local i = 1
while i <= n and x[i] < xi do
i = i + 1
end
local m = math.min(i + 3, n)
local k = math.max(i - 4, 1)
local result = 0
for i=k, m do
local term = y[i]
for j=k, m do
if j ~= i then
term = term*( (xi - x[j]) / (x[i] - x[j]) )
end
end
result = result + term -- term used to be on at the start multiplied by y[i] on this line. Don't know if that makes a difference. It's more lisible for me and I'm a dumb ape
end
return clamp(result,math.min(unpack(y)),math.max(unpack(y))) -- Here I clamp the result cause largrange interp can do some weird sutff and go above maxy/bellow miny between two xs
-- This is suboptimal... Maybe i'm not using the right interp for some data sets or I shouldn't be using interp for those at all. It'll do for now.
end
-- Return min a max of data set of format {x,y} in order minx, maxx, miny, maxy
function get_min_max(coords)
return math.min(unpack(coords["x"])), math.max(unpack(coords["x"])), math.min(unpack(coords["y"])), math.max(unpack(coords["y"]))
end
-- str_explode but they get parsed into numbers
function str_explode_num(str, sep, plain)
if not (str and sep) then
printe("!ERROR str_explode | missing parameter str = %s, sep = %s",str,sep)
callstack()
end
if not (sep ~= "" and str:find(sep,1,plain)) then
return { tonumber(str) }
end
local t = {}
local size = 0
for s in str:gsplit(sep,plain) do
size = size + 1
t[size] = tonumber(trim(s))
end
return t
end
-- input:
-- coords is a table with x and y, each a list of integers
-- iterations is how many times to run, pass nil to run until we get something
-- returns a weighted value within the x range based on weights in y
function pick(coords, max_iterations)
if is_empty(coords) then return 0 end
if #coords["x"] ~= #coords["y"] then
printe("Input for coord string %s produced inequal output, returning", str)
return 0
end
local minx, maxx, miny, maxy = get_min_max(coords)
local iter = 0
while true do
rnd_x = math.random(minx, maxx)
local y = lagrange(coords, rnd_x)
if math.random(miny, maxy) + math.random() > y then
return round(rnd_x)
end
iter = iter + 1
if max_iterations and iter >= max_iterations then
return rnd_x
end
end
end
-- input: str of format:
-- X1, X2, X3...XN : Y1, Y2, Y3...Yn
function str_to_coords(str)
coords = {
["x"] = {},
["y"] = {},
}
buffer = str_explode(str, ":")
coords["x"] = str_explode_num(buffer[1], ",")
coords["y"] = str_explode_num(buffer[2], ",")
if #coords["x"] ~= #coords["y"] then
printe("Input for coord string %s produced inequal output, returning", str)
return nil
end
return coords
end
@@ -0,0 +1,25 @@
-- mag support wrapper
local function supports_mags(wpn)
if wuut_mags then
local defaultMagSection = wuut_mags.WeaponGetDefaulMagSection(wpn)
local defaultMagSectionExists = system_ini():section_exist(defaultMagSection)
return defaultMagSectionExists
elseif magazines then
return magazine_binder.is_supported_weapon(wpn)
else return false
end
end
function eject_mag(wpn)
if not supports_mags(wpn) then
wpn:force_unload_magazine(true)
return
end
if wuut_mags and wuut_mags.MagazineInWeaponIsValid(wpn) then
return wuut_mags.weapon_eject_mag_functor(wpn)
elseif magazines then
magazines.eject_magazine(wpn)
else wpn:force_unload_magazine(true) end
end
@@ -0,0 +1,201 @@
--[[
Wrapper class to let you autoinject things via monkey patch to all traders, respecting the restock time.
How to use: Monkey patch the update function here in your script.
ex:
TraderAuto = trader_autoinject.update
function trader_autoinject.update(npc)
TraderAuto(npc)
add_custom_crap(npc) -- you define this function ok
end
Some functions provided below for convenience.
Note: If you want to iterate NPC inventory to check for items, fire a time event to allow the items to register on new game.
--]] --
find = string.find
local function t2c(t)
if not t then return nil end
local ct = game.CTime()
ct:set(t.Y,t.M,t.D,t.h,t.m,t.s,t.ms)
return ct
end
local function c2t(ct)
if not ct then return nil end
-- printf('%s, %s',ct,type(ct))
local Y, M, D, h, m, s, ms = 0, 0, 0, 0, 0, 0, 0
Y, M, D, h, m, s, ms = ct:get(Y, M, D, h, m, s, ms)
return { Y=Y, M=M, D=D, h=h, m=m, s=s, ms=ms }
end
TraderUpdate = trade_manager.update
function trade_manager.update(npc, force_refresh)
local id = npc:id()
if not npc or not npc:alive() then
return
end
local reup_time = trade_manager.get_trade_profile(id, "resupply_time")
TraderUpdate(npc, force_refresh)
local restock_time = game_difficulties.get_eco_factor("restock") or 24
if force_refresh then restock_time = 0 end
if reup_time and game.get_game_time():diffSec(t2c(reup_time)) < (restock_time * 3600) then
-- print_dbg("Not time to resupply yet!")
return
end
disable_info("sleep_active")
CreateTimeEvent("custom_update"..npc:id(), "custom_resupply"..npc:id(), 0.1, timed_update, npc)
end
-- Add easier to trace callback
function timed_update(npc)
update(npc)
SendScriptCallback("trader_on_restock",npc)
return true
end
-- monkeypatch me
function update(npc)
end
-- util functions to help with monkey patching
function get_faction_goodwill(faction)
end
COMPANION = 0 -- companions got special trade logic, this is just to catch errors
MECHANIC = 1 -- mechanics/techs
BARMAN = 2 -- exclusive food suppliers like Spirit
MEDIC = 3 -- medics
SUPPLIER = 4 -- everyone else that sells crap
-- return trader type as int, or nil if error
function get_trader_type(npc)
local st = db.storage[npc:id()]
if not st then return -1 end
local trader = false
if npc:character_community() == "trader" or npc:clsid() == clsid.script_trader or npc:clsid() == clsid.trader then
trader = true
end
if find(npc:section(),"trader") then
trader = true
end
local cini = st.ini
local logic = st.section_logic
if not logic and not trader then return -1 end
local trade_logic = cini and cini:r_string_ex(logic, "trade")
if not trade_logic then return -1 end
if find(trade_logic, "companion") then
return COMPANION
elseif find(trade_logic, "trade_generic_mechanic") then
return MECHANIC
elseif find(trade_logic, "trade_generic_barman") then
return BARMAN
elseif find(trade_logic, "trade_generic_medic") then
return MEDIC
else
return SUPPLIER
end
end
-- return supply level of npc, like suppy_1, supply_2, etc
-- as_number removes the supply_ prefix and only returns as int
function supply_level(npc, as_number)
local profile = trade_manager.get_trade_profile(npc:id(), "cfg_ltx")
-- printf("Profile is %s", profile)
local config = trade_manager.get_trade_cfg(profile)
if not config then return end
local str = config:r_string_ex("trader", "buy_supplies")
if not (str) then
return -- no buy_supplies this is normal
end
local condlist = xr_logic.parse_condlist(npc, "trader", "buy_supplies", str)
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if as_number then
local num = str_explode(str, "_")
return tonumber(num[2])
else
return str
end
end
-- collapse several tables into one table, the way sections work in ltx files
-- tables should be in section -> amount format
-- precedence goes up to last table, meaning whatever is in the last table will be the last changes applied
function merge_tables(tables)
local final_table = {}
if #tables > 0 then
copy_table(final_table, tables[1])
if #tables > 1 then
for i=2, #tables do
for k,v in pairs(tables[i]) do
final_table[k] = v
end
end
end
end
return final_table
end
local furniture = {
["esc_m_trader"] = true,
["red_m_lesnik"] = true
}
local blacklisted_comms = {
["trader"] = true,
["monster"] = true
}
-- used to get the real community of the NPC by checking spawn id
-- author: HarukaSai
function get_real_community(npc, default)
if furniture[npc:name()] then
return "stalker"
end
local community = character_community(npc)
if not blacklisted_comms[community] then
return community
end
local squad_community = get_object_squad(npc):get_squad_community()
if not blacklisted_comms[squad_community] then
return squad_community
else
return default
end
end
-- to_spawn should be table of sections to amount
-- if check_existing is true, only spawns up to that amount in trader inventory. else arbitrarily spawns
function spawn_items(npc, to_spawn, check_existing)
local npc_name = npc:name()
local alive_or_furniture = xr_conditions.is_alive(db.actor, npc) or furniture[npc_name]
if not alive_or_furniture then return end
local supply_table = {}
copy_table(supply_table, to_spawn)
if check_existing then
local function itr_inv(temp, item)
if supply_table[item:section()] and supply_table[item:section()] > 0 then
-- printf("Found 1 of %s", item:section())
supply_table[item:section()] = supply_table[item:section()] - 1
end
end
npc:iterate_inventory(itr_inv)
end
for k,v in pairs(supply_table) do
-- printf("Creating %s of %s", v, k)
for i=1, v do
-- printf("Created %s", k)
alife_create_item(k, npc)
end
end
end
AddScriptCallback("trader_on_restock")
@@ -0,0 +1,74 @@
local new_art = {}
--[[
categories:
section -> {
section = name of category
articles = section name (title, append _text for info)
}
]]
-- just holds the new categories
local new_cat = {}
_g.ui_pda_autoinject = "blocked" --blocks this script under old name from being loaded.
function parse_cat()
local ini_cat = ini_file("plugins\\encyclopedia_custom\\categories\\importer.ltx")
ini_cat:section_for_each(function(section)
printf("category: processing %s", section)
table.insert(new_cat, section)
end)
local ini_art = ini_file("plugins\\encyclopedia_custom\\articles\\importer.ltx")
ini_art:section_for_each(function(section)
printf("article: processing %s", section)
local line_count = ini_art:line_count(section) or 0
for i=0,line_count-1 do
local junk1, article, category = ini_art:r_line(section, i, "", "")
if not new_art[category] then new_art[category] = {section = category} end
if not new_art[category].articles then new_art[category].articles = {} end
table.insert(new_art[category].articles, article)
end
end)
end
InitArticles = ui_pda_encyclopedia_tab.pda_encyclopedia_tab.InitArticles
function ui_pda_encyclopedia_tab.pda_encyclopedia_tab:InitArticles(section_c)
InitArticles(self, section_c)
if new_art[section_c] then
local category = new_art[section_c]
local articles = category and category.articles or nil
if (not articles) then return end
-- Create each article item and add it to the category.
local item = nil
local section = nil
local n = 1
for i = 1, #articles do
section = articles[i]
if (section) then
local clr = ui_pda_encyclopedia_tab.UpdateColor(section)
item = ui_pda_encyclopedia_tab.pda_encyclopedia_entry(section, n, clr)
self.article_list:AddExistingItem(item)
n = n + 1
end
end
end
end
InitCategories = ui_pda_encyclopedia_tab.pda_encyclopedia_tab.InitCategories
function ui_pda_encyclopedia_tab.pda_encyclopedia_tab:InitCategories()
InitCategories(self)
printf("there are %s new categories", #new_cat)
for k,v in pairs(new_cat) do
local clr = ui_pda_encyclopedia_tab.UpdateColor(v)
item = ui_pda_encyclopedia_tab.pda_encyclopedia_entry(v, k, clr)
self.category_list:AddExistingItem(item)
end
end
function on_game_load()
parse_cat()
end
function on_game_start()
RegisterScriptCallback("on_game_load",on_game_load)
end
@@ -0,0 +1,29 @@
-- standalone class to enable custom code on rclick props
class "UICellPropertiesCustom" (utils_ui.UICellProperties)
function UICellPropertiesCustom:__init(functor) super()
self.functor = functor
end
function UICellPropertiesCustom:OnListItemDbClicked()
if self.list_box:GetSize()==0 then return end
local item = self.list_box:GetSelectedItem()
if not (item) then
return
end
if item.func then
if item.params then
pcall(self.functor, unpack(item.params))
else
pcall(self.functor)
end
self.action_moment = time_continual()
end
if (self:IsShown()) then
self:OnHide()
end
end
@@ -0,0 +1,131 @@
ini_drops = ini_file("items\\settings\\wpo_drop_cond.ltx")
ini_prices = ini_file("items\\settings\\part_prices.ltx")
ini_parts = itms_manager.ini_parts
-- temp condition for trade
print_dbg = arti_jamming.print_dbg
has_parts = arti_jamming.has_parts
is_part = arti_jamming.is_part
get_parts_list = arti_jamming.get_parts_list
get_config = a_arti_jamming_mcm.get_config
math_ceil = math.ceil
parts_list = a_wpo_parts.parts_list
TraderAuto = trader_autoinject.update
function trader_autoinject.update(npc)
TraderAuto(npc)
add_parts(npc) -- you define this function ok
end
local BASE_AMT = 15
function add_parts(npc)
if trader_autoinject.get_trader_type(npc) == trader_autoinject.MECHANIC then
-- purge any existing parts
function itr(temp, item)
if item and is_part(item:section()) then
local se_itm = alife_object(item:id())
if se_item then
alife_release_id(item:id())
end
end
end
npc:iterate_inventory(itr)
-- generate an amount of parts based on trader type
local tbl = {}
local supply_level = trader_autoinject.supply_level(npc, true) or 1
print_dbg("npc %s has supply level %s", npc:name(), supply_level)
for i=1,supply_level * BASE_AMT do
local part = random_key_table(parts_list)
print_dbg("Adding %s to trader %s", part, npc:name())
if tbl[part] then
tbl[part] = tbl[part] + 1
else
tbl[part] = 1
end
end
if supply_level > 1 then
tbl["partskit_tool"] = 1
end
-- add the parts
trader_autoinject.spawn_items(npc, tbl, true)
end
end
function on_get_item_cost(kind, obj, profile, calculated_cost, ret)
-- ret.new_cost = 500
if profile.mode == 2 then
local sec = obj:section()
local price = ini_prices:r_float_ex("wpo_part_prices", sec) or 0
if price and price > 0 then
ret.new_cost = price * profile.discount
end
elseif has_parts(obj) and get_config("saletype") == 1 then
local parts = se_load_var(obj:id(), obj:name(), "parts")
local count, count_dmg = 0, 0
calculated_cost = ret.new_cost or calculated_cost
for k,v in pairs(parts) do
if is_part(k) then
count = count + 1
if v < 60 then
count_dmg = count_dmg + 1
end
end
end
ret.new_cost = clamp(calculated_cost * (1 - count_dmg/count), 1, calculated_cost)
end
end
DeathWeaponDrop = death_manager.set_weapon_drop_condition
-- weapon drop patching
-- read the custom drop configs and apply lagrange formula to decide condition
function death_manager.set_weapon_drop_condition(npc,itm)
DeathWeaponDrop(npc, itm)
local has_part = has_parts(itm)
if not has_part then return end
local rank = npc:character_community() == "zombied" and "novice" or ranks.get_obj_rank_name(npc)
local condition = 0
local drop_sec = get_config("altroll") and "weapons_larp" or "weapons"
local rank_drops = ini_drops:r_string_ex(drop_sec, rank)
if get_config("altroll") then
print_dbg("Using larp eval")
condition = larp.pick(larp.str_to_coords(rank_drops), 10)
else
conds = larp.str_explode_num(rank_drops, ",")
condition = math.random(conds[1], conds[2])
end
print_dbg("New custom condition for item %s, rank %s is %s", itm:section(), rank, condition)
condition = clamp(condition,5,100)
condition = condition / 100
itm:set_condition(condition)
-- custom eval parts
if has_part and get_config("altpartroll") then
print_dbg("alt eval for weapon")
weapon_eval_parts(itm)
end
end
function weapon_eval_parts(wpn)
local parts = get_parts_list(wpn)
local con = math_ceil(wpn:condition()*100)
local parts_data = {}
local final_chance = 25 + math_ceil(con/2.5)
print_dbg("Chance to beat is %s", final_chance)
for i,part in pairs(str_explode(parts, ",")) do
drop = math.random(100) < final_chance and "above" or "below"
coords = ini_drops:r_string_ex("weapon_parts", drop)
parts_data[part] = larp.pick(larp.str_to_coords(coords), 10)
end
se_save_var( wpn:id(), wpn:name(), "parts", parts_data )
end
function on_game_start()
if utils_item.on_get_item_cost then
RegisterScriptCallback("on_get_item_cost", on_get_item_cost)
end
end
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.