mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e574882f3 | ||
|
|
5995592664 | ||
|
|
982c5fcb42 |
@@ -1,42 +0,0 @@
|
||||
name: Auto Format with Clang
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor != 'github-actions[bot]' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref || github.ref_name }}
|
||||
token: ${{ secrets.PAT_FOR_ACTIONS }}
|
||||
|
||||
- name: Run clang-format via Docker
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v ${{ github.workspace }}:/app --workdir /app \
|
||||
--user $(id -u):$(id -g) silkeh/clang:18 \
|
||||
bash -c 'find src -type f \( -name "*.cc" -o -name "*.h" \) -print0 | xargs -0 clang-format -i'
|
||||
|
||||
|
||||
# https://github.com/actions/checkout?tab=readme-ov-file#push-a-commit-to-a-pr-using-the-built-in-token
|
||||
- name: Check and commit changes if needed
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
if ! git diff --quiet; then
|
||||
git diff
|
||||
git commit -am "chore: auto-format with clang-format"
|
||||
git push
|
||||
else
|
||||
echo "No formatting changes"
|
||||
fi
|
||||
|
||||
|
||||
@@ -96,36 +96,17 @@ The main configuration file is `fallout2.cfg`. There are several important setti
|
||||
|
||||
The `sound` folder (with `music` folder inside) might be located either in `data` folder, or be in the Fallout folder. Update `music_path1` setting to match your hierarchy, usually it's `data/sound/music/` or `sound/music/`. Make sure it matches your path exactly (so it might be `SOUND/MUSIC/` if you've installed Fallout from CD). Music files themselves (with `ACM` extension) should be all uppercased, regardless of `sound` and `music` folders.
|
||||
|
||||
The second configuration file is `f2_res.ini`. Use it to change game window size, enable/disable fullscreen mode and configure IFACE settings (the control bar at the bottom of the game screen).
|
||||
The second configuration file is `f2_res.ini`. Use it to change game window size and enable/disable fullscreen mode.
|
||||
|
||||
```ini
|
||||
[MAIN]
|
||||
SCR_WIDTH=1280
|
||||
SCR_HEIGHT=720
|
||||
WINDOWED=1 ; 0 = fullscreen
|
||||
SCALE_2X=1 ; 0 = original scale, 1 = 2x - requires increasing the minimum resolution from 640x480 to 1280x960.
|
||||
SCALE_2X=1 ; 0 = original scale, 1 = 2x
|
||||
|
||||
[IFACE]
|
||||
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
|
||||
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
|
||||
IFACE_BAR_MODE=0
|
||||
|
||||
;if IFACE_BAR_SIDE_ART=0 - Black, No Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=1 - Metal (grey) look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=2 - Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=3-6 - Alternative Metal look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=7 - Alternative Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=8 - Metal (brown) look Iface-bar side art used.
|
||||
IFACE_BAR_SIDE_ART=2
|
||||
|
||||
;if IFACE_BAR_SIDES_ORI=0 - Iface-bar side graphics extend from the Iface-Bar to the Screen edges.
|
||||
;if IFACE_BAR_SIDES_ORI=1 - Iface-bar side graphics extend from the Screen edges to the Iface-Bar.
|
||||
IFACE_BAR_SIDES_ORI=0
|
||||
|
||||
;This will increase the width of the interface bar expanding the area used to display text.
|
||||
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat.
|
||||
IFACE_BAR_WIDTH=640
|
||||
IFACE_BAR_MODE, IFACE_BAR_SIDE_ART, IFACE_BAR_SIDES_ORI, IFACE_BAR_WIDTH supported (require assets in appropriate places)
|
||||
```
|
||||
|
||||
Recommendations:
|
||||
@@ -133,30 +114,18 @@ Recommendations:
|
||||
- **Tablets**: Set these values to logical resolution of your device, for example iPad Pro 11 is 1668x2388 (pixels), but it's logical resolution is 834x1194 (points).
|
||||
- **Mobile phones**: Set height to 480, calculate width according to your device screen (aspect) ratio, for example Samsung S21 is 20:9 device, so the width should be 480 * 20 / 9 = 1067.
|
||||
|
||||
In time this stuff will receive in-game interface, right now you have to do it manually. For a sample f2_res.ini configuration file, containing all currently working settings use this link: [f2_res.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/mainmenu/files/f2_res.ini)
|
||||
In time this stuff will receive in-game interface, right now you have to do it manually.
|
||||
|
||||
*Note*: use of the IFACE_BAR settings requires the f2_res.dat file, which contains graphical assets. Various versions are available, but one compatible with the above f2_res.ini be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/mainmenu/files/f2_res.dat)
|
||||
|
||||
The third configuration file is `ddraw.ini` (part of Sfall). There are dozens of options that adjust or override engine behaviour and gameplay mechanics. This file is intended for modders and advanced users.
|
||||
|
||||
For a sample ddraw.ini configuration file, containing all currently working settings use this link: [ddraw.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/main/files/ddraw.ini)
|
||||
|
||||
## Quality of life benefits over vanilla Fallout
|
||||
|
||||
* High resolution support
|
||||
* Increased pathfinding nodes 5x for more accurate pathfinding
|
||||
* Ctrl-click to quickly move items when bartering, looting, or stealing
|
||||
* _a_ to select "all" when selecting item quantity
|
||||
* _a_ to `Take All` when looting
|
||||
* When bartering, caps default to the right amount to balance the trade (if possible)
|
||||
* Music continues playing between maps (requires config)
|
||||
* Auto open doors (requires config)
|
||||
The third configuration file is `ddraw.ini` (part of Sfall). There are dozens of options that adjust or override engine behaviour and gameplay mechanics. This file is intended for modders and advanced users. Currently only a small subset of these settings are actually implemented. For high res configs, the following is recommended:
|
||||
```[Main]
|
||||
HiResMode=1
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. Please no large scale refactorings at this time as we need to reconcile changes from Reference Edition, which will make this process slow and error-prone. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
|
||||
|
||||
### Integrating Sfall
|
||||
### Intergrating Sfall
|
||||
|
||||
There are literally hundreds if not thousands of fixes and features in sfall. I guess not all of them are needed in Community Edition, but for the sake of compatibility with big mods out there, let's integrate them all.
|
||||
|
||||
|
||||
-207
@@ -1,207 +0,0 @@
|
||||
;sfall configuration settings for Fallout 2 CE
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Main]
|
||||
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
;HiResMode=1
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Misc]
|
||||
|
||||
;Uncomment these lines to change the timers of how many days after the game starts Hakunin dream sequences will occur
|
||||
;MovieTimer_artimer1=5000
|
||||
;MovieTimer_artimer2=5000
|
||||
;MovieTimer_artimer3=5000
|
||||
;MovieTimer_artimer4=5000
|
||||
|
||||
;To start a new game somewhere other than artemple.map, uncomment the next line and set it to the map you want to load
|
||||
;StartingMap=V13ent.map
|
||||
|
||||
;To change the 'FALLOUT II v1.02d' version string on the main menu, uncomment the next line
|
||||
;You can use up to 2 %d's in this if you want to include Fallout's version number somewhere
|
||||
;VersionString=FALLOUT II v1.02d
|
||||
|
||||
;To use a config file other than fallout2.cfg, uncomment the next line and add the name of your new file
|
||||
;ConfigFile=
|
||||
|
||||
;To use a patch file other than patch000.dat, uncomment the next line and add your new file name
|
||||
;If you want to load multiple patch files (up to 1000) at once, you can include a %d in the file name (sprintf syntax)
|
||||
;PatchFile=patch%03d.dat
|
||||
|
||||
;Set to 1 to allow using the caret character '^' in dialog msg files to specify alternative text in dialogue based on the player's gender
|
||||
;The text must be enclosed in angle brackets (example: <MaleText^FemaleText>)
|
||||
;DialogGenderWords=0
|
||||
|
||||
;To change the default and starting player models, uncomment the next four lines.
|
||||
;The default models can also be changed in-game via script
|
||||
;MaleStartModel=hmjmps
|
||||
;MaleDefaultModel=hmjmps
|
||||
;FemaleStartModel=hfjmps
|
||||
;FemaleDefaultModel=hfjmps
|
||||
|
||||
;To change the starting year, month or day, uncomment the next 3 lines
|
||||
;Both StartMonth and StartDay are 0-indexed (i.e. 0 is January or the first day of a month)
|
||||
;StartYear=2241
|
||||
;StartMonth=01
|
||||
;StartDay=01
|
||||
|
||||
;Set to 1 if you want the pipboy to be available at the start of the game
|
||||
;Set to 2 to make the pipboy available by only skipping the vault suit movie check
|
||||
;PipBoyAvailableAtGameStart=1
|
||||
|
||||
;Choose the damage formula used to calculate combat damage.
|
||||
;Don't set this to anything other than 0 unless another mod you're using explicitly tells you to!
|
||||
;0 - Fallout default
|
||||
;1 - Glovz's Damage Fix
|
||||
;2 - Glovz's Damage Fix with Damage Multiplier tweak
|
||||
;5 - Haenlomal's Yet Another Ammo Mod
|
||||
;DamageFormula=0
|
||||
|
||||
;Prevents you from using 0 to escape from dialogue at any time.
|
||||
;DialogueFix=1
|
||||
|
||||
;Prevents you from using number keys to enter unvisited areas on a town map
|
||||
TownMapHotkeysFix=1
|
||||
|
||||
;Set to 1 to use a CriticalOverrides.ini file to override the default critical table
|
||||
;Set to 2 to use the default critical with bug fixes (doesn't require an ini)
|
||||
;Set to 3 to use a new format CriticalOverrides.ini file, with preadded bug fixes
|
||||
;If the ExtraKillTypes option is enabled, this should be set to 3, with containing entries for any new types
|
||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||
;OverrideCriticalTable=2
|
||||
|
||||
;Set to 1 to get notification of karma changes in the notification window
|
||||
DisplayKarmaChanges=0
|
||||
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
;Set to 2 to also skip the splash screen
|
||||
SkipOpeningMovies=0
|
||||
|
||||
;Change the Skilldex cursor FRM numbers
|
||||
;Default is 293 for all skills
|
||||
Lockpick=293
|
||||
Steal=293
|
||||
Traps=293
|
||||
FirstAid=293
|
||||
Doctor=293
|
||||
Science=293
|
||||
Repair=293
|
||||
|
||||
;Uncomment these lines to control the premade characters offered when starting a new game
|
||||
;Multiple options should be separated by commas, and there must be the same number of entries in both lines
|
||||
;Each name in PremadePaths is limited to 11 characters
|
||||
;PremadePaths=combat,diplomat,stealth
|
||||
;PremadeFIDs=201,203,202
|
||||
|
||||
;Use this line to modify the list of cities and their associated global variables used for city reputations
|
||||
;Syntax is 'city id:global id', with each city/global pair separated by a comma.
|
||||
;CityRepsList=0:5001,2:5003,3:5004,4:5005,5:5006,6:5007,7:5008,8:5009,10:5011,11:5012,60:1640
|
||||
|
||||
;Set this to a valid path to save a copy of the console contents
|
||||
;ConsoleOutputPath=console.txt
|
||||
|
||||
;Set to 1 to add additional pages of save slots !!! can be implemented !!!
|
||||
;ExtraSaveSlots=1
|
||||
|
||||
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand, set the next two lines
|
||||
;Quick save will cyclically overwrite saves from the first slot on the specified page to the last slot on the n-th page
|
||||
;AutoQuickSave sets how many pages you want to use for quick saving (valid range: 1..10)
|
||||
;Set to 0 to disable
|
||||
AutoQuickSave=0
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
;Number of KarmaPoints should be 1 less than number of KarmaFRMs
|
||||
;KarmaFRMs=47,48,49
|
||||
;KarmaPoints=-100,100
|
||||
|
||||
;Set to 1 to allow science and repair to be used on the player, or 2 for all critters. (Rather than only brahmin/robots)
|
||||
ScienceOnCritters=0
|
||||
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
BonusHtHDamageFix=1
|
||||
|
||||
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
|
||||
;DisplayBonusDamage=1
|
||||
|
||||
;Set to 1 to remove the limits that stop the game from rolling critical successes/failures in the first few days of game time
|
||||
RemoveCriticalTimelimits=0
|
||||
|
||||
;Change the colour of the font used on the main menu for the Fallout/sfall version string and copyright text
|
||||
;It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
|
||||
;1 - change the colour for the version string only
|
||||
;2 - underline text for the version string
|
||||
;4 - use monospace font for the version string
|
||||
;MainMenuFontColour=0x000055
|
||||
;Change the colour of the font used on the main menu for the button text
|
||||
;MainMenuBigFontColour=0x3C
|
||||
|
||||
;Uncomment the next four lines to move the main menu buttons and credit text (the 'Copyright(c)' line on the main menu)
|
||||
;MainMenuOffsetX=392
|
||||
;MainMenuOffsetY=26
|
||||
;MainMenuCreditsOffsetX=0
|
||||
;MainMenuCreditsOffsetY=0
|
||||
|
||||
;These options modify the bullet distribution of burst attacks
|
||||
;All the bullets are divided into three groups: center, left, and right
|
||||
;These groups will then travel along three parallel tracks, trying to hit targets on the way
|
||||
;CenterMult/Div set the ratio of how many bullets go to the center group, and the remaining are divided equally to the left and right sides
|
||||
;TargetMult/Div set the ratio of how many bullets in the center group will attack the primary target directly
|
||||
;Multiplier values are capped at divisor values
|
||||
;ComputeSpray_CenterMult=1
|
||||
;ComputeSpray_CenterDiv=3
|
||||
;ComputeSpray_TargetMult=1
|
||||
;ComputeSpray_TargetDiv=2
|
||||
|
||||
;Set to 1 to make explosions and projectiles emit light
|
||||
;ExplosionsEmitLight=1
|
||||
|
||||
;Uncomment these lines to change explosives damage. DmgMax can be set to 9999 at max, and DmgMin is capped at DmgMax
|
||||
;Dynamite_DmgMax=50
|
||||
;Dynamite_DmgMin=30
|
||||
;PlasticExplosive_DmgMax=80
|
||||
;PlasticExplosive_DmgMin=40
|
||||
|
||||
;To add additional game msg files, uncomment the next line and set a comma delimited list of filenames without .msg extension
|
||||
;By default, the files will have consecutive numbers assigned beginning with 0
|
||||
;You can use the syntax 'filename:number' to manually assign numbers to specific msg files, with each pair separated by a comma
|
||||
;If a file after the specified pair does not have a number assigned, it will have the next consecutive number from the last pair
|
||||
;You need to use the message_str_game script function to get messages from the files
|
||||
;ExtraGameMsgFileList=
|
||||
|
||||
;Set to 1 to display numbered dialogue options
|
||||
NumbersInDialogue=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
; Configuration ini files
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
;To change the path and filename of the critical table file, uncomment the next line
|
||||
;OverrideCriticalFile=config\CriticalOverrides.ini
|
||||
|
||||
;To add additional books to the game, uncomment the next line and point to a file containing book information
|
||||
;See the Books.ini in the modders pack for an example file
|
||||
;BooksFile=sfall\Books.ini
|
||||
|
||||
;Point to an ini file containing elevator data
|
||||
;ElevatorsFile=config\Elevators.ini
|
||||
|
||||
;Allows you to change the requirements and effects of unarmed attacks
|
||||
;See the Unarmed.ini in the modders pack for an example file
|
||||
;UnarmedFile=sfall\Unarmed.ini
|
||||
|
||||
;To change some engine parameters for the game mechanics, uncomment the next line
|
||||
;TweaksFile=sfall\Tweaks.ini
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Scripts]
|
||||
|
||||
;Comma-separated list of masked paths to load global scripts from
|
||||
;Only use single backslash \ as the directory separator
|
||||
;Paths outside of scripts folder are supported
|
||||
;GlobalScriptPaths=scripts\gl_*.int,scripts\sfall\gl*.int
|
||||
|
||||
;Uncomment the option to specify an additional directory for ini files used by scripts
|
||||
;The game will search for ini files first relative to this directory and then relative to the root directory if not found
|
||||
;The path length is limited to 61 characters
|
||||
;IniConfigFolder=mods\iniConfigs
|
||||
Binary file not shown.
@@ -1,50 +0,0 @@
|
||||
;hi-res configuration settings for Fallout 2 CE
|
||||
|
||||
;##################################################################################################################
|
||||
[MAIN]
|
||||
|
||||
; Set SCALE_2X=1 to scale the game x2.
|
||||
; Note: This will increase the minimum resolution to from 640x480 to 1280x960.
|
||||
SCALE_2X=1
|
||||
|
||||
; Set the Fullscreen resolution here.
|
||||
SCR_WIDTH=640
|
||||
SCR_HEIGHT=480
|
||||
|
||||
; Set WINDOWED=1 to enable windowed mode.
|
||||
WINDOWED=1
|
||||
|
||||
;##################################################################################################################
|
||||
[IFACE]
|
||||
|
||||
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
|
||||
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
|
||||
IFACE_BAR_MODE=0
|
||||
|
||||
;if IFACE_BAR_SIDE_ART=0 - Black, No Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=1 - Metal (grey) look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=2 - Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=3-6 - Alternative Metal look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=7 - Alternative Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=8 - Metal (brown) look Iface-bar side art used.
|
||||
IFACE_BAR_SIDE_ART=2
|
||||
|
||||
|
||||
;if IFACE_BAR_SIDES_ORI=0 - Iface-bar side graphics extend from the Iface-Bar to the Screen edges.
|
||||
;if IFACE_BAR_SIDES_ORI=1 - Iface-bar side graphics extend from the Screen edges to the Iface-Bar.
|
||||
IFACE_BAR_SIDES_ORI=0
|
||||
|
||||
;This will increase the width of the interface bar expanding the area used to display text.
|
||||
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat. Note
|
||||
|
||||
IFACE_BAR_WIDTH=640
|
||||
|
||||
;##################################################################################################################
|
||||
[STATIC_SCREENS]
|
||||
|
||||
; if set to 0 - background image will display at its original size.
|
||||
; if set to 1 - background image will stretch to fit the screen while maintaining its aspect ratio.
|
||||
; if set to 2 - background image will stretch to fill the screen.
|
||||
SPLASH_SCRN_SIZE=2
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker run --rm \
|
||||
-v $(pwd):/app --workdir /app \
|
||||
--user $(id -u):$(id -g) silkeh/clang:18 \
|
||||
bash -c 'find src -type f -name \*.cc -o -name \*.h | xargs clang-format -i'
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*.int
|
||||
@@ -1,33 +0,0 @@
|
||||
# Testing sFall scripting features
|
||||
|
||||
## Basic info
|
||||
|
||||
This folder contains scripts which can be used for sFall opcodes.
|
||||
|
||||
## Build script using sFall Script Editor
|
||||
|
||||
1. Get "Fallout sFall Script Editor v4.1.7.RC1", for example from https://nuclear-grot.ucoz.net/forum/12-20-1
|
||||
|
||||
2. Run script editor, add "sfall_headers" into "Location folder of headers files" in the options
|
||||
|
||||
3. Open any script here and compile it
|
||||
|
||||
4. This shoud create compiled script <file.int>
|
||||
|
||||
|
||||
## Run test script
|
||||
|
||||
1. Move compiled .int file into game folder as `mods/tests/SCRIPTS/OBJ_DUDE.INT` (case-sensitive!)
|
||||
|
||||
2. Change `mods/mods_order.txt` file: add a line `tests` there
|
||||
|
||||
3. Run game, check that game displays message about tests
|
||||
|
||||
4. Comment tests line in `mods/mods_order.txt` in order to enable game back
|
||||
|
||||
|
||||
|
||||
## TODO
|
||||
|
||||
- Use custom global script instead of `obj_dude`
|
||||
- Add note about compile.exe and https://marketplace.visualstudio.com/items?itemName=BGforge.bgforge-mls
|
||||
@@ -1,201 +0,0 @@
|
||||
#include "lib.arrays.h"
|
||||
|
||||
// #include "define_lite.h"
|
||||
|
||||
|
||||
variable test_suite_errors := 0;
|
||||
variable test_suite_verbose := true;
|
||||
|
||||
#ifndef assertEquals
|
||||
procedure assertEquals(variable desc, variable a, variable b) begin
|
||||
if (a != b or typeof(a) != typeof(b)) then begin
|
||||
display_msg("Assertion failed \""+desc+"\": "+a+" != "+b);
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("Assert \""+desc+"\" ok");
|
||||
end
|
||||
end
|
||||
|
||||
procedure assertNotEquals(variable desc, variable a, variable b) begin
|
||||
if (a == b) then begin
|
||||
display_msg("Assertion failed \""+desc+"\": "+a+" == "+b);
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("Assert \""+desc+"\" ok");
|
||||
end
|
||||
end
|
||||
#endif
|
||||
|
||||
#define ARRAY_MAX_STRING (255)
|
||||
#define ARRAY_MAX_SIZE (100000)
|
||||
|
||||
procedure array_test_suite begin
|
||||
variable arr, i, arr2, map, k, v, s;
|
||||
test_suite_errors := 0;
|
||||
|
||||
display_msg("Testing arrays_equal functions...");
|
||||
call assertEquals("array_equals 1", arrays_equal([9, 7, 2, 1], [9, 7, 2, 1]), true);
|
||||
call assertEquals("array_equals 2", arrays_equal([9, 7, 0, 1], [9, 7, 2, 1]), false);
|
||||
call assertEquals("array_equals 3", arrays_equal([1, 1, 1, 1], [1, 1, 1]), false);
|
||||
call assertEquals("array_equals 4", arrays_equal([], []), true);
|
||||
call assertEquals("array_equals 5", arrays_equal({}, []), false);
|
||||
call assertEquals("array_equals 6", arrays_equal({1: 1.0, 2: 2.0}, {1: 1.000, 2: 2.000}), true);
|
||||
call assertEquals("array_equals 7", arrays_equal({"name": "John", "dept": 15.20}, {"name": "John"}), false);
|
||||
|
||||
|
||||
display_msg("Testing utility functions...");
|
||||
call assertEquals("strlen", strlen("testing"), 7);
|
||||
call assertEquals("substr 1", substr("testing", 4, 2), "in");
|
||||
call assertEquals("substr 2", substr("testing", 1, -1), "estin");
|
||||
call assertEquals("substr 3", substr("testing", -5, 5), "sting");
|
||||
call assertEquals("typeof 1", typeof(1), VALTYPE_INT);
|
||||
call assertEquals("typeof 2", typeof(1.0), VALTYPE_FLOAT);
|
||||
call assertEquals("typeof 3", typeof("1.0"), VALTYPE_STR);
|
||||
|
||||
// Basic array functionality
|
||||
display_msg("Testing basic arrays functionality...");
|
||||
arr := create_array(5,0);
|
||||
call assertEquals("array size", len_array(arr), 5);
|
||||
arr[0]:=100;
|
||||
call assertEquals("get array", get_array(arr, 0), 100);
|
||||
arr[1]:=5.555;
|
||||
call assertEquals("get array float", get_array(arr, 1), 5.555);
|
||||
arr[2]:="hello";
|
||||
call assertEquals("get array str", get_array(arr, 2), "hello");
|
||||
call assertEquals("get array invalid index", get_array(arr, -1), 0);
|
||||
call assertEquals("get array invalid index", get_array(arr, 6), 0);
|
||||
resize_array(arr, 77);
|
||||
call assertEquals("list resize", len_array(arr), 77);
|
||||
resize_array(arr, ARRAY_MAX_SIZE + 100);
|
||||
call assertEquals("resize max", len_array(arr), ARRAY_MAX_SIZE);
|
||||
free_array(arr);
|
||||
call assertEquals("not exists check", len_array(arr), -1);
|
||||
arr := create_array(ARRAY_MAX_SIZE + 100, 0);
|
||||
call assertEquals("create max", len_array(arr), ARRAY_MAX_SIZE);
|
||||
|
||||
free_array(arr);
|
||||
arr := [6, 1, 10, "one", 10, "two", 5, "three"];
|
||||
arr[0] := "wtf";
|
||||
//display_msg(debug_array_str(arr));
|
||||
call assertEquals("scan list", scan_array(arr, 10), 2);
|
||||
call assertEquals("scan list 2", scan_array(arr, "two"), 5);
|
||||
call assertEquals("array_key", array_key(arr, 5), 5);
|
||||
call assertEquals("array_key out of range", array_key(arr, 9), 0);
|
||||
call assertEquals("is list", array_key(arr, -1), 0);
|
||||
|
||||
call assertEquals("get array as substr", get_array("NiCe", 1), "i");
|
||||
|
||||
arr := [78, 12, 99, 1, -5];
|
||||
sort_array(arr);
|
||||
call assertEquals("sort ASC", arrays_equal(arr, [-5, 1, 12, 78, 99]), true);
|
||||
|
||||
arr := ["Albert", "John", "Mike", "David"];
|
||||
sort_array_reverse(arr);
|
||||
call assertEquals("sort DESC", arrays_equal(arr, ["Mike", "John", "David", "Albert"]), true);
|
||||
reverse_array(arr);
|
||||
call assertEquals("reverse list", arrays_equal(arr, ["Albert", "David", "John", "Mike"]), true);
|
||||
shuffle_array(arr);
|
||||
call assertEquals("shuffle list 1", arrays_equal(arr, ["Albert", "David", "John", "Mike"]), false);
|
||||
call assertEquals("shuffle list 2", len_array(arr), 4);
|
||||
if (test_suite_verbose) then display_array(arr);
|
||||
|
||||
// some additional stuff
|
||||
call assertEquals("string_split", get_array(string_split("this+is+good", "+"), 2), "good");
|
||||
call assertEquals("string_split 2", len_array(string_split("advice", "")), 6);
|
||||
s := "";
|
||||
for (i := 0; i < ARRAY_MAX_STRING+30; i+=10) begin
|
||||
s += "Verbosity.";
|
||||
end
|
||||
arr[0] := s;
|
||||
call assertEquals("array max string", strlen(arr[0]), ARRAY_MAX_STRING-1);
|
||||
|
||||
// ASSOC ARRAYS TEST
|
||||
display_msg("Testing associative arrays...");
|
||||
arr := create_array(-1,0);
|
||||
call assertEquals("is map", array_key(arr, -1), 1);
|
||||
call assertEquals("exists check", len_array(arr), 0);
|
||||
arr["123"] := 100;
|
||||
call assertEquals("set/get str=>int", arr["123"], 100);
|
||||
arr["123"] := 50;
|
||||
call assertEquals("overwrite 1", arr["123"], 50);
|
||||
call assertEquals("overwrite 2", len_array(arr), 1);
|
||||
arr[-1] := "wtf";
|
||||
call assertEquals("set/get int=>str", arr[-1], "wtf");
|
||||
arr[3.14] := 0.00001;
|
||||
call assertEquals("set/get float=>float", arr[3.14], 0.00001);
|
||||
arr["fourth"] := "elem";
|
||||
call assertEquals("map size", len_array(arr), 4);
|
||||
arr[-1] := 0;
|
||||
call assertEquals("unset key: length", len_array(arr), 3);
|
||||
call assertEquals("unset key: hashmap", arr[3.14], 0.00001);
|
||||
call assertEquals("key not exist", arr[777], 0);
|
||||
free_array(arr);
|
||||
call assertEquals("not exists check", len_array(arr), -1);
|
||||
arr := {6:5, 1.001:0.5, 10:"A", 5:0, "wtf":1.1, 10:0.0001, "some":"What"}; // 7 here
|
||||
// 10:"A" will be overwritten by 10:0.0001
|
||||
call assertEquals("assoc array expr", len_array(arr), 6); // 6 actual
|
||||
|
||||
call assertEquals("scan map 1", scan_array(arr, 1.1), "wtf");
|
||||
call assertEquals("scan map 2", scan_array(arr, 5), 6);
|
||||
call assertEquals("scan map 3", scan_array(arr, "What"), "some");
|
||||
call assertEquals("array_key 1", array_key(arr, 0), 6);
|
||||
call assertEquals("array_key 2", array_key(arr, 4), "wtf");
|
||||
call assertEquals("array_key 3", array_key(arr, 1), 1.001);
|
||||
|
||||
resize_array(arr, 2);
|
||||
call assertEquals("map resize 1", len_array(arr), 2);
|
||||
call assertEquals("map resize 2", arrays_equal(arr, {6:5, 1.001:0.5}), true);
|
||||
resize_array(arr, 0);
|
||||
call assertEquals("map clear", len_array(arr), 0);
|
||||
|
||||
display_msg("Testing foreach...");
|
||||
s := "ar";
|
||||
arr := [6, 10, 0.5, "wtf"];
|
||||
foreach v in arr begin
|
||||
s += v;
|
||||
end
|
||||
call assertEquals("foreach 1", s, "ar6100.50000wtf");
|
||||
s := "ar2=";
|
||||
arr := {"name": "John", "hp": 25, 0: 5.5};
|
||||
foreach k: v in arr begin
|
||||
s += k+":"+v+";";
|
||||
end
|
||||
call assertEquals("foreach 2", s, "ar2=name:John;hp:25;0:5.50000;");
|
||||
|
||||
|
||||
/*
|
||||
display_msg("Testing save/load...");
|
||||
arr := [2,1];
|
||||
arr2 := {1:2};
|
||||
save_array("myarray", arr);
|
||||
call assertEquals("load 1", load_array("myarray"), arr);
|
||||
save_array("myarray", arr2);
|
||||
call assertEquals("load 2", load_array("myarray"), arr2);
|
||||
free_array(arr2);
|
||||
call assertEquals("not exists check", len_array(arr2), -1);
|
||||
call assertEquals("load fail", load_array("myarray"), 0);
|
||||
save_array(0.1, arr);
|
||||
call assertEquals("save as float", load_array(0.1), arr);
|
||||
arr2 := list_saved_arrays; // list of array names
|
||||
//display_msg(debug_array_str(arr2));
|
||||
call assertNotEquals("saved arrays 1", scan_array(arr2, 0.1), -1);
|
||||
call assertEquals("saved arrays 2", scan_array(arr2, "myarray"), -1);
|
||||
save_array(0, arr);
|
||||
call assertEquals("unsave array 1", load_array(0.1), 0);
|
||||
call assertEquals("unsave array 2", len_array(arr), 2);
|
||||
call assertEquals("saved arrays 3", len_array(list_saved_arrays), len_array(arr2) - 1);
|
||||
*/
|
||||
|
||||
display_msg("All tests finished with "+test_suite_errors+" errors.");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
procedure map_enter_p_proc begin
|
||||
display_msg("Starting tests");
|
||||
call array_test_suite();
|
||||
end
|
||||
+1
-70
@@ -789,62 +789,6 @@ struct CustomKarmaFolderDescription {
|
||||
static std::vector<CustomKarmaFolderDescription> gCustomKarmaFolderDescriptions;
|
||||
static std::vector<TownReputationEntry> gCustomTownReputationEntries;
|
||||
|
||||
/* Explaining characterEditorSelectedItem
|
||||
|
||||
0-6: Primary Stats (SPECIAL)
|
||||
|
||||
- 0-6 = The seven primary stats (Strength, Perception, Endurance, Charisma, Intelligence, Agility, Luck)
|
||||
- Used for highlighting which SPECIAL stat is selected
|
||||
|
||||
7-9: Level/Experience Area
|
||||
|
||||
- 7 = Level display
|
||||
- 8 = Experience points display
|
||||
- 9 = Experience needed for next level
|
||||
|
||||
10-42: Folder Content Area (Perks/Karma/Kills)
|
||||
|
||||
- 10-42 = Items within the currently selected folder tab (perks, karma, or kills)
|
||||
- 10 = First visible item in the folder
|
||||
- The actual content depends on which folder is active (characterEditorWindowSelectedFolder)
|
||||
- This is the range where mouse wheel scrolling is active
|
||||
- When scrolling, items shift but the selection stays within this range
|
||||
|
||||
43-50: Status Conditions
|
||||
|
||||
- 43 = Hit Points (EDITOR_HIT_POINTS)
|
||||
- 44 = Poisoned status (EDITOR_POISONED)
|
||||
- 45 = Radiated status (EDITOR_RADIATED)
|
||||
- 46 = Eye damage (EDITOR_EYE_DAMAGE)
|
||||
- 47 = Crippled right arm (EDITOR_CRIPPLED_RIGHT_ARM)
|
||||
- 48 = Crippled left arm (EDITOR_CRIPPLED_LEFT_ARM)
|
||||
- 49 = Crippled right leg (EDITOR_CRIPPLED_RIGHT_LEG)
|
||||
- 50 = Crippled left leg (EDITOR_CRIPPLED_LEFT_LEG)
|
||||
|
||||
51-60: Derived Stats
|
||||
|
||||
- 51-60 = The 10 derived stats (EDITOR_FIRST_DERIVED_STAT + EDITOR_DERIVED_STAT_*)
|
||||
- Armor Class, Action Points, Carry Weight, Melee Damage, etc.
|
||||
|
||||
61-78: Skills
|
||||
|
||||
- 61-78 = The 18 skills (EDITOR_FIRST_SKILL to EDITOR_FIRST_SKILL + SKILL_COUNT)
|
||||
- Small Guns, Big Guns, Energy Weapons, Unarmed, etc.
|
||||
- characterEditorSelectedItem - 61 gives the actual skill index
|
||||
|
||||
79-81: Skill Controls
|
||||
|
||||
- 79 = Tag Skill button (EDITOR_TAG_SKILL)
|
||||
- 80 = Skills header/button (EDITOR_SKILLS)
|
||||
- 81 = Optional Traits button (EDITOR_OPTIONAL_TRAITS)
|
||||
|
||||
82-97: Optional Traits
|
||||
|
||||
- 82-97 = The 16 trait slots (EDITOR_FIRST_TRAIT to EDITOR_FIRST_TRAIT + TRAIT_COUNT)
|
||||
- Fast Metabolism, Bruiser, Small Frame, etc.
|
||||
- Can be arranged in 2 columns (left: 82-89, right: 90-97)
|
||||
*/
|
||||
|
||||
// 0x431DF8
|
||||
int characterEditorShow(bool isCreationMode)
|
||||
{
|
||||
@@ -882,20 +826,7 @@ int characterEditorShow(bool isCreationMode)
|
||||
_frame_time = getTicks();
|
||||
int keyCode = inputGetInput();
|
||||
|
||||
// check for mouse wheel over the "folder" area (perks/karma/kills)
|
||||
if (keyCode == -1 && (mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0 && !gCharacterEditorIsCreationMode && mouseHitTestInWindow(gCharacterEditorWindow, 34, 364, 314, 364 + 9 * (fontGetLineHeight() + 1))) {
|
||||
int wheelX, wheelY;
|
||||
mouseGetWheel(&wheelX, &wheelY);
|
||||
if (wheelY > 0) { // Scroll up
|
||||
characterEditorFolderViewScroll(-1);
|
||||
} else if (wheelY < 0) { // Scroll down
|
||||
characterEditorFolderViewScroll(1);
|
||||
}
|
||||
characterEditorDrawCard();
|
||||
windowRefresh(gCharacterEditorWindow);
|
||||
} else {
|
||||
convertMouseWheelToArrowKey(&keyCode);
|
||||
}
|
||||
convertMouseWheelToArrowKey(&keyCode);
|
||||
|
||||
bool done = false;
|
||||
if (keyCode == 500) {
|
||||
|
||||
+2
-2
@@ -123,7 +123,7 @@ MessageList gMiscMessageList;
|
||||
static void** gGameGlobalPointers = nullptr;
|
||||
|
||||
// 0x442580
|
||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int flags, int argc, char** argv)
|
||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4, int argc, char** argv)
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
|
||||
@@ -150,7 +150,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int fl
|
||||
messageListRepositoryInit();
|
||||
|
||||
programWindowSetTitle(windowTitle);
|
||||
_initWindow(1, flags);
|
||||
_initWindow(1, a4);
|
||||
paletteInit();
|
||||
|
||||
const char* language = settings.system.language.c_str();
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ extern int _game_user_wants_to_quit;
|
||||
|
||||
extern MessageList gMiscMessageList;
|
||||
|
||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int flags, int argc, char** argv);
|
||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int a3, int a4, int argc, char** argv);
|
||||
void gameReset();
|
||||
void gameExit();
|
||||
int gameHandleKey(int eventCode, bool isInCombatMode);
|
||||
|
||||
+10
-47
@@ -548,8 +548,6 @@ static FrmImage _redButtonNormalFrmImage;
|
||||
static FrmImage _redButtonPressedFrmImage;
|
||||
static FrmImage _lowerHighlightFrmImage;
|
||||
static FrmImage _upperHighlightFrmImage;
|
||||
static FrmImage _littleRedButtonNormalFrmImage;
|
||||
static FrmImage _littleRedButtonPressedFrmImage;
|
||||
|
||||
static int _gdialogReset();
|
||||
static void gameDialogEndLips();
|
||||
@@ -625,9 +623,7 @@ static void gameDialogHighlightsInit();
|
||||
static void gameDialogHighlightsExit();
|
||||
|
||||
static void gameDialogRedButtonsInit();
|
||||
static void gameDialogLittleRedButtonsInit();
|
||||
static void gameDialogRedButtonsExit();
|
||||
static void gameDialogLittleRedButtonsExit();
|
||||
|
||||
static bool gGameDialogFix;
|
||||
static bool gNumberOptions;
|
||||
@@ -918,7 +914,6 @@ int _gdialogInitFromScript(int headFid, int reaction)
|
||||
|
||||
// CE: Fix Barter button.
|
||||
gameDialogRedButtonsInit();
|
||||
gameDialogLittleRedButtonsInit();
|
||||
|
||||
_gdCreateHeadWindow();
|
||||
tickersAdd(gameDialogTicker);
|
||||
@@ -971,7 +966,6 @@ int _gdialogExitFromScript()
|
||||
|
||||
// CE: Fix Barter button.
|
||||
gameDialogRedButtonsExit();
|
||||
gameDialogLittleRedButtonsExit();
|
||||
|
||||
fontSetCurrent(_oldFont);
|
||||
|
||||
@@ -3241,12 +3235,12 @@ int _gdialog_barter_create_win()
|
||||
backgroundFrmImage.unlock();
|
||||
|
||||
// TRADE
|
||||
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 40, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 41, 163, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
if (_gdialog_buttons[0] != -1) {
|
||||
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// TALK
|
||||
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 583, 161, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 584, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
if (_gdialog_buttons[1] != -1) {
|
||||
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
@@ -3413,7 +3407,7 @@ int partyMemberControlWindowInit()
|
||||
partyMemberControlWindowFree();
|
||||
return -1;
|
||||
}
|
||||
buttonSetCallbacks(_gdialog_buttons[2], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// USE BEST ARMOR
|
||||
_gdialog_buttons[3] = buttonCreate(gGameDialogWindow, 235, 46, 14, 14, -1, -1, -1, KEY_LOWERCASE_A, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
@@ -3421,7 +3415,7 @@ int partyMemberControlWindowInit()
|
||||
partyMemberControlWindowFree();
|
||||
return -1;
|
||||
}
|
||||
buttonSetCallbacks(_gdialog_buttons[3], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
buttonSetCallbacks(_gdialog_buttons[2], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
_control_buttons_start = 4;
|
||||
|
||||
@@ -3890,7 +3884,7 @@ int partyMemberCustomizationWindowInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
buttonSetCallbacks(_gdialog_buttons[optionButton], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
buttonSetCallbacks(_gdialog_buttons[index], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
}
|
||||
|
||||
_custom_current_selected[PARTY_MEMBER_CUSTOMIZATION_OPTION_AREA_ATTACK_MODE] = aiGetAreaAttackMode(gGameDialogSpeaker);
|
||||
@@ -4125,23 +4119,17 @@ int _gdCustomSelect(int a1)
|
||||
|
||||
backgroundFrmImage.unlock();
|
||||
|
||||
int btn1 = buttonCreate(win, 70, 164, _littleRedButtonNormalFrmImage.getWidth(), _littleRedButtonNormalFrmImage.getHeight(), -1, -1, -1, 500, _littleRedButtonNormalFrmImage.getData(), _littleRedButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
int btn1 = buttonCreate(win, 70, 164, 14, 14, -1, -1, -1, KEY_RETURN, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
if (btn1 == -1) {
|
||||
windowDestroy(win);
|
||||
return -1;
|
||||
}
|
||||
if (btn1 != -1) {
|
||||
buttonSetCallbacks(btn1, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
}
|
||||
|
||||
int btn2 = buttonCreate(win, 176, 163, _littleRedButtonNormalFrmImage.getWidth(), _littleRedButtonNormalFrmImage.getHeight(), -1, -1, -1, KEY_ESCAPE, _littleRedButtonNormalFrmImage.getData(), _littleRedButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
int btn2 = buttonCreate(win, 176, 163, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
if (btn2 == -1) {
|
||||
windowDestroy(win);
|
||||
return -1;
|
||||
}
|
||||
if (btn2 != -1) {
|
||||
buttonSetCallbacks(btn2, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
}
|
||||
|
||||
fontSetCurrent(103);
|
||||
|
||||
@@ -4181,13 +4169,10 @@ int _gdCustomSelect(int a1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (keyCode == KEY_RETURN || keyCode == 500) {
|
||||
if (keyCode == KEY_RETURN) {
|
||||
STRUCT_5189E4* ptr = &(_custom_settings[a1][value]);
|
||||
_custom_current_selected[a1] = value;
|
||||
_gdCustomUpdateSetting(a1, ptr->value);
|
||||
if (keyCode != 500) {
|
||||
soundPlayFile("ib1p1xx1");
|
||||
}
|
||||
done = true;
|
||||
} else if (keyCode == KEY_ESCAPE) {
|
||||
done = true;
|
||||
@@ -4361,9 +4346,6 @@ int _gdialog_window_create()
|
||||
// TODO: Not sure about offsets.
|
||||
blitBufferToBuffer(bgWindowBuf + screenWidth * (GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len), screenWidth, _dialogue_subwin_len, screenWidth, windowBuf, screenWidth);
|
||||
|
||||
// BARTER/TRADE - button moved here to set above background window
|
||||
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
|
||||
if (_dialogue_just_started) {
|
||||
windowRefresh(gGameDialogBackgroundWindow);
|
||||
_gdialog_scroll_subwin(gGameDialogWindow, true, backgroundFrmData, windowBuf, nullptr, _dialogue_subwin_len, true);
|
||||
@@ -4372,6 +4354,8 @@ int _gdialog_window_create()
|
||||
_gdialog_scroll_subwin(gGameDialogWindow, true, backgroundFrmData, windowBuf, nullptr, _dialogue_subwin_len, false);
|
||||
}
|
||||
|
||||
// BARTER/TRADE
|
||||
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), nullptr, BUTTON_FLAG_TRANSPARENT);
|
||||
if (_gdialog_buttons[0] != -1) {
|
||||
buttonSetMouseCallbacks(_gdialog_buttons[0], nullptr, nullptr, nullptr, gameDialogBarterButtonUpMouseUp);
|
||||
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
@@ -4740,27 +4724,6 @@ static void gameDialogRedButtonsInit()
|
||||
}
|
||||
}
|
||||
|
||||
static void gameDialogLittleRedButtonsInit()
|
||||
{
|
||||
// di_rdbt2.frm - dialog red button up
|
||||
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
if (!_littleRedButtonNormalFrmImage.lock(normalFid)) {
|
||||
gameDialogLittleRedButtonsExit();
|
||||
}
|
||||
|
||||
// di_rdbt1.frm - dialog red button down
|
||||
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
if (!_littleRedButtonPressedFrmImage.lock(pressedFid)) {
|
||||
gameDialogLittleRedButtonsExit();
|
||||
}
|
||||
}
|
||||
|
||||
static void gameDialogLittleRedButtonsExit()
|
||||
{
|
||||
_littleRedButtonNormalFrmImage.unlock();
|
||||
_littleRedButtonPressedFrmImage.unlock();
|
||||
}
|
||||
|
||||
static void gameDialogRedButtonsExit()
|
||||
{
|
||||
_redButtonNormalFrmImage.unlock();
|
||||
|
||||
+7
-7
@@ -352,20 +352,20 @@ void takeScreenshot()
|
||||
return;
|
||||
}
|
||||
|
||||
WINDOWDRAWINGPROC old_src = _scr_blit;
|
||||
WINDOWDRAWINGPROC v0 = _scr_blit;
|
||||
_scr_blit = screenshotBlitter;
|
||||
|
||||
WINDOWDRAWINGPROC old_mouse = _mouse_blit;
|
||||
WINDOWDRAWINGPROC v2 = _mouse_blit;
|
||||
_mouse_blit = screenshotBlitter;
|
||||
|
||||
WindowDrawingProc2* old_mouse_trans = _mouse_blit_trans;
|
||||
WindowDrawingProc2* v1 = _mouse_blit_trans;
|
||||
_mouse_blit_trans = nullptr;
|
||||
|
||||
windowRefreshAll(&_scr_size);
|
||||
|
||||
_mouse_blit_trans = old_mouse_trans;
|
||||
_mouse_blit = old_mouse;
|
||||
_scr_blit = old_src;
|
||||
_mouse_blit_trans = v1;
|
||||
_mouse_blit = v2;
|
||||
_scr_blit = v0;
|
||||
|
||||
unsigned char* palette = _getSystemPalette();
|
||||
gScreenshotHandler(width, height, gScreenshotBuffer, palette);
|
||||
@@ -373,7 +373,7 @@ void takeScreenshot()
|
||||
}
|
||||
|
||||
// 0x4C8FF0
|
||||
static void screenshotBlitter(unsigned char* src, int srcPitch, int _, int srcX, int srcY, int width, int height, int destX, int destY)
|
||||
static void screenshotBlitter(unsigned char* src, int srcPitch, int a3, int srcX, int srcY, int width, int height, int destX, int destY)
|
||||
{
|
||||
int destWidth = _scr_size.right - _scr_size.left + 1;
|
||||
blitBufferToBuffer(src + srcPitch * srcY + srcX, width, height, srcPitch, gScreenshotBuffer + destWidth * destY + destX, destWidth);
|
||||
|
||||
+125
-99
@@ -269,7 +269,7 @@ static void inventoryWindowOpenContextMenu(int eventCode, int inventoryWindowTyp
|
||||
static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object* targetObj, bool isPlanting);
|
||||
static int _barter_compute_value(Object* dude, Object* npc);
|
||||
static int _barter_attempt_transaction(Object* dude, Object* offerTable, Object* npc, Object* barterTable);
|
||||
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayer, bool fromInventory, bool immediate);
|
||||
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayer, bool fromInventory);
|
||||
static void _barter_move_inventory(Object* item, int quantity, int slotIndex, int indexOffset, Object* npc, Object* sourceTable, bool fromDude);
|
||||
static void _barter_move_from_table_inventory(Object* item, int quantity, int slotIndex, Object* npc, Object* sourceTable, bool fromDude);
|
||||
static void inventoryWindowRenderInnerInventories(int win, Object* leftTable, Object* rightTable, int draggedSlotIndex);
|
||||
@@ -281,8 +281,6 @@ static void _draw_amount(int value, int inventoryWindowType);
|
||||
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int maximum, int defaultValue = 1);
|
||||
static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item);
|
||||
static int inventoryQuantityWindowFree(int inventoryWindowType);
|
||||
static bool _ctrl_pressed();
|
||||
static void _drag_item_loop(Object* item, bool immediate);
|
||||
|
||||
// 0x46E6D0
|
||||
static const int gSummaryStats[7] = {
|
||||
@@ -466,7 +464,7 @@ static Object* _ptable;
|
||||
static InventoryPrintItemDescriptionHandler* gInventoryPrintItemDescriptionHandler;
|
||||
|
||||
// 0x59E93C
|
||||
static int _im_value; // "keyCode" corresponding to an inventory item "button", or -1 if nothing
|
||||
static int _im_value;
|
||||
|
||||
// 0x59E940
|
||||
static int gInventoryCursor;
|
||||
@@ -2313,8 +2311,7 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
break;
|
||||
}
|
||||
|
||||
// fix for disappearing/not disappearing inventory items
|
||||
if (itemIndex == -1 || _pud->items[_pud->length - (itemIndex + indexOffset + 1)].quantity <= 1) { // slots
|
||||
if (itemIndex == -1 || _pud->items[indexOffset + itemIndex].quantity <= 1) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
if (gInventoryRightHandItem != gInventoryLeftHandItem || item != gInventoryLeftHandItem) {
|
||||
int height;
|
||||
@@ -2362,21 +2359,42 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
_display_inventory(indexOffset, itemIndex, INVENTORY_WINDOW_TYPE_NORMAL);
|
||||
}
|
||||
|
||||
FrmImage itemInventoryFrmImage;
|
||||
int itemInventoryFid = itemGetInventoryFid(item);
|
||||
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
|
||||
int width = itemInventoryFrmImage.getWidth();
|
||||
int height = itemInventoryFrmImage.getHeight();
|
||||
unsigned char* data = itemInventoryFrmImage.getData();
|
||||
mouseSetFrame(data, width, height, width, width / 2, height / 2, 0);
|
||||
soundPlayFile("ipickup1");
|
||||
}
|
||||
|
||||
if (itemInHand != nullptr) {
|
||||
_inven_update_lighting(nullptr);
|
||||
}
|
||||
|
||||
// SFALL: allow ctrl-click to unequip
|
||||
bool immediate = itemIndex == -1 && _ctrl_pressed();
|
||||
_drag_item_loop(item, immediate);
|
||||
do {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y)) {
|
||||
inputGetInput();
|
||||
_display_body(-1, INVENTORY_WINDOW_TYPE_NORMAL);
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
} while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0);
|
||||
|
||||
if (itemInventoryFrmImage.isLocked()) {
|
||||
itemInventoryFrmImage.unlock();
|
||||
soundPlayFile("iputdown");
|
||||
}
|
||||
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y)) {
|
||||
int x;
|
||||
int y;
|
||||
mouseGetPositionInWindow(gInventoryWindow, &x, &y);
|
||||
|
||||
int targetIndex = (y - 39) / INVENTORY_SLOT_HEIGHT + indexOffset;
|
||||
if (!immediate && targetIndex < _pud->length) {
|
||||
if (targetIndex < _pud->length) {
|
||||
Object* targetItem = _pud->items[targetIndex].item;
|
||||
if (targetItem != item) {
|
||||
// Dropping item on top of another item.
|
||||
@@ -2392,7 +2410,7 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
}
|
||||
}
|
||||
|
||||
if (immediate || itemIndex == -1) {
|
||||
if (itemIndex == -1) {
|
||||
// TODO: Holy shit, needs refactoring.
|
||||
*itemSlot = nullptr;
|
||||
if (itemAdd(_inven_dude, item, 1)) {
|
||||
@@ -4255,7 +4273,7 @@ int inventoryOpenLooting(Object* looter, Object* target)
|
||||
break;
|
||||
}
|
||||
|
||||
if (keyCode == KEY_UPPERCASE_A || keyCode == KEY_LOWERCASE_A) {
|
||||
if (keyCode == KEY_UPPERCASE_A) {
|
||||
if (!_gIsSteal) {
|
||||
int maxCarryWeight = critterGetStat(looter, STAT_CARRY_WEIGHT);
|
||||
int currentWeight = objectGetInventoryWeight(looter);
|
||||
@@ -4509,7 +4527,6 @@ int inventoryOpenStealing(Object* thief, Object* target)
|
||||
}
|
||||
|
||||
// 0x474708
|
||||
// note: this is looting and stealing, not the inventory screen
|
||||
static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object* targetObj, bool isPlanting)
|
||||
{
|
||||
bool needRefresh = true;
|
||||
@@ -4559,17 +4576,40 @@ static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object*
|
||||
windowRefreshRect(gInventoryWindow, &rect);
|
||||
}
|
||||
|
||||
bool immediate = _ctrl_pressed();
|
||||
_drag_item_loop(item, immediate);
|
||||
FrmImage itemInventoryFrmImage;
|
||||
int itemInventoryFid = itemGetInventoryFid(item);
|
||||
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
|
||||
int width = itemInventoryFrmImage.getWidth();
|
||||
int height = itemInventoryFrmImage.getHeight();
|
||||
unsigned char* data = itemInventoryFrmImage.getData();
|
||||
mouseSetFrame(data, width, height, width, width / 2, height / 2, 0);
|
||||
soundPlayFile("ipickup1");
|
||||
}
|
||||
|
||||
do {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
inputGetInput();
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
} while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0);
|
||||
|
||||
if (itemInventoryFrmImage.isLocked()) {
|
||||
itemInventoryFrmImage.unlock();
|
||||
soundPlayFile("iputdown");
|
||||
}
|
||||
|
||||
InventoryMoveResult result = INVENTORY_MOVE_RESULT_FAILED;
|
||||
MessageListItem messageListItem;
|
||||
|
||||
if (isPlanting) {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_RIGHT_SCROLLER_X, INVENTORY_LOOT_RIGHT_SCROLLER_Y, INVENTORY_LOOT_RIGHT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_RIGHT_SCROLLER_Y)) {
|
||||
int quantityToMove = quantity;
|
||||
if (quantity > 1 && !immediate) {
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_RIGHT_SCROLLER_X, INVENTORY_LOOT_RIGHT_SCROLLER_Y, INVENTORY_LOOT_RIGHT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_RIGHT_SCROLLER_Y)) {
|
||||
int quantityToMove;
|
||||
if (quantity > 1) {
|
||||
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
|
||||
} else {
|
||||
quantityToMove = 1;
|
||||
}
|
||||
|
||||
if (quantityToMove != -1) {
|
||||
@@ -4593,10 +4633,12 @@ static InventoryMoveResult _move_inventory(Object* item, int slotIndex, Object*
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_LEFT_SCROLLER_X, INVENTORY_LOOT_LEFT_SCROLLER_Y, INVENTORY_LOOT_LEFT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_LEFT_SCROLLER_Y)) {
|
||||
int quantityToMove = quantity;
|
||||
if (quantity > 1 && !immediate) {
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_LEFT_SCROLLER_X, INVENTORY_LOOT_LEFT_SCROLLER_Y, INVENTORY_LOOT_LEFT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_LEFT_SCROLLER_Y)) {
|
||||
int quantityToMove;
|
||||
if (quantity > 1) {
|
||||
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
|
||||
} else {
|
||||
quantityToMove = 1;
|
||||
}
|
||||
|
||||
if (quantityToMove != -1) {
|
||||
@@ -4724,7 +4766,7 @@ static int _barter_attempt_transaction(Object* dude, Object* offerTable, Object*
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayer, bool fromInventory, bool immediate)
|
||||
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayer, bool fromInventory)
|
||||
{
|
||||
if (maxQuantity <= 1) {
|
||||
return maxQuantity;
|
||||
@@ -4740,54 +4782,11 @@ static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool
|
||||
|
||||
if ((balance < 0 && fromInventory) || (balance > 0 && !fromInventory)) {
|
||||
suggestedValue = std::min(std::abs(balance), maxQuantity);
|
||||
if (immediate) {
|
||||
return suggestedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (immediate) {
|
||||
return maxQuantity;
|
||||
}
|
||||
|
||||
return inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, maxQuantity, suggestedValue);
|
||||
}
|
||||
|
||||
// clicked on an inventory in preparation of dragging or immediate transfer
|
||||
static void _drag_item_loop(Object* item, bool immediate)
|
||||
{
|
||||
if (immediate) {
|
||||
soundPlayFile("iputdown");
|
||||
// prevent item look from occuring after immediate move
|
||||
_im_value = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
FrmImage itemInventoryFrmImage;
|
||||
int itemInventoryFid = itemGetInventoryFid(item);
|
||||
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
|
||||
int width = itemInventoryFrmImage.getWidth();
|
||||
int height = itemInventoryFrmImage.getHeight();
|
||||
unsigned char* data = itemInventoryFrmImage.getData();
|
||||
mouseSetFrame(data, width, height, width, width / 2, height / 2, 0);
|
||||
soundPlayFile("ipickup1");
|
||||
}
|
||||
|
||||
do {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
inputGetInput();
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
} while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0);
|
||||
|
||||
if (itemInventoryFrmImage.isLocked()) {
|
||||
itemInventoryFrmImage.unlock();
|
||||
soundPlayFile("iputdown");
|
||||
}
|
||||
}
|
||||
|
||||
// 0x474DAC
|
||||
static void _barter_move_inventory(Object* item, int quantity, int slotIndex, int indexOffset, Object* npc, Object* sourceTable, bool fromDude)
|
||||
{
|
||||
@@ -4818,14 +4817,35 @@ static void _barter_move_inventory(Object* item, int quantity, int slotIndex, in
|
||||
windowRefreshRect(gInventoryWindow, &rect);
|
||||
}
|
||||
|
||||
bool immediate = _ctrl_pressed();
|
||||
_drag_item_loop(item, immediate);
|
||||
FrmImage itemInventoryFrmImage;
|
||||
int itemInventoryFid = itemGetInventoryFid(item);
|
||||
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
|
||||
int width = itemInventoryFrmImage.getWidth();
|
||||
int height = itemInventoryFrmImage.getHeight();
|
||||
unsigned char* data = itemInventoryFrmImage.getData();
|
||||
mouseSetFrame(data, width, height, width, width / 2, height / 2, 0);
|
||||
soundPlayFile("ipickup1");
|
||||
}
|
||||
|
||||
do {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
inputGetInput();
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
} while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0);
|
||||
|
||||
if (itemInventoryFrmImage.isLocked()) {
|
||||
itemInventoryFrmImage.unlock();
|
||||
soundPlayFile("iputdown");
|
||||
}
|
||||
|
||||
MessageListItem messageListItem;
|
||||
|
||||
if (fromDude) {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, true, true, immediate);
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, true, true);
|
||||
if (quantityToMove != -1) {
|
||||
if (itemMoveForce(_inven_dude, sourceTable, item, quantityToMove) == -1) {
|
||||
// There is no space left for that item.
|
||||
@@ -4837,8 +4857,8 @@ static void _barter_move_inventory(Object* item, int quantity, int slotIndex, in
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, false, true, immediate);
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, false, true);
|
||||
if (quantityToMove != -1) {
|
||||
if (itemMoveForce(npc, sourceTable, item, quantityToMove) == -1) {
|
||||
// You cannot pick that up. You are at your maximum weight capacity.
|
||||
@@ -4884,14 +4904,35 @@ static void _barter_move_from_table_inventory(Object* item, int quantity, int sl
|
||||
windowRefreshRect(gInventoryWindow, &rect);
|
||||
}
|
||||
|
||||
bool immediate = _ctrl_pressed();
|
||||
_drag_item_loop(item, immediate);
|
||||
FrmImage itemInventoryFrmImage;
|
||||
int itemInventoryFid = itemGetInventoryFid(item);
|
||||
if (itemInventoryFrmImage.lock(itemInventoryFid)) {
|
||||
int width = itemInventoryFrmImage.getWidth();
|
||||
int height = itemInventoryFrmImage.getHeight();
|
||||
unsigned char* data = itemInventoryFrmImage.getData();
|
||||
mouseSetFrame(data, width, height, width, width / 2, height / 2, 0);
|
||||
soundPlayFile("ipickup1");
|
||||
}
|
||||
|
||||
do {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
inputGetInput();
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
} while ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0);
|
||||
|
||||
if (itemInventoryFrmImage.isLocked()) {
|
||||
itemInventoryFrmImage.unlock();
|
||||
soundPlayFile("iputdown");
|
||||
}
|
||||
|
||||
MessageListItem messageListItem;
|
||||
|
||||
if (fromDude) {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, true, false, immediate);
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, true, false);
|
||||
if (quantityToMove != -1) {
|
||||
if (itemMoveForce(sourceTable, _inven_dude, item, quantityToMove) == -1) {
|
||||
// There is no space left for that item.
|
||||
@@ -4903,8 +4944,8 @@ static void _barter_move_from_table_inventory(Object* item, int quantity, int sl
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (immediate || mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, false, false, immediate);
|
||||
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) {
|
||||
int quantityToMove = _barter_get_quantity_moved_items(item, quantity, false, false);
|
||||
if (quantityToMove != -1) {
|
||||
if (itemMoveForce(sourceTable, npc, item, quantityToMove) == -1) {
|
||||
// You cannot pick that up. You are at your maximum weight capacity.
|
||||
@@ -5012,12 +5053,6 @@ static void inventoryWindowRenderInnerInventories(int win, Object* leftTable, Ob
|
||||
fontSetCurrent(oldFont);
|
||||
}
|
||||
|
||||
static bool _ctrl_pressed()
|
||||
{
|
||||
const Uint8* keyboardState = SDL_GetKeyboardState(nullptr);
|
||||
return keyboardState[SDL_SCANCODE_LCTRL] || keyboardState[SDL_SCANCODE_RCTRL];
|
||||
}
|
||||
|
||||
// 0x4757F0
|
||||
void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object* bartererTable, int barterMod)
|
||||
{
|
||||
@@ -5115,13 +5150,11 @@ void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object*
|
||||
_barter_mod = barterMod + modifier;
|
||||
|
||||
if (keyCode == KEY_LOWERCASE_T || modifier <= -30) {
|
||||
// T == return to talk
|
||||
itemMoveAll(bartererTable, barterer);
|
||||
itemMoveAll(playerTable, gDude);
|
||||
_barter_end_to_talk_to();
|
||||
break;
|
||||
} else if (keyCode == KEY_LOWERCASE_M) {
|
||||
// M == attempt offer
|
||||
if (playerTable->data.inventory.length != 0 || _btable->data.inventory.length != 0) {
|
||||
if (_barter_attempt_transaction(_inven_dude, playerTable, barterer, bartererTable) == 0) {
|
||||
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
|
||||
@@ -5195,7 +5228,6 @@ void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object*
|
||||
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
|
||||
inventoryWindowRenderInnerInventories(win, playerTable, nullptr, -1);
|
||||
} else {
|
||||
// player inventory
|
||||
int slotIndex = keyCode - 1000;
|
||||
if (slotIndex + _stack_offset[_curr_stack] < _pud->length) {
|
||||
int offset = _stack_offset[_curr_stack];
|
||||
@@ -5209,7 +5241,6 @@ void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object*
|
||||
|
||||
keyCode = -1;
|
||||
} else if (keyCode >= 2000 && keyCode <= 2000 + gInventorySlotsCount) {
|
||||
// merchant inventory
|
||||
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
|
||||
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
|
||||
inventoryWindowRenderInnerInventories(win, nullptr, bartererTable, -1);
|
||||
@@ -5227,7 +5258,6 @@ void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object*
|
||||
|
||||
keyCode = -1;
|
||||
} else if (keyCode >= 2300 && keyCode <= 2300 + gInventorySlotsCount) {
|
||||
// player table (offer)
|
||||
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
|
||||
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
|
||||
inventoryWindowRenderInnerInventories(win, playerTable, nullptr, -1);
|
||||
@@ -5244,7 +5274,6 @@ void inventoryOpenTrade(int win, Object* barterer, Object* playerTable, Object*
|
||||
|
||||
keyCode = -1;
|
||||
} else if (keyCode >= 2400 && keyCode <= 2400 + gInventorySlotsCount) {
|
||||
// merchant table (offer)
|
||||
if (gInventoryCursor == INVENTORY_WINDOW_CURSOR_ARROW) {
|
||||
inventoryWindowOpenContextMenu(keyCode, INVENTORY_WINDOW_TYPE_TRADE);
|
||||
inventoryWindowRenderInnerInventories(win, nullptr, bartererTable, -1);
|
||||
@@ -5609,19 +5638,16 @@ static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int ma
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (keyCode == KEY_RETURN || keyCode == 500) {
|
||||
if (keyCode == KEY_RETURN) {
|
||||
if (value >= min && value <= max) {
|
||||
if (inventoryWindowType != INVENTORY_WINDOW_TYPE_SET_TIMER || value % 10 == 0) {
|
||||
if (keyCode != 500) {
|
||||
soundPlayFile("ib1p1xx1");
|
||||
}
|
||||
soundPlayFile("ib1p1xx1");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
soundPlayFile("iisxxxx1");
|
||||
}
|
||||
break;
|
||||
|
||||
} else if (keyCode == 5000 || keyCode == KEY_LOWERCASE_A) {
|
||||
soundPlayFile("iisxxxx1");
|
||||
} else if (keyCode == 5000) {
|
||||
isTyping = false;
|
||||
value = max;
|
||||
_draw_amount(value, inventoryWindowType);
|
||||
@@ -5881,7 +5907,7 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
500,
|
||||
KEY_RETURN,
|
||||
_moveFrmImages[4].getData(),
|
||||
_moveFrmImages[5].getData(),
|
||||
nullptr,
|
||||
|
||||
+6
-6
@@ -781,17 +781,17 @@ int _movieRun(int win, char* filePath)
|
||||
}
|
||||
|
||||
// 0x487B1C
|
||||
int _movieRunRect(int win, char* filePath, int x, int y, int w, int h)
|
||||
int _movieRunRect(int win, char* filePath, int a3, int a4, int a5, int a6)
|
||||
{
|
||||
if (_running) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
_movieX = x;
|
||||
_movieY = y;
|
||||
_movieOffset = x + y * windowGetWidth(win);
|
||||
_movieW = w;
|
||||
_movieH = h;
|
||||
_movieX = a3;
|
||||
_movieY = a4;
|
||||
_movieOffset = a3 + a4 * windowGetWidth(win);
|
||||
_movieW = a5;
|
||||
_movieH = a6;
|
||||
_movieSubRectFlag = 1;
|
||||
|
||||
return _movieStart(win, filePath);
|
||||
|
||||
+2
-2
@@ -28,11 +28,11 @@ typedef int(MovieBlitFunc)(int win, unsigned char* data, int width, int height,
|
||||
void movieInit();
|
||||
void movieExit();
|
||||
void _movieStop();
|
||||
int movieSetFlags(int flags);
|
||||
int movieSetFlags(int a1);
|
||||
void _movieSetPaletteFunc(MovieSetPaletteEntriesProc* proc);
|
||||
void movieSetPaletteProc(MovieSetPaletteProc* proc);
|
||||
int _movieRun(int win, char* filePath);
|
||||
int _movieRunRect(int win, char* filePath, int x, int y, int w, int h);
|
||||
int _movieRunRect(int win, char* filePath, int a3, int a4, int a5, int a6);
|
||||
void movieSetBuildSubtitleFilePathProc(MovieBuildSubtitleFilePathProc* proc);
|
||||
void movieSetVolume(int volume);
|
||||
void _movieUpdate();
|
||||
|
||||
+2
-3
@@ -687,9 +687,8 @@ static int pipboyWindowInit(int intent)
|
||||
buttonSetCallbacks(alarmButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
}
|
||||
|
||||
int y = 340;
|
||||
int y = 341;
|
||||
int eventCode = 500;
|
||||
int yOffsets[] = { 27, 27, 29, 25, 27 }; // handles slighlty misaligned buttons on background
|
||||
for (int index = 0; index < 5; index += 1) {
|
||||
if (index != 1) {
|
||||
int btn = buttonCreate(gPipboyWindow,
|
||||
@@ -712,7 +711,7 @@ static int pipboyWindowInit(int intent)
|
||||
eventCode += 1;
|
||||
}
|
||||
|
||||
y += yOffsets[index];
|
||||
y += 27;
|
||||
}
|
||||
|
||||
if (intent == PIPBOY_OPEN_INTENT_REST) {
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ namespace fallout {
|
||||
#define SFALL_CONFIG_PIPBOY_AVAILABLE_AT_GAMESTART "PipBoyAvailableAtGameStart"
|
||||
#define SFALL_CONFIG_USE_WALK_DISTANCE "UseWalkDistance"
|
||||
#define SFALL_CONFIG_AUTO_OPEN_DOORS "AutoOpenDoors"
|
||||
#define SFALL_CONFIG_GAPLESS_MUSIC "GaplessMusic" // note: this isn't an sfall config
|
||||
#define SFALL_CONFIG_GAPLESS_MUSIC "GaplessMusic"
|
||||
|
||||
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1
|
||||
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3
|
||||
|
||||
+1
-1
@@ -298,7 +298,7 @@ unsigned char* directDrawGetPalette()
|
||||
}
|
||||
|
||||
// 0x4CB850
|
||||
void _GNW95_ShowRect(unsigned char* src, int srcPitch, int _, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY)
|
||||
void _GNW95_ShowRect(unsigned char* src, int srcPitch, int a3, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY)
|
||||
{
|
||||
blitBufferToBuffer(src + srcPitch * srcY + srcX, srcWidth, srcHeight, srcPitch, (unsigned char*)gSdlSurface->pixels + gSdlSurface->pitch * destY + destX, gSdlSurface->pitch);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user