mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
219
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
342fbdd3ae | ||
|
|
0adc9c9e77 | ||
|
|
af413125bd | ||
|
|
ea0afc84fa | ||
|
|
c663d79b97 | ||
|
|
eaa9091bcd | ||
|
|
76ab99cf73 | ||
|
|
bed9555f9a | ||
|
|
9c5294ca88 | ||
|
|
781d8ab282 | ||
|
|
afd99fa01b | ||
|
|
34ef1c2f26 | ||
|
|
fdc54cfd0b | ||
|
|
3e469ea8e8 | ||
|
|
ddefda32e7 | ||
|
|
0334b8de05 | ||
|
|
1cab275037 | ||
|
|
7eb269bab8 | ||
|
|
c18d7ab25e | ||
|
|
59bf337583 | ||
|
|
88179574e8 | ||
|
|
0733acfad7 | ||
|
|
a63aff09ce | ||
|
|
1388ca1f83 | ||
|
|
3d2aced2f7 | ||
|
|
1d6111b89f | ||
|
|
21c906cc5c | ||
|
|
a67fe7ead1 | ||
|
|
f0691d2c24 | ||
|
|
fb30648e2e | ||
|
|
216cbb3861 | ||
|
|
be63df4bf6 | ||
|
|
4cf35fd946 | ||
|
|
dd418ee0f5 | ||
|
|
eb5cc7be4f | ||
|
|
8c6f28b018 | ||
|
|
2e36030389 | ||
|
|
a88ca9f7e7 | ||
|
|
72d9ae85c8 | ||
|
|
a8f2de1a56 | ||
|
|
51b82ac1ac | ||
|
|
0d97222797 | ||
|
|
b30463ab01 | ||
|
|
9d932b0d2c | ||
|
|
8d76b9655c | ||
|
|
0e6c4d9684 | ||
|
|
02c5efac26 | ||
|
|
b7933f6b80 | ||
|
|
fcb1680db2 | ||
|
|
ea4d978bc1 | ||
|
|
22548a3c70 | ||
|
|
7767aabdce | ||
|
|
9cb2b83db1 | ||
|
|
75ca12e07c | ||
|
|
f85e8ba67b | ||
|
|
07876ddaf9 | ||
|
|
7288f8eeb7 | ||
|
|
1a46d0f59f | ||
|
|
7c2dfa9af1 | ||
|
|
3dc89d49e2 | ||
|
|
822d5dfd7d | ||
|
|
879634bf9c | ||
|
|
d681e7be69 | ||
|
|
795ef54d70 | ||
|
|
14b06d2dcc | ||
|
|
ed959edbbb | ||
|
|
7940ea791c | ||
|
|
3f270aa4cc | ||
|
|
8294e15d3c | ||
|
|
4278d1a1d0 | ||
|
|
b8769fded1 | ||
|
|
43d5b6028d | ||
|
|
b2675ad1ac | ||
|
|
da3f1cc426 | ||
|
|
a892461dac | ||
|
|
209d2d027b | ||
|
|
b8385d7775 | ||
|
|
a3c365f9fe | ||
|
|
87d4a4b8ca | ||
|
|
1aa53a4720 | ||
|
|
6bcf2952f6 | ||
|
|
e2927e1d0e | ||
|
|
bb839cd6c1 | ||
|
|
caa0e1bf1a | ||
|
|
f3759d07a5 | ||
|
|
604fde895f | ||
|
|
f46c391e5d | ||
|
|
5dafa019c9 | ||
|
|
8888fc46d6 | ||
|
|
001bdbee5c | ||
|
|
1e45b0184b | ||
|
|
40471e5a0b | ||
|
|
ad776876a1 | ||
|
|
224f1088f2 | ||
|
|
05b692f403 | ||
|
|
190906bb5f | ||
|
|
447ea23862 | ||
|
|
41dd2ccd81 | ||
|
|
72786c4d43 | ||
|
|
04e93cabd7 | ||
|
|
a31af0671d | ||
|
|
72df28f53a | ||
|
|
7e3bd36f86 | ||
|
|
94ce0fbe11 | ||
|
|
a368f27ad4 | ||
|
|
d8d411e847 | ||
|
|
5eef9af7a9 | ||
|
|
0419efad8f | ||
|
|
21f432afbb | ||
|
|
aed05c0daf | ||
|
|
8a8b54d4b7 | ||
|
|
8ee543ec16 | ||
|
|
161bb82f30 | ||
|
|
22bd1ffbba | ||
|
|
f46f1c78d4 | ||
|
|
3d0e206825 | ||
|
|
47a9891e0e | ||
|
|
f1e5cde84f | ||
|
|
015909fdef | ||
|
|
1e91b401f1 | ||
|
|
29a0be50f4 | ||
|
|
9e3ce4cd8d | ||
|
|
592882b7b8 | ||
|
|
3d3e47c9db | ||
|
|
a9726cab56 | ||
|
|
400aa4d8a3 | ||
|
|
cbd7b45736 | ||
|
|
599d3ab392 | ||
|
|
84336d4655 | ||
|
|
220fb8e190 | ||
|
|
5a29fc1815 | ||
|
|
a083779fb2 | ||
|
|
95d254cd45 | ||
|
|
0d8f4cc711 | ||
|
|
aabc971dd5 | ||
|
|
696e926177 | ||
|
|
30babd7e1f | ||
|
|
6ff0b411e4 | ||
|
|
9f623f3f3e | ||
|
|
d8bee457f4 | ||
|
|
fcabd63561 | ||
|
|
73c024c705 | ||
|
|
27da084b65 | ||
|
|
dfa610f352 | ||
|
|
a0a597725a | ||
|
|
7ae194a8ee | ||
|
|
b069e3b941 | ||
|
|
823f72492f | ||
|
|
e5f3734e08 | ||
|
|
e37522d388 | ||
|
|
07a361f63a | ||
|
|
515bec4c82 | ||
|
|
42bfdc7343 | ||
|
|
0fd5e59575 | ||
|
|
0d0578f111 | ||
|
|
dacda99b98 | ||
|
|
dfb0463b02 | ||
|
|
1903e04c6e | ||
|
|
abec3681b0 | ||
|
|
7f7e103465 | ||
|
|
5a9f8fb46c | ||
|
|
721e40f784 | ||
|
|
3659c834ae | ||
|
|
196553ec46 | ||
|
|
57f1229a51 | ||
|
|
413c843ff5 | ||
|
|
995102d515 | ||
|
|
dd867446ea | ||
|
|
4f91e38cc0 | ||
|
|
016c83bc48 | ||
|
|
59c64451ff | ||
|
|
965f360578 | ||
|
|
3f79d79f25 | ||
|
|
cad023a73e | ||
|
|
7490c900b3 | ||
|
|
d8dc05597b | ||
|
|
7d9e1612c6 | ||
|
|
848bd97e42 | ||
|
|
5c5512277d | ||
|
|
016f853c0a | ||
|
|
9edbf0dd72 | ||
|
|
36af4b2ea8 | ||
|
|
67a6119f34 | ||
|
|
aa036c574e | ||
|
|
a17d7fb7d5 | ||
|
|
8ed777ba83 | ||
|
|
145cf6bbcc | ||
|
|
5b39307f61 | ||
|
|
547cabc42d | ||
|
|
d2a3d61dcb | ||
|
|
2d1966f0af | ||
|
|
a406c5f019 | ||
|
|
9ca540f05e | ||
|
|
4678e19edd | ||
|
|
485d2253f4 | ||
|
|
72309fc9dc | ||
|
|
fda6fd0646 | ||
|
|
2126e23161 | ||
|
|
0fa90a1a00 | ||
|
|
9bfc3e83cd | ||
|
|
2f974aefed | ||
|
|
b27093b7ac | ||
|
|
6f240acf0a | ||
|
|
7c182b66a6 | ||
|
|
f6320d3a66 | ||
|
|
5dbcfd997c | ||
|
|
ec2ecd17d9 | ||
|
|
de06827c01 | ||
|
|
e3437a8d0e | ||
|
|
f12babe525 | ||
|
|
cb990ac154 | ||
|
|
a3fc8d21be | ||
|
|
cc805db194 | ||
|
|
a3d37e11c1 | ||
|
|
0e18e77901 | ||
|
|
9d2db5b36a | ||
|
|
b88230426d | ||
|
|
bbf52f6b2d | ||
|
|
89a9d1ae12 |
@@ -0,0 +1,42 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ jobs:
|
||||
folder: fallout2-ce-ems/dist
|
||||
target-folder: ${{ steps.set-path.outputs.DEST_DIR }}
|
||||
clean: false
|
||||
single-commit: true
|
||||
|
||||
- name: Comment preview URL on PR
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: os/android/app/.cxx
|
||||
key: android-cmake-v2
|
||||
key: android-cmake-v100
|
||||
|
||||
- name: Setup signing config
|
||||
if: env.KEYSTORE_FILE_BASE64 != '' && env.KEYSTORE_PROPERTIES_FILE_BASE64 != ''
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: ios-cmake-v5
|
||||
key: ios-cmake-v100
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: linux-${{ matrix.arch }}-cmake-v3
|
||||
key: linux-${{ matrix.arch }}-cmake-v100
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -288,7 +288,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: macos-cmake-v6
|
||||
key: macos-cmake-v100
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -313,7 +313,7 @@ jobs:
|
||||
windows:
|
||||
name: Windows (${{ matrix.arch }})
|
||||
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2025
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -328,19 +328,28 @@ jobs:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Visual Studio 2019 Build Tools with v141_xp
|
||||
shell: cmd
|
||||
run: |
|
||||
choco install visualstudio2019buildtools -y --package-parameters="'--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.xp --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.10240 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP --add Microsoft.VisualStudio.Component.WinXP'"
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: out
|
||||
key: windows-${{ matrix.arch }}-cmake-v2
|
||||
key: windows-${{ matrix.arch }}-cmake-v100
|
||||
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --preset windows-${{ matrix.arch }}
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& cmake --preset windows-${{ matrix.arch }}
|
||||
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build --preset windows-${{ matrix.arch }}-release
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& cmake --build --preset windows-${{ matrix.arch }}-release
|
||||
|
||||
- name: Change executable file name
|
||||
run: |
|
||||
|
||||
@@ -29,5 +29,18 @@ jobs:
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git commit -am "đźš® Remove preview for closed PR #${{ github.event.pull_request.number }}"
|
||||
git push
|
||||
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
echo "Current branch: $CURRENT_BRANCH"
|
||||
|
||||
if [ "$CURRENT_BRANCH" != "gh-pages" ]; then
|
||||
echo "❌ Refusing to force-push to non-gh-pages branch: $CURRENT_BRANCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit --amend -m "đźš® Remove preview for closed PR #${{ github.event.pull_request.number }}"
|
||||
git push --force
|
||||
fi
|
||||
@@ -243,7 +243,7 @@ jobs:
|
||||
windows:
|
||||
name: Windows (${{ matrix.arch }})
|
||||
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2025
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -258,6 +258,11 @@ jobs:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Visual Studio 2019 Build Tools with v141_xp
|
||||
shell: cmd
|
||||
run: |
|
||||
choco install visualstudio2019buildtools -y --package-parameters="'--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.xp --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.10240 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP --add Microsoft.VisualStudio.Component.WinXP'"
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
@@ -265,19 +270,16 @@ jobs:
|
||||
key: windows-${{ matrix.arch }}-cmake-v1
|
||||
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake \
|
||||
-B build \
|
||||
-G "Visual Studio 16 2019" \
|
||||
-A ${{ matrix.generator-platform }} \
|
||||
# EOL
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& cmake -B build -G "Visual Studio 16 2019" -A ${{ matrix.generator-platform }}
|
||||
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake \
|
||||
--build build \
|
||||
--config RelWithDebInfo \
|
||||
# EOL
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& cmake --build build --config RelWithDebInfo
|
||||
|
||||
- name: Upload
|
||||
run: |
|
||||
|
||||
@@ -290,6 +290,7 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/sfall_arrays.h"
|
||||
"src/touch.cc"
|
||||
"src/touch.h"
|
||||
"src/scan_unimplemented.cc"
|
||||
)
|
||||
|
||||
if(IOS)
|
||||
|
||||
@@ -96,16 +96,32 @@ 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).
|
||||
Additionally, the [graphics] section provides options for fine tuning the appearence of the game. The included settings are:
|
||||
|
||||
```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.
|
||||
```
|
||||
[graphics]
|
||||
fullscreen=0 ; 1 = fullscreeen, 0 = windowed
|
||||
game_height=480 ; main play area height
|
||||
game_width=640 ; main play area width
|
||||
scale2x=0 ; 0 = original scale, 1 = 2x - requires increasing the minimum resolution from 640x480 to 1280x960.
|
||||
splash_size=0 ; 0 = normal, 1 = aspect stretch, 2 = fullscreen stretch
|
||||
```
|
||||
|
||||
[IFACE]
|
||||
Recommendations:
|
||||
- **Desktops**: Use any size you see fit.
|
||||
- **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 graphcs settings will receive an in-game interface. For the time being it must be configured manually.
|
||||
|
||||
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)
|
||||
|
||||
Further, Fallout2-CE supports the following additional settings in ddraw.ini:
|
||||
|
||||
```
|
||||
[Misc]
|
||||
; 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
|
||||
@@ -125,21 +141,21 @@ 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_WIDTH=640
|
||||
```
|
||||
|
||||
Recommendations:
|
||||
- **Desktops**: Use any size you see fit.
|
||||
- **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.
|
||||
*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 be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/mainmenu/files/f2_res.dat)
|
||||
|
||||
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)
|
||||
## Quality of life benefits over vanilla Fallout
|
||||
|
||||
*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)
|
||||
* Large game area support (through HiResMode=1 in ddraw.ini and game_height=480 and game_width=640 settings in fallout2.cfg)
|
||||
* 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)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
+29
-1
@@ -4,11 +4,39 @@
|
||||
[Main]
|
||||
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
;HiResMode=1
|
||||
;EnableHighResolutionStencil=1
|
||||
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Misc]
|
||||
|
||||
; 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=5
|
||||
|
||||
|
||||
;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=1
|
||||
|
||||
;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.
|
||||
IFACE_BAR_WIDTH=800
|
||||
|
||||
;Adds Fallout 1 style travel/trail dots
|
||||
WorldMapTravelMarkers=0
|
||||
|
||||
;Prevents pausing music between map areas with the same music
|
||||
GaplessMusic=0
|
||||
|
||||
;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
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/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'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
*.int
|
||||
@@ -0,0 +1,51 @@
|
||||
# Testing sFall scripting features
|
||||
|
||||
## Basic info
|
||||
|
||||
This folder contains scripts which can be used for sFall opcodes.
|
||||
|
||||
## Building
|
||||
|
||||
Get latest `compile.exe` from [modders pack](https://sourceforge.net/projects/sfall/files/Modders%20pack/) or from [repository](https://github.com/sfall-team/sslc) and run it this way:
|
||||
|
||||
```sh
|
||||
compile.exe -q -p -l -O2 -d -s -n -I<sfall_headers_id> <script_name.ssl>
|
||||
```
|
||||
|
||||
(sfall headers can be found in modderspack)
|
||||
|
||||
|
||||
### Build script using sFall Script Editor
|
||||
|
||||
- Get "Fallout sFall Script Editor v4.1.7.RC1", for example from https://nuclear-grot.ucoz.net/forum/12-20-1
|
||||
|
||||
- Run script editor, add "sfall_headers" into "Location folder of headers files" in the options
|
||||
|
||||
- Open any script here and compile it
|
||||
|
||||
- This shoud create compiled script <file.int>
|
||||
|
||||
|
||||
### Build script using VSCode extension
|
||||
|
||||
- Install [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=BGforge.bgforge-mls)
|
||||
|
||||
|
||||
|
||||
## Run test script
|
||||
|
||||
1. Move compiled `.int` file into game folder as `data/scripts/gl_<script_name>.int`
|
||||
|
||||
2. Change `ddraw.ini` and add this section:
|
||||
```ini
|
||||
[Scripts]
|
||||
GlobalScriptPaths=data/scripts/gl*.int
|
||||
```
|
||||
|
||||
(or add new path using comma as separator)
|
||||
|
||||
Note that on non-Windows it have to be `/` as folder separator
|
||||
|
||||
3. Run game, check that game displays message about tests
|
||||
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
#include "lib.arrays.h"
|
||||
#include "test_utils.h"
|
||||
// #include "define_lite.h"
|
||||
|
||||
|
||||
|
||||
#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.");
|
||||
|
||||
call report_test_results("arrays");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
procedure start begin
|
||||
display_msg("Starting tests");
|
||||
call array_test_suite();
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "lib.arrays.h" // For arrays_equal, len_array, etc.
|
||||
#include "test_utils.h" // For assertEquals, VALTYPE_STR, report_test_results
|
||||
|
||||
// To test: copy test.ini into the game folder before running
|
||||
procedure ini_test_suite begin
|
||||
variable result_array, expected_array, key_type, value_type, count, key_val_pair;
|
||||
|
||||
display_msg("--- Testing ini functions");
|
||||
|
||||
// Test Case 1: Valid file, valid section
|
||||
result_array := get_ini_section("test.ini", "ValidSection");
|
||||
expected_array := {"Key1": "Value1", "Key2": "2"};
|
||||
call assertEquals("TC1 Size", len_array(result_array), 2);
|
||||
call assertEquals("TC1 Content", arrays_equal(result_array, expected_array), true);
|
||||
count := 0;
|
||||
foreach key_val_pair in result_array begin
|
||||
count += 1;
|
||||
call assertEquals("TC1 Key Type " + count, typeof(key_val_pair[0]), VALTYPE_STR);
|
||||
call assertEquals("TC1 Value Type " + count, typeof(key_val_pair[1]), VALTYPE_STR);
|
||||
end
|
||||
|
||||
// basic fetchers
|
||||
call assertEquals("TC2 Specific Key1 Value", result_array["Key1"], "Value1");
|
||||
call assertEquals("TC2 get_ini_setting string", get_ini_setting("test.ini|ValidSection|Key1"), 0);
|
||||
call assertEquals("TC2 get_ini_string string", get_ini_string("test.ini|ValidSection|Key1"), "Value1");
|
||||
call assertEquals("TC2 get_ini_setting int", get_ini_setting("test.ini|ValidSection|Key2"), 2);
|
||||
call assertEquals("TC2 get_ini_string int", get_ini_string("test.ini|ValidSection|Key2"), "2");
|
||||
|
||||
// INI file not found
|
||||
result_array := get_ini_section("nonexistent.ini", "AnySection");
|
||||
call assertEquals("TC3 Size", len_array(result_array), 0);
|
||||
call assertEquals("TC3 Is Map", array_key(result_array, -1), 1); // Should still be an associative array
|
||||
call assertEquals("TC3 get_ini_setting", get_ini_setting("notexist.ini|ValidSection|Key2"), 0);
|
||||
call assertEquals("TC3 get_ini_string", get_ini_string("notexist.ini|ValidSection|Key2"), "");
|
||||
|
||||
// Valid file, section not found
|
||||
result_array := get_ini_section("test.ini", "NonExistentSection");
|
||||
call assertEquals("TC4 Size", len_array(result_array), 0);
|
||||
call assertEquals("TC4 Is Map", array_key(result_array, -1), 1);
|
||||
call assertEquals("TC4 get_ini_setting", get_ini_setting("test.ini|NonExistentSection|Key2"), 0);
|
||||
call assertEquals("TC4 get_ini_string", get_ini_string("test.ini|NonExistentSection|Key2"), "");
|
||||
|
||||
|
||||
// Valid file, empty section
|
||||
result_array := get_ini_section("test.ini", "EmptySection");
|
||||
call assertEquals("TC5 Size", len_array(result_array), 0);
|
||||
call assertEquals("TC5 Is Map", array_key(result_array, -1), 1);
|
||||
call assertEquals("TC5 get_ini_setting", get_ini_setting("test.ini|EmptySection|Key2"), 0);
|
||||
call assertEquals("TC5 get_ini_string", get_ini_string("test.ini|EmptySection|Key2"), "");
|
||||
|
||||
// set ini setting
|
||||
set_ini_setting("test_set.ini|ValidSection|Key3", "OldValue");
|
||||
call assertEquals("TC6 set_ini_setting 1", get_ini_string("test_set.ini|ValidSection|Key3"), "OldValue");
|
||||
set_ini_setting("test_set.ini|ValidSection|Key3", "NewValue");
|
||||
call assertEquals("TC6 set_ini_setting 2", get_ini_string("test_set.ini|ValidSection|Key3"), "NewValue");
|
||||
set_ini_setting("test_set.ini|ValidSection|Key3", 2);
|
||||
call assertEquals("TC6 set_ini_setting int", get_ini_setting("test_set.ini|ValidSection|Key3"), 2);
|
||||
|
||||
// get_init_sections
|
||||
result_array := get_ini_sections("test.ini");
|
||||
call assertEquals("TC7 get_ini_sections size", len_array(result_array), 3);
|
||||
call assertTrue("TC7 get_ini_sections", scan_array(result_array, "TestMisc") >= 0);
|
||||
|
||||
call report_test_results("ini");
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
call ini_test_suite();
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
|
||||
procedure start begin
|
||||
|
||||
display_msg("Testing math functions...");
|
||||
|
||||
call assertFloat("sin(0)", sin(0), 0.0);
|
||||
call assertFloat("sin(PI/2)", sin(1.5708), 1.0);
|
||||
call assertFloat("sin(PI)", sin(3.1416), 0.0);
|
||||
call assertFloat("sin(-PI/2)", sin(-1.5708), -1.0);
|
||||
|
||||
call assertFloat("cos(0)", cos(0), 1.0);
|
||||
call assertFloat("cos(PI/2)", cos(1.5708), 0.0);
|
||||
call assertFloat("cos(PI)", cos(3.1416), -1.0);
|
||||
call assertFloat("cos(-PI)", cos(-3.1416), -1.0);
|
||||
|
||||
call assertFloat("tan(0)", tan(0), 0.0);
|
||||
call assertFloat("tan(PI/4)", tan(0.7854), 1.0);
|
||||
call assertFloat("tan(-PI/4)", tan(-0.7854), -1.0);
|
||||
|
||||
call assertFloat("arctan(0, 1)", arctan(0, 1), 0.0);
|
||||
call assertFloat("arctan(1, 1)", arctan(1, 1), 0.7854);
|
||||
call assertFloat("arctan(-1, 1)", arctan(-1, 1), -0.7854);
|
||||
call assertFloat("arctan(1, 0)", arctan(1, 0), 1.5708);
|
||||
|
||||
call assertFloat("log(1)", log(1), 0.0);
|
||||
call assertFloat("log(e)", log(2.7183), 1.0);
|
||||
call assertFloat("log(10)", log(10), 2.3026);
|
||||
|
||||
call assertFloat("exponent(0)", exponent(0), 1.0);
|
||||
call assertFloat("exponent(1)", exponent(1), 2.7183);
|
||||
call assertFloat("exponent(2)", exponent(2), 7.3891);
|
||||
call assertFloat("exponent(-1)", exponent(-1), 0.3679);
|
||||
|
||||
call assertEquals("ceil(2.1)", ceil(2.1), 3);
|
||||
call assertEquals("ceil(2.0)", ceil(2.0), 2);
|
||||
call assertEquals("ceil(-2.1)", ceil(-2.1), -2);
|
||||
call assertEquals("ceil(-2.9)", ceil(-2.9), -2);
|
||||
|
||||
call assertEquals("floor2(2.1)", floor2(2.1), 2);
|
||||
call assertEquals("floor2(2.9)", floor2(2.9), 2);
|
||||
call assertEquals("floor2(-2.1)", floor2(-2.1), -3);
|
||||
call assertEquals("floor2(-2.9)", floor2(-2.9), -3);
|
||||
|
||||
call assertEquals("2^3", 2^3, 8);
|
||||
call assertEquals("4^2", 4^2, 16);
|
||||
call assertEquals("3^0", 3^0, 1);
|
||||
call assertFloat("2^-1", 2^-1, 0); // note: int truncation
|
||||
call assertFloat("2^-1", 2^-1.0, 0.5);
|
||||
call assertFloat("4^0.5", 4^0.5, 2.0);
|
||||
call assertFloat("8^(1/3)", 8^(1.0/3.0), 2.0);
|
||||
call assertFloat("2.5^2", 2.5^2, 6.25);
|
||||
|
||||
call assertEquals("round(2.3)", round(2.3), 2);
|
||||
call assertEquals("round(2.5)", round(2.5), 3);
|
||||
call assertEquals("round(2.7)", round(2.7), 3);
|
||||
call assertEquals("round(-2.3)", round(-2.3), -2);
|
||||
call assertEquals("round(-2.5)", round(-2.5), -3);
|
||||
call assertEquals("round(-2.7)", round(-2.7), -3);
|
||||
call assertEquals("round(0.0)", round(0.0), 0);
|
||||
call assertEquals("round(1.0)", round(1.0), 1);
|
||||
call assertEquals("round(<int>)", round(1), 1);
|
||||
|
||||
call assertFloat("sin(arctan(1, 1))", sin(arctan(1, 1)), 0.7071);
|
||||
call assertFloat("cos(arctan(1, 1))", cos(arctan(1, 1)), 0.7071);
|
||||
call assertFloat("log(ceil(2.7))", log(ceil(2.7)), 1.0986);
|
||||
call assertFloat("exponent(log(5))", exponent(log(5)), 5.0);
|
||||
|
||||
call report_test_results("math");
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
|
||||
procedure start begin
|
||||
// TODO: move this to a more suitable place, once we have more functions implemented
|
||||
// These are in the "Other" category in the sfall documentation
|
||||
display_msg("Testing misc functions...");
|
||||
variable hand := active_hand;
|
||||
toggle_active_hand;
|
||||
call assertEquals("active_hand toggled", active_hand, 1 - hand);
|
||||
toggle_active_hand;
|
||||
call assertEquals("active_hand toggled", active_hand, hand);
|
||||
|
||||
call report_test_results("misc");
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
|
||||
#define REPEAT_64 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
#define REPEAT_512 REPEAT_64 REPEAT_64 REPEAT_64 REPEAT_64 REPEAT_64 REPEAT_64 REPEAT_64 REPEAT_64
|
||||
#define REPEAT_1024 REPEAT_512 REPEAT_512
|
||||
|
||||
procedure start begin
|
||||
|
||||
display_msg("Testing sprintf...");
|
||||
|
||||
call assertEquals("sprintf hello world", sprintf("Hello %s", "World"), "Hello World");
|
||||
|
||||
call assertEquals("sprintf empty string", sprintf("", 123), "");
|
||||
|
||||
call assertEquals("sprintf number string", sprintf("%d", 123), "123");
|
||||
|
||||
call assertEquals("sprintf number inside string", sprintf("Hello %d !", 123), "Hello 123 !");
|
||||
|
||||
call assertEquals("sprintf ascii code", sprintf("Hello %c !", 123), "Hello { !");
|
||||
|
||||
call assertEquals("sprintf float string", sprintf("Hello %f !", 3.4), "Hello 3.400000 !");
|
||||
|
||||
call assertEquals("sprintf float string", sprintf("Hello %d !", 10/4), "Hello 2 !");
|
||||
|
||||
call assertEquals("sprintf two strings", sprintf("Hello %s %s", "World"), "Hello World World");
|
||||
|
||||
call assertEquals("Long string", sprintf(REPEAT_1024"x", 1), "Error");
|
||||
|
||||
call assertEquals("Not so long", sprintf(REPEAT_1024, 1), REPEAT_1024);
|
||||
|
||||
|
||||
call assertEquals("string_format1 hello world", string_format1("Hello %s!", "World"), "Hello World!");
|
||||
call assertEquals("string_format1 auto hello world", string_format("Hello %s!", "World"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format2 hello world", string_format2("Hello %s%s!", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format2 auto hello world", string_format("Hello %s%s!", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format3 hello world", string_format3("Hell%s %s%s!", "o", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format3 auto hello world", string_format("Hell%s %s%s!", "o", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format4 hello world", string_format4("Hel%s%s %s%s!", "l", "o", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format4 auto hello world", string_format("Hel%s%s %s%s!", "l", "o", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format5 hello world", string_format5("He%s%s%s %s%s!", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format5 auto hello world", string_format("He%s%s%s %s%s!", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format6 hello world", string_format6("H%s%s%s%s %s%s!", "e", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format6 auto hello world", string_format("H%s%s%s%s %s%s!", "e", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("string_format7 hello world", string_format7("%s%s%s%s%s %s%s!", "H", "e", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
call assertEquals("string_format7 auto hello world", string_format("%s%s%s%s%s %s%s!", "H", "e", "l", "l", "o", "Wo","rld"), "Hello World!");
|
||||
|
||||
call assertEquals("formatted string length 1024", strlen(sprintf(REPEAT_1024, 1)), 1024);
|
||||
|
||||
call assertEquals("formatted string length 5119", strlen(
|
||||
string_format7(
|
||||
"%s%s%s%s%s%s%s",
|
||||
REPEAT_1024,
|
||||
REPEAT_1024,
|
||||
REPEAT_1024,
|
||||
REPEAT_1024,
|
||||
REPEAT_1024,
|
||||
REPEAT_1024,
|
||||
REPEAT_1024)), 5119);
|
||||
|
||||
call assertEquals("string_tolower", string_tolower("miXeD CaSe"), "mixed case");
|
||||
call assertEquals("string_toupper", string_toupper("miXeD CaSe"), "MIXED CASE");
|
||||
|
||||
call assertEquals("string_find ok", string_find("Hello World", "World"), 6);
|
||||
call assertEquals("string_find missing", string_find("Hello World", "Zebra"), -1);
|
||||
call assertEquals("string_find_from", string_find_from("Hello World", "o", 6), 7);
|
||||
|
||||
call assertEquals("string_compare ok", string_compare("Hello World", "HeLlO WoRld"), 1);
|
||||
call assertEquals("string_compare neq", string_compare("Hello World", "HeLlO WoRld!"), 0);
|
||||
call assertEquals("string_compare_locale", string_compare_locale("Hello World", "HeLlO WoRld", 866), 1); // TODO: would be nice to compare cyrillic
|
||||
|
||||
call assertEquals("charcode", charcode("A"), 65);
|
||||
call assertEquals("charcode empty", charcode(""), 0);
|
||||
|
||||
call report_test_results("sprintf");
|
||||
end
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "define_lite.h"
|
||||
#include "sfall.h"
|
||||
#include "test_utils.h"
|
||||
#include "command_lite.h"
|
||||
|
||||
procedure test_stat_pc(variable stat_id) begin
|
||||
display_msg("Stat " + stat_id + " = " +
|
||||
get_pc_base_stat(stat_id) + " + " +
|
||||
get_pc_extra_stat(stat_id));
|
||||
|
||||
|
||||
call assertNotEquals("Not interesting stat, base stat is zero", get_pc_base_stat(stat_id), 0);
|
||||
|
||||
variable old_base_stat := get_pc_base_stat(stat_id);
|
||||
variable old_extra_stat := get_pc_extra_stat(stat_id);
|
||||
|
||||
set_pc_base_stat(stat_id, old_base_stat + 2);
|
||||
set_pc_extra_stat(stat_id, old_extra_stat + 4);
|
||||
// display_msg("Stat after update " + stat_id + " = " +
|
||||
// get_pc_base_stat(stat_id) + " + " +
|
||||
// get_pc_extra_stat(stat_id));
|
||||
if (stat_id > STAT_lu) then begin
|
||||
call assertNotEquals("Base stat was updated while it shouldn't",
|
||||
get_pc_base_stat(stat_id), old_base_stat + 2);
|
||||
end else begin
|
||||
call assertEquals("Base stat updated",
|
||||
get_pc_base_stat(stat_id), old_base_stat + 2);
|
||||
end
|
||||
|
||||
set_pc_base_stat(stat_id, old_base_stat);
|
||||
set_pc_extra_stat(stat_id, old_extra_stat);
|
||||
|
||||
// display_msg("Stat after reset " + stat_id + " = " +
|
||||
// get_pc_base_stat(stat_id) + " + " +
|
||||
// get_pc_extra_stat(stat_id));
|
||||
|
||||
call assertEquals("Base stat reset",
|
||||
get_pc_base_stat(stat_id), old_base_stat);
|
||||
|
||||
call assertEquals("Extra stat reset",
|
||||
get_pc_extra_stat(stat_id), old_extra_stat);
|
||||
end
|
||||
|
||||
procedure test_stat_critter(variable critter, variable stat_id) begin
|
||||
display_msg("Stat " + stat_id + " = " +
|
||||
get_critter_base_stat(critter, stat_id) + " + " +
|
||||
get_critter_extra_stat(critter, stat_id));
|
||||
|
||||
call assertNotEquals("Not interesting stat, base stat is zero",
|
||||
get_critter_base_stat(critter, stat_id), 0);
|
||||
|
||||
variable old_base_stat := get_critter_base_stat(critter, stat_id);
|
||||
variable old_extra_stat := get_critter_extra_stat(critter, stat_id);
|
||||
|
||||
set_critter_base_stat(critter, stat_id, old_base_stat + 2);
|
||||
set_critter_extra_stat(critter, stat_id, old_extra_stat + 4);
|
||||
// display_msg("Stat after update " + stat_id + " = " +
|
||||
// get_critter_base_stat(critter, stat_id) + " + " +
|
||||
// get_critter_extra_stat(critter, stat_id));
|
||||
if (stat_id > STAT_lu) then begin
|
||||
call assertNotEquals("Base stat was updated while it shouldn't",
|
||||
get_critter_base_stat(critter, stat_id), old_base_stat + 2);
|
||||
end else begin
|
||||
call assertEquals("Base stat updated",
|
||||
get_critter_base_stat(critter, stat_id), old_base_stat + 2);
|
||||
end
|
||||
|
||||
set_critter_base_stat(critter, stat_id, old_base_stat);
|
||||
set_critter_extra_stat(critter, stat_id, old_extra_stat);
|
||||
// display_msg("Stat after reset " + stat_id + " = " +
|
||||
// get_critter_base_stat(critter, stat_id) + " + " +
|
||||
// get_critter_extra_stat(critter, stat_id));
|
||||
call assertEquals("Base stat reset",
|
||||
get_critter_base_stat(critter, stat_id), old_base_stat);
|
||||
call assertEquals("Extra stat reset",
|
||||
get_critter_extra_stat(critter, stat_id), old_extra_stat);
|
||||
end
|
||||
|
||||
procedure test_derived_base_stat_critter(variable critter) begin
|
||||
display_msg("Testing derived stats on " + obj_name(critter));
|
||||
|
||||
variable old_agility;
|
||||
old_agility := get_critter_base_stat(critter, STAT_ag);
|
||||
|
||||
call assertNotEquals("Initial agility is 10", old_agility, 10);
|
||||
|
||||
call assertNotEquals("Action points is 10 while agility is not 10", get_critter_base_stat(critter, STAT_max_move_points), 10);
|
||||
|
||||
set_critter_base_stat(critter, STAT_ag, 10);
|
||||
|
||||
call assertEquals("Action points updated to 10",
|
||||
get_critter_base_stat(critter, STAT_max_move_points), 10);
|
||||
|
||||
set_critter_base_stat(critter, STAT_ag, old_agility);
|
||||
|
||||
call assertNotEquals("Action points updated from 10",
|
||||
get_critter_base_stat(critter, STAT_max_move_points), 10);
|
||||
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
display_msg("Testing stats...");
|
||||
test_suite_errors := 0;
|
||||
|
||||
call test_stat_pc(STAT_max_hit_points);
|
||||
|
||||
call test_stat_pc(STAT_lu);
|
||||
|
||||
|
||||
variable critter;
|
||||
variable closest_critter := dude_obj;
|
||||
foreach critter in list_as_array(LIST_CRITTERS) begin
|
||||
if (is_critter_dead(critter)) then begin
|
||||
continue;
|
||||
end
|
||||
if tile_distance(dude_tile, tile_num(critter)) == 0 then begin
|
||||
continue;
|
||||
end
|
||||
if (tile_distance(dude_tile, tile_num(critter)) <
|
||||
tile_distance(dude_tile, tile_num(closest_critter))) or
|
||||
(closest_critter == dude_obj)
|
||||
then begin
|
||||
closest_critter := critter;
|
||||
end
|
||||
end
|
||||
|
||||
// display_msg("Closest " + obj_name(closest_critter) + " distance: " +
|
||||
// tile_distance(dude_tile, tile_num(closest_critter)));
|
||||
|
||||
call test_stat_critter(dude_obj, STAT_max_hit_points);
|
||||
call test_stat_critter(dude_obj, STAT_lu);
|
||||
|
||||
if closest_critter != dude_obj then begin
|
||||
display_msg("Testing stats for " + obj_name(closest_critter));
|
||||
call test_stat_critter(closest_critter, STAT_max_hit_points);
|
||||
call test_stat_critter(closest_critter, STAT_lu);
|
||||
end else begin
|
||||
display_msg("FAIL: No other critters found to test stats");
|
||||
test_suite_errors++;
|
||||
end
|
||||
|
||||
|
||||
if
|
||||
get_critter_base_stat(dude_obj, STAT_lu) ==
|
||||
get_critter_base_stat(closest_critter, STAT_lu)
|
||||
and
|
||||
get_critter_extra_stat(dude_obj, STAT_max_hit_points) ==
|
||||
get_critter_extra_stat(closest_critter, STAT_max_hit_points) then begin
|
||||
display_msg("FAIL: Very sus eq values for dude and closest critter");
|
||||
test_suite_errors++;
|
||||
end
|
||||
|
||||
|
||||
call test_derived_base_stat_critter(dude_obj);
|
||||
call test_derived_base_stat_critter(closest_critter);
|
||||
|
||||
call report_test_results("stats");
|
||||
|
||||
|
||||
// set_pc_base_stat(STAT_lu, 10);
|
||||
// set_pc_extra_stat(STAT_max_hit_points, 500);
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "sfall.h"
|
||||
|
||||
procedure start begin
|
||||
// this isn't a unit test, just a way to easily test different values manually
|
||||
display_msg("Setting world map mult");
|
||||
set_map_time_multi(1.0);
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
[ValidSection]
|
||||
Key1=Value1
|
||||
Key2=2
|
||||
|
||||
[SectionWithSpaces]
|
||||
LeadingSpaceKey = LeadingSpaceValue
|
||||
TrailingSpaceKey = TrailingSpaceValue
|
||||
Both Sides Space Key = Both Sides Space Value
|
||||
SimpleKey=SimpleValue
|
||||
|
||||
[EmptySection]
|
||||
|
||||
; This is TestMisc, it's not empty but won't be directly tested for content here.
|
||||
[TestMisc]
|
||||
Alpha=Beta
|
||||
Gamma=Delta
|
||||
@@ -0,0 +1,123 @@
|
||||
#ifndef TEST_UTILS_H
|
||||
#define TEST_UTILS_H
|
||||
|
||||
#include "define_lite.h"
|
||||
|
||||
variable test_suite_errors := 0;
|
||||
variable test_suite_verbose := false;
|
||||
variable test_suite_assertions := 0;
|
||||
|
||||
procedure assertTrue(variable desc, variable a) begin
|
||||
test_suite_assertions++;
|
||||
|
||||
if (not a) then begin
|
||||
display_msg("Assertion failed \""+desc+"\": is not true");
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("Assert \""+desc+"\" ok");
|
||||
end
|
||||
end
|
||||
|
||||
procedure assertEquals(variable desc, variable a, variable b) begin
|
||||
test_suite_assertions++;
|
||||
|
||||
if (a != b or typeof(a) != typeof(b)) then begin
|
||||
display_msg("FAIL \""+desc+"\": "+a+" != "+b);
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("ok \""+desc+"\"");
|
||||
end
|
||||
end
|
||||
|
||||
procedure assertNotEquals(variable desc, variable a, variable b) begin
|
||||
test_suite_assertions++;
|
||||
|
||||
if (a == b) then begin
|
||||
display_msg("FAIL \""+desc+"\": "+a+" == "+b);
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("ok \""+desc+"\"");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
procedure assertFloat(variable desc, variable a, variable b, variable tolerance = 0.001) begin
|
||||
test_suite_assertions++;
|
||||
|
||||
variable diff := abs(a - b);
|
||||
if (diff > tolerance) then begin
|
||||
display_msg("FAIL \""+desc+"\": "+a+" != "+b+" (diff: "+diff+")");
|
||||
test_suite_errors ++;
|
||||
end else if (test_suite_verbose) then begin
|
||||
display_msg("ok \""+desc+"\"");
|
||||
end
|
||||
end
|
||||
|
||||
procedure report_test_results(variable desc) begin
|
||||
|
||||
display_msg("DONE " + desc + " " +
|
||||
(test_suite_assertions-test_suite_errors) + "/" + test_suite_assertions + "");
|
||||
display_msg("================");
|
||||
|
||||
|
||||
#define GL_VAR_TESTING_INFO_ARRAY_ID "TestArra"
|
||||
#define TEST_ARR_IDENTIFIER_KEY "__testing_info_array__"
|
||||
variable arr_id = get_sfall_global_int(GL_VAR_TESTING_INFO_ARRAY_ID);
|
||||
if arr_id != 0 then begin
|
||||
// Let's check that it is actually our testing array
|
||||
if array_key(arr_id, -1) == 0 then begin
|
||||
// It is not even associative array, so it is not our testing array
|
||||
arr_id = 0;
|
||||
end else begin
|
||||
if arr_id[TEST_ARR_IDENTIFIER_KEY] != 1 then begin
|
||||
// It is associative array, but it is not our testing array
|
||||
arr_id = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
if arr_id == 0 then begin
|
||||
arr_id = create_array(-1, 0);
|
||||
arr_id[TEST_ARR_IDENTIFIER_KEY] = 1;
|
||||
set_sfall_global(GL_VAR_TESTING_INFO_ARRAY_ID, arr_id);
|
||||
end
|
||||
|
||||
|
||||
#define TEST_SUITES "Test suites"
|
||||
#define TEST_ASSERTIONS_TOTAL "Tests assertings total"
|
||||
#define TEST_ASSERTIONS_FAILED "Tests assertings failed"
|
||||
|
||||
if arr_id[TEST_SUITES] == 0 then begin
|
||||
arr_id[TEST_SUITES] = create_array(-1, 0);
|
||||
end
|
||||
|
||||
//set_sfall_global("test_suite_errors", test_suite_errors);
|
||||
|
||||
arr_id[TEST_ASSERTIONS_TOTAL] += test_suite_assertions;
|
||||
arr_id[TEST_ASSERTIONS_FAILED] += test_suite_errors;
|
||||
arr_id[TEST_SUITES][desc] += 1;
|
||||
|
||||
variable total_suites_names = "";
|
||||
variable total_suites_count = 0;
|
||||
|
||||
variable key, item;
|
||||
foreach (key: item in arr_id[TEST_SUITES]) begin
|
||||
total_suites_count += item;
|
||||
if (total_suites_names != "") then begin
|
||||
total_suites_names += ", ";
|
||||
end
|
||||
total_suites_names += key;
|
||||
end
|
||||
|
||||
|
||||
variable assertions_stats_str = (arr_id[TEST_ASSERTIONS_TOTAL]-arr_id[TEST_ASSERTIONS_FAILED]) +
|
||||
"/" + arr_id[TEST_ASSERTIONS_TOTAL];
|
||||
if (arr_id[TEST_ASSERTIONS_FAILED] == 0) then begin
|
||||
float_msg(dude_obj, "Tested " + total_suites_count + " cases: " + total_suites_names + ". " +
|
||||
assertions_stats_str + " assertions passed!", FLOAT_MSG_GREEN);
|
||||
end else begin
|
||||
float_msg(dude_obj, "Tested " + total_suites_count + " cases: " + total_suites_names + ". " +
|
||||
assertions_stats_str + " assertions passed", FLOAT_MSG_RED);
|
||||
end
|
||||
end
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user