For some RPU elevator transitions, I was seeing the screen partially not update. This was due to rejecting the setCenterTile due scroll blockers (I think). This turns those off if EDG support is enabled.
This also seems to fix some of the jittery scrolling I was seeing in diagonal areas like SF
* Fix elevator cancelation in RPU
If you step into an elevator in RPU and cancel the floor selection, the door closes behind you (sometimes with glitchy graphics). This is a latent bug in the elevators code that vanilla doesn't hit
- elevator_select_ mutates the caller’s elevation to a UI/display level before the modal loop.
- Escape/cancel returns 0 without writing a destination tile.
- Caller then sees map == current map and elevation != current elevation, so it closes the nearby door.
- tile is still -1.
* NovaRains approach
* dont default to first floor if not found
* We call skillGetValue(gDude, SKILL_SNEAK) for every target
* For non-critters, that can result in OOB memory reads
* We only need it for gDude for sneaking
So let's only call it when dude is sneaking and is the target
* Correct `get_object_data` indexes
Currently they are raw offset pointers. This does not work with CE since pointers are wide (64bit) on some (most) platforms. So, we can treat these offsets like constants and return the appropriate fields instead.
There are already used for the most part as enum constants:
* Sfall fix for > 160 maps for automap code (RPU triggers this)
* Logic fix for action menu, where actionIndex was incremented unconditionally and could go out of bounds. This was a regression from vanilla
Add equipment slots to the companion loot screen.
Items can be equipped directly from player or companion inventory. This also allows switching between party members so you can manage all companion's inventories easily. Does not allow equipping items that would otherwise be disallowed.
Also:
Calls HOOK_UNWIELD when adding/removing equipment, meaning mods like npc armor work
Uses HOOK_CANUSE for weapon use checks
Ctrl-click to equip is not implemented since it already transfers items between the two inventories. I tried making it work only for equippable items (and otherwise transfer), but that felt awkward and random. Ctrl-click unequip is implemented.
* Add offset tracking to --scan-unimplemented
* Add a bunch of missing opcodes
* Hardcode a list of implemented hooks to avoid filtering a long list of hooks that are already done
* Add tracking of specific offsets accessed in unsafe scripting so we can plan replacements
Sample output
```
OFFSET write_int (0x81d1 - 0x1d1 - 465):
0x5190f8 (5345528):
- ./mods/InventoryFilter.dat/scripts/gl_InvenFilter_debug.int
- ./mods/InventoryFilter.dat/scripts/release_gl_InvenFilter.int
0x59e95c (5892444):
- ./mods/InventoryFilter.dat/scripts/gl_InvenFilter_debug.int
- ./mods/InventoryFilter.dat/scripts/release_gl_InvenFilter.int
```
Then we can corrlated it with source:
```
// 0x5190F8 curr_rot
static int gInventoryWindowDudeRotation = 0;
```
* PR feedback
* Grow ability for `ce-dat-tool` to extract a list of files
This is needed for Et Tu installation, which selectively extracts files from fo1's master.dat. (It doesn't work if everything is extracted)
* cache entry list to avoid O(n) cost when extracting many files
Currently it isn't playing at all, since we're not doing renderPresent() during the animation loop.
This fixes that. Also, it optimizes the time the animation takes by starting it before the interface combat start/end animation. This saves half a second or so.
* Remove hidden items when trading with Goris
Also, fix the fix to allow looting with Goris
This adds major simplification and deduplication to inventory.cc, including the start of an "InventoryScroller" class that can manage inventory events without duplicate handling everywhere. This is needed as we add more complexity to the page.
* Fix crash due to corrupted `whoHitMe`
It's possible for some object's `whoHitMe` to contain `-1`. It's supposed to be resolved to `nullptr`, but doesn't reliably happen in all cases, esp outside of combat. The main fix here is to normalize to nullptr when loading the object, instead of just map load, or combat paths.
At some point I thought the problem might have been attacker being a non-critter. Added some guards against that regardless. Also, found several bugs and messiness in `apply_damage` which are now fixed.
Fixes https://github.com/alexbatalov/fallout2-ce/issues/368
* Fix ddraw.ini -> game.cfg migration on unix-y systems
We were using `compat_splitpath` on a windows path. We want to work on windows paths, so that's good. This fixes compat_splitpath so that it works with both folder separators. Also tweak `compat_makepath` to recognize both, for consistency.
This means that filenames with `\` will be broken, but I think we can (and should) live with that)
* Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* chore: auto-format with clang-format
* fix
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Better fix for directory detection
A couple places we used compat_file_exists to distinguish between files and folders/dirs, but this breaks on POSIX. This attempts to fix it more holistically
* Make compat_file_exists to be consistent
All platforms now return false for folders/dirs
* Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Most are of this type
```
warning: 'size' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
sfall_arrays.cc:313:26: note: overridden virtual function is here
313 | virtual ProgramValue GetArrayKey(int index, Program* program) = 0;
|
```
* Change `use_walk_distance` to match sfall setting
It's pointless to set this to 0,1 because you don't move if the target is adjacent or yourself, so sfall changes this to "number of spaces" between player and target. We were reading the old ddraw.ini setting before, incorrectly.
Also add a small optimization to not compute path for adjacent targets
* add comment
* return true when distance is self/adjacent
Similar to HRP/Sfall, except:
Does not support non-aspect-ratio-preserving scale mode
Uses vanilla art if it fits without scaling (e.g. 640x480 or non-scaling res like 800x480). The scaled-down HR assets looks considerably worse.
* Bundle Sfall's gl_highlight.ssl
Most mods/distributions assume this is exists since it is bundled with Sfall. It's also a highly requested feature
I decided to merge this as a first-class game config instead of continuing to read mods/sfall-mods.ini. I think most people to this to be a default capability that can be toggled in-engine. Open to other thoughts on the matter. Lost of people will already have sfall-mods.ini configured, which is a reason to keep it the way it was.
* PR feedback
* Change output sound buffer to 44.1 kHz
This allow CE to play 44.1 kHz input files without loss of precision. In particular, it plays HQ music that ships with RPU.
There is a very similar fix in Sfall
* use generic sound loading path to allow .ogg/.wav music files
* rm a few dangling references
* PR feedback
* rm references to audio file
* rm audio_file.cc/h
* restore default audio io
* PR fixes
* Implement `set_unique_id`
* save/load watermark, including compat with previous saves (would be `0`)
* metarule to set and reset unique_id
* inventory stacking rules
This bring CE much closer to sfall's load order, and fixes RPU install.
master_patches > critter_patches > mods_order.txt > PatchFileXX > patchXXX.dat > sfall.dat > critter_dat > f2_res_patches > f2_res_dat > master_dat
Also fixed typo in `showMessageBox`, and added a debugPrint in that function, so errors are visible in the log (LLMs otherwise find it hard to figure out what happened)
* Add "trade/loot" context menu for party members.
This was an idea I saw listed on NMA. Veterans of classic Fallout know you can trade with your companions much more easily using the steal skill, But this would be difficult for most new players to discover. This replaces the dialogue option in the long press (which is redundant since it is the default action) with the hand, which is normally used to loot from containers and corpses.
This does introduce a slight inconsistency in the default action, not being present when you long press. how almost everyone will be single-clicking to talk to NPCs.
Also, "you plant..." and "you steal..." messages when trading with companions this way. Put this behind the same flag in case someone wants the original experience.
* Full context menu
* container -> target
* PR feedback
* rebase on main
* rename function
* Add original symbol beside all function offsets
e.g.
```
// 0x414E98 register_object_call
int animationRegisterCallback(
// 0x414E20 register_object_must_erase
int animationRegisterHideObjectForced(
```
This was programmatically generated so there could be errors. Spot checking looks pretty good though
* [HRP] Enable HR dialog screen
(It's not really "hi resolution", just adds a border so it looks less funny.)
Also, picked up @NovaRain's suggestion of centering dialog on the play area if it is large enough, which matches Sfall.
Very simple party barter support. Builds upon the loot screen so is very little code:
Switch party members with left/right arrow keys
When leaving barter with items on the table (canceling), all items go to the PC's inventory
No special handling of money (yet)
The mod pins the player's money stack on top of the inventory list for all party members. That's nice, but also feels a little odd, but likely just because I'm used to the money stack being stuck at bottom. We can iterate on that.
Adding an interface will require art. I considered enabling mouse use triggered by clicking on the avatar which would be quite simple.
* Speed up Fallout1 .dat reader
It was reallocating a buffer on a loop, which caused large files to take minutes. Fixing this reduced it to a reasonable time, but still ~120s for the entire Fallout1 master.dat.
Also, bump the F2 gzip buffer to 4kB. It was only 400 bytes
In 8b2ead8a2b, soundLoad started honoring AudioFileInfo.channels, but the ACM decoder path historically only propagated sample rate. This changes playback in a way that caused the bug.
Verified by talking to good ol' Sulik
* Add support for new talking heads
Add [Heads] config section in ddraw.ini that maps critter PIDs to talking
head indices in art\heads\heads.lst. When a dialog script starts with
headId=-1, the engine now checks the critter proto's headFid first, then
falls back to the [Heads] mapping. This lets mods add talking heads
without patching dialog scripts.
Includes Cassidy mapping (PID 16777305 → head index 13) for use with
cassidy_head.dat mod.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Implement HOOK_INVENWIELD, HOOK_CANUSEWEAPON and fix HOOK_ADJUSTFID
Wire the sfall hooks that npc_armor.mod relies on so party-member sprites
actually change when armor is equipped:
- HOOK_INVENWIELD fires from inventoryEquipFunc/inventoryUnequipFunc with
(critter, item, slot, isWield). Script may veto by returning 0. Slot
values mirror interpreter_extra.cc: WORN=0, RIGHT_HAND=1, LEFT_HAND=2.
- HOOK_CANUSEWEAPON fires from _ai_search_inven_weap so the mod's
weapon-anim restriction can veto AI weapon picks.
- HOOK_ADJUSTFID arg list corrected to match sfall (single currFid arg,
critter resolved via dude_obj).
- ProgramValue::isEmpty no longer treats string values as empty — sfall
scripts like npc_armor's `while (sect.PID)` loop depend on a non-empty
string being truthy.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* enum class
* chore: auto-format with clang-format
* bad merge
* PR feedback
* restore isEmpty() to vanilla while fixing bug
* fixes
* minor fixes
* extra
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: tectiv3 <tectiv3@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Sfall-like sound system
(I would like a better name for this system, but the opcodes themselves are called `play|stop_sfall_sound` and I can't think of a better name)
This is a sound management system very similar to Sfall's. With a few differences:
* No support for new sound formats yet. Support for at least ogg+wav will come next
* Does support reading from .dat files, hence playing any sound effect in the base game
* Support mode=3 for speech volume. This exists in Sfall but is ignored when called from the opcode.
Also, change GaplessMusic to use this system to play the "wind2" loading sound. This restores the "vanilla" feel map transitions, so I think it's reasonable to make GaplessMusic=1 the default. I can't imagine someone wanting to change it to 0 unless they are ultra purists
* Implement HOOK_RESTTIMER
Et tu + other mods use this
* PR comments + missing doc for ce-dat-tool
* chore: auto-format with clang-format
* document timer wrap
* cleanups
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* `--dev-load-game` commandline arg
This allows you to use --dev-load-game=SLOTXX` to immediately load a saved game after the game is launched. This is mostly useful so that LLMs can launch the game and see the result of an .ssl test script without a human needing to be in the loop
* `set/remove_script` and `HOOK_STDPROCEDURE{_END}`
These were implemented together as I thought HOOK_STDPROCEDURE would be useful for testing set_script.