Compare commits

...
Author SHA1 Message Date
Mike Klaas 46376960d9 WIP Et tu working-ish 2026-05-04 21:43:45 -07:00
Mike Klaas 8b2ead8a2b Sfall-like sound system (#429)
* 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
2026-05-04 07:21:37 -07:00
Mike Klaas 4f89bb7d77 Companions can be the "looter" in loot screen (#435) 2026-05-03 09:57:25 -07:00
Vlad K 0d8741e082 Debug logging improvements (#434)
* debug log buffering to catch early logs, always duplicate log to stdout, const char* for debug fns

* AI nitpicking fixes
2026-05-03 09:15:13 +00:00
Vlad Kandgithub-actions[bot] 6ce6bea309 Sfall Saved Arrays (#431)
* Sfall saved arrays support

* Add "...all_arrays..." special case for a list of saved arrays

* Adjust error message on load fail

* Fix crash in GetArrayKey when index == size

* chore: auto-format with clang-format

* Update sfall compatibility md

* Add keyIndex for Assoc Arrays for O(1) key lookups

* Review feedback, more error logging

* Fix build, increase ARRAY_MAX_STRING to 1024 to match sfall, fix gl_test_arrays triggering dynamic string block merge failure, prevent potential string buffer corruption on very long strings

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-03 01:24:30 +02:00
Mike Klaas 6027c7cf2e Vertically center inventory above interface, isntead of related to screen (#428) 2026-05-01 12:53:02 -07:00
Mike Klaas 7d1c8e7eea Bundle ce.dat into release packages, and update README (#425) 2026-05-01 09:59:46 -07:00
Vlad K a7de228978 frm2png fix unable to convert most FRM's (#426)
* frm2png: fix incorrect byte order detection logic and size check

* Remove unnecessary little endian support

* Add frame size check matching engine logic

* Zero frame size condition reverted

* Tiny fix
2026-05-01 16:49:51 +00:00
Vlad Kandgithub-actions[bot] 3aa6c12244 New concepts for easier UI coding (using game_dialog.cc as a test bed) (#424)
* game_dialog.cc: code debloat, simpler partial cleanup via RAII, fix dialog button during scroll anim

* game_dialog.cc: get rid of awkward button FRM locking using new buttonCreateWithFrm

* chore: auto-format with clang-format

* Code review fixes

* chore: auto-format with clang-format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-01 12:09:50 +02:00
Mike Klaas afdd110d60 2 column inventory and loot (#413)
Also, fix jesse container bug
2026-04-30 20:35:40 -07:00
Mike Klaas 2f491fa6d5 HOOK_EXPLOSIVETIMER (#423) 2026-04-29 20:37:43 -07:00
tectiv3 4382ec3305 iOS/iPad: touch gestures, HUD tap-through, and quick-actions toolbar (#377)
* iOS: add touch gestures, HUD tap-through, quick-actions toolbar

Makes fallout2-ce playable on iPad without a keyboard, while leaving
non-iOS builds unchanged (all additions are TARGET_OS_IOS-guarded).

Touch gestures (src/mouse.cc):
- 3-finger swipe down → ESC
- 4-finger long-press → F6 (quicksave)
- 3-finger long-press → hold LShift (FO2tweaks highlighting). Uses
  SDL_PushEvent so sfall's SDL_GetKeyboardState-based key_pressed()
  sees the held key, not just the engine's own kb state.

HUD ergonomics (src/mouse.cc):
- Taps on interface-bar buttons inject the button's keyCode directly
  so the cursor stays put. Taps on belt chrome are consumed rather
  than teleporting the cursor to inert pixels.
- Two-finger taps on belt buttons → right-click handler.

Gameplay cursor (src/game_mouse.cc):
- On iPad, keep GAME_MOUSE_MODE_MOVE in relative (trackpad) mode so
  screen taps don't teleport the cursor during combat. UI screens
  that explicitly enable touchscreen mode are unaffected.

Quick-actions toolbar (src/platform/ios/quick_toolbar.{cc,h}):
- Optional iOS-only HUD strip above the belt with skill shortcuts
  and end-turn. Header provides no-op stubs for non-iOS builds so
  interface.cc can call it unconditionally.
- game.cc refactor: skilldex result handling factored into
  gameHandleSkilldexResult() so the toolbar and the keyboard
  shortcut share one path.

README: iPad controls section.

* iOS: add quick toolbar visibility preference

Adds a ui.quick_toolbar_visible config flag (default true)

* iOS: skip HUD tap-through when interface bar is hidden

When the interface bar window is hidden (e.g. on the world map),
windowGetRect still returns its rect, causing taps in that screen
area to be consumed as overHud even though there's nothing to interact
with. Check WINDOW_HIDDEN before treating the rect as active HUD.

Addresses Copilot review comment on PR #377.

* iOS: fix dialog options near bottom unclickable on iPad

Enable touchscreen mode for dialog UI so taps reach dialog option
buttons directly. The HUD tap interception in mouse.cc was consuming
taps that landed inside the interface bar rect, even when a dialog
window overlapped that region. Dialog options near the bottom of the
screen were silently swallowed by the belt chrome catch-all.

Skip HUD tap interception when touchscreen mode is active, since a UI
screen (dialog, inventory, skilldex, etc.) owns input in that state.
Add touch_get_touchscreen_mode() getter to support the check.

* iOS: add pipboy touch exception

* Apply fixes from review

* Change quick toolbar default visibility to false

* Add touch mode to character selector

update readme and simplify switch condition
2026-04-28 23:20:15 -07:00
Mike Klaas b012e62e32 ce-frm2png tool (#419) 2026-04-28 22:55:29 -07:00
Mike Klaas 0f69c50df0 Implement HOOK_AMMOCOST (#421) 2026-04-28 22:36:50 -07:00
Mike Klaasandgithub-actions[bot] 1e387beebd Implement HOOK_RESTTIMER (#417)
* 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>
2026-04-26 21:32:49 -07:00
c8a905ea14 Expanded 4-slot barter UI from sfall + support FrmImage locking cached art by file name (#414)
* Expanded barter window from sfall

* Refactor: FrmImage class to lock based on file name, refactor code from last commit

* Soft limit on named art cache size

* Support localized paths for art loaded by name

* Fix visual issue from original sfall implementation where barter window were scrolling down incorrectly + bufToBuf const correctness

* Fix build error and extra destructor call when adding NamedCacheEntry

* Review fixes

* Update src/art.cc

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Review issues fixed, window made transparent to remove black area below the overlap during scroll down

* chore: auto-format with clang-format

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-26 00:03:14 +02:00
Mike Klaas 6255f49d6a Avoid recursive sfall tap_key hooks (#415)
* Avoid recursive sfall tap_key hooks

* PR cleanup
2026-04-25 14:08:59 -07:00
Mike Klaas c3fa7107f9 Rename fallout2-dat to ce-dat-tool (#416)
This is a generic tool that works with FO1 and FO2 archives
2026-04-25 10:53:43 -07:00
Mike Klaas 2b078f48a9 Implement HOOK_AFTERHITROLL (#411)
* Implement HOOK_AFTERHITROLL
2026-04-25 00:38:04 +00:00
Vlad K 10ebd28a4d Fix f2_res migration never working (#410)
* Fix f2_res migration never working

* Remove config checker usage in game_config.cc
2026-04-24 13:05:50 +00:00
106 changed files with 11139 additions and 1746 deletions
+6 -1
View File
@@ -6,10 +6,15 @@ on:
push:
branches: [main]
permissions:
contents: read
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)
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -39,4 +44,4 @@ jobs:
echo "No formatting changes"
fi
+6 -2
View File
@@ -8,11 +8,16 @@ on:
- opened
- synchronize
permissions:
contents: read
jobs:
build_webassembly_version:
name: Build webassembly version
runs-on: ubuntu-latest
permissions: write-all
permissions:
contents: write
deployments: write
steps:
- name: start deployment
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
@@ -138,4 +143,3 @@ jobs:
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
ref: ${{ github.event.pull_request.head.sha }}
env_url: https://${{ github.repository_owner }}.github.io/fallout2-ce/PR-${{ github.event.pull_request.number }}/
+101 -20
View File
@@ -9,6 +9,9 @@ on:
- opened
- synchronize
permissions:
contents: read
defaults:
run:
shell: bash
@@ -35,6 +38,9 @@ jobs:
name: Code format check
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- name: Clone
@@ -71,6 +77,7 @@ jobs:
name: Android
runs-on: ubuntu-latest
needs: [ce-dat]
steps:
- name: Clone
@@ -104,21 +111,38 @@ jobs:
cd os/android
./gradlew assembleDebug
- name: Change apk file name
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mv os/android/app/build/outputs/apk/debug/app-debug.apk os/android/app/build/outputs/apk/debug/fallout2-ce.apk
mkdir -p out/dist/fallout2-ce-android-debug
cp os/android/app/build/outputs/apk/debug/app-debug.apk out/dist/fallout2-ce-android-debug/fallout2-ce.apk
cp out/dist/ce.dat out/dist/fallout2-ce-android-debug/ce.dat
cd out/dist
zip -r fallout2-ce-android-debug.zip fallout2-ce-android-debug
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-debug.apk
path: os/android/app/build/outputs/apk/debug/fallout2-ce.apk
name: fallout2-ce-android-debug
path: out/dist/fallout2-ce-android-debug.zip
retention-days: 7
ce-dat:
name: Build ce.dat
uses: ./.github/workflows/reusable-build-ce-dat.yml
with:
preset: linux-x64-debug
ios:
name: iOS
runs-on: macos-14
needs: [ce-dat]
steps:
- name: Clone
@@ -143,17 +167,32 @@ jobs:
cd out/build/ios
cpack -C Debug
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mkdir -p out/dist/fallout2-ce-ios
cp out/build/ios/fallout2-ce.ipa out/dist/fallout2-ce-ios/fallout2-ce-ios.ipa
cp out/dist/ce.dat out/dist/fallout2-ce-ios/ce.dat
cd out/dist
zip -r fallout2-ce-ios.zip fallout2-ce-ios
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce.ipa
path: out/build/ios/fallout2-ce.ipa
name: fallout2-ce-ios
path: out/dist/fallout2-ce-ios.zip
retention-days: 7
linux:
name: Linux (${{ matrix.arch }})
runs-on: ubuntu-22.04
needs: [ce-dat]
strategy:
fail-fast: false
@@ -193,21 +232,31 @@ jobs:
run: |
cmake --build --preset linux-${{ matrix.arch }}-debug
- name: Change executable file name
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mv out/build/linux-${{ matrix.arch }}-debug/fallout2-ce out/build/linux-${{ matrix.arch }}-debug/fallout2-ce-linux-${{ matrix.arch }}
mkdir -p out/dist/fallout2-ce-linux-${{ matrix.arch }}
cp out/build/linux-${{ matrix.arch }}-debug/fallout2-ce out/dist/fallout2-ce-linux-${{ matrix.arch }}/fallout2-ce
cp out/dist/ce.dat out/dist/fallout2-ce-linux-${{ matrix.arch }}/ce.dat
tar -czvf out/dist/fallout2-ce-linux-${{ matrix.arch }}.tar.gz -C out/dist fallout2-ce-linux-${{ matrix.arch }}
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-linux-${{ matrix.arch }}
path: out/build/linux-${{ matrix.arch }}-debug/fallout2-ce-linux-${{ matrix.arch }}
path: out/dist/fallout2-ce-linux-${{ matrix.arch }}.tar.gz
retention-days: 7
linux-armhf:
name: Linux (armhf)
runs-on: ubuntu-22.04-arm
needs: [ce-dat]
steps:
- name: Clone
@@ -233,21 +282,31 @@ jobs:
- name: Build
run: cmake --build build
- name: Change executable file name
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mv build/fallout2-ce build/fallout2-ce-linux-armhf
mkdir -p out/dist/fallout2-ce-linux-armhf
cp build/fallout2-ce out/dist/fallout2-ce-linux-armhf/fallout2-ce
cp out/dist/ce.dat out/dist/fallout2-ce-linux-armhf/ce.dat
tar -czvf out/dist/fallout2-ce-linux-armhf.tar.gz -C out/dist fallout2-ce-linux-armhf
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-linux-armhf
path: build/fallout2-ce-linux-armhf
path: out/dist/fallout2-ce-linux-armhf.tar.gz
retention-days: 7
linux-arm64:
name: Linux (arm64)
runs-on: ubuntu-22.04-arm
needs: [ce-dat]
steps:
- name: Clone
@@ -264,15 +323,24 @@ jobs:
- name: Build
run: cmake --build build
- name: Change executable file name
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mv build/fallout2-ce build/fallout2-ce-linux-arm64
mkdir -p out/dist/fallout2-ce-linux-arm64
cp build/fallout2-ce out/dist/fallout2-ce-linux-arm64/fallout2-ce
cp out/dist/ce.dat out/dist/fallout2-ce-linux-arm64/ce.dat
tar -czvf out/dist/fallout2-ce-linux-arm64.tar.gz -C out/dist fallout2-ce-linux-arm64
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-linux-arm64
path: build/fallout2-ce-linux-arm64
path: out/dist/fallout2-ce-linux-arm64.tar.gz
retention-days: 7
macos:
@@ -306,7 +374,7 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-macos.dmg
name: fallout2-ce-macos
path: out/build/macos/Fallout II Community Edition.dmg
retention-days: 7
@@ -314,6 +382,7 @@ jobs:
name: Windows (${{ matrix.arch }})
runs-on: windows-2025
needs: [ce-dat]
strategy:
fail-fast: false
@@ -351,15 +420,25 @@ jobs:
call "%VS_PATH%\Common7\Tools\VsDevCmd.bat" ^
&& cmake --build --preset windows-${{ matrix.arch }}-release
- name: Change executable file name
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Package
run: |
mv out/build/windows-${{ matrix.arch }}/RelWithDebInfo/fallout2-ce.exe out/build/windows-${{ matrix.arch }}/RelWithDebInfo/fallout2-ce-${{ matrix.arch }}.exe
mkdir -p out/dist/fallout2-ce-windows-${{ matrix.arch }}
cp out/build/windows-${{ matrix.arch }}/RelWithDebInfo/fallout2-ce.exe out/dist/fallout2-ce-windows-${{ matrix.arch }}/fallout2-ce.exe
cp out/dist/ce.dat out/dist/fallout2-ce-windows-${{ matrix.arch }}/ce.dat
cd out/dist
7z a fallout2-ce-windows-${{ matrix.arch }}.zip fallout2-ce-windows-${{ matrix.arch }}
- name: Upload
uses: actions/upload-artifact@v4
with:
name: fallout2-ce-windows-${{ matrix.arch }}
path: out/build/windows-${{ matrix.arch }}/RelWithDebInfo/fallout2-ce-${{ matrix.arch }}.exe
path: out/dist/fallout2-ce-windows-${{ matrix.arch }}.zip
retention-days: 7
@@ -367,7 +446,8 @@ jobs:
name: Release Continuous build
runs-on: ubuntu-latest
needs: [android, ios, linux, linux-armhf, linux-arm64, macos, windows]
permissions: write-all
permissions:
contents: write
steps:
- name: Fetch artifacts
if: ${{ always() && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
@@ -387,6 +467,7 @@ jobs:
- name: Move unpacked artifacts to root folder
if: ${{ always() && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
run: |
rm -rf artifacts/ce-dat
ls -Rlah .
find .
cd artifacts/
@@ -5,6 +5,9 @@ on:
types:
- closed
permissions:
contents: read
jobs:
delete_pr_preview:
name: Delete PR preview from gh-pages
+70 -12
View File
@@ -5,15 +5,27 @@ on:
types:
- published
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
ce-dat:
name: Build ce.dat
uses: ./.github/workflows/reusable-build-ce-dat.yml
with:
preset: linux-x64-release
android:
name: Android
runs-on: ubuntu-latest
needs: [ce-dat]
permissions:
contents: write
steps:
- name: Clone
@@ -47,12 +59,21 @@ jobs:
cd os/android
./gradlew assembleRelease
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Upload
run: |
cd os/android/app/build/outputs/apk/release
cp app-release.apk fallout2-ce-android.apk
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-android.apk
rm fallout2-ce-android.apk
mkdir -p out/dist/fallout2-ce-android
cp os/android/app/build/outputs/apk/release/app-release.apk out/dist/fallout2-ce-android/fallout2-ce-android.apk
cp out/dist/ce.dat out/dist/fallout2-ce-android/ce.dat
cd out/dist
zip -r fallout2-ce-android.zip fallout2-ce-android
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-android.zip
rm fallout2-ce-android.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -60,6 +81,9 @@ jobs:
name: iOS
runs-on: macos-14
needs: [ce-dat]
permissions:
contents: write
steps:
- name: Clone
@@ -95,12 +119,21 @@ jobs:
cd build
cpack -C RelWithDebInfo
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Upload
run: |
cd build
cp fallout2-ce.ipa fallout2-ce-ios.ipa
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-ios.ipa
rm fallout2-ce-ios.ipa
mkdir -p out/dist/fallout2-ce-ios
cp build/fallout2-ce.ipa out/dist/fallout2-ce-ios/fallout2-ce-ios.ipa
cp out/dist/ce.dat out/dist/fallout2-ce-ios/ce.dat
cd out/dist
zip -r fallout2-ce-ios.zip fallout2-ce-ios
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-ios.zip
rm fallout2-ce-ios.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -108,6 +141,9 @@ jobs:
name: Linux (${{ matrix.arch }})
runs-on: ubuntu-20.04
needs: [ce-dat]
permissions:
contents: write
strategy:
fail-fast: false
@@ -164,10 +200,18 @@ jobs:
-j $(nproc) \
# EOL
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Upload
run: |
cd build
tar -czvf fallout2-ce-linux-${{ matrix.arch }}.tar.gz fallout2-ce
mkdir -p out/dist/fallout2-ce-linux-${{ matrix.arch }}
cp build/fallout2-ce out/dist/fallout2-ce-linux-${{ matrix.arch }}/fallout2-ce
cp out/dist/ce.dat out/dist/fallout2-ce-linux-${{ matrix.arch }}/ce.dat
tar -czvf fallout2-ce-linux-${{ matrix.arch }}.tar.gz -C out/dist fallout2-ce-linux-${{ matrix.arch }}
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-linux-${{ matrix.arch }}.tar.gz
rm fallout2-ce-linux-${{ matrix.arch }}.tar.gz
env:
@@ -177,6 +221,8 @@ jobs:
name: macOS
runs-on: macos-11
permissions:
contents: write
steps:
- name: Clone
@@ -244,6 +290,9 @@ jobs:
name: Windows (${{ matrix.arch }})
runs-on: windows-2025
needs: [ce-dat]
permissions:
contents: write
strategy:
fail-fast: false
@@ -281,10 +330,19 @@ jobs:
call "%VS_PATH%\Common7\Tools\VsDevCmd.bat" ^
&& cmake --build --preset windows-${{ matrix.arch }}-release
- name: Download ce.dat
uses: actions/download-artifact@v4
with:
name: ce-dat
path: out/dist
- name: Upload
run: |
cd out/build/windows-${{ matrix.arch }}/RelWithDebInfo
7z a fallout2-ce-windows-${{ matrix.arch }}.zip fallout2-ce.exe
mkdir -p out/dist/fallout2-ce-windows-${{ matrix.arch }}
cp out/build/windows-${{ matrix.arch }}/RelWithDebInfo/fallout2-ce.exe out/dist/fallout2-ce-windows-${{ matrix.arch }}/fallout2-ce.exe
cp out/dist/ce.dat out/dist/fallout2-ce-windows-${{ matrix.arch }}/ce.dat
cd out/dist
7z a fallout2-ce-windows-${{ matrix.arch }}.zip fallout2-ce-windows-${{ matrix.arch }}
gh release upload ${{ github.event.release.tag_name }} fallout2-ce-windows-${{ matrix.arch }}.zip
rm fallout2-ce-windows-${{ matrix.arch }}.zip
env:
@@ -0,0 +1,49 @@
name: Reusable Build ce.dat
on:
workflow_call:
inputs:
preset:
required: true
type: string
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
build-ce-dat:
name: Build ce.dat
runs-on: ubuntu-22.04
steps:
- name: Clone
uses: actions/checkout@v4
- name: Dependencies
run: |
sudo apt update
sudo apt install libsdl2-dev zlib1g-dev
- name: Configure
run: |
cmake --preset ${{ inputs.preset }}
- name: Build ce-dat-tool
run: |
cmake --build --preset ${{ inputs.preset }} --target ce-dat-tool
- name: Create ce.dat
run: |
mkdir -p out/dist
out/build/${{ inputs.preset }}/ce-dat-tool create files/ce.dat out/dist/ce.dat
- name: Upload ce.dat artifact
uses: actions/upload-artifact@v4
with:
name: ce-dat
path: out/dist/ce.dat
retention-days: 7
+87 -7
View File
@@ -25,6 +25,9 @@ if(MSVC)
endif()
option(FALLOUT_VENDORED "Use vendored third-party libraries" ON)
option(FALLOUT_AUDIO_OGG "Enable OGG decoding with stb_vorbis when available" ON)
set(FALLOUT_STB_VORBIS_DIR "" CACHE PATH "Directory containing stb_vorbis.c")
if(ANDROID)
add_library(${EXECUTABLE_NAME} SHARED)
@@ -180,6 +183,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/obj_types.h"
"src/object.cc"
"src/object.h"
"src/ogg_decoder.cc"
"src/ogg_decoder.h"
"src/opcode_context.cc"
"src/opcode_context.h"
"src/options.cc"
@@ -297,6 +302,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/sfall_opcodes.cc"
"src/sfall_opcodes.h"
"src/sfall_script_hooks.cc"
"src/script_sound.cc"
"src/script_sound.h"
"src/sfall_arrays.cc"
"src/sfall_arrays.h"
"src/sfall_animation.cc"
@@ -311,10 +318,39 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
target_include_directories(${EXECUTABLE_NAME} PUBLIC "third_party/lodepng")
set(FALLOUT_HAVE_STB_VORBIS OFF)
if(FALLOUT_AUDIO_OGG)
if(EXISTS "${CMAKE_SOURCE_DIR}/third_party/stb_vorbis/stb_vorbis.c")
set(_fallout_stb_vorbis_dir "${CMAKE_SOURCE_DIR}/third_party/stb_vorbis")
else()
set(_fallout_stb_vorbis_dir "${FALLOUT_STB_VORBIS_DIR}")
if(NOT _fallout_stb_vorbis_dir)
find_path(_fallout_stb_vorbis_dir
NAMES "stb_vorbis.c"
DOC "Directory containing stb_vorbis.c")
endif()
endif()
if(_fallout_stb_vorbis_dir AND EXISTS "${_fallout_stb_vorbis_dir}/stb_vorbis.c")
set(FALLOUT_HAVE_STB_VORBIS ON)
target_include_directories(${EXECUTABLE_NAME} PRIVATE "${_fallout_stb_vorbis_dir}")
else()
message(STATUS "OGG support disabled: stb_vorbis.c not found")
endif()
endif()
if(FALLOUT_HAVE_STB_VORBIS)
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE HAVE_STB_VORBIS=1)
else()
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE HAVE_STB_VORBIS=0)
endif()
if(IOS)
target_sources(${EXECUTABLE_NAME} PUBLIC
"src/platform/ios/paths.h"
"src/platform/ios/paths.mm"
"src/platform/ios/quick_toolbar.h"
"src/platform/ios/quick_toolbar.cc"
)
endif()
@@ -367,6 +403,8 @@ if(APPLE)
"os/macos/fallout2-ce.icns"
)
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreFoundation")
target_sources(${EXECUTABLE_NAME} PUBLIC ${RESOURCES})
set_source_files_properties(${RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
@@ -453,7 +491,7 @@ target_link_libraries(${EXECUTABLE_NAME} ${SDL2_LIBRARIES})
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
if((NOT ANDROID) AND (NOT IOS) AND (NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten"))
add_executable(fallout2-dat
add_executable(ce-dat-tool
"tools/dat_tool.cc"
"tools/dat_archive.cc"
"tools/fo1_dat_lzss.cc"
@@ -462,23 +500,65 @@ if((NOT ANDROID) AND (NOT IOS) AND (NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten"))
)
if(APPLE)
set_target_properties(fallout2-dat PROPERTIES
set_target_properties(ce-dat-tool PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
)
endif()
target_link_libraries(fallout2-dat
target_link_libraries(ce-dat-tool
fpattern_windows::fpattern_windows
${ZLIB_LIBRARIES}
${SDL2_LIBRARIES}
)
if(WIN32)
target_link_libraries(fallout2-dat winmm)
target_link_libraries(ce-dat-tool winmm)
endif()
target_include_directories(ce-dat-tool PRIVATE "src")
target_include_directories(ce-dat-tool PRIVATE ${ZLIB_INCLUDE_DIRS})
target_include_directories(ce-dat-tool PRIVATE ${SDL2_INCLUDE_DIRS})
add_executable(ce-frm2png
"tools/ce_frm2png.cc"
"src/platform_compat.cc"
"third_party/lodepng/lodepng.cpp"
)
if(APPLE)
set_target_properties(ce-frm2png PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
)
endif()
target_include_directories(ce-frm2png PRIVATE "src")
target_include_directories(ce-frm2png PRIVATE "third_party/lodepng")
target_include_directories(ce-frm2png PRIVATE ${SDL2_INCLUDE_DIRS})
target_include_directories(ce-frm2png PRIVATE ${ZLIB_INCLUDE_DIRS})
target_link_libraries(ce-frm2png ${SDL2_LIBRARIES})
target_link_libraries(ce-frm2png ${ZLIB_LIBRARIES})
if(APPLE)
file(GLOB_RECURSE CE_DAT_INPUTS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/files/ce.dat/*")
set(CE_DAT_RESOURCE_PATH "${CMAKE_CURRENT_BINARY_DIR}/ce.dat")
add_custom_command(
OUTPUT "${CE_DAT_RESOURCE_PATH}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND $<TARGET_FILE:ce-dat-tool> create "${CMAKE_SOURCE_DIR}/files/ce.dat" "${CE_DAT_RESOURCE_PATH}"
DEPENDS ce-dat-tool ${CE_DAT_INPUTS}
COMMENT "Generating ce.dat for app bundle"
VERBATIM
)
add_custom_target(ce-dat-resource DEPENDS "${CE_DAT_RESOURCE_PATH}")
add_dependencies(${EXECUTABLE_NAME} ce-dat-resource)
target_sources(${EXECUTABLE_NAME} PRIVATE "${CE_DAT_RESOURCE_PATH}")
set_source_files_properties("${CE_DAT_RESOURCE_PATH}" PROPERTIES
GENERATED TRUE
MACOSX_PACKAGE_LOCATION "Resources")
endif()
target_include_directories(fallout2-dat PRIVATE "src")
target_include_directories(fallout2-dat PRIVATE ${ZLIB_INCLUDE_DIRS})
target_include_directories(fallout2-dat PRIVATE ${SDL2_INCLUDE_DIRS})
endif()
if(APPLE)
+37 -8
View File
@@ -55,23 +55,52 @@ TODO: add Visual Studio build instructions. This will likely need a Visual Studi
There is a small command-line archive tool in this repo for inspecting Fallout `.dat` files. It supports both Fallout 2 and Fallout 1 archives.
From the repo root, build it with your normal CMake workflow, targeting `fallout2-dat`:
From the repo root, build it with your normal CMake workflow, targeting `ce-dat-tool`:
`cmake --build out/build/<preset-name> --target fallout2-dat`
`cmake --build out/build/<preset-name> --target ce-dat-tool`
The executable is written to your selected build directory, so the exact path will vary by preset and configuration.
The current tool is read-only. Available commands:
Available commands:
1. `./<BUILD_DIR>/fallout2-dat <archive.dat> list [pattern]`
2. `./<BUILD_DIR>/fallout2-dat <archive.dat> info [pattern]`
3. `./<BUILD_DIR>/fallout2-dat <archive.dat> extract [--lower] <output-dir> [pattern]`
4. `./<BUILD_DIR>/fallout2-dat <archive.dat> cat <entry>`
1. `./<BUILD_DIR>/ce-dat-tool <archive.dat> list [pattern]`
2. `ce-dat-tool <archive.dat> info [pattern]`
3. `ce-dat-tool <archive.dat> extract [--lower] <output-dir> [pattern]`
4. `ce-dat-tool <archive.dat> cat <entry>`
5. `ce-dat-tool create <input-dir> <archive.dat>`
Use `--lower` with `extract` when you want every extracted file and directory name forced to lowercase.
For example:
`fallout2-dat master.dat extract --lower /tmp/fallout2-dat-lower data\\*`
`ce-dat-tool master.dat extract --lower /tmp/ce-dat-tool-lower data\\*`
## `ce-frm2png` CLI Tool
There is also a small FRM conversion tool in this repo for exporting Fallout `.frm` art to `.png`.
From the repo root, build it with your normal CMake workflow, targeting `ce-frm2png`:
`cmake --build out/build/<preset-name> --target ce-frm2png`
The executable is written to your selected build directory, so the exact path will vary by preset and configuration.
Basic usage:
1. `./<BUILD_DIR>/ce-frm2png <input.frm> [output.png]`
2. `./<BUILD_DIR>/ce-frm2png <input.frm> [output.png] --palette <path-to-color.pal>`
3. `./<BUILD_DIR>/ce-frm2png <input.frm> [output.png] --frame <index> --direction <index>`
4. `./<BUILD_DIR>/ce-frm2png - [output.png|-] --palette <path-to-color.pal>`
`-` can be used to take input from stdin (e.g. from `ce-dat-tool cat` or write to stdout).
If `--palette` isn't specified, it will pick up `color.pal` in the .frm's directory or cwd.
Notes:
- The tool expects a raw `color.pal` file. It does not read palettes directly from `master.dat`, so extract `color.pal` first if needed.
- A typical extraction flow is: `ce-dat-tool master.dat extract --lower . 'color.pal'`
- By default palette index `0` becomes transparent in the output PNG. Pass `--opaque` to keep it opaque.
- The current implementation writes RGBA PNGs. It does not preserve the original Fallout palette indices as a palette-indexed PNG.
## Updating SDL
+41 -22
View File
@@ -1,20 +1,22 @@
# Fallout 2 Community Edition
# Fallout 2 Community Engine
Fallout 2 Community Edition is a fully working re-implementation of Fallout 2, with the same original gameplay, engine bugfixes, and some quality of life improvements, that works (mostly) hassle-free on multiple platforms. This is a fork of the original project, which isn't getting regular updates.
Fallout 2 Community Engine is a fully working re-implementation of the Fallout 2 engine, optimized for a hassle-free experience on multiple platforms. It provides high resolution support, quality-of-life improvements, and dozens of bug fixes.
This is a fork of the original Fallout2: CE project, which is no longer getting regular updates.
Popular Fallout 2 total conversion mods are partially supported. Original versions of Nevada and Sonora (that do not rely on extended features provided by Sfall) work. [Fallout 2 Restoration Project](https://github.com/BGforgeNet/Fallout2_Restoration_Project) is supported (in Beta). [Fallout Et Tu](https://github.com/rotators/Fo1in2) and [Olympus 2207](https://olympus2207.com) are not yet supported. Other mods (particularly Resurrection and Yesterday) are not tested.
There is also [Fallout Community Edition](https://github.com/alexbatalov/fallout1-ce) (not affiliated with this fork).
Fallout2: CE has broad (though not total) compatibility with [Sfall](https://github.com/sfall-team/sfall) scripting extensions. Many traditional Fallout mods work out of the box.
For build and contributor notes, see [CONTRIBUTING.md](CONTRIBUTING.md).
There is also [Fallout 1 Community Edition](https://github.com/alexbatalov/fallout1-ce) (not affiliated with this fork).
## Installation
You must own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2), [Epic Games](https://store.epicgames.com/p/fallout-2) or [Steam](https://store.steampowered.com/app/38410). Download latest [release](https://github.com/fallout2-ce/fallout2-ce/releases) or build from source.
You *must* own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2), [Epic Games](https://store.epicgames.com/p/fallout-2) or [Steam](https://store.steampowered.com/app/38410). Download latest [release](https://github.com/fallout2-ce/fallout2-ce/releases) or build from source.
### Windows
Download and copy `fallout2-ce.exe` to your `Fallout2` folder. It serves as a drop-in replacement for `fallout2.exe`.
[Download](https://github.com/fallout2-ce/fallout2-ce/releases) and unzip into your `Fallout2` folder. Launch the game using `fallout2-ce.exe`.
### Linux
@@ -27,7 +29,7 @@ $ sudo apt install innoextract
$ innoextract ~/Downloads/setup_fallout_2_1.02_gog_v1_\(77792\).exe -d Fallout2
```
- Download the Linux release archive, extract `fallout2-ce`, and copy it into this folder.
- Download the Linux release archive, extract `fallout2-ce` and `ce.dat`, and copy them into this folder.
- Run `./fallout2-ce`.
@@ -61,9 +63,11 @@ $ mv fallout2 /Applications/Fallout2
> **NOTE**: From Android standpoint release and debug builds are different apps. Both apps require their own copy of game assets and have their own savegames. This is intentional. As a gamer just stick with release version and check for updates.
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder. Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
- Download the Android [release](https://github.com/fallout2-ce/fallout2-ce/releases), which contains an .apk file and `ce.dat`.
- Download `fallout2-ce.apk` and copy it to your device. Open it with file explorer, follow instructions (install from unknown source).
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder. Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)). Copy `ce.dat` into this folder.
- Copy `fallout2-ce.apk` from the release to your device. Open it with file explorer, follow instructions (install from unknown source).
- When you run the game for the first time it will immediately present file picker. Select the folder from the first step. Wait until this data is copied. A loading dialog will appear, just wait for about 30 seconds. If you're installing total conversion mod or localized version with a large number of unpacked resources in `data` folder it can take up to 20 minutes. Once copied, the game will start automatically.
@@ -75,7 +79,21 @@ $ mv fallout2 /Applications/Fallout2
- Run the game once. You'll see error message saying "Couldn't find/load text fonts". This step is needed for iOS to expose the game via File Sharing feature.
- Use Finder (macOS Catalina and later) or iTunes (Windows and macOS Mojave or earlier) to copy `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder to "Fallout 2" app ([how-to](https://support.apple.com/HT210598)). Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
- Use Finder (macOS Catalina and later) or iTunes (Windows and macOS Mojave or earlier) to copy `master.dat`, `critter.dat`, `patch000.dat`, `ce.dat`, and `data` folder to "Fallout 2" app ([how-to](https://support.apple.com/HT210598)). Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
-
**Controls on iPad:**
- One-finger tap → left click; hold → left button held.
- Two-finger tap → right click (cycles cursor mode between walk and attack).
- One-finger drag → scroll map / windows.
- Two-finger drag → mouse wheel.
- **Three-finger swipe down → ESC** (opens options / main menu).
- **Four-finger long press → F6** (quicksave). Hold four fingers on the screen for about half a second.
- **Three-finger long press → hold Shift** (highlights interactable objects — containers, doors, items — while held).
- Taps on the HUD (interface bar / end-turn / end-combat buttons) act as direct touches so small buttons are easy to hit without aiming.
- A Bluetooth keyboard works for everything else (numbered dialog choices, load game, etc.).
### Browser
@@ -93,7 +111,7 @@ The `sound` folder (with `music` folder inside) might be located either in `data
Additional settings for screen resolution, UI customization, and map options are now integrated into the main `fallout2.cfg` file (previously part of `f2_res.ini` from Mash's HRP). When Fallout 2 CE starts, if it detects an existing `f2_res.ini` file, it automatically migrates these settings into `fallout2.cfg`. After migration, `fallout2.cfg` becomes the single source of truth for this configuration.
The following settings can be configured in `fallout2.cfg` under the `[screen]` and `[ui]` sections:
Here are some important settings in `fallout2.cfg` under the `[screen]` and `[ui]` sections. See [the example config](https://github.com/fallout2-ce/fallout2-ce/tree/refs/heads/main/files/fallout2.cfg) for a full list of settings.
```ini
[screen]
@@ -103,12 +121,12 @@ windowed=1 ; 0 = fullscreen
scale=2 ; 1 = original scale, 2 = 2x scale, etc. (e.g. at scale 2 and screen resolution 1920x1080, in-game resolution will be 960x540, thus every pixel is twice as wide and tall)
[ui]
iface_bar_mode=0 ; 0 = interface bar below game window, 1 = interface bar overlaps game window
iface_bar_width=800 ; Width of interface bar (640 = original, 800 = extended)
iface_bar_side_art=2 ; Interface bar side art style (0=black, 1=metal grey, 2=leather, 3-8=alternative styles)
iface_bar_sides_ori=0 ; Side graphics orientation (0=extend from bar to edges, 1=extend from edges to bar)
;Set to 1 to expand the barter/trade window vertically, adding a 4th item slot per side (requires ce.dat)
expand_barter_window=1
;Maximum number of columns shown in the main inventory and loot/steal windows (valid range: 1..2)
inventory_columns=2
splash_screen_size=1 ; Splash screen scaling (0=original size, 1=fit preserving aspect, 2=stretch to fill)
ignore_map_edges=0 ; Hi-res map scroll edges (0=enabled, 1=ignored)
quick_toolbar_visible=0 ; Skills quick access toolbar visibility (iOS only) (0=hidden, 1=visible)
```
**Recommendations:**
@@ -119,23 +137,24 @@ ignore_map_edges=0 ; Hi-res map scroll edges (0=enabled, 1=ignored)
In time this stuff will receive in-game interface, right now you have to do it manually. To see all currently working fallout2.cfg settings, just run the game once and quit. It will be automatically updated with defaults for every supported setting.
*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 settings can be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/main/files/f2_res.dat)
The second 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
* Expanded 2-column inventory
* Expanded 4-row barter screen
* Expanded AP bar
* 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)
* Music continues playing between maps
* Auto open doors
## Contributing
For build instructions and contributor notes, see [CONTRIBUTING.md](CONTRIBUTING.md).
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
For current sfall compatibility status and the remaining work needed to close gaps, see [SFALL_COMPATIBILITY.md](SFALL_COMPATIBILITY.md).
+6 -6
View File
@@ -43,7 +43,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
| Combat / Knockback | set_weapon_knockback<br>set_target_knockback<br>set_attacker_knockback<br>remove_weapon_knockback<br>remove_target_knockback<br>remove_attacker_knockback | not implemented | - |
| Maps and encounters | in_world_map<br>force_encounter<br>force_encounter_with_flags<br>set_map_time_multi<br>get/set_map_enter_position<br>exec_map_update_scripts<br>get/set_terrain_name<br>set_town_title<br>get/set_can_rest_on_map<br>set_rest_heal_time<br>set_rest_mode<br>set_worldmap_heal_time | implemented: in_world_map, force_encounter, force_encounter_with_flags, set_map_time_multi | - |
| Maps and encounters / Worldmap | get_world_map_x/y_pos<br>set_world_map_pos | âś… | - |
| Audio | eax_available<br>set_eax_environment<br>play_sfall_sound<br>stop_sfall_sound | not implemented | *eax* opcodes will not be implemented |
| Audio | play_sfall_sound<br>stop_sfall_sound | âś… | `play_sfall_sound` currently supports `.acm`, `.wav`, `.ogg` formats, and can load from `.dat` archives. `.mp3` is not yet supported. |
| Combat / Weapons and ammo | get/set_weapon_ammo_pid<br>get/set_weapon_ammo_count | âś… | - |
| Sfall / Version | sfall_ver_major<br>sfall_ver_minor<br>sfall_ver_build | âś… | CE currently reports `4.3.4` |
| Utility / Math | log, exponent, round, sqrt, abs, sin, cos, tan, arctan, ceil, ^, floor2, div | âś… | - |
@@ -58,7 +58,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
| Interface / Tags | show_iface_tag<br>hide_iface_tag<br>is_iface_tag_active<br>set_iface_tag_text<br>add_iface_tag | âś… except set_iface_tag_text, add_iface_tag | CE only handles built-in interface tags here; custom tag creation/text is not supported yet. |
| Global variables | set_sfall_global<br>get_sfall_global_int<br>get_sfall_global_float | âś… except get_sfall_global_float | Current CE storage is int-backed; `set_sfall_global` stores integer values |
| Hooks / Hook functions | init_hook<br>get_sfall_arg<br>get_sfall_args<br>get_sfall_arg_at<br>set_sfall_return<br>set_sfall_arg<br>register_hook<br>register_hook_proc<br>register_hook_proc_spec | âś… | See below for implemented hooks. `init_hook` is deprecated and will not be implemented. register_hook_proc and register_hook_proc_spec both add hooks to the *end* of the hook list, instead of beginning and end, respectively. |
| Arrays / Array functions | create_array<br>temp_array<br>fix_array<br>get/set_array<br>resize_array<br>free_array<br>scan_array<br>len_array<br>save/load_array<br>array_key<br>arrayexpr | âś… except save_array, load_array | - |
| Arrays / Array functions | create_array<br>temp_array<br>fix_array<br>get/set_array<br>resize_array<br>free_array<br>scan_array<br>len_array<br>save/load_array<br>array_key<br>arrayexpr | âś… | - |
| Perks and traits / NPC perks | set_fake_perk_npc<br>set_fake_trait_npc<br>set_selectable_perk_npc<br>has_fake_perk_npc<br>has_fake_trait_npc | not implemented | - |
| Global scripts / Global script functions | set_global_script_repeat<br>set_global_script_type<br>available_global_script_types | âś… except available_global_script_types | - |
| Combat | attack_is_aimed<br>block_combat<br>force_aimed_shots<br>disable_aimed_shots<br>get_attack_type<br>get/set_bodypart_hit_modifier<br>combat_data<br>get/set/reset_critical_table<br>get_last_target<br>get_last_attacker<br>set_critter_burst_disable<br>get/set_critter_current_ap<br>set_spray_settings<br>get/set_combat_free_move | implemented: get_attack_type, get/set_bodypart_hit_modifier, combat_data, get/set_critter_current_ap, get/set_combat_free_move | - |
@@ -81,7 +81,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
| Hook | ID | Compatibility | Notes |
| --- | --- | --- | --- |
| ToHit | `HOOK_TOHIT` | âś… | - |
| AfterHitRoll | `HOOK_AFTERHITROLL` | đźš« | Et tu |
| AfterHitRoll | `HOOK_AFTERHITROLL` | âś… | Overriding `defender` leaves a lot of attack variables in previous state (e.g. distance, ->oops, roundsHitMainTarget) |
| CalcAPCost | `HOOK_CALCAPCOST` | âś… | - |
| DeathAnim1 | `HOOK_DEATHANIM1` | đźš« | Use DEATHANIM2 instead |
| DeathAnim2 | `HOOK_DEATHANIM2` | âś… | - |
@@ -94,7 +94,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
| BarterPrice | `HOOK_BARTERPRICE` | âś… | - |
| MoveCost | `HOOK_MOVECOST` | đźš« | - |
| ItemDamage | `HOOK_ITEMDAMAGE` | đźš« | - |
| AmmoCost | `HOOK_AMMOCOST` | đźš« | Et tu |
| AmmoCost | `HOOK_AMMOCOST` | âś… | Requires `check_weapon_ammo_cost=1` if you want pre-attack ammo validation to respect per-shot/per-round overrides. |
| KeyPress | `HOOK_KEYPRESS` | âś… | Third hook arg is currently `0`; CE doesn't use VK codes. |
| MouseClick | `HOOK_MOUSECLICK` | âś… | - |
| UseSkill | `HOOK_USESKILL` | đźš« | - |
@@ -108,10 +108,10 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
| StdProcedureEnd | `HOOK_STDPROCEDURE_END` | âś… | - |
| CarTravel | `HOOK_CARTRAVEL` | đźš« | - |
| SetGlobalVar | `HOOK_SETGLOBALVAR` | đźš« | - |
| RestTimer | `HOOK_RESTTIMER` | đźš« | Et tu |
| RestTimer | `HOOK_RESTTIMER` | âś… | CE is slightly more strict: only `ret0 == 1` interrupts. Ticks wrap every 6.8y; do not rely on them for absolute game time. |
| GameModeChange | `HOOK_GAMEMODECHANGE` | âś… | - |
| UseAnimObj | `HOOK_USEANIMOBJ` | đźš« | Et tu; (maybe) |
| ExplosiveTimer | `HOOK_EXPLOSIVETIMER` | đźš« | - |
| ExplosiveTimer | `HOOK_EXPLOSIVETIMER` | âś… | - |
| DescriptionObj | `HOOK_DESCRIPTIONOBJ` | đźš« | Et tu |
| UseSkillOn | `HOOK_USESKILLON` | đźš« | Et tu |
| OnExplosion | `HOOK_ONEXPLOSION` | đźš« | (maybe) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -74,6 +74,9 @@ bonus_hth_damage_fix=1
remove_critical_time_limits=0
; Set to 1 to allow science and repair to be used on the player, or 2 for all critters (rather than only brahmin/robots).
science_on_critters=0
; Set to 1 to make pre-attack ammo checks respect weapon ammo cost and HOOK_AMMOCOST type 1 overrides.
; Set to 0 to preserve vanilla behavior where one loaded round is enough to attempt the attack.
check_weapon_ammo_cost=1
; Set to 1 to enable modified burst bullet distribution (spray mod).
burst_enabled=0
; Ratio of bullets going to the center group vs. left/right in burst attacks. Multiplier is capped at divisor.
+7
View File
@@ -98,6 +98,8 @@ display_karma_changes=0
enable_high_resolution_stencil=1
;Set to 1 to extend the action points bar to show up to 16 AP instead of 10 (requires iface_apbar_e.frm)
extend_ap_bar=0
;Set to 1 to expand the barter/trade window vertically, adding a 4th item slot per side (requires barter_e.frm, trade_e.frm, and a screen height of at least 528 pixels)
expand_barter_window=0
iface_bar_mode=0
iface_bar_side_art=2
iface_bar_sides_ori=0
@@ -109,9 +111,14 @@ numbers_in_dialogue=0
;Set to 2 to also skip the splash screen
skip_opening_movies=0
splash_screen_size=1
;Maximum number of columns shown in the main inventory and loot/steal windows (valid range: 1..2)
;2-column Loot/steal window requires minimum screen width of 673px
inventory_columns=2
[qol]
; Automatically open doors that are unlocked and has no script attached.
auto_open_doors=0
; Overrides distance at which walk animation is used when using an object.
use_walk_distance=5
; Allow switching to companions' inventories in loot screens (and barter, in the future)
party_loot_and_barter=1
+3 -6
View File
@@ -4,7 +4,7 @@
#define ARRAY_MAX_STRING (255)
#define ARRAY_MAX_STRING (1024)
#define ARRAY_MAX_SIZE (100000)
procedure array_test_suite begin
@@ -82,8 +82,8 @@ procedure array_test_suite begin
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.";
for (i := 0; i < ARRAY_MAX_STRING+1; i+=100) begin
s += "Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.Verbosity.";
end
arr[0] := s;
call assertEquals("array max string", strlen(arr[0]), ARRAY_MAX_STRING-1);
@@ -141,8 +141,6 @@ procedure array_test_suite begin
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};
@@ -163,7 +161,6 @@ procedure array_test_suite begin
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("Testing nested expressions...");
arr := [["one", "two"]];
+78
View File
@@ -0,0 +1,78 @@
#include "sfall.h"
#include "dik.h"
variable loop_sound_id := 0;
variable quiet_loop_sound_id := 0;
variable music_sound_id := 0;
procedure stop_if_active(variable sound_id, variable label) begin
if (sound_id != 0) then begin
stop_sfall_sound(sound_id);
display_msg(label + " stopped");
end else begin
display_msg(label + " is not active");
end
end
procedure keypress_handler begin
variable pressed := get_sfall_arg_at(0);
variable key := get_sfall_arg_at(1);
variable ignored;
if (not pressed) then return;
if (key == DIK_K) then begin
display_msg("play_sfall_sound mode 0 one-shot: sound\\sfx\\pistol.ACM");
ignored := play_sfall_sound("sound\\sfx\\pistol.ACM", 0);
end else if (key == DIK_N) then begin
if (loop_sound_id != 0) then begin
display_msg(string_format1("loop already active id=%d", loop_sound_id));
return;
end
loop_sound_id := play_sfall_sound("sound\\music\\20CAR.ACM", 1);
display_msg(string_format1("mode 1 loop id=%d", loop_sound_id));
end else if (key == DIK_M) then begin
call stop_if_active(loop_sound_id, "mode 1 loop");
loop_sound_id := 0;
end else if (key == DIK_C) then begin
if (quiet_loop_sound_id != 0) then begin
display_msg(string_format1("quiet loop already active id=%d", quiet_loop_sound_id));
return;
end
quiet_loop_sound_id := play_sfall_sound("sound\\music\\20CAR.ACM", 0x30000001);
display_msg(string_format1("quiet mode 1 loop id=%d", quiet_loop_sound_id));
end else if (key == DIK_X) then begin
call stop_if_active(quiet_loop_sound_id, "quiet mode 1 loop");
quiet_loop_sound_id := 0;
end else if (key == DIK_G) then begin
if (music_sound_id != 0) then begin
display_msg(string_format1("mode 2 music replacement already active id=%d", music_sound_id));
return;
end
music_sound_id := play_sfall_sound("sound\\music\\20CAR.ACM", 2);
display_msg(string_format1("mode 2 music replacement id=%d", music_sound_id));
end else if (key == DIK_H) then begin
call stop_if_active(music_sound_id, "mode 2 music replacement");
music_sound_id := 0;
end else if (key == DIK_V) then begin
display_msg("play_sfall_sound mode 3 speech-volume one-shot: sound\\sfx\\pistol.ACM");
ignored := play_sfall_sound("sound\\sfx\\pistol.ACM", 3);
end else if (key == DIK_B) then begin
display_msg("play_sfall_sound mode 0 one-shot wav: smw_1-up.wav"); // needs a wav file in the game dir
ignored := play_sfall_sound("smw_1-up.wav", 0);
end
end
procedure start begin
if (not game_loaded) then return;
display_msg("sfall_sound manual test ready");
display_msg("One-shots use master.dat SFX and loose-file wav; loops/replacement use music");
display_msg("K one-shot ACM mode0, B one-shot WAV mode0, N start loop mode1, M stop loop");
display_msg("C start quiet loop mode1, X stop quiet loop");
display_msg("G start mode2 music replacement, H stop mode2 replacement, V mode3 one-shot");
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
end
+74
View File
@@ -0,0 +1,74 @@
#include "sfall.h"
#include "dik.h"
#include "define_lite.h"
#include "define_extra.h"
#include "lib.arrays.h"
variable afterhitroll_mode := 0;
procedure afterhitroll_mode_name begin
if (afterhitroll_mode == 1) then return "force_hit";
if (afterhitroll_mode == 2) then return "force_eyes";
if (afterhitroll_mode == 3) then return "retarget_self";
return "log_only";
end
procedure afterhitroll_handler begin
variable
args := get_sfall_args,
roll := args[0],
attacker := args[1],
target := args[2],
bodypart := args[3],
hitChance := args[4],
attackerName := "<null>",
targetName := "<null>";
if (attacker) then attackerName := obj_name(attacker);
if (target) then targetName := obj_name(target);
display_msg(string_format("afterhitroll mode=%s roll=%d chance=%d %s -> %s body=%d",
afterhitroll_mode_name,
roll,
hitChance,
attackerName,
targetName,
bodypart));
if (attacker != dude_obj) then return;
if (afterhitroll_mode == 1) then begin
set_sfall_return(ROLL_SUCCESS);
end else if (afterhitroll_mode == 2) then begin
set_sfall_return(roll);
set_sfall_return(BODY_HIT_EYES);
end else if (afterhitroll_mode == 3) then begin
set_sfall_return(ROLL_SUCCESS);
set_sfall_return(BODY_HIT_TORSO);
set_sfall_return(dude_obj);
end
end
procedure keypress_handler begin
variable
pressed := get_sfall_arg_at(0),
key := get_sfall_arg_at(1);
if (not pressed) then return;
if (key != DIK_J) then return;
afterhitroll_mode := afterhitroll_mode + 1;
if (afterhitroll_mode > 3) then afterhitroll_mode := 0;
display_msg(string_format1("afterhitroll mode -> %s", afterhitroll_mode_name));
end
procedure start begin
if (not game_loaded) then return;
display_msg("afterhitroll manual test ready: press J to cycle log_only / force_hit / force_eyes / retarget_self");
display_msg("attack something in combat and watch hook logs plus the overridden result");
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
register_hook_proc(HOOK_AFTERHITROLL, afterhitroll_handler);
end
+78
View File
@@ -0,0 +1,78 @@
#include "sfall.h"
#include "dik.h"
#include "lib.arrays.h"
#include "lib.obj.h"
variable ammocost_mode := 0;
procedure ammocost_mode_name begin
if (ammocost_mode == 1) then return "double-single";
if (ammocost_mode == 2) then return "burst-x2";
if (ammocost_mode == 3) then return "free";
return "engine";
end
procedure ammocost_item_name(variable item) begin
if (item == 0) then return "<null>";
return obj_name(item);
end
procedure ammocost_handler begin
variable
args := get_sfall_args,
weapon := args[0],
rounds := args[1],
defaultCost := args[2],
hookType := args[3],
weaponPid := 0;
if (weapon) then weaponPid := obj_pid(weapon);
display_msg(string_format6("ammocost mode=%s type=%d rounds=%d default=%d weapon=%s pid=%d",
ammocost_mode_name,
hookType,
rounds,
defaultCost,
ammocost_item_name(weapon),
weaponPid));
if (ammocost_mode == 1) then begin
if (hookType == 0 or hookType == 1) then
set_sfall_return(defaultCost + 1);
end
if (ammocost_mode == 2) then begin
if (hookType == 1 or hookType == 3) then
set_sfall_return(rounds * 2);
if (hookType == 2) then
set_sfall_return(2);
end
if (ammocost_mode == 3) then
set_sfall_return(0);
end
procedure keypress_handler begin
variable
pressed := get_sfall_arg_at(0),
key := get_sfall_arg_at(1);
if (not pressed) then return;
if (key != DIK_H) then return;
ammocost_mode := ammocost_mode + 1;
if (ammocost_mode > 3) then ammocost_mode := 0;
display_msg(string_format1("ammocost mode -> %s", ammocost_mode_name));
intface_redraw;
end
procedure start begin
if (not game_loaded) then return;
display_msg("ammocost manual test ready: press H to cycle engine/double-single/burst-x2/free");
display_msg("check single-shot ammo use, burst ammo use, and pre-attack ammo validation with CheckWeaponAmmoCost");
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
register_hook_proc(HOOK_AMMOCOST, ammocost_handler);
end

Some files were not shown because too many files have changed in this diff Show More