├── Data ├── PCX │ └── InvFilterArt │ │ ├── btn_all_hover_off.pcx │ │ ├── btn_all_off.pcx │ │ ├── btn_all_on.pcx │ │ ├── btn_ammo_hover_off.pcx │ │ ├── btn_ammo_off.pcx │ │ ├── btn_ammo_on.pcx │ │ ├── btn_armor_hover_off.pcx │ │ ├── btn_armor_off.pcx │ │ ├── btn_armor_on.pcx │ │ ├── btn_drug_hover_off.pcx │ │ ├── btn_drug_off.pcx │ │ ├── btn_drug_on.pcx │ │ ├── btn_misc_hover_off.pcx │ │ ├── btn_misc_off.pcx │ │ ├── btn_misc_on.pcx │ │ ├── btn_tool_hover_off.pcx │ │ ├── btn_tool_off.pcx │ │ ├── btn_tool_on.pcx │ │ ├── btn_weapon_hover_off.pcx │ │ ├── btn_weapon_off.pcx │ │ ├── btn_weapon_on.pcx │ │ ├── dropall_back.pcx │ │ ├── en │ │ ├── dropall_dn.pcx │ │ ├── dropall_up.pcx │ │ ├── giveall_dn.pcx │ │ └── giveall_up.pcx │ │ ├── left_dn.pcx │ │ ├── left_up.pcx │ │ ├── main.pcx │ │ ├── right_dn.pcx │ │ ├── right_up.pcx │ │ ├── ru │ │ ├── dropall_dn.pcx │ │ ├── dropall_up.pcx │ │ ├── giveall_dn.pcx │ │ └── giveall_up.pcx │ │ └── swap_win.pcx └── scripts │ └── gl_InvenFilter.int ├── README.md ├── Resources_old ├── ivfiltermenu_buttons.psd ├── swap_win.psd └── weight_old.psd ├── archive ├── F2-InventoryFilter_v1.5.9_en.rar ├── F2-InventoryFilter_v1.5.9_ru.rar ├── F2-InventoryFilter_v1.6.0_en.rar ├── F2-InventoryFilter_v1.6.0_ru.rar ├── F2-InventoryFilter_v1.6.1_en.rar ├── F2-InventoryFilter_v1.6.1_ru.rar ├── F2-InventoryFilter_v1.6.2_en.rar ├── F2-InventoryFilter_v1.6.2_ru.rar ├── F2-InventoryFilter_v2.0.0_en.rar ├── F2-InventoryFilter_v2.0.0_ru.rar ├── F2-InventoryFilter_v2.0.2_en.rar ├── F2-InventoryFilter_v2.0.2_ru.rar ├── F2-InventoryFilter_v2.0.3_en.rar ├── F2-InventoryFilter_v2.0.3_ru.rar ├── F2-InventoryFilter_v2.0.4_en.rar └── F2-InventoryFilter_v2.0.4_ru.rar ├── ini ├── InvenFilter_en.ini └── InvenFilter_ru.ini ├── pics ├── installed.png ├── scr_barter.png ├── scr_loot.png └── scr_player_inv.png └── source ├── gl_InvenFilter.ssl └── iface.h /Data/PCX/InvFilterArt/btn_all_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_all_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_all_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_all_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_all_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_all_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_ammo_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_ammo_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_ammo_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_ammo_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_ammo_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_ammo_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_armor_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_armor_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_armor_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_armor_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_armor_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_armor_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_drug_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_drug_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_drug_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_drug_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_drug_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_drug_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_misc_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_misc_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_misc_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_misc_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_misc_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_misc_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_tool_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_tool_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_tool_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_tool_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_tool_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_tool_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_weapon_hover_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_weapon_hover_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_weapon_off.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_weapon_off.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/btn_weapon_on.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/btn_weapon_on.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/dropall_back.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/dropall_back.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/en/dropall_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/en/dropall_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/en/dropall_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/en/dropall_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/en/giveall_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/en/giveall_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/en/giveall_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/en/giveall_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/left_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/left_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/left_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/left_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/main.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/main.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/right_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/right_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/right_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/right_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/ru/dropall_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/ru/dropall_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/ru/dropall_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/ru/dropall_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/ru/giveall_dn.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/ru/giveall_dn.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/ru/giveall_up.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/ru/giveall_up.pcx -------------------------------------------------------------------------------- /Data/PCX/InvFilterArt/swap_win.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/PCX/InvFilterArt/swap_win.pcx -------------------------------------------------------------------------------- /Data/scripts/gl_InvenFilter.int: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Data/scripts/gl_InvenFilter.int -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Inventory Filter mod for Fallout 2 2 | 3 | A mirror repository of the Inventory Filter mod for Fallout 2 by Mr.Stalin, based on the idea of JimTheDinosaur's [Inventory Sort Buttons mod](https://www.nma-fallout.com/threads/inventory-sort-buttons-mod.203180). 4 | 5 | ## Features 6 | * Quickly find ammo for weapons from tons of junk in the inventory: if you click the middle mouse button on the "Weapons" and "Ammo" menu buttons, these items will be displayed simultaneously in the player's inventory. 7 | * Money is always shown at the top when bartering, or if the "All" filter is selected (the feature does not work right after opening the inventory). 8 | * Quickly exchange your party members when bartering or opening containers. 9 | * Displays the weight value for items in the selected category, as well as the amount of money the merchant has in barter. 10 | * The **"Drop All"** button. 11 | * Hotkeys to switch between the selected categories. 12 | 13 | ## Installation 14 | 1. Download `F2-InventoryFilter_v*_.rar` from the [release archive](archive). 15 | 2. Extract the `mods` folder to your main game directory. 16 | 3. Inventory Filter v2.0.4 requires [**sfall**](https://github.com/sfall-team/sfall) (`ddraw.dll`) version 4.2.8.1/3.8.37 or later. The **AllowUnsafeScripting** option in `ddraw.ini` must be enabled for the filter to function correctly. 17 | 4. If a `mods_order.txt` already exists in your `mods` folder, add **InventoryFilter.dat** to it. 18 | 5. Edit `mods\InventoryFilter.dat\InvenFilter.ini` to configure the behavior of the filter. 19 | 20 | This is how it's supposed to look like when installed: 21 | ![installed](pics/installed.png) 22 | 23 | * Note for the hi-res patch by Mash: DirectDraw 7 graphics mode is known to cause some display glitches with the filter. It is recommended to use **DirectX 9** mode. 24 | 25 | ## Usage Notes 26 | * Click the middle mouse button on the "Weapons" and "Ammo" menu buttons to display items from these categories simultaneously in the player's inventory. Also, clicking the middle mouse button on the "Weapons" menu button will display only the "Guns" type of weapons. 27 | * To quickly switch between filter categories, use the hotkeys: 28 | ``` 29 | Player: Q, 1, 2, 3, 4, 5 30 | NPC: W, 6, 7, 8, 9, 0 31 | ``` 32 | You can change the hotkeys in `InvenFilter.ini`. 33 | * To turn the filter on or off, use the F11 key. 34 | 35 | ## Uninstallation 36 | Delete `mods\InventoryFilter.dat` folder and remove its name from `mods_order.txt`. 37 | 38 | ## Screenshots 39 | ![Player's inventory](pics/scr_player_inv.png) 40 | 41 | ![Opening containers](pics/scr_loot.png) 42 | 43 | ![Barter screen](pics/scr_barter.png) 44 | -------------------------------------------------------------------------------- /Resources_old/ivfiltermenu_buttons.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Resources_old/ivfiltermenu_buttons.psd -------------------------------------------------------------------------------- /Resources_old/swap_win.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Resources_old/swap_win.psd -------------------------------------------------------------------------------- /Resources_old/weight_old.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/Resources_old/weight_old.psd -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.5.9_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.5.9_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.5.9_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.5.9_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.0_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.0_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.0_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.0_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.1_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.1_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.1_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.1_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.2_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.2_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v1.6.2_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v1.6.2_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.0_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.0_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.0_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.0_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.2_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.2_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.2_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.2_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.3_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.3_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.3_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.3_ru.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.4_en.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.4_en.rar -------------------------------------------------------------------------------- /archive/F2-InventoryFilter_v2.0.4_ru.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/archive/F2-InventoryFilter_v2.0.4_ru.rar -------------------------------------------------------------------------------- /ini/InvenFilter_en.ini: -------------------------------------------------------------------------------- 1 | [InventoryFilter] 2 | ;List of PIDs for additional items in the "Useful Items" filter category 3 | ;Fallout: PID_MULTI_TOOL, PID_ELECTRONIC_LOCKPICKS, PID_LOCKPICKS, PID_SUPER_TOOL_KIT, PID_EXP_LOCKPICK_SET, PID_ELEC_LOCKPICK_MKII 4 | ;Nevada: 556, 557, 647 5 | ;Olympus: 247, 393 6 | ToolGroupPids=75,77,84,308,410,411,556,557,647,247,393 7 | 8 | ;Set to 1 to show information about the carry weight and available money from the trader 9 | ShowWeight=1 10 | ShowCaps=1 11 | 12 | ;Set to 1 to display the container capacity as a percentage instead of its size in units 13 | PercentSize=1 14 | 15 | ;Text color for displaying the carry weight and the amount of money 16 | ;0 - green, 1 - yellow, 2 - white 17 | TextColor=2 18 | 19 | ;Set to 1 to enable the smart trading mode 20 | ;The trader or player will always try to make up the balance with available money at the end of a transaction 21 | SmartBarter=0 22 | 23 | ;Set to 1 to enable the "Drop All" button to move all inventory items when exchanging with containers 24 | DropAllButton=1 25 | 26 | ;DX scancode for the "Drop All" hotkey. It will work regardless of the DropAllButtion option 27 | ;32 - 'D' key 28 | DropAllButtonKey=32 29 | 30 | ;Set to 1 to use the additional background image for the "Drop All" button 31 | ;By default, an image of vanilla Fallout2 interface is used. In the case of a different interface, it is recommended to disable this option or use another image 32 | UseBackImage=1 33 | 34 | ;Set to 1 to use different "Drop All" button images for containers and NPCs 35 | UseGiveAllImage=1 36 | 37 | ;Set to 1 to allow switching between party members when bartering or looting containers 38 | SwapParty=1 39 | SwapContainers=1 40 | 41 | ;The offset value of the position of the party member swap panel along the X-axis 42 | SwapBarterOffset=0 43 | SwapLootOffset=0 44 | 45 | ;The offset value of the position of the party member swap panel along the Y-axis 46 | SwapBarterYOffset=0 47 | SwapLootYOffset=0 48 | 49 | ;The offset value of the position of the "weight" label in the player's inventory along the Y-axis 50 | WeightWinShift=0 51 | 52 | ;Position of the filter interface in the barter mode 53 | ;Set to 1 to use the old pre-2.0 interface position (above the barter interface) 54 | OldPosition=0 55 | 56 | ;Info messages 57 | BarterCaps=You have offered another %d money to the trader. 58 | MsgWarning=Close the container before use. 59 | 60 | MsgVersion=Inventory Filter requires sfall 4.2.8.1 or later. 61 | MsgLoad=Warning: Inventory Filter requires the AllowUnsafeScripting option in ddraw.ini to be enabled to work correctly. 62 | 63 | MsgInfo=Inventory Filter is disabled. Press F11 to enable. 64 | MsgOn=Inventory Filter is activated. 65 | MsgOff=Inventory Filter is deactivated. 66 | 67 | MsgSwap=: is out of range for switching. 68 | MsgSwapFilter=Unable to switch party members when a filter category is selected. 69 | 70 | [HotKeys] 71 | ;DX scancodes of the hotkeys for filter categories 72 | ;for the player: Q/1/2/3/4/5 73 | pAll=16 74 | pArmor=2 75 | pWeapon=3 76 | pAmmo=4 77 | pDrug=5 78 | pMisc=6 79 | ;for containers/NPCs: W/6/7/8/9/0 80 | nAll=17 81 | nArmor=7 82 | nWeapon=8 83 | nAmmo=9 84 | nDrug=10 85 | nMisc=11 86 | -------------------------------------------------------------------------------- /ini/InvenFilter_ru.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/ini/InvenFilter_ru.ini -------------------------------------------------------------------------------- /pics/installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/pics/installed.png -------------------------------------------------------------------------------- /pics/scr_barter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/pics/scr_barter.png -------------------------------------------------------------------------------- /pics/scr_loot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/pics/scr_loot.png -------------------------------------------------------------------------------- /pics/scr_player_inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotators/InventoryFilter/3b90bc0d84a46780ec2214a4efa27f7ee6355dac/pics/scr_player_inv.png -------------------------------------------------------------------------------- /source/gl_InvenFilter.ssl: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | Name: Inventory Filter 4 | Description: The plugin filters items in the player's inventory. 5 | 6 | Created: sFall Script Editor 7 | *******************************************************************************/ 8 | 9 | #define SFALL_SC_EVALUATION (true) 10 | 11 | #if TRACE 12 | #define DTRACE(name) debug_msg("Trace: " #name); 13 | #else 14 | #define DTRACE(name) 15 | #endif 16 | 17 | #define SCRIPT_VERSION " [v2.0.4]" 18 | 19 | #define INI_CONFIG_FILE "\\mods\\InventoryFilter.dat\\InvenFilter.ini" 20 | #define INI_CONFIG_FILE_SEC INI_CONFIG_FILE "|InventoryFilter|" 21 | 22 | #define genericCrtBox create_object(PID_MELEE_THUG_MALE, 0, 0) 23 | 24 | /** Возвращает максимальный подъемный вес **/ 25 | #define max_weight(obj) get_critter_stat(obj, STAT_carry_amt) 26 | #define dude_max_weight max_weight(dude_obj) 27 | 28 | /* Include Files */ 29 | #include "..\headers\itempid.h" 30 | #include "..\headers\critrpid.h" 31 | #include "..\headers\party.h" 32 | 33 | #include "..\headers\sfall\define_lite.h" 34 | #include "..\headers\sfall\command_lite.h" 35 | 36 | #include "..\headers\sfall\sfall.h" 37 | #include "..\headers\sfall\define_extra.h" 38 | #include "..\headers\sfall\dik.h" 39 | 40 | #include "iface.h" 41 | 42 | /* Script Procedures */ 43 | procedure start; 44 | procedure GameModeChangeHook; 45 | procedure CreateInvenFilterLeftMenu(variable loot); 46 | procedure CreateInvenFilterRightMenu(variable loot); 47 | procedure DestroyFilterWin; 48 | 49 | procedure refresh_pc_interface_slots; 50 | procedure filter_inventory(variable filter_item_type, variable spec); 51 | procedure filter_inventory_trader(variable filter_item_type); 52 | procedure IsGunWeapon(variable item); 53 | procedure IsToolGroup(variable pid); 54 | procedure filter_inventory_sub(variable filter_item_type, variable spec_item, variable obj_ptr_1, variable obj_ptr_2); 55 | procedure filter_remove_items(variable source_objptr, variable dest_objptr, variable item, variable item_pid); 56 | procedure check_loot_object(variable obj); 57 | critical procedure MoveObjectInventory(variable src_obj, variable dst_obj, variable all); 58 | procedure MoveDudeInventory; 59 | procedure MoveItemPCHook; 60 | procedure MoveItemHook; 61 | procedure BarterHook; 62 | procedure destroy_message_win; 63 | procedure KeyPressHook; 64 | procedure MouseClickHook; 65 | procedure filter_by_key(variable keyType); 66 | 67 | procedure inven_filter_button_toggle(variable p_btn, variable spec); 68 | procedure inven_filter_button_pressed(variable p_btn, variable filter_item_type, variable spec); 69 | procedure inven_filter_trd_button_toggle(variable p_btn); 70 | procedure inven_filter_trd_button_pressed(variable p_btn, variable filter_item_type); 71 | procedure Button_Toggle_Off; 72 | 73 | procedure SelectCreateButton(variable p_btn, variable flag); 74 | procedure create_btn_sub; 75 | procedure create_btn_trd_sub; 76 | procedure Create_btn_all(variable flag, variable trd); 77 | procedure Create_btn_armor(variable flag, variable trd); 78 | procedure Create_btn_weapon(variable flag, variable trd); 79 | procedure Create_btn_ammo(variable flag, variable trd); 80 | procedure Create_btn_drug(variable flag, variable trd); 81 | procedure Create_btn_tool(variable flag, variable trd); 82 | procedure Create_btn_misc(variable flag, variable trd); 83 | procedure subCreateButton(variable btn, variable flag, variable trd, variable vshift); 84 | procedure HightlightButton(variable btn, variable flag, variable trd); 85 | procedure DeletePressButton; 86 | procedure DeletePressButtonTrd; 87 | procedure subDeleteButton(variable btn, variable type, variable flag); 88 | 89 | procedure refresh_pc_weight; 90 | procedure weight_win(variable weight, variable type); 91 | procedure weight_loot_win(variable obj); 92 | procedure barter_weight_win(variable weight); 93 | procedure party_weight_win(variable weight); 94 | procedure print_weight(variable weight, variable maxWeight); 95 | procedure trader_cost_win; 96 | procedure hack_engine_weight(variable hack); 97 | 98 | procedure GetAndSaveDudeWeight; 99 | procedure GetDudeWeightBonus; 100 | procedure SwappingParty(variable type, variable value); 101 | procedure SetDudeSwapWeight(variable swapCritter); 102 | procedure get_party_array(variable ptr_check); 103 | procedure swap_button_pressed(variable btn); 104 | procedure next_swap_ptr; 105 | procedure back_swap_ptr; 106 | procedure barter_swap_win; 107 | procedure loot_swap_win; 108 | procedure create_swap_win(variable x_offset, variable y_offset); 109 | procedure swap_name(variable name); 110 | procedure destroy_swap; 111 | 112 | procedure CreateDropAllBtn; 113 | procedure check_dude_equp_items(variable isSize); 114 | critical procedure key_drop_press; 115 | procedure key_drop_null; 116 | procedure key_drop_release; 117 | 118 | /* Defines */ 119 | #define item_type_tool_group (8) 120 | 121 | #define Explosive(x) (x == PID_DYNAMITE) or (x == PID_PLASTIC_EXPLOSIVES) or (x == PID_ACTIVE_DYNAMITE) or (x == PID_ACTIVE_PLASTIC_EXPLOSIVE) 122 | #define ExcludeDoctor(x) (x != PID_FIRST_AID_KIT) and (x != PID_DOCTORS_BAG) and (x != PID_PARAMEDICS_BAG) and (x != PID_FIELD_MEDIC_KIT) 123 | #define IncludeDoctor(x) (x == PID_FIRST_AID_KIT) or (x == PID_DOCTORS_BAG) or (x == PID_PARAMEDICS_BAG) or (x == PID_FIELD_MEDIC_KIT) 124 | 125 | /* Local variables which do not need to be saved */ 126 | variable begin 127 | iniConfig; 128 | sfall_version; 129 | 130 | interfaceX, interfaceY; 131 | menu_x, menu_y, x_mouse, y_mouse, posXmouse, posYmouse, r_menu_x; 132 | weight_win_x, weight_win_y, r_weight_win_x, weight_win_y_shift := 318; 133 | 134 | filterRightMenu; 135 | barterOutsideInterface = 1; // location of the menu outside the dialog interface 136 | filterMessageWin; 137 | 138 | enableState; 139 | IsCreated; 140 | 141 | weightIsEnabled := false; 142 | capsIsEnabled := false; 143 | 144 | btn_all, btn_armor, btn_weapon, btn_ammo, btn_drug, btn_tool, btn_misc; 145 | btn_trd_all, btn_trd_armor, btn_trd_weapon, btn_trd_ammo, btn_trd_drug, btn_trd_tool, btn_trd_misc; 146 | btn_toggle_off; 147 | btn_trd_toggle_off; 148 | 149 | isPressed; 150 | special; 151 | sec_click; 152 | filterOnlyGun; 153 | filter_done := true; 154 | 155 | crtTempBoxPC; // контенер для отфильрованных предметов 156 | // for barter 157 | crtTempBoxNPC, dialogCritter; 158 | pcInBarter, isPartyBarter; 159 | 160 | // for loot 161 | lootObject; 162 | lootFilter, lootIsContainer, lootIsFriendContaner, sortFilter; 163 | 164 | inven_weight; 165 | inven_loot_weight; 166 | inven_party_weight; 167 | inven_caps; 168 | loot_weight; 169 | refresh_weight; 170 | 171 | pc_bTable, tr_bTable; 172 | smart_barter, trade_money_msg; 173 | 174 | // for Swapping Party 175 | swapIsEnabled, swapAllContainers; 176 | swap_contaner; // здесь храниться предметы игрока 177 | swap_ptr; // указатель на партийца, куда нужно будет возвращать предметы 178 | swap_party_array; // массив указателей партийцев 179 | len_party_array, current_swap_number := -1; 180 | 181 | swap_win_x, swap_win_y, swap_barter_offset, swap_barter_y_offset, swap_loot_offset, swap_loot_y_offset; 182 | 183 | btnDropAll, btnGiveAll, useBackImage, dropPress, drop_key_code, dropButtonWin; 184 | 185 | dudeBaseMaxWeight, dudeExtraMaxWeight, dudeEquipItemsWeight, dudeWeightBonus, swapMaxWeight := -1; 186 | partyMaxWeight, partyExtraWeightStat := -1; 187 | npcMaxWeight, npcExtraWeightStat = -1; 188 | containerMaxSize = -1; 189 | showPercentSize = 1; 190 | 191 | toolGroupPids; 192 | hotKeys; 193 | r := 0.0, g := 0.9, b := 0.2; // green 194 | end 195 | 196 | procedure start begin 197 | variable item, pid, iniConfigFile, i; 198 | 199 | if game_loaded then begin 200 | iniConfigFile := INI_CONFIG_FILE; 201 | iniConfig := INI_CONFIG_FILE_SEC; 202 | 203 | // for sFall 4.2.8+ format 4208 204 | sfall_version := (1000 * sfall_ver_major) + (100 * sfall_ver_minor) + sfall_ver_build; 205 | if ((sfall_version < 3837) orElse (sfall_version >= 4000 and sfall_version < 4208)) then begin 206 | display_msg(get_ini_string(iniConfig + "MsgVersion")); // Inventory фильтр требует sfall 4.2.8 или более поздней версии. 207 | return; 208 | end 209 | if get_ini_setting("ddraw.ini|Debugging|AllowUnsafeScripting") <= 0 then begin 210 | display_msg(get_ini_string(iniConfig + "MsgLoad")); 211 | end 212 | 213 | barterOutsideInterface := (get_ini_setting(iniConfig + "OldPosition") == 0); 214 | weightIsEnabled := get_ini_setting(iniConfig + "ShowWeight"); 215 | capsIsEnabled := get_ini_setting(iniConfig + "ShowCaps"); 216 | smart_barter := get_ini_setting(iniConfig + "SmartBarter"); 217 | trade_money_msg = get_ini_string(iniConfig + "BarterCaps"); 218 | 219 | if (weightIsEnabled) then begin 220 | showPercentSize := get_ini_setting(iniConfig + "PercentSize"); 221 | 222 | //read_byte(0x477EE1) == 0x75) then hack_w_allow = true; 223 | end 224 | 225 | drop_key_code := get_ini_setting(iniConfig + "DropAllButtonKey"); 226 | if drop_key_code < 0 then drop_key_code := 0; 227 | 228 | // for sFall 4.1+ 229 | btnDropAll := get_ini_setting(iniConfig + "DropAllButton"); 230 | btnGiveAll := get_ini_setting(iniConfig + "UseGiveAllImage"); 231 | useBackImage := get_ini_setting(iniConfig + "UseBackImage"); 232 | 233 | // for sFall 4.2+ 234 | hotKeys := get_ini_section(iniConfigFile, "HotKeys"); 235 | foreach (i : item in hotKeys) begin 236 | if (typeof(i) == VALTYPE_STR) then hotKeys[i] := atoi(item); 237 | end 238 | fix_array(hotKeys); 239 | 240 | switch (get_ini_setting(iniConfig + "TextColor")) begin 241 | case 1 : r := 0.72; g := 0.72; b := 0.2; // yellow 242 | case 2 : r := 0.90; g := 0.90; b := 0.9; // near white 243 | end 244 | 245 | register_hook_proc(HOOK_KEYPRESS, KeyPressHook); 246 | register_hook_proc(HOOK_MOUSECLICK, MouseClickHook); 247 | register_hook_proc_spec(HOOK_BARTERPRICE, BarterHook); // register_hook_proc(HOOK_BARTERPRICE, hBarter); 248 | register_hook_proc(HOOK_REMOVEINVENOBJ, MoveItemHook); 249 | register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChangeHook); 250 | register_hook_proc(HOOK_INVENTORYMOVE, MoveItemPCHook); 251 | 252 | set_global_script_type(1); 253 | 254 | enableState := get_sfall_global_int("INV_FLTR"); 255 | if (enableState == 0) then enableState := 1; 256 | if (enableState == 2) then display_msg(get_ini_string(iniConfig + "MsgInfo")); 257 | 258 | if (get_screen_height > 480) then begin 259 | swapIsEnabled := get_ini_setting(iniConfig + "SwapParty"); 260 | if (swapIsEnabled) then begin 261 | swapAllContainers := get_ini_setting(iniConfig + "SwapContainers"); 262 | swap_loot_offset := get_ini_setting(iniConfig + "SwapLootOffset"); 263 | swap_barter_offset := get_ini_setting(iniConfig + "SwapBarterOffset"); 264 | swap_loot_y_offset := get_ini_setting(iniConfig + "SwapLootYOffset"); 265 | swap_barter_y_offset := get_ini_setting(iniConfig + "SwapBarterYOffset"); 266 | end 267 | end 268 | 269 | toolGroupPids = [ 270 | PID_STEALTH_BOY, PID_GEIGER_COUNTER, PID_MOTION_SENSOR, PID_ACTIVE_GEIGER_COUNTER, PID_ACTIVE_STEALTH_BOY, 271 | PID_BIG_BOOK_OF_SCIENCE, PID_DEANS_ELECTRONICS, PID_FIRST_AID_BOOK, PID_SCOUT_HANDBOOK, PID_GUNS_AND_BULLETS 272 | ]; 273 | fix_array(toolGroupPids); 274 | 275 | variable pids = string_split(get_ini_string(iniConfig + "ToolGroupPids"), ","); 276 | resize_array(toolGroupPids, 10 + len_array(pids)); 277 | i = 10; 278 | foreach (pid in pids) begin 279 | toolGroupPids[i] = atoi(pid); 280 | i++; 281 | end 282 | 283 | weight_win_y_shift := weight_win_y_shift + get_ini_setting(iniConfig + "WeightWinShift"); 284 | 285 | #if DEBUG // test items 286 | foreach (pid in toolGroupPids) begin 287 | debug_msg("ToolPid: " + pid); 288 | end 289 | item_caps_adjust(dude_obj, 1000); 290 | add_mult_objs_to_inven(dude_obj, create_object(PID_BAG, 0, 0), 1); 291 | add_mult_objs_to_inven(dude_obj, create_object(PID_10MM_PISTOL, 0, 0), 10); 292 | // item := 50; 293 | // while item > 0 do begin 294 | // pid := random(1, 600); 295 | // if get_proto_data(pid, PROTO_IT_TYPE) != item_type_container then begin 296 | // add_mult_objs_to_inven(dude_obj, create_object(pid, 0, 0), 1); 297 | // item -= 1; 298 | // end 299 | // end 300 | #endif 301 | end 302 | else begin 303 | if (IsCreated) then begin 304 | if (weightIsEnabled) then begin // refresh weight win 305 | if (loot_weight andAlso lootFilter) then begin 306 | DTRACE("refresh weight 1") 307 | if (lootIsFriendContaner) then call weight_loot_win(lootObject); 308 | call weight_win(who_carry_amount(dude_obj), 0); 309 | loot_weight := false; 310 | end 311 | if (refresh_weight) then begin 312 | DTRACE("refresh weight 2") 313 | if (inven_weight) then call barter_weight_win(0); 314 | if (inven_party_weight) then call party_weight_win(0); 315 | refresh_weight := false; 316 | end 317 | end 318 | if (sortFilter) then call Button_Toggle_Off; 319 | end 320 | end 321 | end 322 | 323 | procedure GameModeChangeHook begin 324 | variable mode = get_game_mode; 325 | if (filterMessageWin andAlso (mode bwand (WORLDMAP bwor LOADGAME) or get_sfall_arg)) then call destroy_message_win; 326 | if (enableState == 2) then return; 327 | 328 | if (mode bwand (INTFACEUSE bwor INVENTORY bwor BARTER bwor INTFACELOOT)) then begin 329 | lootFilter = mode bwand INTFACELOOT; 330 | 331 | if not(IsCreated) then begin 332 | IsCreated := true; 333 | call CreateInvenFilterLeftMenu(lootFilter); 334 | if (lootIsFriendContaner orElse (mode bwand BARTER)) then begin 335 | call CreateInvenFilterRightMenu(lootFilter); 336 | end 337 | end 338 | end 339 | else if (IsCreated) then begin 340 | call DestroyFilterWin; 341 | end 342 | end 343 | 344 | procedure CreateInvenFilterLeftMenu(variable isLoot) begin 345 | DTRACE("CreateInvenFilterLeftMenu") 346 | 347 | variable mode = get_game_mode; 348 | if (mode bwand BARTER) then begin 349 | interfaceX = get_interface_x(WINTYPE_DIALOG); 350 | interfaceY = get_interface_y(WINTYPE_DIALOG); 351 | if (barterOutsideInterface) then begin 352 | menu_x = interfaceX - menu_width; 353 | menu_y = interfaceY + 480 - menu_heigh; 354 | end 355 | else begin 356 | menu_x = interfaceX + 10; 357 | menu_y = interfaceY + 100; 358 | end 359 | end 360 | else begin // for PC/USE/LOOT inventory 361 | interfaceX = get_interface_x(WINTYPE_INVENTORY); 362 | interfaceY = get_interface_y(WINTYPE_INVENTORY); 363 | menu_x = interfaceX - menu_width; 364 | menu_y = interfaceY; 365 | if (menu_x < 0) then menu_x := 0; 366 | 367 | if (isLoot) then begin 368 | lootObject = loot_obj; 369 | lootIsContainer = (obj_item_subtype(lootObject) == item_type_container); 370 | sortFilter = (lootIsContainer == false) andAlso (party_member_obj(obj_pid(lootObject)) == 0); 371 | end 372 | end 373 | 374 | // создание окна 375 | createWin("inven_filter", menu_x, menu_y, menu_width, menu_heigh); 376 | selectWin("inven_filter"); 377 | Display(mainPCXFile); 378 | 379 | if (sortFilter == false) then call Create_btn_all("on", 0); 380 | call Create_btn_armor("off", 0); 381 | call Create_btn_weapon("off", 0); 382 | call Create_btn_ammo("off", 0); 383 | call Create_btn_drug("off", 0); 384 | call Create_btn_tool("off", 0); 385 | call Create_btn_misc("off", 0); 386 | 387 | showWin; 388 | 389 | if (weightIsEnabled andAlso mode bwand INVENTORY) then begin 390 | weight_win_x = interfaceX + 48; 391 | weight_win_y = interfaceY + weight_win_y_shift; 392 | end 393 | 394 | if (isLoot) then begin 395 | lootIsFriendContaner = check_loot_object(lootObject); 396 | if (lootIsContainer) then begin 397 | containerMaxSize = get_proto_data(obj_pid(lootObject), PROTO_CN_MAX_SIZE); 398 | end 399 | if (weightIsEnabled) then begin 400 | loot_weight := true; // включает отображение окна с весом для LOOT 401 | weight_win_x = interfaceX + 48; 402 | weight_win_y = interfaceY + 120; 403 | r_weight_win_x = interfaceX + 426; 404 | end 405 | if (btnDropAll) then begin 406 | if (useBackImage) then begin 407 | interface_art_draw(WINTYPE_INVENTORY, "PCX\\InvFilterArt\\DropAll_Back.pcx", 63, 188); 408 | end 409 | /*if (lootIsFriendContaner) then*/ call CreateDropAllBtn; 410 | end 411 | end 412 | if ((mode bwand INTFACEUSE) == false andAlso (weightIsEnabled orElse sortFilter)) then set_global_script_repeat(1); 413 | 414 | if (mode bwand BARTER) then begin 415 | weight_win_x = interfaceX + 20; 416 | weight_win_y = interfaceY + 398; 417 | r_weight_win_x = interfaceX + 562; 418 | 419 | dialogCritter = dialog_obj; 420 | if swapIsEnabled then call barter_swap_win; 421 | if weightIsEnabled then call barter_weight_win(0); 422 | end 423 | else if (swapIsEnabled andAlso isLoot andAlso (swapAllContainers orElse lootObject == Trunk_Ptr)) then begin 424 | if (lootIsFriendContaner) then call loot_swap_win; 425 | end 426 | 427 | btn_all := not(sortFilter); 428 | btn_armor := false; 429 | btn_weapon := false; 430 | btn_ammo := false; 431 | btn_drug := false; 432 | btn_tool := false; 433 | btn_misc := false; 434 | special := false; 435 | end 436 | 437 | procedure CreateInvenFilterRightMenu(variable isLoot) begin 438 | DTRACE("CreateInvenFilterRightMenu") 439 | 440 | // параметры окна 441 | if (isLoot) then begin 442 | r_menu_x := interfaceX + 537; // for Loot 443 | end 444 | else begin 445 | // for Barter 446 | if (barterOutsideInterface) then 447 | r_menu_x := interfaceX + 640; 448 | else 449 | r_menu_x := interfaceX + 630 - menu_width; 450 | end 451 | 452 | //создание окна 453 | createWin("inven_filter_trd", r_menu_x, menu_y, menu_width, menu_heigh); 454 | selectWin("inven_filter_trd"); 455 | display(mainPCXFile); 456 | 457 | if (sortFilter == false) then call Create_btn_all("on", 1); 458 | call Create_btn_armor("off", 1); 459 | call Create_btn_weapon("off", 1); 460 | call Create_btn_ammo("off", 1); 461 | call Create_btn_drug("off", 1); 462 | call Create_btn_tool("off", 1); 463 | call Create_btn_misc("off", 1); 464 | 465 | showWin; 466 | 467 | if (isLoot == false) then begin 468 | isPartyBarter := party_member_obj(obj_pid(dialogCritter)) != 0; 469 | 470 | if (weightIsEnabled andAlso isPartyBarter) then begin 471 | partyMaxWeight := max_weight(dialogCritter); 472 | call party_weight_win(0); 473 | end 474 | end 475 | 476 | btn_trd_all := not(sortFilter); 477 | btn_trd_armor := false; 478 | btn_trd_weapon := false; 479 | btn_trd_ammo := false; 480 | btn_trd_drug := false; 481 | btn_trd_tool := false; 482 | btn_trd_misc := false; 483 | 484 | filterRightMenu = true; 485 | end 486 | 487 | procedure DestroyFilterWin begin 488 | debug_msg("Inventory filter windows destroy."); 489 | 490 | set_global_script_repeat(0); 491 | IsCreated := false; 492 | deleteWin("inven_filter"); 493 | 494 | if crtTempBoxPC then begin 495 | move_obj_inven_to_obj(crtTempBoxPC, dude_obj); 496 | destroy_object(crtTempBoxPC); 497 | end 498 | 499 | if (dropButtonWin) then begin 500 | deleteWin("drop_win"); 501 | dropButtonWin := false; 502 | end 503 | 504 | if (filterRightMenu) then begin 505 | if (lootFilter) then begin 506 | lootIsFriendContaner := false; 507 | if (crtTempBoxNPC) then move_obj_inven_to_obj(crtTempBoxNPC, lootObject); 508 | if (dialogCritter) then destroy_object(dialogCritter); 509 | if (containerMaxSize != -1) then begin 510 | set_proto_data(obj_pid(lootObject), PROTO_CN_MAX_SIZE, containerMaxSize); 511 | containerMaxSize = -1; 512 | end 513 | end 514 | else begin 515 | if (crtTempBoxNPC) then move_obj_inven_to_obj(crtTempBoxNPC, dialogCritter); 516 | if inven_caps then deleteWin("inven_caps"); 517 | inven_caps := false; 518 | tr_bTable := 0; 519 | pc_bTable := 0; 520 | 521 | if (isPartyBarter) then begin 522 | if (partyExtraWeightStat != -1) then begin 523 | debug_msg("Filter: Restore party member carry stat."); 524 | set_critter_extra_stat(dialogCritter, STAT_carry_amt, partyExtraWeightStat); 525 | partyExtraWeightStat = -1; 526 | end 527 | if inven_party_weight then deleteWin("inven_party_weight"); 528 | inven_party_weight := false; 529 | end 530 | end 531 | if (swapMaxWeight != -1) then begin 532 | debug_msg("Filter: Restore dude carry stats."); 533 | set_pc_base_stat(STAT_carry_amt, dudeBaseMaxWeight); 534 | set_pc_extra_stat(STAT_carry_amt, dudeExtraMaxWeight); 535 | swapMaxWeight := -1; 536 | end 537 | if (npcExtraWeightStat != -1) then begin 538 | debug_msg("Filter: Restore critter carry stat."); 539 | set_critter_extra_stat(lootObject, STAT_carry_amt, npcExtraWeightStat); 540 | npcExtraWeightStat = -1; 541 | end 542 | if (crtTempBoxNPC) then destroy_object(crtTempBoxNPC); 543 | deleteWin("inven_filter_trd"); 544 | btn_trd_all := true; 545 | pcInBarter := false; 546 | if (swapIsEnabled andAlso current_swap_number > -1) then call destroy_swap; 547 | filterRightMenu = false; 548 | end 549 | 550 | if (inven_weight) then deleteWin("inven_weight"); 551 | if (inven_loot_weight) then deleteWin("inven_loot_weight"); 552 | 553 | sortFilter = false; 554 | inven_loot_weight := false; 555 | inven_weight := false; 556 | crtTempBoxPC := 0; 557 | crtTempBoxNPC := 0; 558 | dialogCritter := 0; 559 | filterOnlyGun := false; 560 | //if (_hack_weight) then call hack_engine_weight(false); 561 | end 562 | 563 | inline procedure refresh_pc_interface_slots begin 564 | inventory_redraw(0); 565 | end 566 | 567 | procedure filter_inventory(variable filter_item_type, variable spec) begin 568 | variable item, spec_item := -1, 569 | crttr, weight; 570 | 571 | DTRACE("filter_inventory") 572 | 573 | filter_done := false; 574 | 575 | if (spec == 1) then begin 576 | if filter_item_type == item_type_ammo then 577 | spec_item := item_type_weapon; 578 | else 579 | spec_item := item_type_ammo; 580 | end 581 | else if (spec == 2) then begin 582 | spec_item = item_type_weapon; 583 | end 584 | 585 | // создать криттера в качестве временного контенера для перемещения отфильрованных предметов 586 | if crtTempBoxPC == 0 then 587 | crtTempBoxPC := genericCrtBox; 588 | else 589 | move_obj_inven_to_obj(crtTempBoxPC, dude_obj); 590 | 591 | if filter_item_type != (-1) then weight := filter_inventory_sub(filter_item_type, spec_item, dude_obj, crtTempBoxPC); 592 | 593 | //показывать деньги сверху в режиме бартера при выборе категории ALL/MISC 594 | if (filter_item_type == (-1) or filter_item_type == item_type_misc_item) and not(get_game_mode bwand INTFACELOOT) then begin 595 | item := obj_carrying_pid_obj(dude_obj, PID_BOTTLE_CAPS); 596 | if item != 0 then begin 597 | call filter_remove_items(dude_obj, dude_obj, item, PID_BOTTLE_CAPS); 598 | end 599 | end 600 | 601 | if (pcInBarter or lootFilter) then begin 602 | if (sortFilter) then begin // принцип сортировки для LOOT интерфейса 603 | // перемещаем инвентарь dude в инвентарь временного криттера (решение бага с надетой броней, когда применяется функция move_obj_inven_to_obj характеристики брони уходят в минуса) 604 | crttr := MoveDudeInventory; // TODO - Требуется протестировать этот баг на напарниках, возможно он также имеется. 605 | 606 | move_obj_inven_to_obj(crtTempBoxPC, dude_obj); 607 | move_obj_inven_to_obj(crttr, dude_obj); 608 | destroy_object(crttr); 609 | end 610 | else begin // for dude_in_barter 611 | // сохраняем статы веса игрока если еще не были сохранены 612 | if (swapMaxWeight == -1) then call GetAndSaveDudeWeight; 613 | 614 | // уменьшаем максимальный вес PC, для того чтобы игрок не смог превысить допустимый переносимый вес 615 | weight := who_carry_amount(crtTempBoxPC); // вес отфильтрованных предметов 616 | set_pc_base_stat(STAT_carry_amt, dudeWeightBonus); // учитываем возможный -/+ бонус у игрока 617 | 618 | // проверить ведется ли свап обмен 619 | if (swap_ptr and swap_ptr != dude_obj) then begin 620 | weight += who_carry_amount(swap_ptr); // + экипировка криттера 621 | set_pc_extra_stat(STAT_carry_amt, max_weight(swap_ptr) - weight + dudeEquipItemsWeight); 622 | end 623 | else begin 624 | set_pc_extra_stat(STAT_carry_amt, swapMaxWeight - weight); 625 | end 626 | end 627 | call refresh_pc_interface_slots; 628 | end 629 | else begin 630 | if (get_game_mode bwand INVENTORY) then begin 631 | if not(weightIsEnabled) then begin 632 | // if (hack_w_allow) then begin 633 | // if (_hack_weight == false and filter_item_type != (-1)) then 634 | // call hack_engine_weight(true); 635 | // else if (filter_item_type == (-1)) then 636 | // call hack_engine_weight(false); 637 | // end 638 | end else call weight_win(weight, filter_item_type); 639 | display_stats; 640 | end 641 | tap_key(DIK_HOME); 642 | end 643 | filter_done := true; 644 | filterOnlyGun = false; 645 | end 646 | 647 | procedure filter_inventory_trader(variable filter_item_type) begin 648 | variable item; 649 | 650 | DTRACE("filter_inventory_trader") 651 | 652 | // перемещаем инвентарь контейнера в инвентарь криттера 653 | if lootFilter then begin 654 | filter_done := false; 655 | if dialogCritter == 0 then dialogCritter := genericCrtBox; 656 | move_obj_inven_to_obj(lootObject, dialogCritter); 657 | end 658 | 659 | if (crtTempBoxNPC == 0) then 660 | crtTempBoxNPC := genericCrtBox; 661 | else 662 | move_obj_inven_to_obj(crtTempBoxNPC, dialogCritter); 663 | 664 | if (filter_item_type != (-1)) then call filter_inventory_sub(filter_item_type, -1, dialogCritter, crtTempBoxNPC); 665 | 666 | //показывать деньги сверху в режиме бартера 667 | if (get_game_mode bwand DIALOG) and (filter_item_type == item_type_misc_item or filter_item_type == (-1)) then begin 668 | item := obj_carrying_pid_obj(dialogCritter, PID_BOTTLE_CAPS); 669 | if (item != 0) then call filter_remove_items(dialogCritter, dialogCritter, item, PID_BOTTLE_CAPS); 670 | end 671 | 672 | // принцип сортировки для LOOT интерфейса 673 | if (lootFilter) then begin 674 | if (sortFilter) then move_obj_inven_to_obj(crtTempBoxNPC, lootObject); //возвращаем инвентарь в контейнер 675 | move_obj_inven_to_obj(dialogCritter, lootObject); 676 | filter_done := true; 677 | 678 | // уменьшаем максимальный вес, для того что бы игрок не смог превысить допустимый переносимый вес 679 | if (sortFilter == false) then begin 680 | if (lootIsContainer) then begin 681 | set_proto_data(obj_pid(lootObject), PROTO_CN_MAX_SIZE, containerMaxSize - get_current_inven_size(crtTempBoxNPC)); 682 | end 683 | else begin 684 | if (npcExtraWeightStat == -1) then begin 685 | npcExtraWeightStat = get_critter_extra_stat(lootObject, STAT_carry_amt); 686 | npcMaxWeight = max_weight(lootObject); 687 | end 688 | set_critter_extra_stat(lootObject, STAT_carry_amt, npcExtraWeightStat - who_carry_amount(crtTempBoxNPC)); // отнимаем вес отфильтрованных предметов 689 | end 690 | end 691 | end 692 | else if (isPartyBarter) then begin 693 | // уменьшаем максимальный вес, для того что бы игрок не смог превысить допустимый переносимый вес 694 | if (partyExtraWeightStat == -1) then partyExtraWeightStat := get_critter_extra_stat(dialogCritter, STAT_carry_amt); 695 | set_critter_extra_stat(dialogCritter, STAT_carry_amt, partyExtraWeightStat - who_carry_amount(crtTempBoxNPC)); // отнимаем вес отфильтрованных предметов 696 | end 697 | 698 | inventory_redraw(1); 699 | end 700 | 701 | procedure IsGunWeapon(variable pid) begin 702 | variable wAnim = get_proto_data(pid, PROTO_WP_ANIM); 703 | return (wAnim >= WPN_ANIM_PISTOL andAlso wAnim <= WPN_ANIM_ROCKET_LAUNCHER); 704 | end 705 | 706 | procedure IsToolGroup(variable ipid) begin 707 | variable pid; 708 | foreach (pid in toolGroupPids) begin 709 | if (pid == ipid) then return true; 710 | end 711 | return false; 712 | end 713 | 714 | procedure filter_inventory_sub(variable filter_item_type, variable spec_item, variable source_objptr, variable dest_objptr) begin 715 | variable item_pid, item, weight, remove, 716 | item_counter := 0, 717 | prev_counter := 0; 718 | 719 | item := inven_ptr(source_objptr, item_counter); 720 | while (item and item_counter < 1000) do begin 721 | item_pid := obj_pid(item); 722 | //в режиме торговли если предмет деньги то остаются в инвентаре игрока. 723 | if (item_pid != PID_BOTTLE_CAPS or (get_game_mode bwand (INVENTORY bwor INTFACEUSE bwor INTFACELOOT))) then begin 724 | if filter_item_type < item_type_misc_item then begin 725 | if filter_item_type == item_type_drug then begin 726 | //не исключаются drugs 727 | if (obj_item_subtype(item) != item_type_drug) then begin 728 | call filter_remove_items(source_objptr, dest_objptr, item, item_pid); 729 | end 730 | else item_counter++; 731 | end 732 | else begin 733 | remove = true; 734 | 735 | variable type = obj_item_subtype(item); 736 | if (type == filter_item_type orElse type == spec_item) then begin // не исключаются предметы тип которых соответствует фильтру 737 | // onlyGun - оставлять оружие типа GUNS, когда 738 | variable onlyGun = filterOnlyGun orElse (filter_item_type == spec_item andAlso filter_item_type == item_type_weapon); 739 | if (onlyGun == false orElse IsGunWeapon(item_pid)) then remove = false; // не удалять 740 | end 741 | 742 | if (remove) then 743 | call filter_remove_items(source_objptr, dest_objptr, item, item_pid); 744 | else item_counter++; 745 | end 746 | end 747 | else begin 748 | if (filter_item_type == item_type_tool_group) then begin 749 | if (IsToolGroup(item_pid) or IncludeDoctor(item_pid) or Explosive(item_pid) or obj_item_subtype(item) == item_type_container) then 750 | item_counter++; // неисключаются полезные вещи из категории misc 751 | else 752 | call filter_remove_items(source_objptr, dest_objptr, item, item_pid); 753 | end 754 | else if (filter_item_type == item_type_misc_item) then begin 755 | type = obj_item_subtype(item); 756 | if (type > item_type_misc_item or (type == item_type_misc_item andAlso 757 | ExcludeDoctor(item_pid) andAlso not(Explosive(item_pid)) andAlso not(IsToolGroup(item_pid)) )) 758 | then 759 | item_counter++; // не исключаются misc и key 760 | else begin 761 | call filter_remove_items(source_objptr, dest_objptr, item, item_pid); 762 | end 763 | end 764 | end 765 | 766 | if (weightIsEnabled and (item_counter > prev_counter)) then begin // если больше то считаем вес этого предмета 767 | weight += item_weight(item) * obj_is_carrying_obj(dude_obj, item); 768 | 769 | // if enable_weight and obj_item_subtype(item) == item_type_weapon then 770 | // weight += call_offset_r1(0x477B88, item) * items; /* Engine get weight for weapon */ 771 | // else if (armor_engine_weight(item_pid)) then 772 | // weight += (proto_data(item_pid, it_weight) / 2) * items; 773 | // else 774 | // weight += proto_data(item_pid, it_weight) * items; 775 | 776 | prev_counter := item_counter; 777 | end 778 | end 779 | else begin 780 | item_counter++; 781 | prev_counter++; 782 | end 783 | item := inven_ptr(source_objptr, item_counter); 784 | end 785 | return weight; 786 | end 787 | 788 | procedure filter_remove_items(variable source_objptr, variable dest_objptr, variable item, variable item_pid) begin 789 | variable items := rm_mult_objs_from_inven(source_objptr, item, obj_is_carrying_obj(source_objptr, item)); 790 | //debug_msg("item remove count " + count + " removed " + items); 791 | 792 | // обход бага в функции add_mult_objs_to_inven для монет если количество превышает 99999 793 | if (item_pid == PID_BOTTLE_CAPS) then 794 | item_caps_adjust(dest_objptr, items); 795 | else 796 | add_mult_objs_to_inven(dest_objptr, item, items); 797 | 798 | end 799 | 800 | // Возарвщает True если объект является контенером или членом группы 801 | procedure check_loot_object(variable obj) begin 802 | variable objtype = obj_item_subtype(obj); 803 | if (objtype != item_type_container) then begin 804 | return is_in_array(obj, party_member_list_critters); // проверка на обмен с партийцем 805 | end 806 | return true; 807 | end 808 | 809 | procedure MoveObjectInventory(variable src_obj, variable dst_obj, variable all) begin 810 | variable flags, item_ptr, pid, slot; 811 | 812 | item_ptr := inven_ptr(src_obj, slot); 813 | while item_ptr do begin 814 | pid := obj_pid(item_ptr); 815 | if (all or pid != PID_BOTTLE_CAPS) then begin //loot_filter 816 | flags := get_flags(item_ptr); 817 | if not(flags bwand (FLAG_LEFT_HAND bwor FLAG_RIGHT_HAND bwor FLAG_WORN)) then 818 | call filter_remove_items(src_obj, dst_obj, item_ptr, pid); 819 | else slot++; 820 | end else slot++; 821 | item_ptr := inven_ptr(src_obj, slot); 822 | end 823 | end 824 | 825 | procedure MoveDudeInventory begin 826 | variable item_ptr, crtr := genericCrtBox; 827 | 828 | item_ptr := inven_ptr(dude_obj, 0); 829 | while item_ptr do begin 830 | call filter_remove_items(dude_obj, crtr, item_ptr, obj_pid(item_ptr)); 831 | item_ptr := inven_ptr(dude_obj, 0); 832 | end 833 | return crtr; 834 | end 835 | 836 | procedure MoveItemPCHook begin 837 | if (inven_weight) then begin 838 | if (pcInBarter) then begin 839 | call barter_weight_win(-item_weight(get_sfall_arg_at(1))); 840 | end 841 | else call refresh_pc_weight in 0; // делает небольшую задержку, чтобы правильно обновить вес 842 | end 843 | end 844 | 845 | procedure MoveItemHook begin 846 | /* 847 | critter arg1 - the critter the object is being removed from 848 | item arg2 - the item that is being removed 849 | int arg3 - a flag, or possibly the number of items to remove 850 | int arg4 - The reason the object is being removed. (Actually, the site from which _item_remove_mult was called) 851 | */ 852 | variable obj, item, count; //weight; 853 | 854 | if (enableState == 2) then return; 855 | 856 | if (weightIsEnabled and lootFilter and filter_done and not(loot_weight)) then begin 857 | loot_weight := true; 858 | return; 859 | end 860 | 861 | // обновление веса в инвентаре игрока 862 | if (filter_done and inven_weight and get_game_mode bwand INVENTORY) then begin 863 | call refresh_pc_weight in 0; // делает небольшую задержку, чтобы правильно обновить вес 864 | end 865 | 866 | if (inven_weight == false or pcInBarter == false) then return; 867 | 868 | obj := get_sfall_arg; 869 | if (obj != dude_obj and obj != pc_bTable and obj != dialogCritter and obj != tr_bTable) then return; 870 | 871 | item := get_sfall_arg; 872 | count := get_sfall_arg; 873 | 874 | // flag 875 | if get_sfall_arg == RMOBJ_TRADE then begin 876 | DTRACE("hMoveItem RMOBJ_TRADE") 877 | 878 | refresh_weight := true; 879 | /* 880 | weight := call_offset_r1(0x477B88, item) * count; // item_weight_ 881 | if (obj == dude_obj or obj == pc_bTable) then begin 882 | if (obj == dude_obj) then weight := -weight; 883 | end 884 | else if (obj != dialogCritter) then begin 885 | weight := -weight; 886 | end 887 | call barter_weight_win(weight); 888 | 889 | if (inven_party_weight) then begin 890 | weight := -weight; // инвертирование знака веса 891 | call party_weight_win(weight); 892 | end 893 | */ 894 | end 895 | end 896 | 897 | procedure BarterHook begin 898 | /* 899 | critter arg0 - the critter doing the bartering (either dude_obj or inven_dude) 900 | critter arg1 - the critter being bartered with 901 | int arg2 - общая стоимость предложенных товаров у тоговца (the default value of the goods) 902 | critter arg3 - the barter critter (has all of the goods being traded in its inventory) 903 | int arg4 - the amount of actual caps in the barter stack (as opposed to goods) 904 | int arg5 - цена всех товаров (the value of all goods being traded before skill modifications) 905 | + 906 | critter arg6 - указатель на "стол" с предложенными игроком товарами 907 | int arg7 - общая стоимость предложенных игроком товаров (отдельно можно узнать количество денег с помощью item_caps_total(arg7)) 908 | int arg8 - 1 если была нажата кнопка "предложения обмена" не сопартийцу, иначе 0. 909 | */ 910 | variable barter_args, caps, diff, playerCost; 911 | 912 | if (enableState == 2) then return; 913 | barter_args := get_sfall_args; 914 | 915 | if (pcInBarter == false) then begin 916 | pcInBarter := true; 917 | dialogCritter := barter_args[1]; // на всякий случай 918 | tr_bTable := barter_args[3]; 919 | pc_bTable := barter_args[6]; 920 | end 921 | 922 | if (smart_barter and barter_args[8] and party_member_obj(obj_pid(dialogCritter)) == 0) then begin 923 | diff := barter_args[2] - barter_args[7]; // разница цены в предложенных товарах, отрицательное - задолженность для торговца 924 | if (diff < 0) then begin 925 | caps := item_caps_total(dialogCritter); 926 | if (caps > 0) then begin 927 | if (0 - diff) > caps then diff := 0 - caps; 928 | end else diff := 0; 929 | end 930 | else if (item_caps_total(pc_bTable) == 0 or item_caps_total(dude_obj) < diff) then diff := 0; 931 | 932 | if (diff != 0) then begin 933 | item_caps_adjust(dude_obj, -diff); 934 | item_caps_adjust(dialogCritter, diff); 935 | if (diff > 0 and trade_money_msg) then display_msg(sprintf(trade_money_msg, diff)); 936 | 937 | playerCost := barter_args[7]; 938 | set_sfall_arg(2, playerCost); 939 | set_sfall_return(playerCost); // возвращаем цену для торговца равную общей стоимости товаров игрока 940 | end 941 | end 942 | if (capsIsEnabled andAlso isPartyBarter == false) then call trader_cost_win; 943 | end 944 | 945 | procedure destroy_message_win begin 946 | if (filterMessageWin) then DeleteWin("filter_msg"); 947 | filterMessageWin = false; 948 | end 949 | 950 | procedure KeyPressHook begin 951 | variable type := get_sfall_arg, // event type: 1 - pressed, 0 - released 952 | key := get_sfall_arg, 953 | text; 954 | 955 | if key == DIK_F11 and type == 0 and get_game_mode == 0 then begin 956 | if (enableState == 1) then begin 957 | text = get_ini_string(iniConfig + "MsgOff"); //"Inventory Filter is disabled." 958 | end else begin 959 | text = get_ini_string(iniConfig + "MsgOn") + SCRIPT_VERSION; //"Inventory Filter is enabled." 960 | end 961 | 962 | SetFont(101); 963 | variable w = get_text_width(text) + 10; 964 | create_win_flag("filter_msg", get_screen_width - w - 5, 10, w, 15, WIN_FLAG_TRANSPARENT); 965 | SelectWin("filter_msg"); 966 | GotoXY(2, 2); 967 | SetTextColor(1.0, 1.0, 1.0); 968 | SetTextFlags(textnofill bwor textshadow); // default 969 | Print(text); 970 | ShowWin; 971 | 972 | filterMessageWin = true; 973 | enableState++; 974 | if (enableState > 2) then enableState := 1; 975 | set_sfall_global("INV_FLTR", enableState); 976 | 977 | call destroy_message_win in 3; 978 | end 979 | else if ((enableState == 1) and IsCreated) then begin 980 | if (key == drop_key_code and (get_game_mode bwand INTFACELOOT)) then begin 981 | if (type == 1) then call key_drop_press; 982 | if (type == 0) then call key_drop_release; 983 | end 984 | else if (type == 1 andAlso (get_game_mode bwand COUNTERWIN) == false) then begin 985 | variable i, hotKey; 986 | foreach (i : hotKey in hotKeys) begin 987 | if (key == hotKey) then begin 988 | call filter_by_key(i); 989 | break; 990 | end 991 | end 992 | end 993 | if (type == 0 andAlso isPressed) then isPressed := false; 994 | end 995 | end 996 | 997 | procedure MouseClickHook begin 998 | variable type, button; 999 | 1000 | if ((enableState == 1) andAlso (get_game_mode bwand (INVENTORY bwor INTFACEUSE bwor INTFACELOOT bwor BARTER))) then begin 1001 | 1002 | type := get_sfall_arg; // event type: 1 - pressed, 0 - released 1003 | button := get_sfall_arg; // button number (0 - left, 1 - right, up to 7) 1004 | 1005 | posXmouse := get_mouse_x; 1006 | posYmouse := get_mouse_y; 1007 | 1008 | if (button == 0) then begin 1009 | if (type == 1) then begin 1010 | x_mouse := get_mouse_x; 1011 | y_mouse := get_mouse_y; 1012 | end 1013 | 1014 | if (type) then begin 1015 | if inven_filter_button_all and not(btn_all) and not(sortFilter) then // button all no filter 1016 | call inven_filter_button_pressed("all", -1, 0); 1017 | else if inven_filter_button_armor and not(btn_armor) then // button armor 1018 | call inven_filter_button_pressed("armor", item_type_armor, 0); 1019 | else if inven_filter_button_weapon and not(btn_weapon) then begin // button weapon 1020 | call inven_filter_button_pressed("weapon", item_type_weapon, 0); 1021 | sec_click := true; 1022 | end 1023 | else if inven_filter_button_ammo and not(btn_ammo) then // button ammo 1024 | call inven_filter_button_pressed("ammo", item_type_ammo, 0); 1025 | else if inven_filter_button_drug and not(btn_drug) then // button drug 1026 | call inven_filter_button_pressed("drug", item_type_drug, 0); 1027 | else if inven_filter_button_tool and not(btn_tool) then // button tool 1028 | call inven_filter_button_pressed("tool", item_type_tool_group, 0); 1029 | else if inven_filter_button_misc and not(btn_misc) then // button misc 1030 | call inven_filter_button_pressed("misc", item_type_misc_item, 0); 1031 | // for trader/loot 1032 | else if (filterRightMenu) then begin 1033 | if inven_filter_trd_button_all and not(btn_trd_all) and not(sortFilter) then // button all no filter 1034 | call inven_filter_trd_button_pressed("all", -1); 1035 | else if inven_filter_trd_button_armor and not(btn_trd_armor) then // button armor 1036 | call inven_filter_trd_button_pressed("armor", item_type_armor); 1037 | else if inven_filter_trd_button_weapon and not(btn_trd_weapon) then // button weapon 1038 | call inven_filter_trd_button_pressed("weapon", item_type_weapon); 1039 | else if inven_filter_trd_button_ammo and not(btn_trd_ammo) then // button ammo 1040 | call inven_filter_trd_button_pressed("ammo", item_type_ammo); 1041 | else if inven_filter_trd_button_drug and not(btn_trd_drug) then // button drug 1042 | call inven_filter_trd_button_pressed("drug", item_type_drug); 1043 | else if inven_filter_trd_button_tool and not(btn_trd_tool) then // button tool 1044 | call inven_filter_trd_button_pressed("tool", item_type_tool_group); 1045 | else if inven_filter_trd_button_misc and not(btn_trd_misc) then // button mis 1046 | call inven_filter_trd_button_pressed("misc", item_type_misc_item); 1047 | end 1048 | 1049 | if (swapIsEnabled andAlso (lootIsFriendContaner orElse pcInBarter) andAlso current_swap_number > -1) then begin 1050 | if swap_next_button then 1051 | call swap_button_pressed(true); 1052 | else if swap_back_button then 1053 | call swap_button_pressed(false); 1054 | end 1055 | end 1056 | end // клик средней кнопкой мышки по кнопкам патроны или оружие 1057 | else if (button == 2) then begin 1058 | if (btn_ammo orElse btn_weapon) then begin 1059 | if inven_filter_button_ammo and not(btn_ammo) then // button ammo 1060 | call inven_filter_button_pressed("ammo", item_type_ammo, 1); 1061 | else if inven_filter_button_weapon and not(btn_weapon) then // button weapon 1062 | call inven_filter_button_pressed("weapon", item_type_weapon, 1); 1063 | end 1064 | if inven_filter_button_weapon and (not(btn_weapon) or sec_click) then begin // button misc 1065 | call inven_filter_button_pressed("weapon", item_type_weapon, 2); 1066 | sec_click := false; 1067 | filterOnlyGun = true; 1068 | end 1069 | end 1070 | if (isPressed andAlso type == 0) then isPressed := false; 1071 | end 1072 | end 1073 | 1074 | procedure filter_by_key(variable keyType) begin 1075 | if (keyType[0] == "n" andAlso (pcInBarter orElse lootFilter) == false) then return; 1076 | 1077 | switch (keyType) begin 1078 | case "pAll": 1079 | if not(btn_all) and not(sortFilter) then call inven_filter_button_pressed("all", -1, 0); 1080 | case "pArmor": 1081 | if not(btn_armor) then call inven_filter_button_pressed("armor", item_type_armor, 0); 1082 | case "pWeapon": 1083 | if not(btn_weapon) then begin 1084 | call inven_filter_button_pressed("weapon", item_type_weapon, 0); 1085 | sec_click := true; 1086 | end 1087 | else if (sec_click) then begin 1088 | call inven_filter_button_pressed("weapon", item_type_weapon, 2); 1089 | filterOnlyGun = true; 1090 | sec_click := false; 1091 | end 1092 | case "pAmmo": 1093 | if not(btn_ammo) then call inven_filter_button_pressed("ammo", item_type_ammo, 0); 1094 | case "pDrug": 1095 | if not(btn_drug) then call inven_filter_button_pressed("drug", item_type_drug, 0); 1096 | case "pMisc": 1097 | if not(btn_tool) then 1098 | call inven_filter_button_pressed("tool", item_type_tool_group, 0); 1099 | else if (btn_tool) then begin 1100 | call inven_filter_button_pressed("misc", item_type_misc_item, 0); 1101 | end 1102 | // for trader/loot 1103 | case "nAll": 1104 | if not(btn_trd_all) and not(sortFilter) then call inven_filter_trd_button_pressed("all", -1); 1105 | case "nArmor": 1106 | if not(btn_trd_armor) then call inven_filter_trd_button_pressed("armor", item_type_armor); 1107 | case "nWeapon": 1108 | if not(btn_trd_weapon) then call inven_filter_trd_button_pressed("weapon", item_type_weapon); 1109 | case "nAmmo": 1110 | if not(btn_trd_ammo) then call inven_filter_trd_button_pressed("ammo", item_type_ammo); 1111 | case "nDrug": 1112 | if not(btn_trd_drug) then call inven_filter_trd_button_pressed("drug", item_type_drug); 1113 | case "nMisc": 1114 | if not(btn_trd_tool) then 1115 | call inven_filter_trd_button_pressed("tool", item_type_tool_group); 1116 | else if (btn_trd_tool) then begin 1117 | call inven_filter_trd_button_pressed("misc", item_type_misc_item); 1118 | end 1119 | end 1120 | end 1121 | 1122 | procedure inven_filter_button_pressed(variable p_btn, variable filter_item_type, variable spec) begin 1123 | if not(isPressed) then begin 1124 | isPressed := true; 1125 | 1126 | //call_offset_v2(0x476394, 2500, 0); //функция закрыть открытую сумку? первый равен 2500 для _curr_stack или 2501 для _target_curr_stack, второй указывает режим — 0 (INVENTORY), 1 (INTFACEUSE), 2 (INTFACELOOT) и 3 (BARTER) 1127 | if (read_int(0x59E96C) > 0) then begin // проверить открыты ли сумки 1128 | play_sfx("IISXXXX1"); 1129 | variable text := get_ini_string(iniConfig + "MsgWarning"); 1130 | if not(pcInBarter) then create_message_window(text); else display_msg(text); 1131 | end 1132 | else begin 1133 | play_sfx("IB2P1XX1"); 1134 | call inven_filter_button_toggle(p_btn, spec); //button down so highlight! 1135 | call filter_inventory(filter_item_type, spec); 1136 | end 1137 | end 1138 | end 1139 | 1140 | procedure inven_filter_button_toggle(variable p_btn, variable spec) begin 1141 | if (sortFilter) then btn_toggle_off := true; 1142 | 1143 | selectWin("inven_filter"); 1144 | if not((spec == 1) and (btn_ammo or btn_weapon)) then begin 1145 | call create_btn_sub; 1146 | 1147 | if (special) then begin 1148 | call DeletePressButton; 1149 | call Create_btn_ammo("off", 0); 1150 | special := false; 1151 | end 1152 | end 1153 | else special := true; 1154 | 1155 | call SelectCreateButton(p_btn, false); 1156 | showWin; 1157 | end 1158 | 1159 | procedure inven_filter_trd_button_pressed(variable p_btn, variable filter_item_type) begin 1160 | variable _target_curr_stack, text; 1161 | 1162 | if not(isPressed) then begin 1163 | isPressed := true; 1164 | 1165 | _target_curr_stack := read_int(0x59E948); // проверить открыты ли сумки у цели 1166 | if _target_curr_stack > 0 then begin 1167 | play_sfx("IISXXXX1"); 1168 | text := get_ini_string(iniConfig + "MsgWarning"); 1169 | if lootFilter then create_message_window(text); else display_msg(text); 1170 | end 1171 | else begin 1172 | play_sfx("IB2P1XX1"); 1173 | call inven_filter_trd_button_toggle(p_btn); //button down so highlight! 1174 | call filter_inventory_trader(filter_item_type); 1175 | end 1176 | end 1177 | end 1178 | 1179 | procedure inven_filter_trd_button_toggle(variable p_btn) begin 1180 | if sortFilter then btn_trd_toggle_off := true; 1181 | 1182 | selectWin("inven_filter_trd"); 1183 | 1184 | call create_btn_trd_sub; 1185 | call SelectCreateButton(p_btn, true); 1186 | 1187 | showWin; 1188 | end 1189 | 1190 | procedure Button_Toggle_Off begin 1191 | if get_mouse_buttons == 0 then begin 1192 | if btn_toggle_off then begin 1193 | btn_toggle_off := false; 1194 | selectWin("inven_filter"); 1195 | call create_btn_sub; 1196 | showWin; 1197 | end 1198 | else if btn_trd_toggle_off then begin 1199 | btn_trd_toggle_off := false; 1200 | selectWin("inven_filter_trd"); 1201 | call create_btn_trd_sub; 1202 | showWin; 1203 | end 1204 | end 1205 | end 1206 | 1207 | /////////////////////////////////////// INTERFACE /////////////////////////////////////////// 1208 | 1209 | procedure SelectCreateButton(variable p_btn, variable flag) begin 1210 | //удалить кнопку которая была нажата 1211 | call subDeleteButton(p_btn, "off", flag); 1212 | 1213 | // создать новую кнопку которая была нажата. 1214 | switch p_btn begin 1215 | case "all" : call Create_btn_all("on", flag); 1216 | case "armor" : call Create_btn_armor("on", flag); 1217 | case "weapon" : call Create_btn_weapon("on", flag); 1218 | case "ammo" : call Create_btn_ammo("on", flag); 1219 | case "drug" : call Create_btn_drug("on", flag); 1220 | case "tool" : call Create_btn_tool("on", flag); 1221 | case "misc" : call Create_btn_misc("on", flag); 1222 | end 1223 | end 1224 | 1225 | procedure create_btn_sub begin 1226 | // удалить предыдущую нажатую кнопку 1227 | call DeletePressButton; 1228 | 1229 | //создать на месте удаленной кнопки новую кнопку (закрыть дыру) 1230 | if btn_all then call Create_btn_all("off", 0); 1231 | else if btn_armor then call Create_btn_armor("off", 0); 1232 | else if btn_weapon then call Create_btn_weapon("off", 0); 1233 | else if btn_ammo then call Create_btn_ammo("off", 0); 1234 | else if btn_drug then call Create_btn_drug("off", 0); 1235 | else if btn_tool then call Create_btn_tool("off", 0); 1236 | else if btn_misc then call Create_btn_misc("off", 0); 1237 | 1238 | end 1239 | 1240 | procedure create_btn_trd_sub begin 1241 | // удалить предыдущую нажатую кнопку 1242 | call DeletePressButtonTrd; 1243 | 1244 | //создать на месте удаленной кнопки новую кнопку (закрыть дыру) 1245 | if btn_trd_all then call Create_btn_all("off", 1); 1246 | else if btn_trd_armor then call Create_btn_armor("off", 1); 1247 | else if btn_trd_weapon then call Create_btn_weapon("off", 1); 1248 | else if btn_trd_ammo then call Create_btn_ammo("off", 1); 1249 | else if btn_trd_drug then call Create_btn_drug("off", 1); 1250 | else if btn_trd_tool then call Create_btn_tool("off", 1); 1251 | else if btn_trd_misc then call Create_btn_misc("off", 1); 1252 | 1253 | end 1254 | 1255 | procedure Create_btn_all(variable flag, variable trd) begin 1256 | call subCreateButton("all", flag, trd, 0); 1257 | 1258 | if not(trd) then begin 1259 | if flag == "on" then btn_all := true; else btn_all := false; 1260 | end else if flag == "on" then btn_trd_all := true; else btn_trd_all := false; 1261 | end 1262 | 1263 | procedure Create_btn_armor(variable flag, variable trd) begin 1264 | call subCreateButton("armor", flag, trd, 1); 1265 | 1266 | if not(trd) then begin 1267 | if flag == "on" then btn_armor := true; else btn_armor := false; 1268 | end else if flag == "on" then btn_trd_armor := true; else btn_trd_armor :=false; 1269 | end 1270 | 1271 | procedure Create_btn_weapon(variable flag, variable trd) begin 1272 | call subCreateButton("weapon", flag, trd, 2); 1273 | 1274 | if not(trd) then begin 1275 | if flag == "on" then btn_weapon := true; else btn_weapon := false; 1276 | end else if flag == "on" then btn_trd_weapon := true; else btn_trd_weapon := false; 1277 | end 1278 | 1279 | procedure Create_btn_ammo(variable flag, variable trd) begin 1280 | call subCreateButton("ammo", flag, trd, 3); 1281 | 1282 | if not(trd) then begin 1283 | if flag == "on" then btn_ammo := true; else btn_ammo := false; 1284 | end else if flag == "on" then btn_trd_ammo := true; else btn_trd_ammo := false; 1285 | end 1286 | 1287 | procedure Create_btn_drug(variable flag, variable trd) begin 1288 | call subCreateButton("drug", flag, trd, 4); 1289 | 1290 | if not(trd) then begin 1291 | if flag == "on" then btn_drug := true; else btn_drug := false; 1292 | end else if flag == "on" then btn_trd_drug := true; else btn_trd_drug := false; 1293 | end 1294 | 1295 | procedure Create_btn_tool(variable flag, variable trd) begin 1296 | call subCreateButton("tool", flag, trd, 5); 1297 | 1298 | if not(trd) then begin 1299 | if flag == "on" then btn_tool := true; else btn_tool := false; 1300 | end else if flag == "on" then btn_trd_tool := true; else btn_trd_tool := false; 1301 | end 1302 | 1303 | procedure Create_btn_misc(variable flag, variable trd) begin 1304 | call subCreateButton("misc", flag, trd, 6); 1305 | 1306 | if not(trd) then begin 1307 | if flag == "on" then btn_misc := true; else btn_misc := false; 1308 | end else if flag == "on" then btn_trd_misc := true; else btn_trd_misc := false; 1309 | end 1310 | 1311 | procedure subCreateButton(variable btn, variable flag, variable trd, variable vshift) begin 1312 | variable btn_name, btn_on, btn_off, btn_hover; 1313 | 1314 | btn_name := "filter_" + btn + "_" + flag + trd; 1315 | btn_on := buttonPCXFile + btn + "_on.pcx"; 1316 | btn_off := buttonPCXFile + btn + "_" + flag + ".pcx"; 1317 | btn_hover := buttonPCXFile + btn + "_hover_" + flag + ".pcx"; 1318 | 1319 | addButton(btn_name, xPos, 1 + yPos + (btnHeight * vshift), btnWidth, bHeight); 1320 | addButtonGfx(btn_name, btn_on, btn_off, btn_hover); 1321 | end 1322 | 1323 | procedure HightlightButton(variable btn, variable flag, variable trd) begin 1324 | variable btn_name, btn_on, btn_hover; 1325 | 1326 | btn_name := "filter_" + btn + "_" + flag + trd; 1327 | btn_on := buttonPCXFile + btn + "_on.pcx"; 1328 | btn_hover := buttonPCXFile + btn + "_hover_on.pcx"; 1329 | 1330 | selectWin("inven_filter"); 1331 | AddButtonGFX(btn_name, btn_on, btn_on, btn_hover); 1332 | end 1333 | 1334 | procedure DeletePressButton begin 1335 | variable btn; 1336 | 1337 | if btn_all then btn := "all"; 1338 | else if btn_armor then btn := "armor"; 1339 | else if btn_weapon then btn := "weapon"; 1340 | else if btn_ammo then btn := "ammo"; 1341 | else if btn_drug then btn := "drug"; 1342 | else if btn_tool then btn := "tool"; 1343 | else if btn_misc then btn := "misc"; 1344 | else return; 1345 | 1346 | call subDeleteButton(btn, "on", false); 1347 | end 1348 | 1349 | procedure DeletePressButtonTrd begin 1350 | variable btn; 1351 | 1352 | if btn_trd_all then btn := "all"; 1353 | else if btn_trd_armor then btn := "armor"; 1354 | else if btn_trd_weapon then btn := "weapon"; 1355 | else if btn_trd_ammo then btn := "ammo"; 1356 | else if btn_trd_drug then btn := "drug"; 1357 | else if btn_trd_tool then btn := "tool"; 1358 | else if btn_trd_misc then btn := "misc"; 1359 | else return; 1360 | 1361 | call subDeleteButton(btn, "on", true); 1362 | end 1363 | 1364 | procedure subDeleteButton(variable btn, variable type, variable flag) begin 1365 | deleteButton("filter_" + btn + "_" + type + flag); 1366 | end 1367 | 1368 | /////////////////////////////////////// WEIGHT /////////////////////////////////////////// 1369 | 1370 | procedure refresh_pc_weight begin 1371 | variable equp, item; 1372 | DTRACE("refresh_pc_weight") 1373 | 1374 | item := critter_inven_obj(dude_obj, INVEN_TYPE_WORN); 1375 | if (item) then equp := item_weight(item); 1376 | 1377 | item := critter_inven_obj2(dude_obj, INVEN_TYPE_LEFT_HAND); 1378 | if (item) then equp += item_weight(item); 1379 | 1380 | item := critter_inven_obj2(dude_obj, INVEN_TYPE_RIGHT_HAND); 1381 | if (item) then equp += item_weight(item); 1382 | 1383 | call weight_win(who_carry_amount(dude_obj) - equp, 0); 1384 | end 1385 | 1386 | procedure weight_win(variable weight, variable type) begin 1387 | DTRACE("weight_win") 1388 | 1389 | //создание окна для отображения веса предметов для игрока 1390 | if (inven_weight == false) then begin 1391 | create_win_flag("inven_weight", weight_win_x, weight_win_y, 60, 20, win_flags); 1392 | selectWin("inven_weight"); 1393 | inven_weight := true; 1394 | end 1395 | else if (type == -1) then begin 1396 | DeleteWin("inven_weight"); 1397 | inven_weight := false; 1398 | return; 1399 | end 1400 | else begin 1401 | selectWin("inven_weight"); 1402 | sfall_func0("win_fill_color"); 1403 | end 1404 | 1405 | variable wMax := swapMaxWeight if (swapMaxWeight != -1) else dude_max_weight; 1406 | 1407 | SetFont(101); 1408 | if (current_swap_number > 0) then begin 1409 | weight += who_carry_amount(swap_ptr); // swap-critter current equip items 1410 | weight -= dudeEquipItemsWeight; 1411 | end 1412 | 1413 | if (lootFilter andAlso crtTempBoxPC) then weight += who_carry_amount(crtTempBoxPC); 1414 | 1415 | if (weight > wMax) then 1416 | SetTextColor(1.0, 0.1, 0.0); // red color 1417 | else 1418 | SetTextColor(r, g, b); 1419 | 1420 | if (lootFilter) then begin 1421 | Format(weight + "/" + wMax, 0, 5, 60, 10, justifycenter); 1422 | end else 1423 | Format(mstr_inventry(30) + ": " + weight, 0, 8, 60, 10, justifycenter); 1424 | 1425 | showWin; 1426 | end 1427 | 1428 | procedure weight_loot_win(variable obj) begin 1429 | variable weight; 1430 | DTRACE("weight_loot_win") 1431 | 1432 | // создание окна для отображения размера для контенеров 1433 | if (inven_loot_weight == false) then begin 1434 | create_win_flag("inven_loot_weight", r_weight_win_x, weight_win_y, 60, 20, win_flags); 1435 | selectWin("inven_loot_weight"); 1436 | //AddRegion "tip" { 10,5, 50,5, 50,15, 10,15}; 1437 | //AddRegionProc("tip", ShowSize, HideSize, 0, 0); 1438 | inven_loot_weight := true; 1439 | end 1440 | else begin 1441 | selectWin("inven_loot_weight"); 1442 | sfall_func0("win_fill_color"); 1443 | end 1444 | SetFont(101); 1445 | 1446 | if (obj_type(obj) == OBJ_TYPE_CRITTER) then begin 1447 | weight = who_carry_amount(obj); 1448 | if (crtTempBoxNPC) then weight += who_carry_amount(crtTempBoxNPC); 1449 | call print_weight(weight, (npcMaxWeight if (npcExtraWeightStat != -1) else max_weight(obj))); 1450 | end 1451 | else begin 1452 | // получает процент заполненности контейнера 1453 | weight := get_current_inven_size(obj); 1454 | if (crtTempBoxNPC) then weight += get_current_inven_size(crtTempBoxNPC); 1455 | 1456 | if (showPercentSize) then begin 1457 | weight := round((weight / (containerMaxSize + 0.0)) * 100.0); 1458 | end 1459 | call print_weight(weight, 0); 1460 | end 1461 | end 1462 | 1463 | procedure barter_weight_win(variable weight) begin 1464 | DTRACE("barter_weight_win") 1465 | 1466 | weight += who_carry_amount(dude_obj); 1467 | if crtTempBoxPC then weight += who_carry_amount(crtTempBoxPC); 1468 | if (tr_bTable) then weight += who_carry_amount(tr_bTable); 1469 | 1470 | //создание окна для отображения веса для игрока в бартере 1471 | if (inven_weight == false) then begin 1472 | create_win_flag("inven_weight", weight_win_x, weight_win_y, 60, 20, win_flags); 1473 | inven_weight := true; 1474 | selectWin("inven_weight"); 1475 | end 1476 | else begin 1477 | selectWin("inven_weight"); 1478 | sfall_func0("win_fill_color"); 1479 | end 1480 | 1481 | if (current_swap_number > 0) then begin 1482 | weight += who_carry_amount(swap_ptr); // swap-critter current equip items 1483 | weight -= dudeEquipItemsWeight; 1484 | end 1485 | 1486 | call print_weight(weight, swapMaxWeight if (swapMaxWeight != -1) else dude_max_weight); 1487 | end 1488 | 1489 | procedure party_weight_win(variable weight) begin 1490 | DTRACE("party_weight_win") 1491 | 1492 | //создание окна для отображения веса у напарника во время обмена в бартере 1493 | if (inven_party_weight == false) then begin 1494 | create_win_flag("inven_party_weight", r_weight_win_x, weight_win_y, 60, 20, win_flags); 1495 | selectWin("inven_party_weight"); 1496 | inven_party_weight := true; 1497 | end 1498 | else begin 1499 | selectWin("inven_party_weight"); 1500 | sfall_func0("win_fill_color"); 1501 | end 1502 | 1503 | weight += who_carry_amount(dialogCritter); 1504 | if (pc_bTable) then weight += who_carry_amount(pc_bTable); 1505 | if (crtTempBoxNPC) then weight += who_carry_amount(crtTempBoxNPC); 1506 | 1507 | call print_weight(weight, partyMaxWeight); 1508 | end 1509 | 1510 | // печатает текущий вес в текущее окно веса 1511 | procedure print_weight(variable weight, variable maxWeight) begin 1512 | DTRACE("print_weight") 1513 | 1514 | if (maxWeight and weight > maxWeight) then 1515 | SetTextColor(1.0, 0.1, 0.0); 1516 | else 1517 | SetTextColor(r, g, b); 1518 | 1519 | if (maxWeight) then 1520 | Format(weight_cur_max, 0, 5, 60, 10, justifycenter); 1521 | else begin 1522 | if (showPercentSize) then 1523 | Format(weight_percent, 0, 5, 60, 10, justifycenter); 1524 | else begin 1525 | maxWeight = containerMaxSize; 1526 | Format(weight_cur_max, 0, 5, 60, 10, justifycenter); 1527 | end 1528 | end 1529 | showWin; 1530 | end 1531 | 1532 | procedure trader_cost_win begin 1533 | //создание окна для отображения налички у торговца 1534 | if (inven_caps == false) then begin 1535 | create_win_flag("inven_caps", r_weight_win_x, weight_win_y, 60, 20, win_flags); 1536 | selectWin("inven_caps"); 1537 | inven_caps := true; 1538 | end 1539 | else begin 1540 | selectWin("inven_caps"); 1541 | sfall_func0("win_fill_color"); 1542 | end 1543 | 1544 | startcritical; 1545 | SetTextColor(r, g, b); 1546 | Format("$" + item_caps_total(dialogCritter), 0, 5, 60, 10, justifycenter); 1547 | showWin; 1548 | endcritical; 1549 | end 1550 | 1551 | procedure hack_engine_weight(variable hack) begin 1552 | // if (hack) then begin 1553 | // _hack_weight := true; 1554 | // write_byte(0x477EE1, 0xEB); 1555 | // end 1556 | // else begin 1557 | // _hack_weight := false; 1558 | // write_byte(0x477EE1, 0x75); 1559 | // end 1560 | end 1561 | 1562 | /////////////////////////////////////// EXCHANGE FEATURE /////////////////////////////////////////// 1563 | 1564 | procedure GetAndSaveDudeWeight begin 1565 | dudeBaseMaxWeight := get_pc_base_stat(STAT_carry_amt); 1566 | dudeExtraMaxWeight := get_pc_extra_stat(STAT_carry_amt); 1567 | dudeWeightBonus = GetDudeWeightBonus; // engine -/+ bonus 1568 | swapMaxWeight = dude_max_weight; 1569 | end 1570 | 1571 | procedure GetDudeWeightBonus begin 1572 | variable bonus; 1573 | set_pc_base_stat(STAT_carry_amt, 100); 1574 | set_pc_extra_stat(STAT_carry_amt, 0); 1575 | bonus = 100 - dude_max_weight; 1576 | set_pc_base_stat(STAT_carry_amt, dudeBaseMaxWeight); 1577 | set_pc_extra_stat(STAT_carry_amt, dudeExtraMaxWeight); 1578 | return bonus; // возвращает положительное значение бонуса, если имеется движковое пенальти к максимальному весу 1579 | end 1580 | 1581 | procedure SwappingParty(variable type, variable value) begin 1582 | variable ptr, name, skip, flag, loop := true; 1583 | variable currW, fid; 1584 | 1585 | DTRACE("SwappingParty") 1586 | 1587 | while (read_int(0x59E96C)) do begin // проверить открыты ли сумки 1588 | call_offset_v2(0x476394, 2500, 2 + pcInBarter); //функция закрыть открытую сумку 1589 | end 1590 | 1591 | ptr := swap_party_array[current_swap_number]; 1592 | name := obj_name(ptr); 1593 | 1594 | while (loop and current_swap_number > 0) do begin 1595 | skip := false; 1596 | flag := get_proto_data(obj_pid(ptr), PROTO_CR_FLAGS); 1597 | if (flag bwand CFLG_BARTER) == false or (flag bwand CFLG_NOSTEAL) then skip := true; 1598 | if skip or (tile_distance_objs(dude_obj, ptr) > 30) then begin 1599 | if not(skip) then display_msg(name + get_ini_string(iniConfig + "MsgSwap")); 1600 | current_swap_number += value; 1601 | if (current_swap_number > len_party_array) then current_swap_number := 0; 1602 | ptr := swap_party_array[current_swap_number]; 1603 | name := obj_name(ptr); 1604 | end 1605 | else loop := false; 1606 | end 1607 | 1608 | if (swap_contaner == 0) then begin 1609 | if (current_swap_number == 0) then return; 1610 | swap_contaner := genericCrtBox; 1611 | call MoveObjectInventory(dude_obj, swap_contaner, lootFilter); // перемещаем инвентарь игрока 1612 | dudeEquipItemsWeight := who_carry_amount(dude_obj); // вес экипированных вещей 1613 | end 1614 | 1615 | debug_msg("Filter: Swapping with " + name); 1616 | 1617 | if (swap_ptr != 0) then begin 1618 | if (swap_ptr == dude_obj and ptr != dude_obj) then begin 1619 | call MoveObjectInventory(dude_obj, swap_contaner, lootFilter); // перемещаем инвентарь игрока 1620 | dudeEquipItemsWeight := who_carry_amount(dude_obj); 1621 | end 1622 | else call MoveObjectInventory(dude_obj, swap_ptr, lootFilter); //возвращаем инвентарь партийца обратно 1623 | end 1624 | 1625 | swap_ptr := ptr; 1626 | if (swap_ptr == dude_obj) then begin 1627 | move_obj_inven_to_obj(swap_contaner, dude_obj); //возвращаем инвентарь игрока обратно 1628 | end 1629 | else begin 1630 | call MoveObjectInventory(swap_ptr, dude_obj, lootFilter); 1631 | end 1632 | 1633 | // set carry 1634 | if (swap_ptr != dude_obj) then begin 1635 | call SetDudeSwapWeight(swap_ptr); 1636 | swapMaxWeight := max_weight(swap_ptr); // максимальный подъемный вес криттера 1637 | end 1638 | else begin 1639 | set_pc_base_stat(STAT_carry_amt, dudeBaseMaxWeight); 1640 | set_pc_extra_stat(STAT_carry_amt, dudeExtraMaxWeight); 1641 | swapMaxWeight := dude_max_weight; 1642 | end 1643 | 1644 | if (type) then begin 1645 | if (pcInBarter andAlso weightIsEnabled) then call barter_weight_win(0); 1646 | call refresh_pc_interface_slots; 1647 | call swap_name(name); 1648 | showWin; 1649 | end 1650 | 1651 | if (swap_ptr == dude_obj) then begin 1652 | fid := get_object_data(dude_obj, 0x20); 1653 | end 1654 | else begin 1655 | fid := obj_art_fid(swap_ptr); 1656 | fid := (fid bwand 0xFF00FFFF); 1657 | end 1658 | 1659 | write_int(0x59E95C, fid); // i_fid 1660 | if (value) then begin 1661 | write_int(0x5190F8, 2); // set body rotation 1662 | call_offset_v2(0x470650, -1, (2 + (pcInBarter))); /* display_body_ */ 1663 | end 1664 | end 1665 | 1666 | procedure SetDudeSwapWeight(variable swapCritter) begin 1667 | variable 1668 | // максимальный подъемный вес криттера 1669 | base = get_critter_base_stat(swapCritter, STAT_carry_amt), 1670 | extra = get_critter_extra_stat(swapCritter, STAT_carry_amt), 1671 | directWeight = base + extra - who_carry_amount(swapCritter); // минус текущий вес экипировки криттера 1672 | 1673 | set_critter_base_stat(swapCritter, STAT_carry_amt, 100); 1674 | set_critter_extra_stat(swapCritter, STAT_carry_amt, 0); 1675 | 1676 | directWeight += max_weight(swapCritter) - 100; // учитываем возможный -/+ бонус движка 1677 | 1678 | set_critter_base_stat(swapCritter, STAT_carry_amt, base); 1679 | set_critter_extra_stat(swapCritter, STAT_carry_amt, extra); 1680 | 1681 | // устанавливаем вес игроку в соответствии с характеристиками криттера 1682 | set_pc_base_stat(STAT_carry_amt, dudeWeightBonus); 1683 | set_pc_extra_stat(STAT_carry_amt, directWeight + dudeEquipItemsWeight); 1684 | end 1685 | 1686 | procedure get_party_array(variable ptr_check) begin 1687 | swap_party_array := party_member_list_critters; 1688 | len_party_array := len_array(swap_party_array) - 1; 1689 | if ((len_party_array < 1) or (is_in_array(ptr_check, swap_party_array))) then begin 1690 | swap_party_array := 0; 1691 | return 0; 1692 | end 1693 | fix_array(swap_party_array); 1694 | 1695 | current_swap_number := 0; 1696 | return 1; 1697 | end 1698 | 1699 | procedure swap_button_pressed(variable btn) begin 1700 | if (isPressed == false) then begin 1701 | isPressed := true; 1702 | if (not(btn_all)) then begin 1703 | if (pcInBarter) then begin 1704 | dialog_message(get_ini_string(iniConfig + "MsgSwapFilter")); 1705 | end 1706 | else begin 1707 | display_msg(get_ini_string(iniConfig + "MsgSwapFilter")); 1708 | end 1709 | play_sfx("IISXXXX1"); 1710 | return; 1711 | end 1712 | 1713 | if (btn) then begin 1714 | call next_swap_ptr; 1715 | end 1716 | else begin 1717 | call back_swap_ptr; 1718 | end 1719 | play_sfx("IB2P1XX1"); 1720 | if (btn == 0) then btn--; 1721 | 1722 | if (swapMaxWeight == -1) then call GetAndSaveDudeWeight; // сохраняем статы веса игрока если еще не были сохранены 1723 | call SwappingParty(true, btn); 1724 | end 1725 | end 1726 | 1727 | procedure next_swap_ptr begin 1728 | current_swap_number++; 1729 | if current_swap_number > len_party_array then current_swap_number := 0; 1730 | end 1731 | 1732 | procedure back_swap_ptr begin 1733 | current_swap_number--; 1734 | if current_swap_number < 0 then current_swap_number := len_party_array; 1735 | end 1736 | 1737 | procedure barter_swap_win begin 1738 | if get_party_array(dialogCritter) then call create_swap_win(swap_brtr_win_x + swap_barter_offset, swap_brtr_win_y + swap_barter_y_offset); 1739 | end 1740 | 1741 | procedure loot_swap_win begin 1742 | SetFont(101); 1743 | if get_party_array(lootObject) then call create_swap_win(swap_loot_win_x + swap_loot_offset, swap_loot_win_y + swap_loot_y_offset); 1744 | end 1745 | 1746 | procedure create_swap_win(variable x_offset, variable y_offset) begin 1747 | DTRACE("create_swap_win") 1748 | 1749 | swap_win_x := interfaceX + x_offset; 1750 | swap_win_y := interfaceY + y_offset; 1751 | 1752 | create_win("swap_win", swap_win_x, swap_win_y, 150, 36); 1753 | call swap_name(obj_name(dude_obj)); 1754 | 1755 | AddButton("btn_next", 123, 9, 23, 20); 1756 | AddButtonGFX("btn_next", "PCX\\InvFilterArt\\right_dn.pcx", "PCX\\InvFilterArt\\right_up.pcx", ""); 1757 | 1758 | AddButton("btn_back", 4, 9, 23, 20); 1759 | AddButtonGFX("btn_back", "PCX\\InvFilterArt\\left_dn.pcx", "PCX\\InvFilterArt\\left_up.pcx", ""); 1760 | 1761 | showWin; 1762 | end 1763 | 1764 | procedure swap_name(variable name) begin 1765 | selectWin("swap_win"); 1766 | Display("PCX\\InvFilterArt\\swap_win.pcx"); 1767 | SetTextColor(1.0, 1.0, 1.0); 1768 | Format(name, 0, 13, 150, 10, justifycenter); 1769 | end 1770 | 1771 | procedure destroy_swap begin 1772 | DeleteWin("swap_win"); 1773 | 1774 | if (swap_contaner) then begin 1775 | if (current_swap_number > 0) then begin 1776 | current_swap_number := 0; 1777 | call SwappingParty(false, 0); 1778 | end 1779 | destroy_object(swap_contaner); 1780 | end 1781 | swap_ptr := 0; 1782 | swap_contaner := 0; 1783 | current_swap_number := -1; 1784 | 1785 | if (swap_party_array) then begin 1786 | free_array(swap_party_array); 1787 | swap_party_array := 0; 1788 | end 1789 | end 1790 | 1791 | /////////////////////////////////////// DROP BUTTON //////////////////////////////////////////////// 1792 | 1793 | procedure CreateDropAllBtn begin 1794 | if ((obj_type(lootObject) == OBJ_TYPE_CRITTER // объект является криттером 1795 | and has_trait(TRAIT_OBJECT, lootObject, OBJECT_TEAM_NUM) != 0 // и криттер не относится к команде игрока 1796 | and (critter_state(lootObject) != CRITTER_IS_DEAD) // и он не мертв, то выход 1797 | /*orElse (get_proto_data(obj_pid(lootObject), PROTO_CR_FLAGS) bwand CFLG_NOSTEAL)*/)) then // или криттер мертв и уст. флаг, то выход 1798 | begin 1799 | return; 1800 | end 1801 | 1802 | create_win("drop_win", interfaceX + 70, interfaceY + 201, 40, 40); 1803 | selectWin("drop_win"); 1804 | AddButton("btn_drop", 0, 0, 40, 40); 1805 | 1806 | if (btnGiveAll and (obj_type(lootObject) == OBJ_TYPE_CRITTER and critter_state(lootObject) != CRITTER_IS_DEAD)) then 1807 | AddButtonGFX("btn_drop", "PCX\\InvFilterArt\\GiveAll_Dn.pcx", "PCX\\InvFilterArt\\GiveAll_Up.pcx", ""); 1808 | else 1809 | AddButtonGFX("btn_drop", "PCX\\InvFilterArt\\DropAll_Dn.pcx", "PCX\\InvFilterArt\\DropAll_Up.pcx", ""); 1810 | showWin; 1811 | 1812 | AddButtonProc("btn_drop", key_drop_null, key_drop_null, key_drop_press, key_drop_release); 1813 | dropButtonWin := true; 1814 | end 1815 | 1816 | procedure check_dude_equp_items(variable isWeight) begin 1817 | variable item, i, size = 0; // TODO: баг при декомпиляции отсутствует объявление переменной size 1818 | 1819 | for (i := INVEN_TYPE_WORN; i <= INVEN_TYPE_LEFT_HAND; i++) begin 1820 | item := critter_inven_obj2(dude_obj, i); 1821 | if (item == 0) then continue; 1822 | if (isWeight) then 1823 | size += item_weight(item); 1824 | else 1825 | size += proto_data(obj_pid(item), it_size); 1826 | end 1827 | return size; 1828 | end 1829 | 1830 | critical procedure key_drop_press begin 1831 | variable cSize, dSize, maxSize, isWeight; 1832 | DTRACE("key_drop_press") 1833 | 1834 | if (dropPress == 0) then begin 1835 | play_sfx("IB1P1XX1"); 1836 | dropPress := 1; 1837 | end 1838 | 1839 | if (dropPress == 2 orElse get_object_data(dude_obj, 0x2C) <= 0) then return; // check dude inventory empty 1840 | dropPress := 2; 1841 | 1842 | variable object = loot_obj; 1843 | isWeight := (obj_item_subtype(object) != item_type_container); 1844 | if isWeight then begin 1845 | dSize := who_carry_amount(dude_obj); 1846 | cSize := who_carry_amount(object); 1847 | maxSize := max_weight(object); 1848 | end 1849 | else begin 1850 | dSize := get_current_inven_size(dude_obj); 1851 | cSize := get_current_inven_size(object); 1852 | maxSize := get_proto_data(obj_pid(object), PROTO_CN_MAX_SIZE); 1853 | end 1854 | 1855 | dSize -= check_dude_equp_items(isWeight); // check equp item 1856 | if (dSize > (maxSize - cSize)) then begin 1857 | create_message_window(mstr_inventry(26)); 1858 | return; 1859 | end 1860 | 1861 | call MoveObjectInventory(dude_obj, object, false); 1862 | sfall_func0("inventory_redraw"); 1863 | end 1864 | 1865 | procedure key_drop_null begin 1866 | dropPress := 0; 1867 | end 1868 | 1869 | procedure key_drop_release begin 1870 | dropPress := 0; 1871 | play_sfx("IB1LU1X1"); 1872 | end 1873 | 1874 | procedure ShowSize begin 1875 | create_win("tipw", get_mouse_x + 15, get_mouse_y + 15 , 75, 20); 1876 | selectWin("tipw"); 1877 | FillWin(0, 0, 0); 1878 | ShowWin; 1879 | debug_msg("ShowSize"); 1880 | end 1881 | 1882 | procedure HideSize begin 1883 | DeleteWin("tipw"); 1884 | debug_msg("HideSize"); 1885 | end 1886 | -------------------------------------------------------------------------------- /source/iface.h: -------------------------------------------------------------------------------- 1 | 2 | /* Defines */ 3 | #define xPos (10) 4 | #define yPos (14) 5 | // button size 6 | #define btnWidth (32) 7 | #define bHeight (20) 8 | #define btnHeight (bHeight + 3) 9 | 10 | #define menu_width (50) 11 | #define menu_heigh (190) 12 | 13 | #define mainPCXFile "PCX\\InvFilterArt\\main.pcx" 14 | #define buttonPCXFile "PCX\\InvFilterArt\\btn_" 15 | 16 | #define weight_cur_max weight + "/" + maxWeight 17 | #define weight_percent mstr_inventry(30) + " " + weight + "%" 18 | 19 | #define win_flags (WIN_FLAG_TRANSPARENT + WIN_FLAG_MOVEONTOP) 20 | 21 | #define swap_loot_win_x (0) 22 | #define swap_loot_win_y (-36) 23 | #define swap_brtr_win_x (245) 24 | #define swap_brtr_win_y (480) 25 | 26 | #define swap_next_button ((posXmouse > swap_win_x + 121 and posXmouse < swap_win_x + 145) and (posYmouse > swap_win_y + 8 and posYmouse < swap_win_y + 29)) 27 | #define swap_back_button ((posXmouse > swap_win_x + 2 and posXmouse < swap_win_x + 26) and (posYmouse > swap_win_y + 8 and posYmouse < swap_win_y + 29)) 28 | 29 | #define inven_filter_button_all ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + yPos and posYmouse < menu_y + (yPos + 21))) 30 | #define inven_filter_button_armor ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + btnHeight)) and posYmouse < menu_y + (yPos + 21 + btnHeight)) 31 | #define inven_filter_button_weapon ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 2)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 2)))) 32 | #define inven_filter_button_ammo ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 3)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 3)))) 33 | #define inven_filter_button_drug ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 4)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 4)))) 34 | #define inven_filter_button_tool ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 5)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 5)))) 35 | #define inven_filter_button_misc ((posXmouse > menu_x + xPos and posXmouse < menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 6)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 6)))) 36 | 37 | #define inven_filter_trd_button_all ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + yPos and posYmouse < menu_y + (yPos + 21))) 38 | #define inven_filter_trd_button_armor ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + btnHeight) and posYmouse < menu_y + (yPos + 21 + btnHeight))) 39 | #define inven_filter_trd_button_weapon ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 2)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 2)))) 40 | #define inven_filter_trd_button_ammo ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 3)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 3)))) 41 | #define inven_filter_trd_button_drug ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 4)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 4)))) 42 | #define inven_filter_trd_button_tool ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 5)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 5)))) 43 | #define inven_filter_trd_button_misc ((posXmouse > r_menu_x + xPos and posXmouse < r_menu_x + (xPos + btnWidth)) and (posYmouse > menu_y + (yPos + (btnHeight * 6)) and posYmouse < menu_y + (yPos + 21 + (btnHeight * 6)))) 44 | --------------------------------------------------------------------------------