mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3552614aa | ||
|
|
a966e9a553 | ||
|
|
6b0f1ae8c7 | ||
|
|
7ec6664dc3 | ||
|
|
bd6a8f7e60 | ||
|
|
ae2c70be44 | ||
|
|
1d4cc9b5e6 | ||
|
|
1d72544cbb | ||
|
|
dd60d8795f | ||
|
|
765574056c | ||
|
|
6d9deca69d | ||
|
|
2545e0980d | ||
|
|
f321591610 | ||
|
|
4062dee345 | ||
|
|
0bd2707c3f | ||
|
|
bd62603293 | ||
|
|
fdd311e9c4 | ||
|
|
5188ebd4f4 |
@@ -0,0 +1,25 @@
|
||||
## Further Reading
|
||||
- Refer to the project README for overall architecture.
|
||||
|
||||
## Working With Code
|
||||
- Only search for code and symbols inside the `src/` directory.
|
||||
- NEVER search entire code base for certain file or symbol when it's location isn't known, ask first.
|
||||
- NEVER read entire files unless absolutely necessary for task. Use MCP search instead.
|
||||
- Prefer CLion MCP for searching code and basic refactoring over raw text tools such as grep.
|
||||
- Test changes by compiling (separate cc file for small local changes, or via CLion build_project MCP for big changes).
|
||||
- If game run test is request by prompt, start the game from C:\Games\Fallout2\@CE folder. It always contains last built executable, config file and game assets for full testing.
|
||||
|
||||
## Language Standard
|
||||
- The project targets C++17 (`CMAKE_CXX_STANDARD 17` in `CMakeLists.txt`).
|
||||
- Prefer C++17 library APIs and semantics when they simplify code. For example, `std::string::data()` is mutable in C++17.
|
||||
- static global variable need no prefix. exported globals get g*.
|
||||
- generally prefer camelCase
|
||||
|
||||
## Project Structure
|
||||
- `src/`: 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.
|
||||
|
||||
+2
-12
@@ -62,6 +62,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/combat.h"
|
||||
"src/config.cc"
|
||||
"src/config.h"
|
||||
"src/content_config.cc"
|
||||
"src/content_config.h"
|
||||
"src/credits.cc"
|
||||
"src/credits.h"
|
||||
"src/critter.cc"
|
||||
@@ -98,12 +100,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/file_find.h"
|
||||
"src/file_utils.cc"
|
||||
"src/file_utils.h"
|
||||
"src/fo1db/fo1_assoc.cc"
|
||||
"src/fo1db/fo1_assoc.h"
|
||||
"src/fo1db/fo1_db.cc"
|
||||
"src/fo1db/fo1_db.h"
|
||||
"src/fo1db/fo1_lzss.cc"
|
||||
"src/fo1db/fo1_lzss.h"
|
||||
"src/font_manager.cc"
|
||||
"src/font_manager.h"
|
||||
"src/game_config.cc"
|
||||
@@ -120,8 +116,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/game_movie.h"
|
||||
"src/game_sound.cc"
|
||||
"src/game_sound.h"
|
||||
"src/game_variant.cc"
|
||||
"src/game_variant.h"
|
||||
"src/game_vars.h"
|
||||
"src/game.cc"
|
||||
"src/game.h"
|
||||
@@ -330,10 +324,6 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(${EXECUTABLE_NAME} PRIVATE /EHsc)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${EXECUTABLE_NAME}
|
||||
winmm
|
||||
|
||||
@@ -4,9 +4,13 @@ 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)
|
||||
## Settings (ddraw.ini → fallout2.cfg / game.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.
|
||||
Settings previously read from `ddraw.ini` have been moved into standard CE config files.
|
||||
|
||||
Most settings that control game behavior (premade characters, extra message files, combat tweaks, worldmap, etc.) have been moved into [`<DAT>/config/game.cfg`](files/foce_base.dat/config/game.cfg), which is a content-mod config file intended to be overridden by mods. See that file for the full list with descriptions.
|
||||
|
||||
The following settings were moved into [`fallout2.cfg`](files/fallout2.cfg) instead:
|
||||
|
||||
| ddraw.ini section | ddraw.ini key | fallout2.cfg section | fallout2.cfg key |
|
||||
| --- | --- | --- | --- |
|
||||
|
||||
-127
@@ -6,19 +6,6 @@
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Misc]
|
||||
|
||||
;Uncomment these lines to change the timers of how many days after the game starts Hakunin dream sequences will occur
|
||||
;MovieTimer_artimer1=5000
|
||||
;MovieTimer_artimer2=5000
|
||||
;MovieTimer_artimer3=5000
|
||||
;MovieTimer_artimer4=5000
|
||||
|
||||
;To start a new game somewhere other than artemple.map, uncomment the next line and set it to the map you want to load
|
||||
;StartingMap=V13ent.map
|
||||
|
||||
;To change the 'FALLOUT II v1.02d' version string on the main menu, uncomment the next line
|
||||
;You can use up to 2 %d's in this if you want to include Fallout's version number somewhere
|
||||
;VersionString=FALLOUT II v1.02d
|
||||
|
||||
;To use a config file other than fallout2.cfg, uncomment the next line and add the name of your new file
|
||||
;ConfigFile=
|
||||
|
||||
@@ -26,40 +13,6 @@
|
||||
;If you want to load multiple patch files (up to 1000) at once, you can include a %d in the file name (sprintf syntax)
|
||||
;PatchFile=patch%03d.dat
|
||||
|
||||
;Set to 1 to allow using the caret character '^' in dialog msg files to specify alternative text in dialogue based on the player's gender
|
||||
;The text must be enclosed in angle brackets (example: <MaleText^FemaleText>)
|
||||
;DialogGenderWords=0
|
||||
|
||||
;To change the default and starting player models, uncomment the next four lines.
|
||||
;The default models can also be changed in-game via script
|
||||
;MaleStartModel=hmjmps
|
||||
;MaleDefaultModel=hmjmps
|
||||
;FemaleStartModel=hfjmps
|
||||
;FemaleDefaultModel=hfjmps
|
||||
|
||||
;To change the starting year, month or day, uncomment the next 3 lines
|
||||
;Both StartMonth and StartDay are 0-indexed (i.e. 0 is January or the first day of a month)
|
||||
;StartYear=2241
|
||||
;StartMonth=01
|
||||
;StartDay=01
|
||||
|
||||
;Set to 1 if you want the pipboy to be available at the start of the game
|
||||
;Set to 2 to make the pipboy available by only skipping the vault suit movie check
|
||||
;PipBoyAvailableAtGameStart=1
|
||||
|
||||
;Choose the damage formula used to calculate combat damage.
|
||||
;Don't set this to anything other than 0 unless another mod you're using explicitly tells you to!
|
||||
;0 - Fallout default
|
||||
;1 - Glovz's Damage Fix
|
||||
;2 - Glovz's Damage Fix with Damage Multiplier tweak
|
||||
;5 - Haenlomal's Yet Another Ammo Mod
|
||||
;DamageFormula=0
|
||||
|
||||
;Prevents you from using 0 to escape from dialogue at any time.
|
||||
;DialogueFix=1
|
||||
|
||||
;Prevents you from using number keys to enter unvisited areas on a town map
|
||||
TownMapHotkeysFix=1
|
||||
|
||||
;Set to 1 to use a CriticalOverrides.ini file to override the default critical table
|
||||
;Set to 2 to use the default critical with bug fixes (doesn't require an ini)
|
||||
@@ -67,86 +20,9 @@ TownMapHotkeysFix=1
|
||||
;If the ExtraKillTypes option is enabled, this should be set to 3, with containing entries for any new types
|
||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||
;OverrideCriticalTable=2
|
||||
|
||||
;Change the Skilldex cursor FRM numbers
|
||||
;Default is 293 for all skills
|
||||
Lockpick=293
|
||||
Steal=293
|
||||
Traps=293
|
||||
FirstAid=293
|
||||
Doctor=293
|
||||
Science=293
|
||||
Repair=293
|
||||
|
||||
;Uncomment these lines to control the premade characters offered when starting a new game
|
||||
;Multiple options should be separated by commas, and there must be the same number of entries in both lines
|
||||
;Each name in PremadePaths is limited to 11 characters
|
||||
;PremadePaths=combat,diplomat,stealth
|
||||
;PremadeFIDs=201,203,202
|
||||
|
||||
;Use this line to modify the list of cities and their associated global variables used for city reputations
|
||||
;Syntax is 'city id:global id', with each city/global pair separated by a comma.
|
||||
;CityRepsList=0:5001,2:5003,3:5004,4:5005,5:5006,6:5007,7:5008,8:5009,10:5011,11:5012,60:1640
|
||||
|
||||
;Set to 1 to add additional pages of save slots !!! can be implemented !!!
|
||||
;ExtraSaveSlots=1
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
;Number of KarmaPoints should be 1 less than number of KarmaFRMs
|
||||
;KarmaFRMs=47,48,49
|
||||
;KarmaPoints=-100,100
|
||||
|
||||
;Set to 1 to allow science and repair to be used on the player, or 2 for all critters. (Rather than only brahmin/robots)
|
||||
ScienceOnCritters=0
|
||||
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
BonusHtHDamageFix=1
|
||||
|
||||
;Set to 1 to remove the limits that stop the game from rolling critical successes/failures in the first few days of game time
|
||||
RemoveCriticalTimelimits=0
|
||||
|
||||
;Change the colour of the font used on the main menu for the Fallout/sfall version string and copyright text
|
||||
;It's the last byte ('3C' by default) that picks the colour used. The first byte supplies additional flags for this option
|
||||
;1 - change the colour for the version string only
|
||||
;2 - underline text for the version string
|
||||
;4 - use monospace font for the version string
|
||||
;MainMenuFontColour=0x000055
|
||||
;Change the colour of the font used on the main menu for the button text
|
||||
;MainMenuBigFontColour=0x3C
|
||||
|
||||
;Uncomment the next four lines to move the main menu buttons and credit text (the 'Copyright(c)' line on the main menu)
|
||||
;MainMenuOffsetX=392
|
||||
;MainMenuOffsetY=26
|
||||
;MainMenuCreditsOffsetX=0
|
||||
;MainMenuCreditsOffsetY=0
|
||||
|
||||
;These options modify the bullet distribution of burst attacks
|
||||
;All the bullets are divided into three groups: center, left, and right
|
||||
;These groups will then travel along three parallel tracks, trying to hit targets on the way
|
||||
;CenterMult/Div set the ratio of how many bullets go to the center group, and the remaining are divided equally to the left and right sides
|
||||
;TargetMult/Div set the ratio of how many bullets in the center group will attack the primary target directly
|
||||
;Multiplier values are capped at divisor values
|
||||
;ComputeSpray_CenterMult=1
|
||||
;ComputeSpray_CenterDiv=3
|
||||
;ComputeSpray_TargetMult=1
|
||||
;ComputeSpray_TargetDiv=2
|
||||
|
||||
;Set to 1 to make explosions and projectiles emit light
|
||||
;ExplosionsEmitLight=1
|
||||
|
||||
;Uncomment these lines to change explosives damage. DmgMax can be set to 9999 at max, and DmgMin is capped at DmgMax
|
||||
;Dynamite_DmgMax=50
|
||||
;Dynamite_DmgMin=30
|
||||
;PlasticExplosive_DmgMax=80
|
||||
;PlasticExplosive_DmgMin=40
|
||||
|
||||
;To add additional game msg files, uncomment the next line and set a comma delimited list of filenames without .msg extension
|
||||
;By default, the files will have consecutive numbers assigned beginning with 0
|
||||
;You can use the syntax 'filename:number' to manually assign numbers to specific msg files, with each pair separated by a comma
|
||||
;If a file after the specified pair does not have a number assigned, it will have the next consecutive number from the last pair
|
||||
;You need to use the message_str_game script function to get messages from the files
|
||||
;ExtraGameMsgFileList=
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
; Configuration ini files
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -165,9 +41,6 @@ RemoveCriticalTimelimits=0
|
||||
;See the Unarmed.ini in the modders pack for an example file
|
||||
;UnarmedFile=sfall\Unarmed.ini
|
||||
|
||||
;To change some engine parameters for the game mechanics, uncomment the next line
|
||||
;TweaksFile=sfall\Tweaks.ini
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Scripts]
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
;
|
||||
; Game general config
|
||||
;
|
||||
; Fallout 2
|
||||
;
|
||||
|
||||
[start]
|
||||
; Starting year, month, day. Month and day are 0-indexed (0 = January, 0 = first day of month).
|
||||
year=2241
|
||||
month=6
|
||||
day=24
|
||||
; To start a new game somewhere other than artemple.map, set this to the map file name.
|
||||
map=
|
||||
; Starting (tribal) and default (jumpsuit) player models. Can also be changed in-game via script.
|
||||
model_male=hmwarr
|
||||
model_male_default=hmjmps
|
||||
model_female=hfprim
|
||||
model_female_default=hfjmps
|
||||
; Set to 1 if you want the pipboy to be available at the start of the game.
|
||||
; Set to 2 to make the pipboy available by only skipping the vault suit movie check.
|
||||
pipboy=0
|
||||
|
||||
[karma]
|
||||
; FRM numbers for karma icons on the character screen. Number of points entries should be 1 less than number of frms entries.
|
||||
; Example: frms=47,48,49 points=-100,100
|
||||
frms=
|
||||
points=
|
||||
|
||||
[items]
|
||||
; Proto IDs for healing items.
|
||||
stimpak=40
|
||||
super_stimpak=144
|
||||
healing_powder=273
|
||||
|
||||
[dialog]
|
||||
; Set to 1 to prevent using 0 to escape from dialogue at any time.
|
||||
no_exit_hotkey=1
|
||||
; Set to 1 to allow using '^' in dialog msg files to specify gender-based alternative text.
|
||||
; Text must be enclosed in angle brackets, e.g. <MaleText^FemaleText>.
|
||||
gender_words=0
|
||||
|
||||
[main_menu]
|
||||
; Custom version string shown on the main menu. Supports up to two %d placeholders for the game version numbers.
|
||||
; Example: FALLOUT II v1.02d
|
||||
version_string=
|
||||
; Font color for the version string and copyright text. Last byte picks the color (default 0x3C).
|
||||
; First byte flags: 1 - version string only, 2 - underline, 4 - monospace font.
|
||||
; Example: 0x000055
|
||||
font_color=0
|
||||
; Font color for the main menu button text.
|
||||
big_font_color=0
|
||||
; Pixel offset for main menu buttons.
|
||||
offset_x=0
|
||||
offset_y=0
|
||||
; Pixel offset for the copyright text line.
|
||||
credits_offset_x=0
|
||||
credits_offset_y=0
|
||||
|
||||
[movies]
|
||||
; Number of days after game start when each Hakunin dream sequence becomes available.
|
||||
artimer1=90
|
||||
artimer2=180
|
||||
artimer3=270
|
||||
artimer4=360
|
||||
|
||||
[combat]
|
||||
; Damage formula used to calculate combat damage.
|
||||
; 0 - Fallout default, 1 - Glovz's Damage Fix, 2 - Glovz's Damage Fix with Damage Multiplier tweak, 5 - Haenlomal's Yet Another Ammo Mod
|
||||
; Don't change this unless another mod explicitly requires it.
|
||||
damage_formula=0
|
||||
; Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
bonus_hth_damage_fix=1
|
||||
; Set to 1 to remove the time limits that prevent critical hits/misses in the first few days of the game.
|
||||
remove_critical_time_limits=0
|
||||
; Set to 1 to allow science and repair to be used on the player, or 2 for all critters (rather than only brahmin/robots).
|
||||
science_on_critters=0
|
||||
; Set to 1 to enable modified burst bullet distribution (spray mod).
|
||||
burst_enabled=0
|
||||
; Ratio of bullets going to the center group vs. left/right in burst attacks. Multiplier is capped at divisor.
|
||||
burst_center_mult=1
|
||||
burst_center_div=3
|
||||
; Ratio of center-group bullets that target the primary target directly. Multiplier is capped at divisor.
|
||||
burst_target_mult=1
|
||||
burst_target_div=2
|
||||
|
||||
[explosions]
|
||||
; Set to 1 to make explosions and projectiles emit light.
|
||||
emit_light=0
|
||||
; Dynamite damage range. Max is capped at 9999; min is capped at max.
|
||||
dynamite_max=50
|
||||
dynamite_min=30
|
||||
; Plastic explosive damage range. Max is capped at 9999; min is capped at max.
|
||||
plastic_explosive_max=80
|
||||
plastic_explosive_min=40
|
||||
|
||||
[skilldex]
|
||||
; FRM numbers for Skilldex skill cursors. Default is 293 for all skills.
|
||||
lockpick=293
|
||||
steal=293
|
||||
traps=293
|
||||
first_aid=293
|
||||
doctor=293
|
||||
science=293
|
||||
repair=293
|
||||
|
||||
[worldmap]
|
||||
; Set to 1 to prevent using number keys to enter unvisited areas on a town map.
|
||||
town_map_hotkeys_fix=1
|
||||
; Set to 1 to show travel markers on the world map, or 2 to show only when sneaking.
|
||||
trail_markers=0
|
||||
; Set to 1 to skip the encounter with Frank Horrigan.
|
||||
disable_horrigan=0
|
||||
; City reputation overrides. Syntax: city_id:global_id pairs separated by commas.
|
||||
; Example: 0:5001,2:5003,3:5004
|
||||
city_reputation_list=
|
||||
|
||||
[characters]
|
||||
; Custom premade characters for the character selection screen.
|
||||
; premade_paths is a comma-separated list of file names (max 11 chars each) in the premade\ folder, without extension.
|
||||
; premade_fids is a comma-separated list of FRM numbers for the character portrait, matching the order of premade_paths.
|
||||
; Example: premade_paths=combat,diplomat,stealth premade_fids=201,203,202
|
||||
premade_paths=
|
||||
premade_fids=
|
||||
|
||||
[text]
|
||||
; Comma-separated list of extra game message file names (without .msg extension) to load from the game\ folder.
|
||||
; Use 'filename:number' syntax to assign explicit IDs. Access via message_str_game script function.
|
||||
extra_msg_file_list=
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
#
|
||||
# enddeath.txt
|
||||
#
|
||||
# format of each line is:
|
||||
#
|
||||
# gvar, value, worldAreaKnown, worldAreaNotKnown, minLevel, %, narrator file
|
||||
#
|
||||
# Where:
|
||||
#
|
||||
# gvar is the GVAR_* number for the variable controlling the slide.
|
||||
#
|
||||
# value is the value that the gvar must be >= to for this slide
|
||||
# to be shown
|
||||
#
|
||||
# worldAreaKnown is the # of a worldmap area that has to be known
|
||||
# in order to get this one as an option
|
||||
#
|
||||
# worldAreaNotKnown is the # of a worldmap area that has to be *not*
|
||||
# known in order to get this one as an option
|
||||
#
|
||||
# minLevel is the minimum player level in order to get this one as
|
||||
# an option
|
||||
#
|
||||
# % is the % chance of a given line to occur
|
||||
#
|
||||
# narrator file is the base filename (no path path or extension) used
|
||||
# for the narrator voice-over and subtitles. Maximum of 8 characters.
|
||||
#
|
||||
|
||||
|
||||
#####
|
||||
# Generic Deaths
|
||||
#####
|
||||
-1, 0, -1, -1, 0, 20, NAR_3
|
||||
-1, 0, -1, -1, 0, 20, NAR_4
|
||||
-1, 0, -1, -1, 0, 20, NAR_5
|
||||
-1, 0, -1, -1, 0, 20, NAR_6
|
||||
-1, 0, 8, -1, 0, 20, NAR_8
|
||||
|
||||
#####
|
||||
# Specific Deaths
|
||||
#####
|
||||
-1, 0, -1, 0, 200, 0, nar_dth3
|
||||
-1, 0, -1, 0, 200, 0, nar_dth4
|
||||
-1, 0, -1, 0, 200, 0, nar_dth5
|
||||
-1, 0, -1, 0, 200, 0, nar_dth6
|
||||
-1, 0, -1, 0, 200, 0, nar_dth7
|
||||
-1, 0, -1, 0, 200, 0, nar_dth8
|
||||
-1, 0, -1, 0, 200, 0, nar_dth9
|
||||
|
||||
# Special Radiation Death
|
||||
491, 999, 3, -1, 150, 0, NAR_7
|
||||
|
||||
#####
|
||||
# Joke Deaths
|
||||
#####
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd1
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd3
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd4
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd5
|
||||
-1, 0, -1, -1, 10, 1, nar_jdd6
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,104 +0,0 @@
|
||||
|
||||
;
|
||||
; Party Member valid option data
|
||||
;
|
||||
|
||||
;
|
||||
; Warning: Adding a party member here means you must also add it to party.h!
|
||||
;
|
||||
|
||||
;
|
||||
; Note: Party Member level-up float messages are found in game\misc.msg!
|
||||
;
|
||||
|
||||
|
||||
[Party Member 0] ; Player -- Not actually used!
|
||||
party_member_pid=16777216
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed, unarmed_over_thrown, random
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime, always
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
|
||||
[Party Member 1] ; pMIan_PID
|
||||
party_member_pid=16777292
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, ranged_over_melee, ranged
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, defensive, aggressive, berserk
|
||||
level_minimum=3
|
||||
level_up_every=3
|
||||
level_pids=16777530,16777531,16777532,16777533
|
||||
|
||||
[Party Member 2] ; pMDog_PID
|
||||
party_member_pid=16777338
|
||||
area_attack_mode=
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=unarmed
|
||||
chem_use=clean
|
||||
distance=stay_close, charge, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, aggressive, berserk
|
||||
level_minimum=4
|
||||
level_up_every=3
|
||||
level_pids=16777542,16777543,16777544,16777545
|
||||
|
||||
[Party Member 3] ; pMTycho_PID
|
||||
party_member_pid=16777426
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, defensive, aggressive, berserk
|
||||
level_minimum=4
|
||||
level_up_every=3
|
||||
level_pids=16777534,16777535,16777536,16777537
|
||||
|
||||
[Party Member 4] ; pMKatja_PID
|
||||
party_member_pid=16777518
|
||||
area_attack_mode=sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=stims_when_hurt_little, stims_when_hurt_lots
|
||||
distance=stay_close, charge, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good
|
||||
disposition=none, custom, defensive, aggressive, coward
|
||||
level_minimum=4
|
||||
level_up_every=2
|
||||
level_pids=16777538,16777539,16777540,16777541
|
||||
|
||||
[Party Member 5] ; pMTandi_PID
|
||||
party_member_pid=16777279
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean, stims_when_hurt_little, stims_when_hurt_lots, sometimes, anytime, always
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
|
||||
[Party Member 6] ; pMMrHandyC_PID
|
||||
party_member_pid=16777529
|
||||
area_attack_mode=always, sometimes, be_sure, be_careful, be_absolutely_sure
|
||||
attack_who=whomever_attacking_me, strongest, weakest, whomever, closest
|
||||
best_weapon=no_pref, melee, melee_over_ranged, ranged_over_melee, ranged, unarmed
|
||||
chem_use=clean
|
||||
distance=stay_close, charge, snipe, on_your_own, stay
|
||||
run_away_mode=none, coward, finger_hurts, bleeding, not_feeling_good, tourniquet, never
|
||||
disposition=none, custom, coward, defensive, aggressive, berserk
|
||||
level_minimum=0
|
||||
level_up_every=0
|
||||
level_pids=-1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,402 +0,0 @@
|
||||
;
|
||||
; Fallout team quotes
|
||||
;
|
||||
; The fonts used to display this file are the reverse of the
|
||||
; credits.txt file. In other words, the font used to display
|
||||
; titles in credits.txt (the lines with the '@') is the font
|
||||
; used to display these quotes. Putting an '@' at the start of
|
||||
; a line in this file will use the font used to display the
|
||||
; names in the credits.txt file (currently 104).
|
||||
;
|
||||
; Max line length with the current font (103) is about 63.
|
||||
; Anything longer than that won't be displayed, as it won't fit
|
||||
; on the screen.
|
||||
;
|
||||
; All lines are automatically centered on the display.
|
||||
;
|
||||
; See top of credits.txt for additional info.
|
||||
;
|
||||
@Quotes from the Fallout team:
|
||||
(Press ESC if you don't want to see some raw language)
|
||||
|
||||
|
||||
I asked for anatomically correct, but not naked!
|
||||
- Tim C.
|
||||
|
||||
I appreciate the fact that ?? is only speaking to us when spoken to.
|
||||
- Leonard
|
||||
|
||||
So now that you are past the learning curve,
|
||||
you can blow up people much faster, right?
|
||||
- Tim C.
|
||||
|
||||
So how fast can _you_ draw a bunny?
|
||||
- JT
|
||||
|
||||
I didn't do it yet today because I was waiting for Leonard's head.
|
||||
- Scott C.
|
||||
|
||||
|
||||
|
||||
Did you see Steven Spielberg go by?
|
||||
- Tim C.
|
||||
No, I was taking a piss.
|
||||
- Mark Harrison
|
||||
|
||||
|
||||
|
||||
Blueberry muffins are one of Man's crowning achievements.
|
||||
- JT
|
||||
|
||||
Out of my way. I'm a fucking genius.
|
||||
- Jason
|
||||
|
||||
Dismemberment is just inherently funny.
|
||||
- JT
|
||||
|
||||
I had a wooden one, but Spence broke it.
|
||||
- Jesse
|
||||
|
||||
You can say penis, but you can't say cocksucker.
|
||||
- Leonard
|
||||
|
||||
It's fun to make fun of people who are stupid.
|
||||
- JT
|
||||
|
||||
Crap is the hardest stuff to make.
|
||||
- Michael
|
||||
|
||||
No, I haven't shot anyone today.
|
||||
- JT
|
||||
|
||||
|
||||
|
||||
But 15 _is_ an even number!
|
||||
- Leonard
|
||||
But 15 isn't divisible by 2.
|
||||
- Tim.
|
||||
You know what I mean. I meant 15 is prime.
|
||||
- Leonard
|
||||
|
||||
|
||||
|
||||
I'll be going on to death at the end of the day.
|
||||
- Michael
|
||||
|
||||
I'm tired of looking at that peanut.
|
||||
- Tim C.
|
||||
|
||||
I only wash my nose. It's the only thing that gets dirty.
|
||||
- Fred
|
||||
|
||||
I'm going to jiujitsu his ass.
|
||||
- Leonard
|
||||
|
||||
I'll have to remember or else I'll forget.
|
||||
- Jesse
|
||||
|
||||
You never know what wacky things I'm going to do with my hand.
|
||||
- Tim C.
|
||||
|
||||
Sorry I'm late, but Mary needed marbles and I had lost mine.
|
||||
- Chris T.
|
||||
|
||||
It's fun hitting other people's balls.
|
||||
- Tim C.
|
||||
|
||||
I'm going to kill this game.
|
||||
- Mark Morgan
|
||||
|
||||
Do you want help putting on your bikini?
|
||||
- Fred to Tim C.
|
||||
|
||||
I like to get them in the butt.
|
||||
- Tim C.
|
||||
|
||||
I need more peasants!
|
||||
- Fred
|
||||
|
||||
If I hadn't had sex, I would have called Tom or Jesse.
|
||||
- Scotty
|
||||
|
||||
Did you know you can talk to people who don't have heads?
|
||||
- Jesse
|
||||
|
||||
We'll have a little bowl hair-cut kid so you
|
||||
can't tell if it's a boy or a girl when you're killing it.
|
||||
- Leonard
|
||||
|
||||
It's just a flag!
|
||||
- Scotty
|
||||
|
||||
I'll tell them to give me more exploding peasants.
|
||||
- Fred
|
||||
|
||||
Do you need help changing his pants?
|
||||
- Leonard
|
||||
|
||||
I was getting home and getting ready to get some,
|
||||
and I remembered it was a holiday.
|
||||
- Scotty
|
||||
|
||||
I'd rather drink a bottle of urine than THAT!
|
||||
- Scotty
|
||||
|
||||
Rusty wants any body he can have.
|
||||
- Gus
|
||||
|
||||
Nick's are worn and falling apart and orange.
|
||||
- Jesse
|
||||
|
||||
I never let work interfere with my cooking.
|
||||
- Tim C.
|
||||
|
||||
I don't want you to stop making them,
|
||||
because it's the only time I get any.
|
||||
- Scotty
|
||||
|
||||
I vote for Hate.
|
||||
- Jason
|
||||
|
||||
That reminds me of Toxic Avenger, the unrated version.
|
||||
- Scotty
|
||||
|
||||
You know, we should lock down sex.
|
||||
- Chris T.
|
||||
|
||||
How do I kill people? I need some dead bodies.
|
||||
- Robert H.
|
||||
|
||||
Don't quote me on that.
|
||||
- Leonard
|
||||
|
||||
|
||||
|
||||
I had a weird dream involving Scotty,
|
||||
and I don't even want to remember it.
|
||||
- Jesse
|
||||
What?!
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I don't know what we're going to do about it.
|
||||
I guess we're going to have to start cutting heads.
|
||||
- Tim C.
|
||||
|
||||
Well, that's true and that's untrue.
|
||||
- Gus
|
||||
|
||||
But I like being a woman!
|
||||
- Scotty
|
||||
|
||||
I'm used to playing with myself.
|
||||
- Scotty
|
||||
|
||||
That's the essence of art -- making it all work together.
|
||||
- Leonard
|
||||
|
||||
Did I tell you I broke my thingy?
|
||||
- Dave
|
||||
|
||||
I want more randomness in my randomology.
|
||||
- Robert H.
|
||||
|
||||
I can't finish the AI without drugs.
|
||||
- Tim C.
|
||||
|
||||
Please do not make fun of my poop.
|
||||
- Tim C.
|
||||
|
||||
I know how to tell males from females now.
|
||||
- Tim C.
|
||||
|
||||
Excuse me, my butt did that.
|
||||
- Jesse
|
||||
|
||||
|
||||
|
||||
I'm going to kick you in the butt.
|
||||
- Robert H. to Tim C.
|
||||
Because it's soft as a baby's behind.
|
||||
- Jesse.
|
||||
How do you know?
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I can do Troy. I used to be his monkey.
|
||||
- Chris T.
|
||||
|
||||
I had one once, but I pumped it too hard and I broke it.
|
||||
- Scotty
|
||||
|
||||
I stripped and wiped.
|
||||
- Scotty
|
||||
|
||||
Why can't I be a lesbian?
|
||||
- Shanna
|
||||
|
||||
I wonder what that thing hanging there is.
|
||||
- Shanna
|
||||
|
||||
I need more intelligence.
|
||||
- Nick
|
||||
|
||||
At the same time, I want to make sure that
|
||||
I don't have dead people stand up.
|
||||
- Tim C.
|
||||
|
||||
I'd model dust, if I could.
|
||||
- Jason
|
||||
|
||||
I'm on top now.
|
||||
- Evan
|
||||
|
||||
I do a good cow.
|
||||
- Greg B.
|
||||
|
||||
If he's on top of me, I'm gonna be pissed!
|
||||
- Shanna
|
||||
|
||||
If I was a girl, I'd do him.
|
||||
- Evan
|
||||
|
||||
You won't be here when I get off.
|
||||
- Mike Krueger
|
||||
|
||||
Well, I was playing with it last night but I
|
||||
couldn't get anything to come out!
|
||||
- Mike Krueger
|
||||
|
||||
Stop shaking my monkey!
|
||||
- Matt Murakami
|
||||
|
||||
I like people who say poop.
|
||||
- Savina
|
||||
|
||||
It's not unstable, it's just buggy.
|
||||
There's a difference.
|
||||
- Chris J.
|
||||
|
||||
Instead of sexual urges, they get
|
||||
sucking blood urges.
|
||||
- Scotty
|
||||
|
||||
I like little boys who wear skirts.
|
||||
- Mike Krueger
|
||||
|
||||
His iguana-stick is way too long.
|
||||
- Leonard
|
||||
|
||||
Fallout is "By Americans, For Americans" and
|
||||
the rest of the world can just get stuffed.
|
||||
- Scotty
|
||||
|
||||
All the Brotherhood do it. They know how.
|
||||
- Nick
|
||||
|
||||
I'm going to teach you to script,
|
||||
that'll be torture.
|
||||
- Nick
|
||||
|
||||
His little thing looks better anyway.
|
||||
- Evan
|
||||
|
||||
He TOLD me to touch it!
|
||||
- Nick
|
||||
|
||||
I'm really scared of the people on the Internet.
|
||||
They're all dumb. Except for that one guy.
|
||||
- Scotty
|
||||
|
||||
|
||||
|
||||
I haven't touched it for two months.
|
||||
- Nick
|
||||
Well, you better start touching it.
|
||||
- Evan
|
||||
|
||||
|
||||
|
||||
You can never be paranoid enough.
|
||||
- Scotty
|
||||
|
||||
You should be 14-18 when you blow the Master.
|
||||
- Jess
|
||||
|
||||
Oh, wait a minute, talk to Jesse.
|
||||
Jesse usually has lots of drugs.
|
||||
- Scotty
|
||||
|
||||
I burnt my part, for one thing.
|
||||
- Mark H.
|
||||
|
||||
I'm usually a lot happier about the
|
||||
game when I'm not playing it.
|
||||
- Scotty
|
||||
|
||||
You gotta take it easy, this is my first time.
|
||||
- Dave Hendee
|
||||
|
||||
It's really quick to get it up.
|
||||
- Mark H.
|
||||
|
||||
I can find the hole without looking now.
|
||||
- Ed H.
|
||||
|
||||
I've actually had it both ways, but I'm not sure why...
|
||||
- Dan S.
|
||||
|
||||
I can touch it everywhere and it seems to work.
|
||||
- Scotty
|
||||
|
||||
OK, I was sleeping with Ian...
|
||||
- Gus
|
||||
|
||||
What is the sound of one man working on another?
|
||||
- Dan S.
|
||||
|
||||
I hate being fucked.
|
||||
- Gus
|
||||
|
||||
I think our game has a high potential
|
||||
for being very violent.
|
||||
- Jason A.
|
||||
|
||||
I'm not going to be beaten by cheesecake.
|
||||
- Tim C.
|
||||
|
||||
I have new respect for crowbars.
|
||||
(pause)
|
||||
Well, at least it isn't about sex.
|
||||
- Scotty
|
||||
|
||||
That thing is a little too
|
||||
big to stick right there.
|
||||
- Matt G.
|
||||
|
||||
|
||||
|
||||
I'm not going to do the cows.
|
||||
- Dan S.
|
||||
The cows are glad to hear that.
|
||||
- Robert H.
|
||||
|
||||
|
||||
|
||||
But I love faggot pizza.
|
||||
- Scotty
|
||||
|
||||
It won't crash any more. In theory.
|
||||
- Mark H.
|
||||
|
||||
I wasn't wearing anything
|
||||
the first time I won the game.
|
||||
- Tim C.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@FIN
|
||||
+2
-2
@@ -9,6 +9,7 @@
|
||||
#include "combat.h"
|
||||
#include "combat_ai.h"
|
||||
#include "config.h"
|
||||
#include "content_config.h"
|
||||
#include "critter.h"
|
||||
#include "debug.h"
|
||||
#include "display_monitor.h"
|
||||
@@ -28,7 +29,6 @@
|
||||
#include "random.h"
|
||||
#include "scripts.h"
|
||||
#include "settings.h"
|
||||
#include "sfall_config.h"
|
||||
#include "sfall_script_hooks.h"
|
||||
#include "skill.h"
|
||||
#include "stat.h"
|
||||
@@ -1410,7 +1410,7 @@ int actionUseSkill(Object* user, Object* target, int skill)
|
||||
// SFALL: Science on critters patch.
|
||||
if (1) {
|
||||
int targetType = SCIENCE_REPAIR_TARGET_TYPE_DEFAULT;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SCIENCE_REPAIR_TARGET_TYPE_KEY, &targetType);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "science_on_critters", &targetType, SCIENCE_REPAIR_TARGET_TYPE_DEFAULT);
|
||||
if (targetType == SCIENCE_REPAIR_TARGET_TYPE_DUDE) {
|
||||
if (target == gDude) {
|
||||
break;
|
||||
|
||||
+5
-25
@@ -6,15 +6,14 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "animation.h"
|
||||
#include "content_config.h"
|
||||
#include "debug.h"
|
||||
#include "draw.h"
|
||||
#include "game.h"
|
||||
#include "game_variant.h"
|
||||
#include "memory.h"
|
||||
#include "object.h"
|
||||
#include "proto.h"
|
||||
#include "settings.h"
|
||||
#include "sfall_config.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
@@ -191,28 +190,16 @@ int artInit()
|
||||
|
||||
// SFALL: Modify player model settings.
|
||||
char* jumpsuitMaleFileName = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY, &jumpsuitMaleFileName);
|
||||
if (jumpsuitMaleFileName == nullptr || jumpsuitMaleFileName[0] == '\0') {
|
||||
jumpsuitMaleFileName = gDefaultJumpsuitMaleFileName;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_START_SECTION, "model_male_default", &jumpsuitMaleFileName, gDefaultJumpsuitMaleFileName);
|
||||
|
||||
char* jumpsuitFemaleFileName = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_FEMALE_KEY, &jumpsuitFemaleFileName);
|
||||
if (jumpsuitFemaleFileName == nullptr || jumpsuitFemaleFileName[0] == '\0') {
|
||||
jumpsuitFemaleFileName = gDefaultJumpsuitFemaleFileName;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_START_SECTION, "model_female_default", &jumpsuitFemaleFileName, gDefaultJumpsuitFemaleFileName);
|
||||
|
||||
char* tribalMaleFileName = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_MALE_KEY, &tribalMaleFileName);
|
||||
if (tribalMaleFileName == nullptr || tribalMaleFileName[0] == '\0') {
|
||||
tribalMaleFileName = gDefaultTribalMaleFileName;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_START_SECTION, "model_male", &tribalMaleFileName, gDefaultTribalMaleFileName);
|
||||
|
||||
char* tribalFemaleFileName = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, &tribalFemaleFileName);
|
||||
if (tribalFemaleFileName == nullptr || tribalFemaleFileName[0] == '\0') {
|
||||
tribalFemaleFileName = gDefaultTribalFemaleFileName;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_START_SECTION, "model_female", &tribalFemaleFileName, gDefaultTribalFemaleFileName);
|
||||
|
||||
char* critterFileNames = gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
@@ -232,13 +219,6 @@ int artInit()
|
||||
critterFileNames += 13;
|
||||
}
|
||||
|
||||
// FO1 does not have a tribal look; use jumpsuit as the default player art.
|
||||
if (gameVariantIsFallout1() && _art_vault_guy_num == 0) {
|
||||
_art_vault_guy_num = _art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE];
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = _art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE];
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = _art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE];
|
||||
}
|
||||
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (!fileReadString(string, sizeof(string), stream)) {
|
||||
break;
|
||||
|
||||
+8
-19
@@ -11,6 +11,7 @@
|
||||
#include "art.h"
|
||||
#include "color.h"
|
||||
#include "combat.h"
|
||||
#include "content_config.h"
|
||||
#include "critter.h"
|
||||
#include "cycle.h"
|
||||
#include "db.h"
|
||||
@@ -37,7 +38,6 @@
|
||||
#include "platform_compat.h"
|
||||
#include "proto.h"
|
||||
#include "scripts.h"
|
||||
#include "sfall_config.h"
|
||||
#include "skill.h"
|
||||
#include "stat.h"
|
||||
#include "svga.h"
|
||||
@@ -6988,7 +6988,7 @@ static int karmaInit()
|
||||
|
||||
File* stream = fileOpen("data\\karmavar.txt", "rt");
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char string[256];
|
||||
@@ -7087,7 +7087,7 @@ static int genericReputationInit()
|
||||
|
||||
File* stream = fileOpen("data\\genrep.txt", "rt");
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char string[256];
|
||||
@@ -7167,22 +7167,14 @@ static int genericReputationCompare(const void* a1, const void* a2)
|
||||
static void customKarmaFolderInit()
|
||||
{
|
||||
char* karmaFrms = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_KARMA_FRMS_KEY, &karmaFrms);
|
||||
if (karmaFrms != nullptr && karmaFrms[0] == '\0') {
|
||||
karmaFrms = nullptr;
|
||||
}
|
||||
|
||||
if (karmaFrms == nullptr) {
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_KARMA_SECTION, "frms", &karmaFrms, "");
|
||||
if (!*karmaFrms) {
|
||||
return;
|
||||
}
|
||||
|
||||
char* karmaPoints = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_KARMA_POINTS_KEY, &karmaPoints);
|
||||
if (karmaPoints != nullptr && karmaPoints[0] == '\0') {
|
||||
karmaPoints = nullptr;
|
||||
}
|
||||
|
||||
if (karmaPoints == nullptr) {
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_KARMA_SECTION, "points", &karmaPoints, "");
|
||||
if (!*karmaPoints) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7256,10 +7248,7 @@ static int customKarmaFolderGetFrmId()
|
||||
static void customTownReputationInit()
|
||||
{
|
||||
char* reputationList = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CITY_REPUTATION_LIST_KEY, &reputationList);
|
||||
if (reputationList != nullptr && *reputationList == '\0') {
|
||||
reputationList = nullptr;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_WORLDMAP_SECTION, "city_reputation_list", &reputationList, nullptr);
|
||||
|
||||
char* curr = reputationList;
|
||||
while (curr != nullptr) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "art.h"
|
||||
#include "character_editor.h"
|
||||
#include "color.h"
|
||||
#include "content_config.h"
|
||||
#include "critter.h"
|
||||
#include "db.h"
|
||||
#include "debug.h"
|
||||
@@ -26,7 +27,6 @@
|
||||
#include "preferences.h"
|
||||
#include "proto.h"
|
||||
#include "settings.h"
|
||||
#include "sfall_config.h"
|
||||
#include "skill.h"
|
||||
#include "stat.h"
|
||||
#include "svga.h"
|
||||
@@ -610,8 +610,6 @@ static bool characterSelectorWindowRenderFace()
|
||||
// 0x4A7EA8
|
||||
static bool characterSelectorWindowRenderStats()
|
||||
{
|
||||
static char emptyString[] = "";
|
||||
|
||||
char* str;
|
||||
char text[260];
|
||||
int length;
|
||||
@@ -830,9 +828,6 @@ static bool characterSelectorWindowRenderStats()
|
||||
y += vh;
|
||||
|
||||
str = skillGetName(skills[index]);
|
||||
if (str == nullptr) {
|
||||
str = emptyString;
|
||||
}
|
||||
strcpy(text, str);
|
||||
|
||||
length = fontGetStringWidth(text);
|
||||
@@ -905,16 +900,10 @@ static bool characterSelectorWindowFatalError(bool result)
|
||||
void premadeCharactersInit()
|
||||
{
|
||||
char* fileNamesString;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FILE_NAMES_KEY, &fileNamesString);
|
||||
if (fileNamesString != nullptr && *fileNamesString == '\0') {
|
||||
fileNamesString = nullptr;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_CHARACTERS_SECTION, "premade_paths", &fileNamesString, nullptr);
|
||||
|
||||
char* faceFidsString;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FACE_FIDS_KEY, &faceFidsString);
|
||||
if (faceFidsString != nullptr && *faceFidsString == '\0') {
|
||||
faceFidsString = nullptr;
|
||||
}
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_CHARACTERS_SECTION, "premade_fids", &faceFidsString, nullptr);
|
||||
|
||||
if (fileNamesString != nullptr && faceFidsString != nullptr) {
|
||||
int fileNamesLength = 0;
|
||||
|
||||
+21
-16
@@ -9,6 +9,7 @@
|
||||
#include "art.h"
|
||||
#include "color.h"
|
||||
#include "combat_ai.h"
|
||||
#include "content_config.h"
|
||||
#include "critter.h"
|
||||
#include "db.h"
|
||||
#include "debug.h"
|
||||
@@ -1983,13 +1984,14 @@ static const char* gCritDataMemberKeys[CRIT_DATA_MEMBER_COUNT] = {
|
||||
};
|
||||
|
||||
static bool gBurstModEnabled = false;
|
||||
static int gBurstModCenterMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER;
|
||||
static int gBurstModCenterDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR;
|
||||
static int gBurstModTargetMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_MULTIPLIER;
|
||||
static int gBurstModTargetDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_DIVISOR;
|
||||
static int gBurstModCenterMultiplier = 1;
|
||||
static int gBurstModCenterDivisor = 3;
|
||||
static int gBurstModTargetMultiplier = 1;
|
||||
static int gBurstModTargetDivisor = 2;
|
||||
static UnarmedHitDescription gUnarmedHitDescriptions[HIT_MODE_COUNT];
|
||||
static int gDamageCalculationType;
|
||||
static bool gBonusHthDamageFix;
|
||||
static bool gRemoveCriticalTimeLimits;
|
||||
static bool gDisplayBonusDamage;
|
||||
|
||||
// combat_init
|
||||
@@ -4237,12 +4239,8 @@ static int attackComputeCriticalFailure(Attack* attack)
|
||||
}
|
||||
|
||||
if (attack->attacker == gDude) {
|
||||
// SFALL: Remove criticals time limits.
|
||||
bool criticalsTimeLimitsRemoved = false;
|
||||
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_REMOVE_CRITICALS_TIME_LIMITS_KEY, &criticalsTimeLimitsRemoved);
|
||||
|
||||
unsigned int gameTime = gameTimeGetTime();
|
||||
if (!criticalsTimeLimitsRemoved && gameTime / GAME_TIME_TICKS_PER_DAY < 6) {
|
||||
if (!gRemoveCriticalTimeLimits && gameTime / GAME_TIME_TICKS_PER_DAY < 6) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -6087,6 +6085,8 @@ int combatGetTargetHighlight()
|
||||
|
||||
static void criticalsInit()
|
||||
{
|
||||
configGetBool(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "remove_critical_time_limits", &gRemoveCriticalTimeLimits, false);
|
||||
|
||||
int mode = 2;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_OVERRIDE_CRITICALS_MODE_KEY, &mode);
|
||||
if (mode < 0 || mode > 3) {
|
||||
@@ -6345,12 +6345,17 @@ void criticalsResetValue(int killType, int hitLocation, int effect, int dataMemb
|
||||
}
|
||||
}
|
||||
|
||||
bool criticalsNoTimeLimits()
|
||||
{
|
||||
return gRemoveCriticalTimeLimits;
|
||||
}
|
||||
|
||||
static void burstModInit()
|
||||
{
|
||||
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_ENABLED_KEY, &gBurstModEnabled);
|
||||
configGetBool(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "burst_enabled", &gBurstModEnabled);
|
||||
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_MULTIPLIER_KEY, &gBurstModCenterMultiplier);
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY, &gBurstModCenterDivisor);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "burst_center_mult", &gBurstModCenterMultiplier, 1);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "burst_center_div", &gBurstModCenterDivisor, 3);
|
||||
if (gBurstModCenterDivisor < 1) {
|
||||
gBurstModCenterDivisor = 1;
|
||||
}
|
||||
@@ -6358,8 +6363,8 @@ static void burstModInit()
|
||||
gBurstModCenterMultiplier = gBurstModCenterDivisor;
|
||||
}
|
||||
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY, &gBurstModTargetMultiplier);
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY, &gBurstModTargetDivisor);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "burst_target_mult", &gBurstModTargetMultiplier, 1);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "burst_target_div", &gBurstModTargetDivisor, 2);
|
||||
if (gBurstModTargetDivisor < 1) {
|
||||
gBurstModTargetDivisor = 1;
|
||||
}
|
||||
@@ -6700,10 +6705,10 @@ static int unarmedGetHitModeInRange(int firstHitMode, int lastHitMode, bool isSe
|
||||
static void damageModInit()
|
||||
{
|
||||
gDamageCalculationType = DAMAGE_CALCULATION_TYPE_VANILLA;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DAMAGE_MOD_FORMULA_KEY, &gDamageCalculationType);
|
||||
configGetInt(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "damage_formula", &gDamageCalculationType, DAMAGE_CALCULATION_TYPE_VANILLA);
|
||||
|
||||
gBonusHthDamageFix = true;
|
||||
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BONUS_HTH_DAMAGE_FIX_KEY, &gBonusHthDamageFix);
|
||||
configGetBool(&gContentConfig, CONTENT_CONFIG_COMBAT_SECTION, "bonus_hth_damage_fix", &gBonusHthDamageFix);
|
||||
|
||||
gDisplayBonusDamage = settings.ui.display_bonus_damage;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ int combatGetTargetHighlight();
|
||||
int criticalsGetValue(int killType, int hitLocation, int effect, int dataMember);
|
||||
void criticalsSetValue(int killType, int hitLocation, int effect, int dataMember, int value);
|
||||
void criticalsResetValue(int killType, int hitLocation, int effect, int dataMember);
|
||||
bool criticalsNoTimeLimits();
|
||||
int unarmedGetDamage(int hitMode, int* minDamagePtr, int* maxDamagePtr);
|
||||
int unarmedGetBonusCriticalChance(int hitMode);
|
||||
int unarmedGetActionPointCost(int hitMode);
|
||||
|
||||
+60
-39
@@ -132,6 +132,7 @@ static bool aiCanUseItem(Object* obj, Object* a2);
|
||||
static Object* _ai_search_environ(Object* critter, int itemType);
|
||||
static Object* _ai_retrieve_object(Object* critter, Object* item);
|
||||
static int _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender);
|
||||
static bool _aiIsMeleeThreat(Object* attacker, Object* defender);
|
||||
static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, bool taunt);
|
||||
static int _ai_move_closer(Object* a1, Object* a2, bool taunt);
|
||||
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
|
||||
@@ -420,50 +421,29 @@ int aiInit()
|
||||
if (!configGetInt(&config, sectionEntry->key, "outline_color", &(ai->outline_color))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "chance", &(ai->chance))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "run_start", &(ai->run.start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "run_end", &(ai->run.end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "move_start", &(ai->move.start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "move_end", &(ai->move.end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "attack_start", &(ai->attack.start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "attack_end", &(ai->attack.end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "miss_start", &(ai->miss.start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "miss_end", &(ai->miss.end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_head_start", &(ai->hit[HIT_LOCATION_HEAD].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_head_end", &(ai->hit[HIT_LOCATION_HEAD].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_arm_start", &(ai->hit[HIT_LOCATION_LEFT_ARM].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_arm_end", &(ai->hit[HIT_LOCATION_LEFT_ARM].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_arm_start", &(ai->hit[HIT_LOCATION_RIGHT_ARM].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_arm_end", &(ai->hit[HIT_LOCATION_RIGHT_ARM].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_torso_start", &(ai->hit[HIT_LOCATION_TORSO].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_torso_end", &(ai->hit[HIT_LOCATION_TORSO].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_leg_start", &(ai->hit[HIT_LOCATION_RIGHT_LEG].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_leg_end", &(ai->hit[HIT_LOCATION_RIGHT_LEG].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_leg_start", &(ai->hit[HIT_LOCATION_LEFT_LEG].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_leg_end", &(ai->hit[HIT_LOCATION_LEFT_LEG].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_eyes_start", &(ai->hit[HIT_LOCATION_EYES].start))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_eyes_end", &(ai->hit[HIT_LOCATION_EYES].end))) goto err;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_groin_start", &(ai->hit[HIT_LOCATION_GROIN].start))) goto err;
|
||||
|
||||
// *_end fields are optional: FO1's ai.txt omits them and uses each *_start as
|
||||
// the inclusive upper bound of the preceding range (FO1-CE convention).
|
||||
// FO2's ai.txt always supplies explicit *_end values.
|
||||
if (!configGetInt(&config, sectionEntry->key, "run_end", &(ai->run.end)))
|
||||
ai->run.end = ai->move.start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "move_end", &(ai->move.end)))
|
||||
ai->move.end = ai->attack.start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "attack_end", &(ai->attack.end)))
|
||||
ai->attack.end = ai->miss.start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "miss_end", &(ai->miss.end)))
|
||||
ai->miss.end = ai->hit[HIT_LOCATION_HEAD].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_head_end", &(ai->hit[HIT_LOCATION_HEAD].end)))
|
||||
ai->hit[HIT_LOCATION_HEAD].end = ai->hit[HIT_LOCATION_LEFT_ARM].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_arm_end", &(ai->hit[HIT_LOCATION_LEFT_ARM].end)))
|
||||
ai->hit[HIT_LOCATION_LEFT_ARM].end = ai->hit[HIT_LOCATION_RIGHT_ARM].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_arm_end", &(ai->hit[HIT_LOCATION_RIGHT_ARM].end)))
|
||||
ai->hit[HIT_LOCATION_RIGHT_ARM].end = ai->hit[HIT_LOCATION_TORSO].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_torso_end", &(ai->hit[HIT_LOCATION_TORSO].end)))
|
||||
ai->hit[HIT_LOCATION_TORSO].end = ai->hit[HIT_LOCATION_RIGHT_LEG].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_right_leg_end", &(ai->hit[HIT_LOCATION_RIGHT_LEG].end)))
|
||||
ai->hit[HIT_LOCATION_RIGHT_LEG].end = ai->hit[HIT_LOCATION_LEFT_LEG].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_left_leg_end", &(ai->hit[HIT_LOCATION_LEFT_LEG].end)))
|
||||
ai->hit[HIT_LOCATION_LEFT_LEG].end = ai->hit[HIT_LOCATION_EYES].start;
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_eyes_end", &(ai->hit[HIT_LOCATION_EYES].end)))
|
||||
ai->hit[HIT_LOCATION_EYES].end = ai->hit[HIT_LOCATION_GROIN].start;
|
||||
// groin: FO1 uses last_msg as the inclusive end; CE expects the value before
|
||||
// the ++ below, so store last_msg - 1 so that ++ yields last_msg.
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_groin_end", &(ai->hit[HIT_LOCATION_GROIN].end))) {
|
||||
int lastMsg;
|
||||
if (!configGetInt(&config, sectionEntry->key, "last_msg", &lastMsg)) goto err;
|
||||
ai->hit[HIT_LOCATION_GROIN].end = lastMsg - 1;
|
||||
}
|
||||
if (!configGetInt(&config, sectionEntry->key, "hit_groin_end", &(ai->hit[HIT_LOCATION_GROIN].end))) goto err;
|
||||
|
||||
ai->hit[HIT_LOCATION_GROIN].end++;
|
||||
|
||||
@@ -598,11 +578,8 @@ int aiLoad(File* stream)
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
// TODO: fo1_shims party.txt contains FO2 pids with no valid proto
|
||||
// in FO1. Skip them rather than abort; fix by supplying a minimal
|
||||
// FO1-only party.txt.
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
AiPacket* ai = aiGetPacketByNum(proto->critter.aiPacket);
|
||||
@@ -622,9 +599,8 @@ int aiSave(File* stream)
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
// TODO: same FO1 party.txt issue as aiLoad — skip invalid pids.
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
AiPacket* ai = aiGetPacketByNum(proto->critter.aiPacket);
|
||||
@@ -2376,6 +2352,28 @@ static int _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender)
|
||||
return HIT_MODE_RIGHT_WEAPON_PRIMARY;
|
||||
}
|
||||
|
||||
// Returns true if the defender is primarily a melee threat.
|
||||
static bool _aiIsMeleeThreat(Object* attacker, Object* defender)
|
||||
{
|
||||
if (defender == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object* weapon = critterGetItem2(defender);
|
||||
|
||||
if (weapon != nullptr && itemGetType(weapon) == ITEM_TYPE_WEAPON) {
|
||||
int attackType = weaponGetAttackTypeForHitMode(weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY);
|
||||
if (attackType == ATTACK_TYPE_RANGED || attackType == ATTACK_TYPE_THROW) {
|
||||
return false;
|
||||
}
|
||||
if (attackType == ATTACK_TYPE_MELEE || attackType == ATTACK_TYPE_UNARMED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x429FC8
|
||||
static int _ai_move_steps_closer(Object* critter, Object* target, int actionPoints, bool taunt)
|
||||
{
|
||||
@@ -2746,6 +2744,29 @@ static int _ai_try_attack(Object* attacker, Object* defender)
|
||||
_ai_switch_weapons(attacker, &hitMode, &weapon, defender);
|
||||
}
|
||||
|
||||
AiPacket* ai = aiGetPacket(attacker);
|
||||
if (weapon != nullptr && itemGetType(weapon) == ITEM_TYPE_WEAPON) {
|
||||
int attackType = weaponGetAttackTypeForHitMode(weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY);
|
||||
if (attackType == ATTACK_TYPE_RANGED
|
||||
&& ai->best_weapon != BEST_WEAPON_MELEE
|
||||
&& ai->best_weapon != BEST_WEAPON_MELEE_OVER_RANGED
|
||||
&& _aiIsMeleeThreat(attacker, defender)
|
||||
&& objectGetDistanceBetween(attacker, defender) <= 2) {
|
||||
int attackCost = weaponGetActionPointCost(attacker, hitMode, false);
|
||||
int moveCost = 2;
|
||||
if (attacker->data.critter.combat.ap > attackCost + moveCost) {
|
||||
if (_ai_move_away(attacker, defender, 2) == -1) {
|
||||
}
|
||||
|
||||
weapon = critterGetItem2(attacker);
|
||||
if (weapon != nullptr && itemGetType(weapon) != ITEM_TYPE_WEAPON) {
|
||||
weapon = nullptr;
|
||||
}
|
||||
hitMode = _ai_pick_hit_mode(attacker, weapon, defender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char rotations[800];
|
||||
|
||||
Object* ammo = nullptr;
|
||||
|
||||
@@ -135,6 +135,7 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: use const char** for valuePtr to enforce read-only API
|
||||
// 0x42BF48
|
||||
bool configGetString(Config* config, const char* sectionKey, const char* key, char** valuePtr)
|
||||
{
|
||||
@@ -833,6 +834,17 @@ bool configGetBool(Config* config, const char* sectionKey, const char* key, bool
|
||||
return true;
|
||||
}
|
||||
|
||||
bool configGetBool(Config* config, const char* sectionKey, const char* key, bool* valuePtr, const bool defaultValue)
|
||||
{
|
||||
if (config == nullptr || sectionKey == nullptr || key == nullptr || valuePtr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (!configGetBool(config, sectionKey, key, valuePtr)) {
|
||||
*valuePtr = defaultValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Boolean-typed variant of [configGetInt].
|
||||
bool configSetBool(Config* config, const char* sectionKey, const char* key, bool value)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user