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,125 @@
trashBattery's Hunter's Kit - A Butchery Engine
Version 1.0 - October 23rd 2024
If you are reading this, thanks :3
Enjoy the mod! <3
==================================================
==================================================
What is this mod?
=============
It's a rewrite of the "Monster Loot" engine already present in the game. You can feasibly sustain yourself hunting now. If you enjoy it, you can make money off it. It's not the optimal way to wealth, but it's an optional gameplay avenue now where before it was not.
Why would I want this?
=============
- If you think killing a 300lb pig should provide you with enough calories to eat for a day instead of 15 minutes.
- If you've ever tried using the "Hunter's Kit" and thought "Wow! This thing is a useless piece of shit!"
- You want the bonus of the "Well Dressed" achievement to actually function.
- You want Butcher's missions to actually be worth doing instead of just hoping ALife does them while you sleep on his couch.
- You want to be able to harvest the 1 bird you shot down in anger after realizing how hard they are to actually shoot.
Will this work with other mods? Does it require anything?
=============
- This mod is designed to work standalone, but "Mod Configuration Menu" is fully supported and advised.
- This mod is ready to go without any settings changes for most players, but settings exist for those who want them.
- Modded creatures will still work fine so long as they work in vanilla Anomaly.
- Compatibility is limited only to mods that change "mutant_loot.script". This is required to function and must not be overwritten by other mods. AFIK, nobody's been as masochistic as me yet so I don't expect you'll have many issues.
- Find a mod that conflicts and you want it to work? Let me know, I'll see what I can do!
Food, Drug and Drink Animations (FDDA)
=============
FDDA is awesome and you should use it, but if you use the "Mutant Loot" animations, be aware:
- FDDA's mutant loot animations will prevent the variable harvesting animation speeds from working since they all run at 1 speed.
- FDDA plays animations every time you open a corpse, even if you already opened it before.
- FDDA edits a sound file to mute the vanilla harvesting sound. I've included a configuration option to fix this.
It is advised that you use FDDA, but disable "Mutant Loot" animations for the best experience.
- MCM OPTION: (FDDA) Silent Harvesting Fix - Use if you disabled Mutant Loot animations or you won't have any harvesting sound
- MCM OPTION: (FDDA) Duplicate harvesting SoundFX Fix - Use if you enabled Mutant Loot animations or you'll randomly get unwanted harvesting sounds.
==================================================
==================================================
What does this mod specifically do?
=============
The Hunter's Kit item has been changed to be a backpack and a tool
- It works when not worn, but is quite heavy. If you don't wear it it'll take up significant space.
- While wearing it, the carry bonus offsets the weight and gives you similar storage to the Camping Backpack.
- The gameplay setting to require the kit to be worn is now ignored.
- The Hunter's Kit is craftable using logical items you could realistically obtain. No more random endgame materials to make one.
Mutant loot logic has been completely reworked
- Mutants now drop an amount of meat respective to their fleshy mass, not their difficulty. Fleshes are great sources of low-quality food now. Even birds have something to eat, however it won't be much.
- Mutants that drop things other than meat are unaffected by the Hunter's Kit. No increased chances to find money or porno mags just because you had some proper knives on you.
- Birds are not harvestable! They were always intended to be, but a bug in the crow_binder script was causing issues and has been fixed.
Variable harvesting animation speeds now function
- This is an unfinished, but mostly complete feature of the vanilla game. I've used existing assets to complete it.
- There are 3 harvesting speeds. Fast, Normal, Slow
- Harvesting without the backpack is Normal.
- Harvesting with the backpack is Slow, implying you are using your tools and taking time to gather more.
- Having the "Well Dressed" achievement increases harvesting speeds Without/With to Fast/Normal, respectively
Unused audio now utilized
- The game has 9 different harvesting sounds that were intended for each type of creature, but only 1 was ever implemented.
- The sounds are all generic bone/meat cutting noises so now I have the game select them at random for variance.
What about balance?
=============
There should be no balance issues or exploits because of these changes.
- Game is already balanced around weight. Meat is quite inefficient. Spawning more of it doesn't create an economic problem unless you're able to carry it all somehow. If you can carry it, you'd be better off carrying guns to sell anyway so this isn't going to be a problem.
- Your knife degrades once for each item you take from a carcas, so more meat means you'll want a more durable knife.
- Cooking raw meat already consumes limited resources so having more of it doesn't make survival easy, just less tedious.
- Butcher's payout for meat is still minimal compared to almost every other form of income in the game. Now it's worthwhile.
- If you actually go do Butcher's quests yourself you can make more money by harvesting the creatures.
- Random Stalkers pay good rates for meat, but you're limited by their available funds which is always low.
- Selling meat and killing monsters does not increase/decrease Favor with anyone except Butcher/Loners and only while doing Butcher's daily mission. You will gain rep at the exact same speed as before because monsters themselves have not been changed, only how much meat they drop.
BUT THE LORE??!
==============
Several sources in the game confirm that mutants do not have a lot of viable meat on them. I love this. The difference now is that instead of getting 0.1% of their edible body mass you're getting about 20% of it. That's still a lot of wasted meat. If you don't believe me, go look at how much a single piece of flesh meat weighs. These are not huge steaks, they're small strips even if the icon suggests otherwise. Instead of changing their mass to be larger I chose to increase the quantity you get, suggesting you're scavenging a mutated creature and not happily butchering a prize farm animal.
Technobabble
=============
For those interested, here's what's happened under the hood.
Vanilla loot works on a probability system that is functionally flipping coins, which gets the job done, but feels terrible in practice. This new system uses a progressive probability curve model that gets harder each time it tries to spawn an item, which results in more consistent randomness. No more harvesting 2 animals and getting 0 meat from one and 5 from the other. You're more likely to get 1-3 from each animal and sometimes some extra. This new system feels less like gambling and more like individual differences in animal size and health.
The vanilla Hunter's Kit does work, believe it or not, but it randomly duplicates items when you grab them from the UI and never tells you about them. Now that the UI can handle more than a dozen items, I have the game spawn them into the UI itself and never attempt to duplicate them. You have a higher chance to get items while in possession of the kit, but you can never get more than the max configured.
Because of these changes I decided to change the format for the mutant_loot.ltx config, but I built the system to support the original loot format so modded creatures that don't know about this mod work fine.
VANILLA FORMAT - item, quantity, chance
[boar]
hide_boar, 1, 0.16 <- 16% chance to obtain 1 hide
mutant_part_boar_leg, 4, 0.12 <- Drop 4 items, each one 12% chance
roubles, 9999, 1 <- Always drop 9999 roubles
UPDATED FORMAT - item, quantity, [optional chance]
[boar]
hide_boar, 1, 0.16 <- 16% chance to obtain 1 hide (0.16 forces use of vanilla probability. Kit doubles chance to 0.32)
mutant_part_boar_leg, 4 <- Increasingly difficult chance to get up to 4 maximum legs. (Use new curve. Kit modifies curve favorably)
roubles, 9999 <- Increasingly difficult chance to get up to 9999ru. (Kit does not affect harvest chance of items that don't start with mutant_part_ or hide_. Chance is the same with/without the kit. Likely will get anywhere from 1000-5000 on most rolls.)
The logic for how much meat of each creature to drop was a creative design decision and not an exact science. The abridged logic is as follows:
- Find a measurable IRL analog to the creature
- Determine what percentage of that measurable creature is edible tissue (Only muscle/fat drop in game as food)
- Based on the estimated weight of the game's creature, determine its edible tissue
- Apply an arbitrary loss of 90% to all findings to account for the fact that you're in the zone carving up mutated monsters.
- Divide the item weight by the available mass
- The engine will take this rather large number and do the rest.
EXAMPLE: A Flesh (oink oink)
- Analog: "A really big pig"
- Analog's renderable tissue ratio: 72% (per some basic research into the makeup of farm pigs)
- Est. Weight of an in-game Flesh: ~113kg
- Weight of a "Flesh Meat": 0.163kg
- Useable meat (90% loss): ~8kg
- Suggested drops from a flesh: 50
Resulting config:
[Flesh]
mutant_part_flesh_meat, 50
With 50 drops you can expect ~6-10 without the Hunter's Kit and ~20-30 with the Hunter's Kit.
There is some more nuance to this decision as well which considers how difficult creatures are and how likely their mutations may be to cause more/less meat to be available, but that's well beyond the scope of this writeup. If you want your creature to fit perfectly into my mod for some reason you can message me and I can help. This is more of an art than a science, but you can also always just adjust numbers till it feels right. You won't break anything. Not like people can carry 8000 tonnes of "mutant_part_custom_monster_flesh_22" anyway so too much really isn't that bad for balance, it'll just not seem right when players harvest your creature.
@@ -0,0 +1,3 @@
;Hunting kit is now crafted with logical items. -trashBattery
![2]
x_kit_hunt = 1, recipe_basic_0, itm_backpack,1,prt_i_plastic,4,cutlery,1,leatherman_tool,1
@@ -0,0 +1,192 @@
;DLTX edits intended to interact with the VANILLA values of mod_mutant_loot.ltx -trashBattery (tb)
;Whitelist to ensure that modded creatures and unknowns don't cause loot explosions. -tB
;-- If it's not on the whitelist the hunting kit does not modify the drop chance at all.
@[whitelist]
crow
bloodsucker
boar
burer
chimera
controller
dog
flesh
gigant
psy_dog
pseudodog
snork
tushkano
cat
fracturet
zombie
lurker
psysucker
karlik
;Modified quantities and chances for all mutant loot -tB
;CRITICAL: A loot item must start with "mutant_part_" or "hide_" to be affected by the updated Hunting Kit.
;
;Format is: item_name, quantity, [optional percentage chance override]
;-- Example: mutant_part_tushkano_meat, 12
;===== This will roll for 12 meat where each drop is less likely than the one before it, starting at 100 percent for the first.
;
;-- Example: mutant_part_tushkano_meat, 12, 0.5
;===== This will generate 12 meats by rolling 12 dice at a 50 percent chance.
;
;-- The new system was designed to provide more varied, but natural results compared to the dice roll.
;-- However, the dice roll can be useful for regulating drop chances on individual items like hides and trophies.
;-- Or simply setting a unique drop to be super rare.
![crow]
!mutant_part_crow_beak, 1, 0.02
mutant_part_crow_beak, 1
mutant_part_tushkano_meat, 1
![bloodsucker]
!hide_bloodsucker, 1, 0.21
!mutant_part_krovosos_jaw, 1, 0.21
!mutant_part_krovosos_meat, 2, 0.22
!mutant_part_heart_bloodsucker, 1, 0.4
hide_bloodsucker, 1, 0.8
mutant_part_krovosos_meat, 33
mutant_part_krovosos_meat, 4
mutant_part_krovosos_jaw, 1, 0.4
mutant_part_heart_bloodsucker, 1, 0.4
![boar]
!hide_boar, 1, 0.16
!mutant_part_boar_leg, 4, 0.12
!mutant_part_boar_chop, 2, 0.33
!mutant_part_tusk_boar, 2, 0.33
hide_boar, 1, 0.8
mutant_part_boar_leg, 4
mutant_part_boar_chop, 37
mutant_part_tusk_boar, 2
![burer]
!hide_burer, 1, 0.31
!mutant_part_burer_hand, 2, 0.31
!mutant_part_brain_burer, 1, 0.31
hide_burer, 1, 0.8
mutant_part_burer_hand, 2
mutant_part_brain_burer, 1, 0.4
![chimera]
!hide_chimera, 1, 0.44
!mutant_part_chimera_kogot, 4, 0.45
!mutant_part_chimera_claw, 8, 0.24
!mutant_part_chimera_meat, 2, 0.66
!mutant_part_heart_chimera, 1, 0.25
hide_chimera, 1, 0.8
mutant_part_chimera_kogot, 4
mutant_part_chimera_claw, 8
mutant_part_chimera_meat, 56
mutant_part_heart_chimera, 2
![controller]
!mutant_part_controller_glass, 1, 0.38
!mutant_part_controller_hand, 2, 0.28
!hide_controller, 1, 0.55
mutant_part_controller_glass, 1, 0.4
mutant_part_controller_hand, 2
hide_controller, 1, 0.8
![dog]
!mutant_part_dog_liver, 1, 0.3
!mutant_part_dog_heart, 1, 0.3
!mutant_part_dog_tail, 1, 0.22
!mutant_part_dog_meat, 2, 0.37
mutant_part_dog_liver, 1, 0.4
mutant_part_dog_heart, 1, 0.4
mutant_part_dog_tail, 1
mutant_part_dog_meat, 16
![flesh]
!hide_flesh, 1, 0.45
!mutant_part_flesh_eye, 2, 0.22
!mutant_part_flesh_meat, 3, 0.37
hide_flesh, 1, 0.8
mutant_part_flesh_eye, 4
mutant_part_flesh_meat, 50
![gigant]
!hide_pseudogiant, 1, 0.66
!mutant_part_pseudogigant_hand, 2, 0.44
!mutant_part_pseudogigant_eye, 2, 0.44
hide_pseudogiant, 1, 1
mutant_part_pseudogigant_hand, 4
mutant_part_pseudogigant_eye, 2
![psy_dog]
!mutant_part_fang_psevdodog, 4, 0.33
!hide_psy_dog, 1, 0.44
!mutant_part_controller_glass, 1, 0.22
!mutant_part_psevdodog_tail, 1, 0.44
!mutant_part_psevdodog_meat, 2, 0.44
mutant_part_fang_psevdodog, 4
hide_psy_dog, 1, 0.6
mutant_part_controller_glass, 1, 0.4
mutant_part_psevdodog_tail, 1, 0.4
mutant_part_psevdodog_meat, 5
![pseudodog]
!mutant_part_fang_psevdodog, 4, 0.33
!hide_pseudodog, 1, 0.37
!mutant_part_psevdodog_tail, 1, 0.27
!mutant_part_psevdodog_meat, 2, 0.33
mutant_part_fang_psevdodog, 4
hide_pseudodog, 1, 0.6
mutant_part_psevdodog_tail, 1
mutant_part_psevdodog_meat, 5
![snork]
!mutant_part_snork_leg, 2, 0.37
!mutant_part_snork_hand, 2, 0.22
!mutant_part_snork_mask, 1, 0.22
mutant_part_snork_leg, 2
mutant_part_snork_hand, 2
mutant_part_snork_mask, 1, 0.4
![tushkano]
!mutant_part_tushkano_head, 1, 0.31
!mutant_part_tushkano_meat, 1, 0.44
mutant_part_tushkano_head, 1, 0.4
mutant_part_tushkano_meat, 1
![cat]
!mutant_part_cat_thyroid, 2, 0.4
!mutant_part_cat_claw, 10, 0.33
!mutant_part_cat_tail, 1, 0.44
mutant_part_cat_thyroid, 2
mutant_part_cat_claw, 20
mutant_part_cat_tail, 1
![fracture]
!mutant_part_fracture_hand, 2, 0.44
mutant_part_fracture_hand, 2
![zombie]
!mutant_part_zombi_hand, 2, 0.31
mutant_part_zombi_hand, 2
![lurker]
!hide_lurker, 1, 0.16
!mutant_part_lurker_tail, 1, 0.31
!mutant_part_lurker_eye, 2, 0.22
!mutant_part_lurker_meat, 2, 0.3
hide_lurker, 1, 0.7
mutant_part_lurker_tail, 1
mutant_part_lurker_eye, 2
mutant_part_lurker_meat, 9
![psysucker]
!hide_psysucker, 1, 0.21
!mutant_part_psysucker_hand, 2, 0.2
!mutant_part_psysucker_meat, 2, 0.22
hide_psysucker, 1, 0.7
mutant_part_psysucker_hand, 2
mutant_part_psysucker_meat, 20
![karlik]
!mutant_part_controller_glass, 1, 0.22
mutant_part_controller_glass, 1, 0.4
@@ -0,0 +1,3 @@
;Breaking down the backpack returns everything except most of the plastic used for waterproofing. -trashBattery
![nor_parts_list]
kit_hunt = itm_backpack,prt_i_plastic,cutlery,leatherman_tool
@@ -0,0 +1,9 @@
![kit_hunt]
description = tb_kit_hunt_descr
inv_name = tb_kit_hunt
inv_name_short = tb_kit_hunt
additional_inventory_weight = 31
additional_inventory_weight2 = 31
inv_weight = 4.54
cost = 15345
disassemble_parts = itm_backpack,prt_i_plastic,cutlery,leatherman_tool
@@ -0,0 +1,11 @@
;Contains the settings for the updated ui_mutant_loot.script -trashBattery (tB)
[environment]
harvestHardcap = 92 ;[FLOAT 0-100] Max chance possible for harvest. DEFAULT 0.92 (This feels best during playtests.)
harvestDifficulty = 1 ;[FLOAT 0-∞] Multiplicitave harvest modifier with backpack. 2=double, 0=impossible. DEFAULT 1
scavengeDifficulty = 1 ;[FLOAT 0-∞] Multiplicitave harvest modifier without backpack. 2=double, 0=impossible. DEFAULT 1
minItems = 1 ;[FLOAT -3-∞] Horizontal offset of the probability curve. Negative values lower chances. DEFAULT 1
[compatiblity]
disableExtraSounds = false ;[BOOL] Disables the extra harvesting sounds enabled by this mod.
muteHarvestSounds = false ;[BOOL] This is to allow compatiblity with mods that call their own custom harvesting sounds like FDDA.
useHarvestSoundFallback = false ;[BOOL] Some mods may overwrite the defaault harvesting sound effect. This will use tell the game to use a differnet sound instead.
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="windows-1251" ?>
<string_table>
<string id="tb_kit_hunt">
<text>Hunter's Kit</text>
</string>
<string id="tb_kit_hunt_descr">
<text>A whole bag full of hooks, knives and other equipment used for skinning and gutting animals and mutants. Few stalkers carry professional equipment for mutant hunting. That is probably the reason why so many Zoners suffer from indigestion after eating mutant meat. Despite being heavy and unwieldy, this bag is very comfortable when worn and allows for storage of mutant parts.\n \n
%c[ui_gray_3]PROPERTIES:\n
%c[d_blue] • %c[ui_gray_2] efficient item storage\n
%c[0,100,255,150] • %c[ui_gray_2] usable as stash\n
%c[d_orange] • %c[ui_gray_2] specialist gear\n
%c[d_orange] • %c[ui_gray_2] significantly increases harvest time, but also the number of body parts obtained from mutants\n
%c[d_orange] • %c[ui_gray_2] very heavy if not worn\n
</text>
</string>
<string id="ui_mcm_menu_tb_HuntKit">
<text>Hunter's Kit</text>
</string>
<string id="ui_mcm_menu_tb_HuntKit_features">
<text>Features</text>
</string>
<string id="ui_mcm_menu_tb_HuntKit_settings">
<text>Settings</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_disableExtraSounds">
<text>Disable Reintroduced Sounds</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_disableExtraSounds_desc">
<text>This mod reintroduces 8 unused cutting sounds and plays them at random. You can disable this feature in the event you replaced the default harvesting sound and want to just hear it and nothing else... or if you just really like the default sound ;)</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_harvestHardcap">
<text>Harvesting Hardcap</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_harvestHardcap_desc">
<text>Max possible chance for an item to spawn. Even if you set difficulty modifiers extremely high they will get lowered to this value.\n%c[d_orange]DEFAULT: 92%</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_harvestDifficulty">
<text>Difficulty Scale - Hunting Kit</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_harvestDifficulty_desc">
<text>Multiplicative harvest modifier applied while carrying/wearing the "Hunter's Kit".\n2=Double Drop Chance\n0=Nothing Will Drop.\n%c[d_orange]DEFAULT: 1</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_minItems">
<text>Harvesting Floor</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_minItems_desc">
<text>By default, the first item of each type that can drop always has the max chance to drop. You can change how many items you want to have max chance if you would prefer a higher number, or reduce it to simulate your character's complete ineptitude with basic carving equipment... or just really unhealthy animals.\n \n 2=First 2 Items get Max Drop Chance\n-2=Chances lower as if 2 items have already dropped.\n \n%c[d_red]CAUTION:%c[d_white] Reducing below 1 will cause massive disparity between having and not having the backpack. Reducing below -3 functionally disables all scaling.\n \n%c[d_green]TIP:%c[d_white] Try values between 0 and -2 for a more "hardcore" feel. -1.3 will make finding food without the kit almost impossible and with the kit easy, but less fruitful than 1 does.\n \n%c[d_orange]DEFAULT: 1</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_muteHarvestSounds">
<text>(FDDA) Duplicate harvesting SoundFX Fix</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_muteHarvestSounds_desc">
<text>%c[d_orange]Use this if you have "Food, Drug and Drinks Animations" Monster Loot Animations%c[d_green] ENABLED!\n \n%c[d_white]This will mute the base game's harvesting sounds and is useful if you're using a mod that supplies a custom harvesting sound.\n \n%c[d_red]BEWARE%c[d_white] - If you are using FDDA's animations you cannot benefit from the variable harvesting speed feature enabled by this mod. If you don't know what this means, please read the "Features" tab to your left.</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_scavengeDifficulty">
<text>Difficulty Scale - Scavenging</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_scavengeDifficulty_desc">
<text>Multiplicative harvest modifier applied while %c[d_red]NOT %c[d_white]carrying/wearing the "Hunter's Kit".\n2=Double Drop Chance\n0=Nothing Will Drop.\n%c[d_orange]DEFAULT: 1</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_useHarvestSoundFallback">
<text>(FDDA) Silent Harvesting Fix</text>
</string>
<string id="ui_mcm_tb_HuntKit_tb_HuntKit_settings_useHarvestSoundFallback_desc">
<text>%c[d_orange]Use this if you have "Food, Drug and Drinks Animations" Monster Loot Animations%c[d_red] DISABLED!\n \n%c[d_white]FDDA v0.9 and before ship with a dummy file that replaces the default harvesting sound with silence to prevent duplicate sounds from playing. If you play with FDDA Mutant Loot animations disabled you may end up having no harvesting sounds at all! This fixes that by using a different effect.</text>
</string>
</string_table>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="windows-1251" ?>
<string_table>
<string id="tb_kit_hunt">
<text>Охотничий рюкзак</text>
</string>
<string id="tb_kit_hunt_descr">
<text>Тяжёлый комплект крючков, ножей и прочих инструментов, служащих для профессиональной разделки туш. Всё это укомплектовано по раздельным секциям обычного рюкзака, свободный объём которого может быть использован для хранения добытых трофеев. Из-за мутаций и множества болезней органы местной фауны находятся в ужасном состоянии, почти непригодном для изучения, а мясо её представителей пропитано паразитами и гнилью.\nОхотничий набор позволит более тщательно изучить состояние внутренностей на этапе вскрытия и не повредить научные образцы при разделке, позволяя извлечь из туши мутанта максимум выгоды. В силу крайней неприглядности всего процесса потрошения и относительную редкость достаточно ценных для продажи частей, большинство сталкеров всё же предпочитают охоте мародёрство и поиск артефактов, где значительную роль играет воля случая, а не собственные навыки.\n \n
%c[ui_gray_3]ХАРАКТЕРИСТИКИ:\n
%c[d_blue] • %c[ui_gray_2] повсеместное применение\n
%c[d_blue] • %c[ui_gray_2] используется для хранения предметов\n
%c[0,100,255,150] • %c[ui_gray_2] может быть использован как тайник\n
%c[d_orange] • %c[ui_gray_2] при использовании с мутантов срезается больше частей\n
</text>
</string>
</string_table>
@@ -0,0 +1,5 @@
<w>
<file name="tb_HuntKit\tb_HuntKit_MCMHeader">
<texture id="tb_HuntKit_MCMHeader" x="0" y="0" width="563" height="50" />
</file>
</w>
@@ -0,0 +1,99 @@
--[[Utils_Ui.script
The vanilla Reinit() attempted to sort the arrays by default which caused some issues with
the display of mutant loot when the amount increased in the window. I've made the no-sorting
an optional feature instead of the default. This is only called during mutant looting anyway,
but better safe than sorry.]]
function utils_ui.UICellContainer:Reinit(t, tf, nosort)
self:Reset()
-- If no inventory is passed, this function will just clear cells
if (not t) then
return
end
-- Create cells
self.ignore_scroll = true
self:Print(nil, "Reset | START Number of cells: %s", #self.cell)
local sort_order = self:GetSortMethod()
if(nosort) then
if self.showcase then
for i,sec in pairs(t) do
self:AddItem(nil,sec, tf and tf[i])
end
else
for i,obj in pairs(t) do
self:AddItem(obj, nil, tf and tf[i])
end
end
else
if self.showcase then
for i,sec in spairs(t, sort_order) do
self:AddItem(nil,sec, tf and tf[i])
end
else
for i,obj in spairs(t, sort_order) do
self:AddItem(obj, nil, tf and tf[i])
end
end
end
self.ignore_scroll = false
self:Print(nil, "Reset | END Number of cells: %s", #self.cell)
self:Scroll_Reinit()
end
--[[bind_crow.script
Vanilla update() used a flawed method that would always return false and prevent crows
from being lootable at all. It also was significalty less robust than Faustle's updated
bind_monster update() function, but was checking all the exact same things so I simply
ported it over. Considering my mod would have made existing fixes to crow looting
fail I implemented it myself.]]
function bind_crow.crow_binder:update(delta)
-- standart update
object_binder.update(self, delta)
if not (self.object:alive()) then
if (self.body_timer<=time_global()-120000) and (self.body_timer~=0) then
printf("releasing object ["..self.object:name().."]")
local se_obj = alife_object(self.object:id())
if (se_obj) then
safe_release_manager.release(se_obj)
end
end
--Alundaio
-- By Faustle - Cloned over from bind_monster.script with minimial edits-tB
if not (self.object:alive()) then
local looted = se_load_var(self.object:id(),self.object:name(),"looted")
if (not looted) then
if (item_knife.is_equipped()) then
if (item_knife.get_condition() < 0.15) then
self.object:set_callback(callback.use_object, nil)
self.object:set_tip_text(game.translate_string("st_body_knife_bad"))
return
end
if (not item_knife.can_loot(self.object:section())) then
self.object:set_callback(callback.use_object, nil)
self.object:set_tip_text(game.translate_string("st_body_knife_weak"))
else
self.object:set_callback(callback.use_object, self.use_callback, self)
self.object:set_tip_text(game.translate_string("st_body_loot"))
end
else
self.object:set_callback(callback.use_object, nil)
self.object:set_tip_text(game.translate_string("st_body_knife_needed"))
return
end
else
self.object:set_callback(callback.use_object, nil)
self.object:set_tip_text("")
end
return
end
--
--Alundaio
end
end
@@ -0,0 +1,36 @@
function on_mcm_load()
op = {id= "tb_HuntKit",gr={
{id="tb_HuntKit_settings",sh=true,gr={
{id="header", type="slide", link="tb_HuntKit_MCMHeader", text="tB's Hunter's Kit - A Butchery Engine", size={563,50}, spacing=20},
{type="title", align="l", text="Mod Compatibility - (Hover setting names for details)"},
{id="muteHarvestSounds", type="check", val=1, def=false},
{id="useHarvestSoundFallback", type="check", val=1, def=false},
{id="disableExtraSounds", type="check",val=1, def=false},
{type="line"},
{type="title", align="l", text="Customization - (Hover setting names for details)"},
{type="desc", align="c", text="It is highly advised you leave these options at their defaults. No perminant damage can occur to your saves so feel free to experiment, but alterations may cause balancing issues at any difficulty. This system is complex and scales itself. I spent hours ensuring balance of the default settings were nearest to ideal as possible so you could just install and play, but of course I can't account for everything. In the end, whatever you think is most fun is always best setting -trashBattery"},
{id="harvestHardcap", type = "track", val=2, min=1, max=100, step=1, def=92},
{id="minItems", type="input", val=2, min=-9999, max=9999, def=1},
{id="harvestDifficulty", type="input", val=2, min=-9999, max=9999, def=1},
{id="scavengeDifficulty", type="input", val=2, min=-9999, max=9999, def=1}
}
},
{id="tb_HuntKit_features",sh=true,gr={
{id="header", type="slide", link="tb_HuntKit_MCMHeader", text="tB's Hunter's Kit - A Butchery Engine", size={563,50}, spacing=20},
{type="title", align="l", text="Hunter's Kit"},
{type="desc",text="%c[d_green]•%c[d_white] It works when not worn, but is quite heavy. If you don't wear it it'll take up significant space. \\n%c[d_green]•%c[d_white] While wearing it, the carry bonus offsets the weight and gives you similar storage to the Camping Backpack. \\n%c[d_green]•%c[d_white] The Hunter's Kit is craftable using logical items you could realistically obtain. No more random endgame materials to make one. \\n%c[d_red]• The gameplay setting to require the kit to be worn is now ignored."},
{type="title", align="l", text="Mutant Loot"},
{type="desc",text="%c[d_green]•%c[d_white] Mutants now drop an amount of meat respective to their fleshy mass, not their difficulty. Fleshes are great sources of low-quality food now. Even birds have something to eat, however it won't be much.\\n%c[d_green]•%c[d_white] Mutants that drop things other than meat are unaffected by the Hunter's Kit. No increased chances to find money or porno mags just because you had some proper knives on you.\\n%c[d_green]•%c[d_white] Birds are now harvestable! They were always intended to be, but a bug in the crow_binder script was causing issues and has been fixed."},
{type="title", align="l", text="Variable Harvest Animation Speeds"},
{type="desc",text="%c[d_green]•%c[d_white] There are 3 harvesting speeds. Fast, Normal, Slow \\n%c[d_green]•%c[d_white] Harvesting without the backpack is Normal. \\n%c[d_green]•%c[d_white] Harvesting with the backpack is Slow, implying you are using your tools and taking time to gather more. \\n%c[d_green]•%c[d_white] Having the \"Well Dressed\" achievement increases harvesting speeds Without/With to Fast/Normal, respectively. \\n%c[d_red]• If you are using FDDA make sure you have the correct option enabled in this mod."},
{type="title", align="l", text="Reintroduced Harvesting Sounds"},
{type="desc",text="%c[d_green]•%c[d_white] The game has 9 different harvesting effects that were intended for each type of creature, but only 1 was ever implemented. \\n%c[d_green]•%c[d_white] The sounds are all generic bone/meat cutting noises so now I have the game select them at random for variance. \\n%c[d_green]•%c[d_white] This can be disabled in the options if you like."},
{type="line"},
{type="title", align="l", text="%c[d_orange]Version - 1.0"}
}
}
}
}
return op
end
@@ -0,0 +1,722 @@
--[[
-----------------------------------
Copyright (C) 2012 Alundaio
This program is free software; you can redistribute and/or modify
it under the terms of the Open S.T.A.L.K.E.R. Mod License version 1.0.
-----------------------------------
ponney68
-----------------------------------
Tronex
Last edit: 2019/12/17
Added Loot all button, organized script, inventory cell system, alife spawn handlers
-----------------------------------
trashBattery (tB)
Last edit: 2024/10/23
Rewrote the logic for mutant loot handling to support new "percent of max" method and
removed the vanilla "magical duplication" methods. See readme for more info.
-]]
--Load Reserouces
local ini_mutant = ini_file_ex("items\\settings\\mutant_loot.ltx") --Using ini_file_ex now instead of utils_data:ini_file -tB
local ini_tbHuntKit_settings = ini_file_ex("tbHuntKit_settings.ltx") --Configs for the features added by tbHuntKit (this mod) -tB
local ini_actorFX = ini_file_ex("plugins\\actor_effects.ltx") --Need this for reading the anim data later -tB
--Load configs. Descriptions are in tbHuntKit_settings.ltx -tB
local envHardcap,envHarvestDiff,envScavengeDiff,envMinItems,disableExtraSounds,muteHarvestSounds,useHarvestSoundFallback
function loadConfigs() --Tied to "on_option_change" callback. -tB
if ui_mcm then
envHardcap = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/harvestHardcap")/100 or 0.92
envHarvestDiff = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/harvestDifficulty") or 1.00
envScavengeDiff = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/scavengeDifficulty") or 1.00
envMinItems = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/minItems") or 1.00
disableExtraSounds = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/disableExtraSounds") or false
muteHarvestSounds = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/muteHarvestSounds") or false
useHarvestSoundFallback = ui_mcm.get("tb_HuntKit/tb_HuntKit_settings/useHarvestSoundFallback") or false
printf("-ui_mutant_loot loaded configs from MCM")
else
envHardcap = ini_tbHuntKit_settings:r_float_ex("environment","harvestHardcap")/100 or 0.92
envHarvestDiff = ini_tbHuntKit_settings:r_float_ex("environment","harvestDifficulty") or 1.00
envScavengeDiff = ini_tbHuntKit_settings:r_float_ex("environment","scavengeDifficulty") or 1.00
envMinItems = ini_tbHuntKit_settings:r_float_ex("environment","minItems") or 1.00
disableExtraSounds = ini_tbHuntKit_settings:r_bool_ex("compatiblity","disableExtraSounds") or false
muteHarvestSounds = ini_tbHuntKit_settings:r_bool_ex("compatiblity","muteHarvestSounds") or false
useHarvestSoundFallback = ini_tbHuntKit_settings:r_bool_ex("compatiblity","useHarvestSoundFallback") or false
printf("-ui_mutant_loot loaded configs from tbHuntKit_settings.ltx")
end
end
loadConfigs()
--The game came with 9 sounds for harvesting and only ever uses 1?! Let's use them all (or not if you disable them) :D -tB
local harvestSFX = {
"inv_mutant_loot_animal",
"inv_mutant_loot_animal2",
"inv_mutant_loot_crow",
"inv_mutant_loot_grease",
"inv_mutant_loot_grease2",
"inv_mutant_loot_human",
"inv_mutant_loot_human2",
"inv_mutant_loot_rotten",
"inv_mutant_loot_smaller"
}
--Extract creature whitelist. -tB
local validCreatures = {}
local forIncr = 0
for k in pairs(ini_mutant:collect_section("whitelist")) do
forIncr=forIncr+1
validCreatures[forIncr]=k
end
local sec_kit_hunt = "kit_hunt"
local item_prop_table = { cond_r = {30,70} , cond_ct = "part" , cond_cr = {0.5,0.75,1} }
-- Loot Mutant
local MutantLootDecayTime = ini_mutant:r_float_ex("mutant_loot_mod","decay_time") or 7200
local kind_to_section = {
["SM_KARLIK"] = "karlik",
["SM_PSYSUCKER"] = "psysucker",
["SM_LURKER"] = "lurker"
}
local clsid_to_section = {
[clsid.bloodsucker_s] = "bloodsucker",
[clsid.boar_s] = "boar",
[clsid.burer_s] = "burer",
[clsid.chimera_s] = "chimera",
[clsid.controller_s] = "controller",
[clsid.dog_s] = "dog",
[clsid.flesh_s] = "flesh",
[clsid.gigant_s] = "gigant",
[clsid.poltergeist_s] = "poltergeist",
[clsid.psy_dog_s] = "psy_dog",
[clsid.psy_dog_phantom_s] = "psy_dog",
[clsid.pseudodog_s] = "pseudodog",
[clsid.snork_s] = "snork",
[clsid.tushkano_s] = "tushkano",
[clsid.cat_s] = "cat",
[clsid.fracture_s] = "fracture",
[clsid.zombie_s] = "zombie",
[clsid.crow] = "crow",
[clsid.rat_s] = "rat"
}
local clsdbg_to_section = {
["SM_KARLIK"] = "karlik",
["SM_PSYSUCKER"] = "psysucker",
["SM_LURKER"] = "lurker"
}
local killed_mutant_tbl = { -- ponney68: This table based on "species" of mutants
-- TRX: A-Life Revamp
psysucker = {file="ui\\ui_actor_monsters_pda_3",x="393",y="0",type="small"},
lurker = {file="ui\\ui_actor_monsters_pda_3",x="0",y="0",type="small"},
karlik = {file="ui\\ui_actor_monsters_pda_3",x="0",y="200",type="small"},
snork = {file="ui\\ui_actor_monsters_pda",x="393",y="0",type="small"},
dog = {file="ui\\ui_actor_monsters_pda",x="0",y="800",type="small"},
pseudodog = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
psy_dog = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
poltergeist = {file="ui\\ui_actor_monsters_pda",x="0",y="400",type="small"},
bloodsucker = {file="ui\\ui_actor_monsters_pda",x="393",y="400",type="human"},
controller = {file="ui\\ui_actor_monsters_pda",x="393",y="800",type="human"},
chimera = {file="ui\\ui_actor_monsters_pda",x="0",y="600",type="large"},
tushkano = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="small"},
rat = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="small"},
flesh = {file="ui\\ui_actor_monsters_pda",x="393",y="600",type="large"},
tark = {file="ui\\ui_actor_monsters_pda_2",x="0",y="0",type="human"},
rotan = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="human"},
burer = {file="ui\\ui_actor_monsters_pda_1",x="0",y="0",type="large"},
boar = {file="ui\\ui_actor_monsters_pda_1",x="393",y="0",type="large"},
giant = {file="ui\\ui_actor_monsters_pda_1",x="0",y="200",type="large"},
cat = {file="ui\\ui_actor_monsters_pda_2",x="0",y="0",type="small"},
fracture = {file="ui\\ui_actor_monsters_pda_2",x="393",y="200",type="human"},
bird = {file="ui\\ui_actor_monsters_pda_2",x="393",y="0",type="small"},
zombie = {file="ui\\ui_actor_monsters_pda_2",x="0",y="200",type="human"},
bloodsucker_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="400",type="human"},
burer_arena = {file="ui\\ui_actor_monsters_pda_1",x="0",y="0",type="large"},
pseudodog_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
snork_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="0",type="human"},
}
function check_hunterKit(useNeedsEquipped) --Replaces "is_huntkit" variable with a more versitile function. Ignores the game option by default. The option is redundant due to the new design. -tB
local actor = db.actor
local backpack = actor:item_in_slot(13)
local needs_equipped_hk = false
if useNeedsEquipped then
needs_equipped_hk = ui_options.get("gameplay/general/need_equipped_hkit")
end
if ((needs_equipped_hk and backpack == sec_kit_hunt) or (not needs_equipped_hk and actor:object(sec_kit_hunt))) then
return true
end
return false
end
function actor_effects_getAnimLen(name) --actor_effects.ltx uses a non-standard method of animation formatting so I have to do this -tB
local kMax = 0
for k in pairs(ini_actorFX:collect_section(name)) do
k = tonumber(k)
kMax = k>kMax and k or kMax
end
return kMax
end
function play_harvestAnim(override) --Play the correct harvesting animation based on the state of the player. Return animation time in seconds. -tB
local boost,anim
if (actor_effects) then
if override then
boost = override
else
boost = (game_achievements.has_achievement("well_dressed") and 1 or 0) + (check_hunterKit() and 0 or 1)
end
if (boost >= 2) then
anim = "mutant_looting_boost_2"
elseif (boost == 1) then
anim = "mutant_looting_boost_1"
else
anim = "mutant_looting"
end
end
actor_effects.play_item_fx(anim)
return actor_effects_getAnimLen(anim)/1000
end
function loot_mutant(section, clsid, loot_table, npc, dont_create, victim) -- Prepare mutant loot
npc = npc or db.actor
local clsid = clsid or obj and obj:clsid()
local kind = section and ini_sys:r_string_ex(section,"kind") or "unknown"
if not (clsid) then
return
end
local loot, sec, count
local str_explode = str_explode
local mutant = clsdbg_to_section[kind] or clsid_to_section[clsid]
--Creating possible_items{} using ini_file_ex from _g instead of the old utils_data method. -tB
local possible_items = {}
forIncr=0
for k in pairs(ini_mutant:collect_section(mutant)) do
forIncr=forIncr+1
possible_items[forIncr]=k
end
local sim = alife()
local npc_id = npc and npc:id()
local npc_pos = npc and npc:position()
local npc_lvl_id = npc and npc:level_vertex_id()
local npc_game_id = npc and npc:game_vertex_id()
--Check if the looted creature is part of the whitelist. -tB
local isCreature = false
for i=1,#validCreatures do
if mutant == validCreatures[i] then
isCreature = true
break
end
end
-- Spawn items on NPC if he looted the mutant
for i=1,#possible_items do
local chance
local chanceFloor = envMinItems-1 --Min # of items to drop before scaling takes effect. Using #-1 felt better for configs.-tB
local chanceExp = 1
local flatChance = false
loot = str_explode(possible_items[i],",")
sec = tostring(loot[1])
count = tonumber(loot[2])
if not count then
printf("ui_mutant_loot.loot_mutant() >> Unacceptable quantity of loot item ["..sec.."]")
count = 0
end
--Check if an override chance was set. If so, use vanilla linear probability. Backpack doubles chances. -tB
if loot[3] then
flatChance = true
chance = tonumber(loot[3]) or 1
if (isCreature and (string.match(sec, '^mutant_part_') or (string.match(sec, '^hide_')))) then
if(check_hunterKit()) then
chance = chance*2*envHarvestDiff
else
chance = chance*envScavengeDiff
end
end
else
--Otherwise, configure probability curve. -tB
if (isCreature and (string.match(sec, '^mutant_part_') or (string.match(sec, '^hide_')))) then
if(check_hunterKit()) then
chanceExp = 0.5*(1/(envHarvestDiff+0.001))
else
chanceExp = 2.2*(1/(envScavengeDiff+0.001))
end
end
chanceFloor = chanceFloor + math.floor(count*0.1)
end
for i=1,count do
if not flatChance then
if i < chanceFloor then
chance = 1
else
chance = (1/(i-chanceFloor))^chanceExp
end
end
if chance > envHardcap then chance = envHardcap end
if (math.random() <= chance) then
-- In case we don't want to bother with loot table
local se_obj
if (not dont_create) then
se_obj = alife_create_item(sec, npc, item_prop_table)
end
-- Fill loot table if needed
if (loot_table) then
local sec_d, uses = utils_item.get_defined_uses(sec)
if (not loot_table[sec_d]) then
loot_table[sec_d] = {}
end
local c = loot_table[sec_d].count
c = c and (c + 1) or 1
loot_table[sec_d].count = c
if se_obj then
loot_table[sec_d][c] = se_obj.id
end
--printf("loot_mutant")
--[[
if npc and npc:id() ~= AC_ID then
se_obj = alife_create_item(sec, npc, item_prop_table)
end
--]]
end
end
end
end
-- Unlock relevant mutant article in guide.
if mutant and npc and (npc:id() == AC_ID) then
SendScriptCallback("actor_on_interaction", "mutants", nil, mutant)
end
SendScriptCallback("monster_on_loot_init",victim,loot_table)
end
----------------------------------------------------------------------
GUI = nil -- instance, don't touch
function start(obj, for_bug1, for_bug2)
if (not obj) then
printf("!ERROR ui_mutant_loot | no game object passed!")
return
end
if (not GUI) then
GUI = UIMutantLoot()
end
if (GUI) and (not GUI:IsShown()) then
local can_show = GUI:Reset(obj, for_bug1, for_bug2)
if can_show then
GUI:ShowDialog(true)
Register_UI("UIMutantLoot","ui_mutant_loot")
end
end
end
function start_CreateTimeEvent(obj, for_bug1, for_bug2)
level.enable_input()
start(obj, for_bug1, for_bug2)
return true
end
----------------------------------------------------------------------
-- CALLBACKS
----------------------------------------------------------------------
function monster_on_actor_use_callback(obj,who) -- Open mutant loot UI
-- Return if mutant is already looted
local looted = se_load_var(obj:id(),obj:name(),"looted")
local firstTime = load_var(obj,"loot")
if (looted) then
return
end
se_save_var(obj:id(),obj:name(),"looted",true) --bind_crow.script updatates no longer require the old logic to check if it's a crow. -tB
-- This is important so NPCs don't try to loot the corpse the player is looting
xr_corpse_detection.set_valuable_loot(obj:id(),false)
-- if mutant corpse is lefted for long time, body is decayed
local st = db.storage[obj:id()]
if (st and st.death_time and game.get_game_time():diffSec(st.death_time) > MutantLootDecayTime) then
actor_menu.set_msg(1, game.translate_string("st_body_decayed"),4)
-- Start the Mutant Loot UI
else
--Play the harvest animation and sounds only the frist time the mutant is cut open. -tB
if not firstTime then
item_knife.degradate() --Damage the knife for the first cut into the creatutre. binder will damage further for each item removed. -tB
local aTime = play_harvestAnim()
if not muteHarvestSounds then
if disableExtraSounds then
if useHarvestSoundFallback then
xr_sound.set_sound_play(AC_ID,"inv_mutant_loot_animal2")
else
xr_sound.set_sound_play(AC_ID,"inv_mutant_loot_animal")
end
else
local harvestSFX_RND = harvestSFX[math.random(1,#harvestSFX)]
if harvestSFX_RND == "inv_mutant_loot_animal" and useHarvestSoundFallback then
harvestSFX_RND = "inv_mutant_loot_animal2"
end
xr_sound.set_sound_play(AC_ID,harvestSFX_RND)
end
else
end
level.disable_input()
CreateTimeEvent("UIML_HarvestAnim_e","UIML_HarvestAnim_a",aTime,start_CreateTimeEvent,obj, obj:id(), obj:section(), obj:clsid())
else
start(obj, obj:id(), obj:section(), obj:clsid())
end
end
end
function monster_on_loot_init(obj,t)
-- t['conserva'] = {
-- count = 3
-- }
-- utils_data.print_table(t,obj and obj:name() or "no_obj")
end
function on_game_start()
RegisterScriptCallback("monster_on_actor_use_callback",monster_on_actor_use_callback)
RegisterScriptCallback("monster_on_loot_init",monster_on_loot_init)
RegisterScriptCallback("on_option_change",loadConfigs)
end
----------------------------------------------------------------------
-- UI
----------------------------------------------------------------------
class "UIMutantLoot" (CUIScriptWnd)
function UIMutantLoot:__init() super()
self:InitControls()
self:InitCallBacks()
end
function UIMutantLoot:__finalize()
end
function UIMutantLoot:InitControls()
self:SetWndRect (Frect():set(0,0,1024,768))
self:SetAutoDelete(true)
self.xml = CScriptXmlInit()
self.xml:ParseFile ("ui_mutant_loot.xml")
local xml = self.xml
self.dialog = xml:InitStatic("mutant_loot:background",self)
-- Mutant image
self.image = self.xml:InitStatic("mutant_loot:image",self.dialog)
-- Loot
self.frame = xml:InitStatic("mutant_loot:frame",self.dialog)
self.CC = utils_ui.UICellContainer("loot", self, nil, "mutant_loot:cont_loot", self.dialog)
self.CC.showcase = true
-- self.CC.can_select = true
self.CC.disable_drag = true
self.CC.disable_stack = true
self.CC:SetGridSpecs(35, 2)
self.item_info = utils_ui.UIInfoItem(self, 1000)
-- Button Loot one
self.btn_loot_one = xml:Init3tButton("mutant_loot:btn_loot",self.dialog)
self:Register(self.btn_loot_one, "button_loot")
-- Button Loot all
self.btn_loot_all = xml:Init3tButton("mutant_loot:btn_loot_all",self.dialog)
self:Register(self.btn_loot_all, "button_loot_all")
-- Button Cancel
self.btn_cancel = xml:Init3tButton("mutant_loot:btn_cancel",self.dialog)
self:Register(self.btn_cancel, "button_cancel")
end
function UIMutantLoot:InitCallBacks()
self:AddCallback("button_loot",ui_events.BUTTON_CLICKED,self.OnButton_LootSelected,self)
self:AddCallback("button_loot_all",ui_events.BUTTON_CLICKED,self.OnButton_LootAll,self)
self:AddCallback("button_cancel",ui_events.BUTTON_CLICKED,self.Close,self)
end
function UIMutantLoot:Reset(obj, for_bug1, for_bug2)
local function is_number(var)
local function lets_try(var)
var = tonumber(var)
return (var > 0) or (var < 0) or var or -var
end
if pcall(function() lets_try(var) end) then
return true
else
return false
end
end
if not (is_number(obj)) then
self.section = obj:section()
self.clsid = obj:clsid()
self.id = obj:id()
self.obj = obj
else
self.id = obj
self.section=for_bug1
self.clsid = for_bug2
self.obj = nil
end
self:SetMutantImage()
return self:FillList()
end
function UIMutantLoot:Update()
CUIScriptWnd.Update(self)
-- Highlight selected items
for idx,ci in pairs(self.CC.cell) do
if (not ci:IsCursorOverWindow()) then
if ci.flags.selected then
ci:Highlight(true,"green")
else
ci:Highlight(false)
end
end
end
-- Updating item info box and item cell containers
local found_cell = self.CC:Update(self.item_info)
if (not found_cell) then
self.item_info:Update()
end
end
-- Utility
function UIMutantLoot:SetMutantImage()
local mutant_id = game.translate_string(ini_sys:r_string_ex(self.section,"species") or "")
local kind = ini_sys:r_string_ex(self.section,"kind") or "unknown"
mutant_id = kind_to_section[kind] or mutant_id
local mutant_f = "ui\\ui_actor_monsters_pda_1"
local mutant_x = 0
local mutant_y = 0
mutant_f = tostring(killed_mutant_tbl[mutant_id].file)
mutant_x = tostring(killed_mutant_tbl[mutant_id].x)
mutant_y = tostring(killed_mutant_tbl[mutant_id].y)
local x1 = mutant_x
local y1 = mutant_y
local mutant_width = 393
local mutant_height = 200
local x2 = x1 + mutant_width
local y2 = y1 + mutant_height
self.image:InitTexture(tostring(mutant_f))
self.image:SetTextureRect(Frect():set(x1,y1,x2,y2))
self.image:SetStretchTexture(true)
end
function UIMutantLoot:Loot(loot_all)
local obj_mutant = level.object_by_id(self.id)
if (not obj_mutant) then
self:Close()
return
end
local is_looted
local sim = alife()
local actor = db.actor
--[[Disable old magic hunter kit. I'm leaving this here in case anyone wants to know what it used to be. -tB
local backpack = actor:item_in_slot(13)
local is_huntkit
local needs_equipped_hk = ui_options.get("gameplay/general/need_equipped_hkit")
if (needs_equipped_hk and (backpack and (backpack:section() == sec_kit_hunt))) or (not needs_equipped_hk and db.actor:object(sec_kit_hunt)) then
is_huntkit = true
end
]]--
-- Spawn selected items, clean from loot table
if loot_all then
local tbl = self.loot -- temp
for sec,t in pairs(tbl) do
for i=1,t.count do
is_looted = true
item_knife.degradate()
alife_create_item(sec, db.actor, item_prop_table)
--[[Disable old magic hunter kit. -tB
if is_huntkit and (math.random(100) < bonus_part_chance) then
alife_create_item(sec, db.actor, item_prop_table)
end
]]--
self.loot[sec].count = self.loot[sec].count - 1
if (self.loot[sec].count == 0) then
self.loot[sec] = nil
end
end
end
else
for idx,ci in pairs(self.CC.cell) do
if ci.flags.selected then
local sec = ci.section
is_looted = true
item_knife.degradate()
alife_create_item(sec, db.actor, item_prop_table)
--[[Disable old magic hunter kit. -tB
if is_huntkit and (math.random(100) < bonus_part_chance) then
alife_create_item(sec, db.actor, item_prop_table)
end
]]--
self.loot[sec].count = self.loot[sec].count - 1
if self.loot[sec].count == 0 then
self.loot[sec] = nilt
end
end
end
end
-- If no item is looted, don't proceed
if (not is_looted) then
return
end
-- Increat field dressings stat
game_statistics.increment_statistic("field_dressings")
-- Mutant post-state
save_var(obj_mutant,"loot",self.loot)
local is_more_loot = not is_empty(self.loot)
-- Refill loot list if there's loot left
if ((not actor_effects.is_animations_on()) and is_more_loot) then
self:FillList()
else
self:Close()
end
end
function UIMutantLoot:FillList()
--developed by Dimeyne, copied by Wafel
self.loot = load_var(self.obj,"loot",nil)
if not self.loot then
self.loot = {}
loot_mutant(self.section, self.clsid, self.loot, nil, true, self.obj)
save_var(self.obj,"loot",self.loot)
end
local is_there_loot
local inv = {}
for sec,t in pairs(self.loot) do
for i=1,t.count do
inv[#inv + 1] = sec
end
is_there_loot = true
end
if (self.obj:clsid() ~= clsid.crow) and load_var(self.obj,"looted",nil) then --Exclude crows from this check since they're managed by bind_crow.script -tB
is_there_loot = false
end
if is_there_loot then
--Flipping the inventory array so unique parts show up first like eyes and feet. I could sort it more specificly, but this is good enough. -tB
local flippedInv = {}
for i=#inv, 1, -1 do
flippedInv[#flippedInv + 1] = inv[i]
end
self:ShowDialog(true)
self.CC:Reinit(flippedInv,nil,true)
return true
else
actor_menu.set_msg(1, "st_body_useless",3)
end
end
function UIMutantLoot:SetMutantState(is_more_loot, obj_mutant)
obj_mutant = obj_mutant or level.object_by_id(self.id)
if (is_more_loot == nil) then
is_more_loot = not is_empty(self.loot)
end
-- We set mutant state to looted or not if there's loot left, so other NPCs can decide what to do with the corpse
if obj_mutant then
if is_more_loot then
se_save_var(obj_mutant:id(),obj_mutant:name(),"looted",false)
xr_corpse_detection.set_valuable_loot(self.id,true)
else
se_save_var(obj_mutant:id(),obj_mutant:name(),"looted",true)
xr_corpse_detection.set_valuable_loot(self.id,false)
end
else
printe("!ERROR ui_mutant_loot | can't retrieve online object of mutant [%s](%s)", self.section, self.id)
end
end
-- Callbacks
function UIMutantLoot:On_CC_Mouse1(cont, idx)
local ci = self.CC.cell[idx]
if (not ci) then
return
end
if (not ci.flags.selected) then
ci.flags.selected = true
else
ci.flags.selected = nil
end
end
function UIMutantLoot:OnButton_LootSelected()
self:Loot(false)
end
function UIMutantLoot:OnButton_LootAll()
self:Loot(true)
end
function UIMutantLoot:Close()
self:SetMutantState()
self:HideDialog()
Unregister_UI("UIMutantLoot")
end
function UIMutantLoot:OnKeyboard(dik, keyboard_action)
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
if (res == false) then
self.CC:OnKeyboard(dik, keyboard_action)
if (dik == DIK_keys.DIK_RETURN) then
self:OnButton_LootAll()
elseif (dik == DIK_keys.DIK_ESCAPE) then
self:Close()
end
end
return res
end
@@ -0,0 +1,28 @@
[General]
gameName=stalkeranomaly
modid=0
version=d2024.11.23.0
newestVersion=
category="-1,"
nexusFileStatus=1
installationFile=tbHuntKit_1.0.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-11-23T10:06:24Z
nexusCategory=0
converted=false
validated=false
color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0)
tracked=0
[installedFiles]
1\modid=0
1\fileid=0
size=1