mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dab1e6219 | ||
|
|
dcba8882bf | ||
|
|
62c2621fef | ||
|
|
5188ebd4f4 | ||
|
|
1a77361231 | ||
|
|
ed2db51afd | ||
|
|
53ff2293a1 | ||
|
|
c4e722612f | ||
|
|
8f3ccca71b | ||
|
|
386b6c26c7 | ||
|
|
51b0c3c8c0 | ||
|
|
00a05e5279 | ||
|
|
a65a426e27 | ||
|
|
a697f0b868 | ||
|
|
9e8eaa13f5 | ||
|
|
14839db4f9 | ||
|
|
e1f5f83ebd | ||
|
|
6e6f82414e | ||
|
|
6f0f68d5aa | ||
|
|
141c67575f | ||
|
|
a7a7f0b63c |
@@ -17,15 +17,5 @@
|
||||
|
||||
- *Preview builds are not available for pull requests from forked repositories.* To enable preview builds, submit the PR from a branch within this repository.
|
||||
|
||||
- *Formatting issues? You have two options:*
|
||||
1. **Fix formatting automatically** using the following Docker command: *(If you're using Windows, remove `--user $(id -u):$(id -g)`)*
|
||||
```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'
|
||||
```
|
||||
2. **Skip formatting check** by adding the `skip-formatting` label to this PR.
|
||||
|
||||
--->
|
||||
|
||||
|
||||
+1
-4
@@ -10,6 +10,7 @@
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
.DS_Store
|
||||
.local-tools/
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
@@ -399,7 +400,3 @@ FodyWeavers.xsd
|
||||
# versioning header
|
||||
src/platform/git_version.h
|
||||
CMakeUserPresets.json
|
||||
|
||||
# Local configs for AI agents
|
||||
.aider*
|
||||
.gemini
|
||||
|
||||
@@ -446,6 +446,28 @@ target_include_directories(${EXECUTABLE_NAME} PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(${EXECUTABLE_NAME} ${SDL2_LIBRARIES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||
|
||||
add_executable(fallout2-dat
|
||||
"tools/dat_tool.cc"
|
||||
"src/dfile.cc"
|
||||
"src/platform_compat.cc"
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(fallout2-dat PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(fallout2-dat
|
||||
fpattern_windows::fpattern_windows
|
||||
${ZLIB_LIBRARIES}
|
||||
${SDL2_LIBRARIES}
|
||||
)
|
||||
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})
|
||||
|
||||
if(APPLE)
|
||||
if(IOS)
|
||||
install(TARGETS ${EXECUTABLE_NAME} DESTINATION "Payload")
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
"base"
|
||||
],
|
||||
"generator": "Xcode",
|
||||
"cacheVariables": {
|
||||
"CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY": ""
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
|
||||
@@ -2,6 +2,26 @@
|
||||
|
||||
This file is currently a shell to be filled in over time. For now, it only captures project-specific maintenance notes that are easy to miss.
|
||||
|
||||
## `.dat` CLI Tool
|
||||
|
||||
There is a small command-line archive tool in this repo for inspecting Fallout `.dat` files using the same reader implementation as the game.
|
||||
|
||||
Build it with `make TARGET=fallout2-dat`.
|
||||
|
||||
The executable is written to your selected `BUILD_DIR`, so the default path is `out/build/local-debug-arm64/fallout2-dat` on this macOS setup, but other platforms or custom build directories will differ.
|
||||
|
||||
The current tool is read-only. 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>`
|
||||
|
||||
Use `--lower` with `extract` when you want every extracted file and directory name forced to lowercase.
|
||||
For example, from `/Applications/Fallout2Codex` you can run:
|
||||
|
||||
`/Users/klaas/game/fallout2-ce/out/build/local-debug-arm64/fallout2-dat master.dat extract --lower /tmp/fallout2-dat-lower data\\*`
|
||||
|
||||
## Updating SDL
|
||||
|
||||
SDL is pinned for native builds in `third_party/sdl2/CMakeLists.txt`. Right now, Android also relies on checked-in Java bindings in `os/android/app/src/main/java/org/libsdl/app`, and those bindings must match the SDL version fetched by CMake.
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
# Fallout 2 Community Edition - Gemini Instructions
|
||||
|
||||
## Project Overview
|
||||
Fallout 2 Community Edition is a re-implementation of Fallout 2. It is written in C++ and uses CMake as its build system.
|
||||
|
||||
## Project Rules
|
||||
- Only search for source code and symbols inside the `src/` directory.
|
||||
|
||||
## Coding Standards & Conventions
|
||||
- **Language**: C++17.
|
||||
- **Style**: Follow WebKit style as defined in `.clang-format`.
|
||||
- Use `clang-format` before committing any changes.
|
||||
- Short `if` statements without `else` can be on a single line.
|
||||
- Fix namespace comments.
|
||||
- **File Naming**:
|
||||
- Source files: `.cc`
|
||||
- Header files: `.h`
|
||||
- **Architectural Constraint**:
|
||||
- Don't use complicated and rarely used C++ features, unless they are well encapsulated within reusable code.
|
||||
- Avoid large-scale refactorings. The project aims to reconcile changes from the Reference Edition, and major structural changes make this difficult.
|
||||
- **Integration Priority**: Integrating features and fixes from Sfall is a top priority.
|
||||
|
||||
## Build System (CMake)
|
||||
- **Version**: Requires CMake 3.18 or higher.
|
||||
- **Dependencies**: Uses vendored third-party libraries by default (`FALLOUT_VENDORED=ON`).
|
||||
- **Target**: The main executable is `fallout2-ce`.
|
||||
- **Platforms**: Supports Windows, Linux, macOS, Android, iOS, and Emscripten (WebAssembly).
|
||||
|
||||
## Project Structure
|
||||
- `src/`: Contains all core game logic and engine implementation.
|
||||
- `third_party/`: Vendored dependencies (zlib, SDL2, etc.).
|
||||
- `os/`: Platform-specific assets and configuration (icons, plists, etc.).
|
||||
- `cmake/`: Custom CMake scripts.
|
||||
- `files/`: Default configuration files and data assets.
|
||||
- `sfall_testing/`: SSL scripts for testing Sfall-related functionality.
|
||||
|
||||
## Tool Usage
|
||||
- **Prioritize CLion MCP**: Always use the CLion MCP tools (e.g., `mcp_clion_search_symbols`, `mcp_clion_get_symbol_info`) for finding code definitions and symbols instead of performing manual text-based searches with `grep_search` or `glob`. Use manual text searches only when symbol-based search is not applicable (e.g., searching for non-code text or specific patterns).
|
||||
|
||||
## Development Workflow
|
||||
1. **Research**: Understand how a feature was implemented in the original engine or Sfall before attempting to port or fix it.
|
||||
2. **Strategy**: Maintain compatibility with original game data and savegames.
|
||||
3. **Execution**: Apply surgical changes to `src/`.
|
||||
4. **Validation**: Ensure changes compile across platforms if possible, or at least don't break the build for the current platform.
|
||||
@@ -84,7 +84,7 @@ $ mv app /Applications/Fallout2
|
||||
|
||||
### Browser
|
||||
|
||||
> **NOTE**: WebAssebly build with emscripten
|
||||
> **NOTE**: WebAssembly build with emscripten
|
||||
```
|
||||
docker run --rm -v $(pwd):/src emscripten/emsdk:3.1.74 sh -c 'git config --global --add safe.directory "*" && mkdir -p build && cd build && emcmake cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/Emscripten.cmake && emmake make'
|
||||
```
|
||||
@@ -96,59 +96,35 @@ 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).
|
||||
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:
|
||||
|
||||
```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.
|
||||
[screen]
|
||||
resolution_x=1600 ; actual game window size (screen resolution), in pixels
|
||||
resolution_y=1080
|
||||
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)
|
||||
|
||||
[IFACE]
|
||||
; if IFACE_BAR_MODE=0 - the bottom of the map view window sits at the top of the IFACE Bar.
|
||||
; if IFACE_BAR_MODE=1 - the bottom of the map view window extends to the base of the screen and is overlapped by the IFACE Bar.
|
||||
IFACE_BAR_MODE=0
|
||||
|
||||
;if IFACE_BAR_SIDE_ART=0 - Black, No Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=1 - Metal (grey) look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=2 - Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=3-6 - Alternative Metal look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=7 - Alternative Leather look Iface-bar side art used.
|
||||
;if IFACE_BAR_SIDE_ART=8 - Metal (brown) look Iface-bar side art used.
|
||||
IFACE_BAR_SIDE_ART=2
|
||||
|
||||
;if IFACE_BAR_SIDES_ORI=0 - Iface-bar side graphics extend from the Iface-Bar to the Screen edges.
|
||||
;if IFACE_BAR_SIDES_ORI=1 - Iface-bar side graphics extend from the Screen edges to the Iface-Bar.
|
||||
IFACE_BAR_SIDES_ORI=0
|
||||
|
||||
;This will increase the width of the interface bar expanding the area used to display text.
|
||||
;if IFACE_BAR_WIDTH=640 - Interface bar will remain at it's original width.
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat.
|
||||
;IFACE_BAR_WIDTH=640
|
||||
|
||||
[STATIC_SCREENS]
|
||||
;if SPLASH_SCRN_SIZE=0 - Splash screen shows at original size if it fits, otherwise scales down while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=1 - Splash screen scales to fit the screen while preserving aspect ratio.
|
||||
;if SPLASH_SCRN_SIZE=2 - Splash screen stretches to fill the entire screen.
|
||||
SPLASH_SCRN_SIZE=0
|
||||
|
||||
[MAPS]
|
||||
;if IGNORE_MAP_EDGES=0 - Hi-Res map scroll edges are enabled.
|
||||
;if IGNORE_MAP_EDGES=1 - Hi-Res map scroll edges are ignored.
|
||||
IGNORE_MAP_EDGES=0
|
||||
[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)
|
||||
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)
|
||||
```
|
||||
|
||||
Recommendations:
|
||||
**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 stuff will receive in-game interface, right now you have to do it manually. For a sample f2_res.ini configuration file, containing all currently working settings use this link: [f2_res.ini](https://raw.githubusercontent.com/fallout2-ce/fallout2-ce/refs/heads/mainmenu/files/f2_res.ini)
|
||||
In time this stuff will receive in-game interface, right now you have to do it manually. 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)
|
||||
|
||||
*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.
|
||||
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)
|
||||
|
||||
|
||||
+35
-15
@@ -4,6 +4,24 @@ This document tracks Fallout 2 CE compatibility with sfall. This is for modders
|
||||
|
||||
For now, this covers opcodes/metarules, and hooks. In the future, it will include other ways of modifying the engine (like ini files), and other Sfall-specific behaviour.
|
||||
|
||||
## Settings (ddraw.ini → fallout2.cfg)
|
||||
|
||||
Some settings previously read from `ddraw.ini` have been moved into `fallout2.cfg`. The table below maps each setting to its new location. `HiResMode` had no effect in CE and has been removed.
|
||||
|
||||
| ddraw.ini section | ddraw.ini key | fallout2.cfg section | fallout2.cfg key |
|
||||
| --- | --- | --- | --- |
|
||||
| `Misc` | `SkipOpeningMovies` | `ui` | `skip_opening_movies` |
|
||||
| `Misc` | `DisplayKarmaChanges` | `ui` | `display_karma_changes` |
|
||||
| `Misc` | `DisplayBonusDamage` | `ui` | `display_bonus_damage` |
|
||||
| `Misc` | `NumbersInDialogue` | `ui` | `numbers_in_dialogue` |
|
||||
| `Misc` | `AutoQuickSave` | `ui` | `auto_quick_save` |
|
||||
| `Main` | `EnableHighResolutionStencil` | `ui` | `enable_high_resolution_stencil` |
|
||||
| `Misc` | `ConsoleOutputPath` | `debug` | `console_output_path` |
|
||||
| `Misc` | `GaplessMusic` | `sound` | `gapless_music` |
|
||||
| `Misc` | `ScreenshotsFormat` | `system` | `screenshots_format` |
|
||||
| `Misc` | `UseWalkDistance` | `qol` | `use_walk_distance` |
|
||||
| `Misc` | `AutoOpenDoors` | `qol` | `auto_open_doors` |
|
||||
|
||||
## Opcodes / Metarules
|
||||
|
||||
See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/) for documentation on specific functions.
|
||||
@@ -16,7 +34,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| Skills | get/set_critter_skill_points<br>get/set_available_skill_points<br>set_skill_max<br>set_critter_skill_mod<br>set_base_skill_mod<br>mod_skill_points_per_level | not implemented | - |
|
||||
| Graphics | graphics_funcs_available<br>force_graphics_refresh<br>get_screen_width<br>get_screen_height<br>set_palette | implemented: only get_screen_width, get_screen_height | - |
|
||||
| Shaders | load_shader<br>free_shader<br>activate_shader<br>deactivate_shader<br>set/get_shader_* | đźš« | likely will not implement direct compatibility
|
||||
| Perks and traits | set_perk_image<br>set_perk_*<br>set_pyromaniac_mod<br>apply_heaveho_fix<br>set_swiftlearner_mod<br>set_fake_perk<br>set_fake_trait<br>set_selectable_perk<br>set_perkbox_title<br>hide_real_perks<br>show_real_perks<br>perk_add_mode<br>clear_selectable_perks<br>has_fake_perk<br>has_fake_trait<br>add_trait<br>remove_trait<br>seq_perk_freq | not implemented | - |
|
||||
| Perks and traits | set_perk_image<br>set_perk_*<br>set_pyromaniac_mod<br>apply_heaveho_fix<br>set_swiftlearner_mod<br>has/set_fake_perk<br>has/set_fake_trait<br>set_selectable_perk<br>set_perkbox_title<br>show/hide_real_perks<br>perk_add_mode<br>clear_selectable_perks<br>add/remove_trait<br>seq_perk_freq | not implemented | - |
|
||||
| Virtual file system | fs_create<br>fs_copy<br>fs_find<br>fs_read/write_*<br>fs_delete<br>fs_size<br>fs_pos<br>fs_seek<br>fs_resize | đźš« | Open an issue if you have a use case for these |
|
||||
| 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 | - |
|
||||
@@ -27,7 +45,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| Utility / Math | log, exponent, round, sqrt, abs, sin, cos, tan, arctan, ceil, ^, floor2, div | âś… | - |
|
||||
| Keyboard and mouse | key_pressed<br>tap_key<br>get_mouse_x/y<br>get_mouse_buttons | âś… | - |
|
||||
| Lists | list_begin<br>list_next<br>list_end<br>list_as_array<br>party_member_list | âś… | - |
|
||||
| Explosions | metarule2_explosions<br>set_attack_explosion_pattern<br>set_attack_explosion_art<br>set_attack_explosion_radius<br>set_attack_is_explosion_fire<br>set_explosion_radius<br>set_dynamite_damage<br>set_plastic_damage<br>get_explosion_damage<br>set_explosion_max_targets<br>item_make_explosive | âś… except item_make_explosive | - |
|
||||
| Explosions | set_attack_explosion_pattern<br>set_attack_explosion_art<br>set_attack_explosion_radius<br>set_attack_is_explosion_fire<br>set_explosion_radius<br>set_dynamite_damage<br>set_plastic_damage<br>get_explosion_damage<br>set_explosion_max_targets<br>item_make_explosive | âś… except item_make_explosive | - |
|
||||
| Animations | reg_anim_combat_check<br>reg_anim_destroy<br>reg_anim_animate_and_hide<br>reg_anim_light<br>reg_anim_change_fid<br>reg_anim_take_out<br>reg_anim_turn_towards<br>reg_anim_callback<br>reg_anim_animate_and_move | âś… except reg_anim_callback | - |
|
||||
| Art and appearance | art_exists<br>refresh_pc_art<br>art_cache_clear<br>set_hero_race<br>set_hero_style | implemented: art_exists, refresh_pc_art, art_cache_clear | - |
|
||||
| Tiles and paths | get_tile_fid<br>tile_under_cursor<br>tile_light<br>tile_get_objs<br>tile_refresh_display<br>obj_blocking_tile<br>tile_by_position<br>get_tile_ground_fid<br>get_tile_roof_fid<br>obj_blocking_line<br>path_find_to<br>objects_in_radius | âś… except objects_in_radius | - |
|
||||
@@ -38,19 +56,21 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| 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 | - |
|
||||
| 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 | implemented: all 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: only get_attack_type, get_bodypart_hit_modifier, combat_data, set_bodypart_hit_modifier | - |
|
||||
| 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_bodypart_hit_modifier, combat_data, set_bodypart_hit_modifier, get_critter_current_ap, set_critter_current_ap, get_combat_free_move, set_combat_free_move | - |
|
||||
| Car | set_car_current_town<br>car_gas_amount<br>set_car_intface_art | implemented: all except set_car_intface_art | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window | implemented: only message_box, get_text_width, show_window | - |
|
||||
| Interface / Outline | outlined_object<br>get_outline<br>set_outline | implemented: all except get_outline | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | implemented: only message_box, get_text_width, show_window, create_message_window | - |
|
||||
| Interface / Outline | outlined_object<br>get_outline<br>set_outline | âś… | - |
|
||||
| Interface / Main interface | intface_is_hidden<br>intface_redraw<br>intface_hide<br>intface_show<br>set_quest_failure_value | implemented: only intface_redraw | `intface_redraw` only supports the zero-argument form; the optional-argument path is explicitly unimplemented. |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | implemented: only critter_inven_obj2 | - |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | implemented: critter_inven_obj2, item_weight | - |
|
||||
| Interface / Cursor | get/set_cursor_mode | âś… | - |
|
||||
| Locks | lock_is_jammed<br>unjam_lock<br>set_unjam_locks_time | not implemented | - |
|
||||
| INI settings | modified_ini<br>get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | âś… except modified_ini, get_ini_config, get_ini_config_db | `modified_ini` is intentionally omitted as deprecated. |
|
||||
| Objects and scripts | set_self<br>set_dude_obj<br>real_dude_obj<br>remove_script<br>set_script<br>get_script<br>obj_is_carrying_obj<br>loot_obj<br>dialog_obj<br>obj_under_cursor<br>get_object_data<br>set_object_data<br>get_flags<br>set_flags<br>set_unique_id<br>set_scr_name<br>obj_is_openable<br>get/set_proto_data<br>get_object_ai_data | implemented: set_self, get_script, obj_is_carrying_obj, loot_obj, dialog_obj, obj_under_cursor, get_object_data, get_flags, set_flags, get_proto_data, set_proto_data | - |
|
||||
| Other / Game management | set_movie_path<br>stop_game<br>resume_game<br>mark_movie_played<br>game_loaded<br>get_game_mode<br>get_uptime<br>signal_close_game | implemented: game_loaded, get_game_mode, get_uptime | - |
|
||||
| Other | input_funcs_available<br>get_year<br>set_dm_model<br>set_df_model<br>set_pipboy_available<br>get_kill_counter<br>mod_kill_counter<br>active_hand<br>toggle_active_hand<br>set_pickpocket_max<br>set_hit_chance_max<br>set_xp_mod<br>set_critter_hit_chance_mod<br>set_base_hit_chance_mod<br>inc_npc_level<br>get_npc_level<br>get/set_viewport_x/y<br>set_hp_per_level_mod<br>get/set_unspent_ap_bonus<br>get/set_unspent_ap_perk_bonus<br>hero_select_win<br>create_message_window<br>get_light_level<br>gdialog_get_barter_mod<br>set_inven_ap_cost<br>set_base_pickpocket_mod<br>set_critter_pickpocket_mod<br>message_str_game<br>sneak_success<br>create_spatial<br>unwield_slot<br>get_inven_ap_cost<br>add_g_timer_event<br>add_extra_msg_file<br>get_metarule_table<br>metarule_exist<br>npc_engine_level_up<br>remove_timer_event<br>set_drugs_data<br>spatial_radius | implemented: get_year, active_hand, toggle_active_hand, create_message_window, message_str_game, add_extra_msg_file, metarule_exist | `input_funcs_available`, `nb_create_char` are deprecated in sfall and intentionally absent in CE. `add_extra_msg_file` does not support the explicit `fileNumber` form in CE. |
|
||||
| INI settings | get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | âś… except get_ini_config, get_ini_config_db | `modified_ini` is intentionally omitted as deprecated. |
|
||||
| Objects and scripts | set_self<br>set_dude_obj<br>real_dude_obj<br>remove_script<br>get/set_script<br>obj_is_carrying_obj<br>loot_obj<br>dialog_obj<br>obj_under_cursor<br>get/set_object_data<br>get/set_flags<br>set_unique_id<br>set_scr_name<br>obj_is_openable<br>get/set_proto_data<br>get_object_ai_data | implemented: set_self, get_script, obj_is_carrying_obj, loot_obj, dialog_obj, obj_under_cursor, get_object_data, get_flags, set_flags, obj_is_openable, get_proto_data, set_proto_data | - |
|
||||
| Other / Game management | set_movie_path<br>stop/resume_game<br>mark_movie_played<br>game_loaded<br>get_game_mode<br>get_uptime<br>signal_close_game | implemented: game_loaded, get_game_mode, get_uptime, signal_close_game | - |
|
||||
| Gameplay tweaks | set_pickpocket_max<br>set_hit_chance_max<br>set_xp_mod<br>set_critter_hit_chance_mod<br>set_base_hit_chance_mod<br>set_hp_per_level_mod<br>get_unspent_ap_bonus<br>gdialog_get_barter_mod<br>set_unspent_ap_bonus<br>get/set_unspent_ap_perk_bonus<br>set_inven_ap_cost<br>set_base_pickpocket_mod<br>set_critter_pickpocket_mod<br>get_inven_ap_cost<br>set_drugs_data<br>get_kill_counter<br>mod_kill_counter<br>set_pipboy_available | implemented: gdialog_get_barter_mod | - |
|
||||
| NPCs | inc_npc_level<br>get_npc_level<br>npc_engine_level_up | not implemented | - |
|
||||
| Other | get_year<br>set_dm/df_model<br>active_hand<br>toggle_active_hand<br>get/set_viewport_x/y<br>hero_select_win<br>get_light_level<br>message_str_game<br>sneak_success<br>create_spatial<br>unwield_slot<br>add_g_timer_event<br>add_extra_msg_file<br>get_metarule_table<br>metarule_exist<br>remove_timer_event<br>spatial_radius | implemented: get_year, active_hand, toggle_active_hand, get_light_level, message_str_game, add_extra_msg_file, metarule_exist | `input_funcs_available`, `nb_create_char` are deprecated in sfall and intentionally absent in CE. `add_extra_msg_file` does not support the explicit `fileNumber` form in CE. |
|
||||
|
||||
## Hooks
|
||||
|
||||
@@ -58,11 +78,11 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| --- | --- | --- | --- |
|
||||
| ToHit | `HOOK_TOHIT` | âś… | - |
|
||||
| AfterHitRoll | `HOOK_AFTERHITROLL` | đźš« | Et tu |
|
||||
| CalcAPCost | `HOOK_CALCAPCOST` | đźš« | - |
|
||||
| CalcAPCost | `HOOK_CALCAPCOST` | âś… | - |
|
||||
| DeathAnim1 | `HOOK_DEATHANIM1` | đźš« | Use DEATHANIM2 instead |
|
||||
| DeathAnim2 | `HOOK_DEATHANIM2` | âś… | - |
|
||||
| CombatDamage | `HOOK_COMBATDAMAGE` | âś… | - |
|
||||
| OnDeath | `HOOK_ONDEATH` | đźš« | - |
|
||||
| OnDeath | `HOOK_ONDEATH` | âś… | - |
|
||||
| FindTarget | `HOOK_FINDTARGET` | đźš« | (maybe) |
|
||||
| UseObjOn | `HOOK_USEOBJON` | âś… | - |
|
||||
| UseObj | `HOOK_USEOBJ` | âś… | CE notes an sfall-matching inconsistency around return code `2` behavior between interface contexts. |
|
||||
@@ -72,10 +92,10 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| ItemDamage | `HOOK_ITEMDAMAGE` | đźš« | - |
|
||||
| AmmoCost | `HOOK_AMMOCOST` | đźš« | Et tu |
|
||||
| KeyPress | `HOOK_KEYPRESS` | âś… | Third hook arg is currently `0`; CE doesn't use VK codes. |
|
||||
| MouseClick | `HOOK_MOUSECLICK` | đźš« | - |
|
||||
| MouseClick | `HOOK_MOUSECLICK` | âś… | - |
|
||||
| UseSkill | `HOOK_USESKILL` | đźš« | - |
|
||||
| Steal | `HOOK_STEAL` | đźš« | Et tu |
|
||||
| WithinPerception | `HOOK_WITHINPERCEPTION` | đźš« | Et tu |
|
||||
| WithinPerception | `HOOK_WITHINPERCEPTION` | âś… | - |
|
||||
| InventoryMove | `HOOK_INVENTORYMOVE` | âś… | - |
|
||||
| InvenWield | `HOOK_INVENWIELD` | đźš« | - |
|
||||
| AdjustFID | `HOOK_ADJUSTFID` | đźš« | - |
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[main]
|
||||
RadiationEffectCount=8
|
||||
RadiationLevelCount=6
|
||||
RadiationEffectPrimaryStatCount=6
|
||||
RadiationThresholds=99,199,399,599,999
|
||||
RadiationEnduranceModifiers=2,0,-2,-4,-6,-8
|
||||
RadiationEffectStats=0,1,2,3,4,5,6,7
|
||||
|
||||
[RadiationEffectPenalties]
|
||||
Level0=0,0,0,0,0,0,0,0
|
||||
Level1=-1,0,0,0,0,0,0,0
|
||||
Level2=-1,0,0,0,0,-1,0,-3
|
||||
Level3=-2,0,-1,0,0,-2,-5,-5
|
||||
Level4=-4,-3,-3,-3,-1,-5,-15,-10
|
||||
Level5=-6,-5,-5,-5,-3,-6,-20,-10
|
||||
@@ -3,10 +3,6 @@
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Main]
|
||||
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
;EnableHighResolutionStencil=1
|
||||
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Misc]
|
||||
|
||||
@@ -72,13 +68,6 @@ TownMapHotkeysFix=1
|
||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||
;OverrideCriticalTable=2
|
||||
|
||||
;Set to 1 to get notification of karma changes in the notification window
|
||||
DisplayKarmaChanges=0
|
||||
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
;Set to 2 to also skip the splash screen
|
||||
SkipOpeningMovies=0
|
||||
|
||||
;Change the Skilldex cursor FRM numbers
|
||||
;Default is 293 for all skills
|
||||
Lockpick=293
|
||||
@@ -99,18 +88,9 @@ Repair=293
|
||||
;Syntax is 'city id:global id', with each city/global pair separated by a comma.
|
||||
;CityRepsList=0:5001,2:5003,3:5004,4:5005,5:5006,6:5007,7:5008,8:5009,10:5011,11:5012,60:1640
|
||||
|
||||
;Set this to a valid path to save a copy of the console contents
|
||||
;ConsoleOutputPath=console.txt
|
||||
|
||||
;Set to 1 to add additional pages of save slots !!! can be implemented !!!
|
||||
;ExtraSaveSlots=1
|
||||
|
||||
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand, set the next two lines
|
||||
;Quick save will cyclically overwrite saves from the first slot on the specified page to the last slot on the n-th page
|
||||
;AutoQuickSave sets how many pages you want to use for quick saving (valid range: 1..10)
|
||||
;Set to 0 to disable
|
||||
AutoQuickSave=0
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
;Number of KarmaPoints should be 1 less than number of KarmaFRMs
|
||||
;KarmaFRMs=47,48,49
|
||||
@@ -122,9 +102,6 @@ ScienceOnCritters=0
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
BonusHtHDamageFix=1
|
||||
|
||||
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
|
||||
;DisplayBonusDamage=1
|
||||
|
||||
;Set to 1 to remove the limits that stop the game from rolling critical successes/failures in the first few days of game time
|
||||
RemoveCriticalTimelimits=0
|
||||
|
||||
@@ -170,9 +147,6 @@ RemoveCriticalTimelimits=0
|
||||
;You need to use the message_str_game script function to get messages from the files
|
||||
;ExtraGameMsgFileList=
|
||||
|
||||
;Set to 1 to display numbered dialogue options
|
||||
NumbersInDialogue=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
; Configuration ini files
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
[debug]
|
||||
;Set this to a valid path to save a copy of the console contents
|
||||
console_output_path=
|
||||
mode=log
|
||||
output_map_data_info=1
|
||||
show_load_info=1
|
||||
show_script_messages=1
|
||||
show_tile_num=1
|
||||
window_height=192
|
||||
window_width=300
|
||||
|
||||
[mapper]
|
||||
default_f8_as_game=1
|
||||
fix_map_inventory=0
|
||||
fix_map_objects=0
|
||||
ignore_rebuild_errors=0
|
||||
librarian=0
|
||||
override_librarian=0
|
||||
rebuild_protos=0
|
||||
run_mapper_as_game=0
|
||||
save_text_maps=0
|
||||
show_pid_numbers=0
|
||||
sort_script_list=0
|
||||
use_art_not_protos=0
|
||||
|
||||
[preferences]
|
||||
brightness=1.000000
|
||||
combat_difficulty=1
|
||||
combat_looks=1
|
||||
combat_messages=1
|
||||
combat_speed=50
|
||||
combat_taunts=1
|
||||
game_difficulty=1
|
||||
item_highlight=1
|
||||
language_filter=0
|
||||
mouse_sensitivity=1.000000
|
||||
player_speedup=0
|
||||
running=1
|
||||
running_burning_guy=1
|
||||
subtitles=1
|
||||
target_highlight=1
|
||||
text_base_delay=6.000000
|
||||
text_line_delay=2.000000
|
||||
violence_level=3
|
||||
|
||||
[screen]
|
||||
resolution_x=640
|
||||
resolution_y=480
|
||||
scale=1
|
||||
windowed=1
|
||||
|
||||
[sound]
|
||||
cache_size=448
|
||||
debug=1
|
||||
debug_sfxc=1
|
||||
gapless_music=1
|
||||
initialize=1
|
||||
master_volume=22281
|
||||
music=1
|
||||
music_path1=data\sound\music\
|
||||
music_path2=sound\music\
|
||||
music_volume=22281
|
||||
sndfx_volume=22281
|
||||
sounds=1
|
||||
speech=1
|
||||
speech_volume=22281
|
||||
|
||||
[system]
|
||||
art_cache_size=8
|
||||
color_cycling=1
|
||||
critter_dat=critter.dat
|
||||
critter_patches=data
|
||||
cycle_speed_factor=1
|
||||
executable=game
|
||||
free_space=20480
|
||||
hashing=1
|
||||
interrupt_walk=1
|
||||
language=english
|
||||
master_dat=master.dat
|
||||
master_patches=data
|
||||
screenshots_format=png
|
||||
scroll_lock=0
|
||||
splash=5
|
||||
|
||||
[ui]
|
||||
;Speed up or slow down all UI animations such as screen fade, dialog window show/hide, AC numbers roll, etc.
|
||||
anim_speed=2.000000
|
||||
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand
|
||||
;Quick save will cyclically overwrite saves from the first slot on the specified page to the last slot on the n-th page
|
||||
;auto_quick_save sets how many pages you want to use for quick saving (valid range: 1..10)
|
||||
;Set to 0 to disable
|
||||
auto_quick_save=3
|
||||
;Set to 1 to display additional points of damage from Bonus HtH/Ranged Damage perks in the inventory
|
||||
display_bonus_damage=1
|
||||
;Set to 1 to get notification of karma changes in the notification window
|
||||
display_karma_changes=0
|
||||
;Set to one to hide areas outside map bounds when using higher than 640x480 resolution, and to zero to disable
|
||||
enable_high_resolution_stencil=1
|
||||
iface_bar_mode=0
|
||||
iface_bar_side_art=2
|
||||
iface_bar_sides_ori=0
|
||||
iface_bar_width=800
|
||||
ignore_map_edges=0
|
||||
;Set to 1 to display numbered dialogue options
|
||||
numbers_in_dialogue=0
|
||||
;Set to 1 to skip the 3 opening movies
|
||||
;Set to 2 to also skip the splash screen
|
||||
skip_opening_movies=0
|
||||
splash_screen_size=1
|
||||
|
||||
[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
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
#include "define_lite.h"
|
||||
#include "command_lite.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#define TEST_ITEM_PID 40
|
||||
#define OP_GET_CRITTER_CURRENT_AP 0x8191
|
||||
#define OP_SET_CRITTER_CURRENT_AP 0x8192
|
||||
#define opcode_exists(opcode) sfall_func1("opcode_exists", opcode)
|
||||
|
||||
procedure run_combat_turn_roundtrip begin
|
||||
variable originalAp := get_critter_current_ap(dude_obj);
|
||||
variable originalFreeMove := get_combat_free_move;
|
||||
variable expectedAp := originalAp + 1;
|
||||
variable expectedFreeMove := originalFreeMove + 2;
|
||||
|
||||
set_critter_current_ap(dude_obj, expectedAp);
|
||||
set_combat_free_move(expectedFreeMove);
|
||||
|
||||
call assertEquals("set/get_critter_current_ap roundtrip", get_critter_current_ap(dude_obj), expectedAp);
|
||||
call assertEquals("set/get_combat_free_move roundtrip", get_combat_free_move, expectedFreeMove);
|
||||
|
||||
set_critter_current_ap(dude_obj, originalAp);
|
||||
set_combat_free_move(originalFreeMove);
|
||||
|
||||
call assertEquals("get_critter_current_ap restored", get_critter_current_ap(dude_obj), originalAp);
|
||||
call assertEquals("get_combat_free_move restored", get_combat_free_move, originalFreeMove);
|
||||
call report_test_results("combat_inventory_misc_combat");
|
||||
end
|
||||
|
||||
procedure report_obj_under_cursor begin
|
||||
variable target := obj_under_cursor(0, 1);
|
||||
|
||||
if (target == 0) then begin
|
||||
display_msg("No object under cursor.");
|
||||
return;
|
||||
end
|
||||
|
||||
display_msg("Cursor object: " + obj_name(target) + ", openable=" + obj_is_openable(target));
|
||||
end
|
||||
|
||||
procedure keypress_handler begin
|
||||
variable pressed := get_sfall_arg_at(0);
|
||||
variable key := get_sfall_arg_at(1);
|
||||
|
||||
if (not pressed) then return;
|
||||
|
||||
if (key == DIK_J) then begin
|
||||
call run_combat_turn_roundtrip();
|
||||
end else if (key == DIK_K) then begin
|
||||
call report_obj_under_cursor();
|
||||
end
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
variable testItem;
|
||||
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("Testing combat/inventory/object helpers...");
|
||||
|
||||
call assertEquals("metarule get_combat_free_move", metarule_exist("get_combat_free_move"), 1);
|
||||
call assertEquals("metarule set_combat_free_move", metarule_exist("set_combat_free_move"), 1);
|
||||
call assertEquals("metarule item_weight", metarule_exist("item_weight"), 1);
|
||||
call assertEquals("metarule obj_is_openable", metarule_exist("obj_is_openable"), 1);
|
||||
call assertEquals("opcode get_critter_current_ap", opcode_exists(OP_GET_CRITTER_CURRENT_AP), 1);
|
||||
call assertEquals("opcode set_critter_current_ap", opcode_exists(OP_SET_CRITTER_CURRENT_AP), 1);
|
||||
|
||||
testItem := create_object_sid(TEST_ITEM_PID, 0, 0, -1);
|
||||
call assertEquals("item_weight matches proto weight for test item", item_weight(testItem), obj_weight(testItem));
|
||||
call assertEquals("non-container item is not openable", obj_is_openable(testItem), 0);
|
||||
destroy_object(testItem);
|
||||
|
||||
call report_test_results("combat_inventory_misc");
|
||||
|
||||
display_msg("Manual test: enter combat, wait for your turn, then press J to roundtrip AP/free-move.");
|
||||
display_msg("Manual test: point at a door or container and press K to print obj_is_openable().");
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
end
|
||||
@@ -1,5 +1,25 @@
|
||||
#include "test_utils.h"
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
|
||||
variable signal_close_game_test_done := false;
|
||||
|
||||
procedure keypress_handler begin
|
||||
variable pressed := get_sfall_arg_at(0);
|
||||
variable key := get_sfall_arg_at(1);
|
||||
|
||||
if (not pressed) then return;
|
||||
if (key != DIK_J) then return;
|
||||
|
||||
if (signal_close_game_test_done) then begin
|
||||
display_msg("signal_close_game test already triggered");
|
||||
return;
|
||||
end
|
||||
|
||||
signal_close_game_test_done := true;
|
||||
display_msg("signal_close_game test triggered");
|
||||
signal_close_game;
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
// TODO: move this to a more suitable place, once we have more functions implemented
|
||||
@@ -10,6 +30,8 @@ procedure start begin
|
||||
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");
|
||||
display_msg("signal_close_game manual test ready: press J");
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
end
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
#include "lib.arrays.h"
|
||||
#include "lib.obj.h"
|
||||
|
||||
variable calcapcost_override_enabled := true;
|
||||
|
||||
procedure calcapcost_mode_name begin
|
||||
if (calcapcost_override_enabled) then return "override";
|
||||
return "engine";
|
||||
end
|
||||
|
||||
procedure calcapcost_item_name(variable item) begin
|
||||
if (item == 0) then return "<null>";
|
||||
return obj_name(item);
|
||||
end
|
||||
|
||||
procedure calcapcost_handler begin
|
||||
variable
|
||||
args := get_sfall_args,
|
||||
critter := args[0],
|
||||
attackType := args[1],
|
||||
isAimed := args[2],
|
||||
defaultCost := args[3],
|
||||
weapon := args[4],
|
||||
weaponPid := 0;
|
||||
|
||||
if (critter != dude_obj) then return;
|
||||
if (weapon) then weaponPid := obj_pid(weapon);
|
||||
|
||||
display_msg(string_format("calcapcost mode=%s attack=%d aimed=%d default=%d weapon=%s pid=%d",
|
||||
calcapcost_mode_name,
|
||||
attackType,
|
||||
isAimed,
|
||||
defaultCost,
|
||||
calcapcost_item_name(weapon),
|
||||
weaponPid));
|
||||
|
||||
if (calcapcost_override_enabled) then
|
||||
set_sfall_return(defaultCost + 3);
|
||||
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;
|
||||
|
||||
calcapcost_override_enabled := not calcapcost_override_enabled;
|
||||
display_msg(string_format1("calcapcost mode -> %s", calcapcost_mode_name));
|
||||
intface_redraw;
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("calcapcost manual test ready: press H to toggle override (+3 AP)");
|
||||
display_msg("check weapon, unarmed, and non-weapon hand items; hook logs args for dude only");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
register_hook_proc(HOOK_CALCAPCOST, calcapcost_handler);
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
#include "define_lite.h"
|
||||
|
||||
#define TEST_KEY (DIK_J)
|
||||
|
||||
procedure ondeath_handler begin
|
||||
variable
|
||||
dead_critter := get_sfall_arg_at(0),
|
||||
critter_name := "<null>",
|
||||
critter_pid := -1;
|
||||
|
||||
if (dead_critter) then begin
|
||||
critter_name := obj_name(dead_critter);
|
||||
critter_pid := obj_pid(dead_critter);
|
||||
end
|
||||
|
||||
display_msg(string_format2("ondeath critter=%s pid=%d", critter_name, critter_pid));
|
||||
end
|
||||
|
||||
procedure keypress_handler begin
|
||||
variable
|
||||
pressed := get_sfall_arg_at(0),
|
||||
key := get_sfall_arg_at(1),
|
||||
target;
|
||||
|
||||
if (not pressed) then return;
|
||||
if (key != TEST_KEY) then return;
|
||||
|
||||
target := obj_under_cursor(true, false);
|
||||
if (target == 0) then begin
|
||||
display_msg("ondeath test: no critter under cursor");
|
||||
return;
|
||||
end
|
||||
|
||||
if (target == dude_obj) then begin
|
||||
display_msg("ondeath test: refusing to kill dude");
|
||||
return;
|
||||
end
|
||||
|
||||
display_msg(string_format1("ondeath test: killing %s", obj_name(target)));
|
||||
critter_dmg(target, 9999, DMG_BYPASS_ARMOR);
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("ondeath manual test ready: hover a critter and press J");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
register_hook_proc(HOOK_ONDEATH, ondeath_handler);
|
||||
end
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
#include "lib.arrays.h"
|
||||
#include "lib.obj.h"
|
||||
|
||||
variable withinperception_override := -1;
|
||||
|
||||
procedure withinperception_override_name(variable value) begin
|
||||
if (value == -1) then return "engine";
|
||||
if (value == 0) then return "block";
|
||||
if (value == 1) then return "allow";
|
||||
if (value == 2) then return "force_detect";
|
||||
return "unknown";
|
||||
end
|
||||
|
||||
procedure withinperception_type_name(variable hook_type) begin
|
||||
if (hook_type == 0) then return "engine";
|
||||
if (hook_type == 1) then return "see";
|
||||
if (hook_type == 2) then return "hear";
|
||||
if (hook_type == 3) then return "ai_target";
|
||||
return "unknown";
|
||||
end
|
||||
|
||||
procedure cycle_override begin
|
||||
if (withinperception_override == -1) then withinperception_override := 0;
|
||||
else if (withinperception_override == 0) then withinperception_override := 1;
|
||||
else if (withinperception_override == 1) then withinperception_override := 2;
|
||||
else withinperception_override := -1;
|
||||
|
||||
display_msg(string_format1("withinperception override=%s", withinperception_override_name(withinperception_override)));
|
||||
end
|
||||
|
||||
procedure print_target_checks begin
|
||||
variable
|
||||
target := obj_under_cursor(true, false),
|
||||
canSee,
|
||||
canHear,
|
||||
target_name := "(null)";
|
||||
|
||||
target_name := obj_name_safe(target);
|
||||
|
||||
display_msg(string_format2("withinperception target=%s pid=%d", target_name, target and obj_pid(target)));
|
||||
|
||||
if (target == 0) then begin
|
||||
display_msg("withinperception no target under cursor");
|
||||
return;
|
||||
end
|
||||
|
||||
canSee := obj_can_see_obj(dude_obj, target);
|
||||
canHear := obj_can_hear_obj(dude_obj, target);
|
||||
|
||||
display_msg(string_format2("withinperception see=%d hear=%d", canSee, canHear));
|
||||
end
|
||||
|
||||
procedure withinperception_handler begin
|
||||
variable
|
||||
args := get_sfall_args,
|
||||
watcher := args[0],
|
||||
target := args[1],
|
||||
original_result := args[2],
|
||||
hook_type := args[3],
|
||||
watcher_name := "(null)",
|
||||
target_name := "(null)",
|
||||
override_result := withinperception_override;
|
||||
|
||||
watcher_name := obj_name_safe(watcher);
|
||||
target_name := obj_name_safe(target);
|
||||
|
||||
if (watcher == dude_obj) then begin
|
||||
display_msg(string_format("withinperception %s %s -> %s [res=%d]",
|
||||
withinperception_type_name(hook_type),
|
||||
watcher_name,
|
||||
target_name, original_result));
|
||||
end
|
||||
|
||||
if (override_result == -1) then return;
|
||||
|
||||
if (hook_type != 1 and override_result == 2) then override_result := 1;
|
||||
|
||||
set_sfall_return(override_result);
|
||||
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 begin
|
||||
call print_target_checks;
|
||||
end else if (key == DIK_K) then begin
|
||||
call cycle_override;
|
||||
end
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("withinperception manual test ready: J checks target under cursor, K cycles override");
|
||||
display_msg("withinperception override order: engine -> block -> allow -> force_detect");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
register_hook_proc(HOOK_WITHINPERCEPTION, withinperception_handler);
|
||||
end
|
||||
+1
-1
@@ -3063,7 +3063,7 @@ void _dude_fidget()
|
||||
// 0x56C7E0
|
||||
static Object* candidates[100];
|
||||
|
||||
if (_game_user_wants_to_quit != 0) {
|
||||
if (_game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -475,7 +475,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
break;
|
||||
}
|
||||
|
||||
if (_game_user_wants_to_quit != 0) {
|
||||
if (_game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -919,7 +919,7 @@ int characterEditorShow(bool isCreationMode)
|
||||
} else if (keyCode == KEY_CTRL_Q || keyCode == KEY_CTRL_X || keyCode == KEY_F10) {
|
||||
showQuitConfirmationDialog();
|
||||
windowRefresh(gCharacterEditorWindow);
|
||||
} else if (keyCode == 502 || keyCode == KEY_ESCAPE || keyCode == KEY_UPPERCASE_C || keyCode == KEY_LOWERCASE_C || _game_user_wants_to_quit != 0) {
|
||||
} else if (keyCode == 502 || keyCode == KEY_ESCAPE || keyCode == KEY_UPPERCASE_C || keyCode == KEY_LOWERCASE_C || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
windowRefresh(gCharacterEditorWindow);
|
||||
rc = 1;
|
||||
} else if (gCharacterEditorIsCreationMode && (keyCode == 517 || keyCode == KEY_UPPERCASE_N || keyCode == KEY_LOWERCASE_N)) {
|
||||
@@ -1950,7 +1950,7 @@ static int _get_input_str(int win, int cancelKeyCode, char* text, int maxLength,
|
||||
} else if (keyCode == KEY_RETURN) {
|
||||
soundPlayFile("ib1p1xx1");
|
||||
rc = 0;
|
||||
} else if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) {
|
||||
} else if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
rc = -1;
|
||||
} else {
|
||||
if ((keyCode == KEY_DELETE || keyCode == KEY_BACKSPACE) && nameLength >= 1) {
|
||||
@@ -3435,7 +3435,7 @@ static int characterEditorEditAge()
|
||||
|
||||
windowDestroy(win);
|
||||
return 0;
|
||||
} else if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) {
|
||||
} else if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
break;
|
||||
} else if (keyCode == 501) {
|
||||
age = critterGetStat(gDude, STAT_AGE);
|
||||
@@ -3535,7 +3535,7 @@ static int characterEditorEditAge()
|
||||
}
|
||||
|
||||
keyCode = inputGetInput();
|
||||
if (keyCode == 503 || keyCode == 504 || _game_user_wants_to_quit != 0) {
|
||||
if (keyCode == 503 || keyCode == 504 || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3667,7 +3667,7 @@ static void characterEditorEditGender()
|
||||
break;
|
||||
}
|
||||
|
||||
if (eventCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) {
|
||||
if (eventCode == KEY_ESCAPE || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
critterSetBaseStat(gDude, STAT_GENDER, savedGender);
|
||||
characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0);
|
||||
characterEditorDrawDerivedStats();
|
||||
@@ -3891,7 +3891,7 @@ static int characterEditorShowOptions()
|
||||
|
||||
int keyCode = inputGetInput();
|
||||
|
||||
if (_game_user_wants_to_quit != 0) {
|
||||
if (_game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
rc = 2;
|
||||
} else if (keyCode == 504) {
|
||||
rc = 2;
|
||||
@@ -6016,7 +6016,7 @@ static int perkDialogHandleInput(int count, void (*refreshProc)())
|
||||
}
|
||||
gPerkDialogPreviousCurrentLine = gPerkDialogCurrentLine;
|
||||
refreshProc();
|
||||
} else if (keyCode == 502 || keyCode == KEY_ESCAPE || _game_user_wants_to_quit != 0) {
|
||||
} else if (keyCode == 502 || keyCode == KEY_ESCAPE || _game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
rc = 2;
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
|
||||
@@ -165,7 +165,7 @@ int characterSelectorOpen()
|
||||
while (!done) {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
if (_game_user_wants_to_quit != 0) {
|
||||
if (_game_user_wants_to_quit != GAME_QUIT_REQUEST_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user