mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a4469cc57 | ||
|
|
8bf7064a08 | ||
|
|
dfea73105c | ||
|
|
dd604b22b6 | ||
|
|
e1426a40c6 | ||
|
|
ae6c7aba6e | ||
|
|
e5387bef63 | ||
|
|
76080a4878 | ||
|
|
12314cd5d7 | ||
|
|
a0e1b73116 | ||
|
|
23c38f60f1 | ||
|
|
0c1ecfc3ac | ||
|
|
45676bcc05 | ||
|
|
46152f7e86 | ||
|
|
b6d1a29411 | ||
|
|
6bbd1a48cc | ||
|
|
3b7e1d8916 | ||
|
|
1f05d0b690 | ||
|
|
444565e8a1 |
@@ -142,7 +142,7 @@ jobs:
|
|||||||
ios:
|
ios:
|
||||||
name: iOS
|
name: iOS
|
||||||
|
|
||||||
runs-on: macos-14
|
runs-on: macos-15
|
||||||
needs: [ce-dat]
|
needs: [ce-dat]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -328,7 +328,7 @@ jobs:
|
|||||||
macos:
|
macos:
|
||||||
name: macOS
|
name: macOS
|
||||||
|
|
||||||
runs-on: macos-14
|
runs-on: macos-15
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone
|
- name: Clone
|
||||||
|
|||||||
+2
-2
@@ -6,10 +6,10 @@ set(EXECUTABLE_NAME fallout2-ce)
|
|||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
if(IOS)
|
if(IOS)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12" CACHE STRING "")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "13" CACHE STRING "")
|
||||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "")
|
||||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -42,13 +42,7 @@ The following settings were moved into [`<DAT>/config/game.cfg`](files/ce.dat/co
|
|||||||
|
|
||||||
| ddraw.ini section | ddraw.ini key | game.cfg section | game.cfg key |
|
| ddraw.ini section | ddraw.ini key | game.cfg section | game.cfg key |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `Misc` | `StartingMap` | `start` | `map` |
|
|
||||||
| `Misc` | `StartXPos` | `start` | `worldmap_x` |
|
|
||||||
| `Misc` | `StartYPos` | `start` | `worldmap_y` |
|
|
||||||
| `Misc` | `ViewXPos` | `start` | `worldmap_view_x` |
|
|
||||||
| `Misc` | `ViewYPos` | `start` | `worldmap_view_y` |
|
|
||||||
| `Misc` | `StartGDialogFix` | `dialog` | `start_gdialog_fix` |
|
| `Misc` | `StartGDialogFix` | `dialog` | `start_gdialog_fix` |
|
||||||
| `Misc` | `DisableSpecialMapIDs` | `maps` | `disable_special_map_ids` |
|
|
||||||
|
|
||||||
## Opcodes / Metarules
|
## Opcodes / Metarules
|
||||||
|
|
||||||
@@ -65,7 +59,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
|||||||
| 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 | - |
|
| 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 |
|
| 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 | - |
|
| 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{_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, get_terrain_name, set_terrain_name | - |
|
| Maps and encounters | in_world_map<br>force_encounter{_with_flags}<br>set_map_time_multi<br>get/set_map_enter_position<br>exec_map_update_scripts<br>get/set_terrain_name<br>set_town_title<br>get/set_can_rest_on_map<br>set_rest_heal_time<br>set_rest_mode<br>set_worldmap_heal_time | implemented: in_world_map, force_encounter, force_encounter_with_flags, set_map_time_multi | - |
|
||||||
| Maps and encounters / Worldmap | get_world_map_x/y_pos<br>set_world_map_pos | âś… | - |
|
| Maps and encounters / Worldmap | get_world_map_x/y_pos<br>set_world_map_pos | âś… | - |
|
||||||
| Audio | play_sfall_sound<br>stop_sfall_sound | âś… | `play_sfall_sound` currently supports `.acm`, `.wav`, `.ogg` formats, and can load from `.dat` archives. `.mp3` is not yet supported. |
|
| Audio | play_sfall_sound<br>stop_sfall_sound | âś… | `play_sfall_sound` currently supports `.acm`, `.wav`, `.ogg` formats, and can load from `.dat` archives. `.mp3` is not yet supported. |
|
||||||
| Combat / Weapons and ammo | get/set_weapon_ammo_pid<br>get/set_weapon_ammo_count | âś… | - |
|
| Combat / Weapons and ammo | get/set_weapon_ammo_pid<br>get/set_weapon_ammo_count | âś… | - |
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ month=6
|
|||||||
day=24
|
day=24
|
||||||
; To start a new game somewhere other than artemple.map, set this to the map file name.
|
; To start a new game somewhere other than artemple.map, set this to the map file name.
|
||||||
map=
|
map=
|
||||||
; Starting worldmap marker position. -1 uses the starting map's world area.
|
|
||||||
worldmap_x=-1
|
|
||||||
worldmap_y=-1
|
|
||||||
; Starting worldmap viewport position. -1 uses the default upper-left view.
|
|
||||||
worldmap_view_x=-1
|
|
||||||
worldmap_view_y=-1
|
|
||||||
; Starting (tribal) and default (jumpsuit) player models. Can also be changed in-game via script.
|
; Starting (tribal) and default (jumpsuit) player models. Can also be changed in-game via script.
|
||||||
model_male=hmwarr
|
model_male=hmwarr
|
||||||
model_male_default=hmjmps
|
model_male_default=hmjmps
|
||||||
@@ -26,11 +20,6 @@ model_female_default=hfjmps
|
|||||||
; Set to 2 to make the pipboy available by only skipping the vault suit movie check.
|
; Set to 2 to make the pipboy available by only skipping the vault suit movie check.
|
||||||
pipboy=0
|
pipboy=0
|
||||||
|
|
||||||
[maps]
|
|
||||||
; Set to 1 to apply transition tile, elevation, and rotation overrides on all maps,
|
|
||||||
; including Fallout 2 map IDs 19 and 37.
|
|
||||||
disable_special_map_ids=0
|
|
||||||
|
|
||||||
[karma]
|
[karma]
|
||||||
; FRM numbers for karma icons on the character screen. Number of points entries should be 1 less than number of frms entries.
|
; 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
|
; Example: frms=47,48,49 points=-100,100
|
||||||
|
|||||||
@@ -165,16 +165,6 @@ main_menu_scale_mode=1
|
|||||||
; Set to 1 to show a Help option in the in-game options menu which opens the F1 help screen.
|
; Set to 1 to show a Help option in the in-game options menu which opens the F1 help screen.
|
||||||
in_game_menu_help=1
|
in_game_menu_help=1
|
||||||
|
|
||||||
; Weight/size indicator for PC, critters and containers
|
|
||||||
; Set to 0 for vanilla behavior (no weight indicator)
|
|
||||||
; Set to 1 to show a simple weight indicator; works with all inventory_columns values
|
|
||||||
; Set to 2 to show a detailed weight indicator; works with inventory_columns > 1 only
|
|
||||||
loot_weight_indicator=1
|
|
||||||
|
|
||||||
; Set to 0 to show container indicator at all times
|
|
||||||
; Set to XX to show container indicator when size reaches XX%
|
|
||||||
; Set to 100 to show container indicator when full
|
|
||||||
loot_container_size_indicator_threshold=50
|
|
||||||
|
|
||||||
[qol]
|
[qol]
|
||||||
; Automatically open doors that are unlocked and has no script attached.
|
; Automatically open doors that are unlocked and has no script attached.
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ def assertSdlJavaBindingsMatch = { String variantName ->
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 32
|
compileSdk 32
|
||||||
|
ndkVersion "27.3.13750724"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'com.alexbatalov.fallout2ce'
|
applicationId 'com.alexbatalov.fallout2ce'
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
#include "test_utils.h"
|
|
||||||
#include "sfall.h"
|
|
||||||
|
|
||||||
procedure start begin
|
|
||||||
variable defaultName;
|
|
||||||
|
|
||||||
display_msg("Testing terrain name metarules...");
|
|
||||||
|
|
||||||
call assertEquals("get metarule exists", metarule_exist("get_terrain_name"), 1);
|
|
||||||
call assertEquals("set metarule exists", metarule_exist("set_terrain_name"), 1);
|
|
||||||
|
|
||||||
defaultName := get_terrain_name(0, 0);
|
|
||||||
call assertNotEquals("default terrain name is not error", defaultName, "Error");
|
|
||||||
call assertNotEquals("default terrain name is not empty", defaultName, "");
|
|
||||||
|
|
||||||
set_terrain_name(0, 0, "CE Terrain Override");
|
|
||||||
call assertEquals("terrain override is returned", get_terrain_name(0, 0), "CE Terrain Override");
|
|
||||||
|
|
||||||
set_terrain_name(0, 0, "CE Terrain Override 2");
|
|
||||||
call assertEquals("latest terrain override wins", get_terrain_name(0, 0), "CE Terrain Override 2");
|
|
||||||
call assertEquals("one argument get returns error", sfall_func1("get_terrain_name", 0), -1);
|
|
||||||
call assertEquals("invalid get returns error", get_terrain_name(-1, 0), "Error");
|
|
||||||
call assertNotEquals("current terrain name is available", get_current_terrain_name, "Error");
|
|
||||||
|
|
||||||
call report_test_results("terrain_name");
|
|
||||||
signal_close_game;
|
|
||||||
end
|
|
||||||
+7
-7
@@ -97,7 +97,7 @@ static int _compute_explosion_damage(int min, int max, Object* defender, int* kn
|
|||||||
static int _can_talk_to(Object* obj, Object* critter);
|
static int _can_talk_to(Object* obj, Object* critter);
|
||||||
static int _talk_to(Object* _, Object* critter);
|
static int _talk_to(Object* _, Object* critter);
|
||||||
static int _report_dmg(Attack* attack, Object* _);
|
static int _report_dmg(Attack* attack, Object* _);
|
||||||
static int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, DamageType damageType);
|
static int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType);
|
||||||
|
|
||||||
static int hideProjectile(void* _, void* projectile);
|
static int hideProjectile(void* _, void* projectile);
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ int pickDeathAnim(Object* attacker, Object* defender, Object* weapon, int damage
|
|||||||
int normalViolenceLevelDamageThreshold = 15;
|
int normalViolenceLevelDamageThreshold = 15;
|
||||||
int maximumBloodViolenceLevelDamageThreshold = 45;
|
int maximumBloodViolenceLevelDamageThreshold = 45;
|
||||||
|
|
||||||
DamageType damageType = weaponGetDamageType(attacker, weapon);
|
int damageType = weaponGetDamageType(attacker, weapon);
|
||||||
|
|
||||||
if (weapon != nullptr && weapon->pid == PROTO_ID_MOLOTOV_COCKTAIL) {
|
if (weapon != nullptr && weapon->pid == PROTO_ID_MOLOTOV_COCKTAIL) {
|
||||||
normalViolenceLevelDamageThreshold = 5;
|
normalViolenceLevelDamageThreshold = 5;
|
||||||
@@ -729,7 +729,7 @@ int _action_ranged(Attack* attack, int anim)
|
|||||||
|
|
||||||
weaponGetRange(attack->attacker, attack->hitMode);
|
weaponGetRange(attack->attacker, attack->hitMode);
|
||||||
|
|
||||||
DamageType damageType = weaponGetDamageType(attack->attacker, attack->weapon);
|
int damageType = weaponGetDamageType(attack->attacker, attack->weapon);
|
||||||
|
|
||||||
tileGetTileInDirection(attack->attacker->tile, attack->attacker->rotation, 1);
|
tileGetTileInDirection(attack->attacker->tile, attack->attacker->rotation, 1);
|
||||||
|
|
||||||
@@ -1306,7 +1306,7 @@ int actionLootCritter(Object* critter, Object* target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x4124E0
|
// 0x4124E0
|
||||||
int _action_skill_use(Skill skill)
|
int _action_skill_use(int skill)
|
||||||
{
|
{
|
||||||
if (skill == SKILL_SNEAK) {
|
if (skill == SKILL_SNEAK) {
|
||||||
reg_anim_clear(gDude);
|
reg_anim_clear(gDude);
|
||||||
@@ -1336,7 +1336,7 @@ static int _action_use_skill_in_combat_error(Object* critter)
|
|||||||
|
|
||||||
// skill_use
|
// skill_use
|
||||||
// 0x41255C
|
// 0x41255C
|
||||||
int actionUseSkill(Object* user, Object* target, Skill skill)
|
int actionUseSkill(Object* user, Object* target, int skill)
|
||||||
{
|
{
|
||||||
UseSkillOnHookResult hookResult = scriptHooks_UseSkillOn(&user, target, skill);
|
UseSkillOnHookResult hookResult = scriptHooks_UseSkillOn(&user, target, skill);
|
||||||
if (!hookResult.shouldContinue) {
|
if (!hookResult.shouldContinue) {
|
||||||
@@ -1907,7 +1907,7 @@ int _talk_to(Object* _, Object* critter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x413494
|
// 0x413494
|
||||||
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, DamageType damageType, bool animated, bool bypassArmor)
|
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor)
|
||||||
{
|
{
|
||||||
Attack* attack = (Attack*)internal_malloc(sizeof(*attack));
|
Attack* attack = (Attack*)internal_malloc(sizeof(*attack));
|
||||||
if (attack == nullptr) {
|
if (attack == nullptr) {
|
||||||
@@ -1988,7 +1988,7 @@ int _report_dmg(Attack* attack, Object* _)
|
|||||||
// Calculate damage by applying threshold and resistances.
|
// Calculate damage by applying threshold and resistances.
|
||||||
//
|
//
|
||||||
// 0x413660
|
// 0x413660
|
||||||
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, DamageType damageType)
|
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType)
|
||||||
{
|
{
|
||||||
if (!critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
if (!critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||||
knockbackDistancePtr = nullptr;
|
knockbackDistancePtr = nullptr;
|
||||||
|
|||||||
+3
-5
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "combat_defs.h"
|
#include "combat_defs.h"
|
||||||
#include "obj_types.h"
|
#include "obj_types.h"
|
||||||
#include "proto_types.h"
|
|
||||||
#include "skill_defs.h"
|
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
@@ -15,14 +13,14 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
|
|||||||
int _action_use_an_object(Object* user, Object* targetObj);
|
int _action_use_an_object(Object* user, Object* targetObj);
|
||||||
int actionPickUp(Object* critter, Object* item);
|
int actionPickUp(Object* critter, Object* item);
|
||||||
int actionLootCritter(Object* critter, Object* target);
|
int actionLootCritter(Object* critter, Object* target);
|
||||||
int _action_skill_use(Skill skill);
|
int _action_skill_use(int skill);
|
||||||
int actionUseSkill(Object* user, Object* target, Skill skill);
|
int actionUseSkill(Object* user, Object* target, int skill);
|
||||||
bool _is_hit_from_front(const Object* attacker, const Object* defender);
|
bool _is_hit_from_front(const Object* attacker, const Object* defender);
|
||||||
bool _can_see(Object* source, Object* target);
|
bool _can_see(Object* source, Object* target);
|
||||||
bool _action_explode_running();
|
bool _action_explode_running();
|
||||||
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate);
|
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate);
|
||||||
int actionTalk(Object* obj, Object* critter);
|
int actionTalk(Object* obj, Object* critter);
|
||||||
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, DamageType damageType, bool animated, bool bypassArmor);
|
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
|
||||||
bool actionCheckPush(Object* obj, Object* target);
|
bool actionCheckPush(Object* obj, Object* target);
|
||||||
int actionPush(Object* obj, Object* target);
|
int actionPush(Object* obj, Object* target);
|
||||||
int _action_can_talk_to(Object* obj, Object* critter);
|
int _action_can_talk_to(Object* obj, Object* critter);
|
||||||
|
|||||||
+2
-2
@@ -1736,7 +1736,7 @@ static bool canUseDoor(Object* critter, Object* door)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyType bodyType = critterGetBodyType(critter);
|
int bodyType = critterGetBodyType(critter);
|
||||||
if (bodyType != BODY_TYPE_BIPED && bodyType != BODY_TYPE_ROBOTIC) {
|
if (bodyType != BODY_TYPE_BIPED && bodyType != BODY_TYPE_ROBOTIC) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3019,7 +3019,7 @@ int _check_move(int* actionPointsPtr)
|
|||||||
if (isInCombat()) {
|
if (isInCombat()) {
|
||||||
if (*actionPointsPtr != -1) {
|
if (*actionPointsPtr != -1) {
|
||||||
if (gPressedPhysicalKeys[SDL_SCANCODE_RCTRL] || gPressedPhysicalKeys[SDL_SCANCODE_LCTRL]) {
|
if (gPressedPhysicalKeys[SDL_SCANCODE_RCTRL] || gPressedPhysicalKeys[SDL_SCANCODE_LCTRL]) {
|
||||||
HitMode hitMode;
|
int hitMode;
|
||||||
bool aiming;
|
bool aiming;
|
||||||
interfaceGetCurrentHitMode(&hitMode, &aiming);
|
interfaceGetCurrentHitMode(&hitMode, &aiming);
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1789,13 +1789,11 @@ void FrmImage::resetInternal()
|
|||||||
|
|
||||||
bool FrmImage::setFrame(const Art* art, int frame, int direction)
|
bool FrmImage::setFrame(const Art* art, int frame, int direction)
|
||||||
{
|
{
|
||||||
unsigned char* data = artGetFrameData(art, frame, direction, &_width, &_height, nullptr, nullptr);
|
unsigned char* data = artGetFrameData(art, frame, direction, &_width, &_height, &_xOffset, &_yOffset);
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_xOffset = art->xOffsets[direction];
|
|
||||||
_yOffset = art->yOffsets[direction];
|
|
||||||
_data = data;
|
_data = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+172
-203
File diff suppressed because it is too large
Load Diff
@@ -827,7 +827,7 @@ static bool characterSelectorWindowRenderStats()
|
|||||||
y += vh; // blank line
|
y += vh; // blank line
|
||||||
|
|
||||||
// SKILLS
|
// SKILLS
|
||||||
Skill skills[DEFAULT_TAGGED_SKILLS];
|
int skills[DEFAULT_TAGGED_SKILLS];
|
||||||
skillsGetTagged(skills, DEFAULT_TAGGED_SKILLS);
|
skillsGetTagged(skills, DEFAULT_TAGGED_SKILLS);
|
||||||
|
|
||||||
for (int index = 0; index < DEFAULT_TAGGED_SKILLS; index++) {
|
for (int index = 0; index < DEFAULT_TAGGED_SKILLS; index++) {
|
||||||
|
|||||||
+181
-186
File diff suppressed because it is too large
Load Diff
+21
-21
@@ -9,7 +9,7 @@
|
|||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
extern int _combatNumTurns;
|
extern int _combatNumTurns;
|
||||||
extern CombatState gCombatState;
|
extern unsigned int gCombatState;
|
||||||
|
|
||||||
extern int _combat_free_move;
|
extern int _combat_free_move;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ void combatExit();
|
|||||||
int _find_cid(int a1, int a2, Object** a3, int a4);
|
int _find_cid(int a1, int a2, Object** a3, int a4);
|
||||||
int combatLoad(File* stream);
|
int combatLoad(File* stream);
|
||||||
int combatSave(File* stream);
|
int combatSave(File* stream);
|
||||||
bool _combat_safety_invalidate_weapon(Object* attacker, Object* weapon, HitMode hitMode, Object* defender, int* safeDistancePtr);
|
bool _combat_safety_invalidate_weapon(Object* attacker, Object* weapon, int hitMode, Object* defender, int* safeDistancePtr);
|
||||||
bool _combatTestIncidentalHit(Object* attacker, Object* defender, Object* attackerFriend, Object* weapon);
|
bool _combatTestIncidentalHit(Object* attacker, Object* defender, Object* attackerFriend, Object* weapon);
|
||||||
Object* _combat_whose_turn();
|
Object* _combat_whose_turn();
|
||||||
void _combat_data_init(Object* obj);
|
void _combat_data_init(Object* obj);
|
||||||
@@ -34,19 +34,19 @@ void _combat_over_from_load();
|
|||||||
void _combat_give_exps(int exp_points);
|
void _combat_give_exps(int exp_points);
|
||||||
void _combat_turn_run();
|
void _combat_turn_run();
|
||||||
void _combat(CombatStartData* csd);
|
void _combat(CombatStartData* csd);
|
||||||
void attackInit(Attack* attack, Object* attacker, Object* defender, HitMode hitMode, HitLocation hitLocation);
|
void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode, int hitLocation);
|
||||||
int _combat_attack(Object* attacker, Object* defender, HitMode hitMode, HitLocation hitLocation);
|
int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocation);
|
||||||
int _combat_bullet_start(const Object* attacker, const Object* target);
|
int _combat_bullet_start(const Object* attacker, const Object* target);
|
||||||
void _compute_explosion_on_extras(Attack* attack, bool isFromAttacker, bool isGrenade, bool noDamage);
|
void _compute_explosion_on_extras(Attack* attack, bool isFromAttacker, bool isGrenade, bool noDamage);
|
||||||
int _determine_to_hit(Object* a1, Object* a2, HitLocation hitLocation, HitMode hitMode);
|
int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode);
|
||||||
int _determine_to_hit_no_range(Object* attacker, Object* defender, HitLocation hitLocation, HitMode hitMode, unsigned char* a5);
|
int _determine_to_hit_no_range(Object* attacker, Object* defender, int hitLocation, int hitMode, unsigned char* a5);
|
||||||
int _determine_to_hit_from_tile(Object* attacker, int tile, Object* defender, HitLocation hitLocation, HitMode hitMode);
|
int _determine_to_hit_from_tile(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode);
|
||||||
void attackComputeDeathFlags(Attack* attack);
|
void attackComputeDeathFlags(Attack* attack);
|
||||||
void _apply_damage(Attack* attack, bool animated);
|
void _apply_damage(Attack* attack, bool animated);
|
||||||
void _combat_display(Attack* attack);
|
void _combat_display(Attack* attack);
|
||||||
void _combat_anim_begin();
|
void _combat_anim_begin();
|
||||||
void _combat_anim_finished();
|
void _combat_anim_finished();
|
||||||
CombatBadShot _combat_check_bad_shot(Object* attacker, Object* defender, HitMode hitMode, bool aiming);
|
int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool aiming);
|
||||||
bool _combat_to_hit(Object* target, int* accuracy);
|
bool _combat_to_hit(Object* target, int* accuracy);
|
||||||
void _combat_attack_this(Object* target);
|
void _combat_attack_this(Object* target);
|
||||||
void _combat_outline_on();
|
void _combat_outline_on();
|
||||||
@@ -59,21 +59,21 @@ void _combat_delete_critter(Object* obj);
|
|||||||
void _combatKillCritterOutsideCombat(Object* critter_obj, char* msg);
|
void _combatKillCritterOutsideCombat(Object* critter_obj, char* msg);
|
||||||
|
|
||||||
int combatGetTargetHighlight();
|
int combatGetTargetHighlight();
|
||||||
int criticalsGetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember);
|
int criticalsGetValue(int killType, int hitLocation, int effect, int dataMember);
|
||||||
void criticalsSetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember, int value);
|
void criticalsSetValue(int killType, int hitLocation, int effect, int dataMember, int value);
|
||||||
void criticalsResetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember);
|
void criticalsResetValue(int killType, int hitLocation, int effect, int dataMember);
|
||||||
bool criticalsNoTimeLimits();
|
bool criticalsNoTimeLimits();
|
||||||
int unarmedGetDamage(HitMode hitMode, int* minDamagePtr, int* maxDamagePtr);
|
int unarmedGetDamage(int hitMode, int* minDamagePtr, int* maxDamagePtr);
|
||||||
int unarmedGetBonusCriticalChance(HitMode hitMode);
|
int unarmedGetBonusCriticalChance(int hitMode);
|
||||||
int unarmedGetActionPointCost(HitMode hitMode);
|
int unarmedGetActionPointCost(int hitMode);
|
||||||
bool unarmedIsPenetrating(HitMode hitMode);
|
bool unarmedIsPenetrating(int hitMode);
|
||||||
HitMode unarmedGetPunchHitMode(bool isSecondary);
|
int unarmedGetPunchHitMode(bool isSecondary);
|
||||||
HitMode unarmedGetKickHitMode(bool isSecondary);
|
int unarmedGetKickHitMode(bool isSecondary);
|
||||||
bool unarmedIsPenetrating(HitMode hitMode);
|
bool unarmedIsPenetrating(int hitMode);
|
||||||
bool damageModGetBonusHthDamageFix();
|
bool damageModGetBonusHthDamageFix();
|
||||||
bool damageModGetDisplayBonusDamage();
|
bool damageModGetDisplayBonusDamage();
|
||||||
int combat_get_hit_location_penalty(HitLocation hitLocation);
|
int combat_get_hit_location_penalty(int hit_location);
|
||||||
void combat_set_hit_location_penalty(HitLocation hitLocation, int penalty);
|
void combat_set_hit_location_penalty(int hit_location, int penalty);
|
||||||
void combat_reset_hit_location_penalty();
|
void combat_reset_hit_location_penalty();
|
||||||
Attack* combat_get_data();
|
Attack* combat_get_data();
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ static inline bool isInCombat()
|
|||||||
return (gCombatState & COMBAT_STATE_IN_COMBAT) != 0;
|
return (gCombatState & COMBAT_STATE_IN_COMBAT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isUnarmedHitMode(HitMode hitMode)
|
static inline bool isUnarmedHitMode(int hitMode)
|
||||||
{
|
{
|
||||||
return hitMode == HIT_MODE_PUNCH
|
return hitMode == HIT_MODE_PUNCH
|
||||||
|| hitMode == HIT_MODE_KICK
|
|| hitMode == HIT_MODE_KICK
|
||||||
|
|||||||
+31
-28
@@ -93,19 +93,19 @@ static Object* _ai_danger_source(Object* a1);
|
|||||||
static bool aiHaveAmmo(Object* critter, Object* weapon, Object** ammoPtr);
|
static bool aiHaveAmmo(Object* critter, Object* weapon, Object** ammoPtr);
|
||||||
static bool _caiHasWeapPrefType(AiPacket* ai, int attackType);
|
static bool _caiHasWeapPrefType(AiPacket* ai, int attackType);
|
||||||
static Object* _ai_best_weapon(Object* a1, Object* a2, Object* a3, Object* a4);
|
static Object* _ai_best_weapon(Object* a1, Object* a2, Object* a3, Object* a4);
|
||||||
static bool _ai_can_use_weapon(Object* critter, Object* weapon, HitMode hitMode);
|
static bool _ai_can_use_weapon(Object* critter, Object* weapon, int hitMode);
|
||||||
static bool aiCanUseItem(Object* obj, Object* a2);
|
static bool aiCanUseItem(Object* obj, Object* a2);
|
||||||
static Object* _ai_search_environ(Object* critter, int itemType);
|
static Object* _ai_search_environ(Object* critter, int itemType);
|
||||||
static Object* _ai_retrieve_object(Object* critter, Object* item);
|
static Object* _ai_retrieve_object(Object* critter, Object* item);
|
||||||
static HitMode _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender);
|
static int _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender);
|
||||||
static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, bool taunt);
|
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 _ai_move_closer(Object* a1, Object* a2, bool taunt);
|
||||||
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
|
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
|
||||||
static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile);
|
static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile);
|
||||||
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance);
|
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance);
|
||||||
static int _ai_switch_weapons(Object* a1, HitMode* hitMode, Object** weapon, Object* a4);
|
static int _ai_switch_weapons(Object* a1, int* hitMode, Object** weapon, Object* a4);
|
||||||
static HitLocation _ai_called_shot(Object* attacker, Object* defender, HitMode hitMode);
|
static int _ai_called_shot(Object* attacker, Object* defender, int hitMode);
|
||||||
static int _ai_attack(Object* attacker, Object* defender, HitMode hitMode);
|
static int _ai_attack(Object* attacker, Object* defender, int hitMode);
|
||||||
static int _ai_try_attack(Object* a1, Object* a2);
|
static int _ai_try_attack(Object* a1, Object* a2);
|
||||||
static int _cai_get_min_hp(AiPacket* ai);
|
static int _cai_get_min_hp(AiPacket* ai);
|
||||||
static int _ai_print_msg(Object* critter, int type);
|
static int _ai_print_msg(Object* critter, int type);
|
||||||
@@ -610,7 +610,7 @@ static int aiPacketRead(File* stream, AiPacket* ai)
|
|||||||
if (fileReadInt32(stream, &(ai->miss.start)) == -1) return -1;
|
if (fileReadInt32(stream, &(ai->miss.start)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(ai->miss.end)) == -1) return -1;
|
if (fileReadInt32(stream, &(ai->miss.end)) == -1) return -1;
|
||||||
|
|
||||||
for (int index = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
for (int index = 0; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
||||||
AiMessageRange* range = &(ai->hit[index]);
|
AiMessageRange* range = &(ai->hit[index]);
|
||||||
if (fileReadInt32(stream, &(range->start)) == -1) return -1;
|
if (fileReadInt32(stream, &(range->start)) == -1) return -1;
|
||||||
if (fileReadInt32(stream, &(range->end)) == -1) return -1;
|
if (fileReadInt32(stream, &(range->end)) == -1) return -1;
|
||||||
@@ -654,7 +654,7 @@ static int aiPacketWrite(File* stream, AiPacket* ai)
|
|||||||
if (fileWriteInt32(stream, ai->miss.start) == -1) return -1;
|
if (fileWriteInt32(stream, ai->miss.start) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, ai->miss.end) == -1) return -1;
|
if (fileWriteInt32(stream, ai->miss.end) == -1) return -1;
|
||||||
|
|
||||||
for (int index = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
for (int index = 0; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
||||||
AiMessageRange* range = &(ai->hit[index]);
|
AiMessageRange* range = &(ai->hit[index]);
|
||||||
if (fileWriteInt32(stream, range->start) == -1) return -1;
|
if (fileWriteInt32(stream, range->start) == -1) return -1;
|
||||||
if (fileWriteInt32(stream, range->end) == -1) return -1;
|
if (fileWriteInt32(stream, range->end) == -1) return -1;
|
||||||
@@ -1619,7 +1619,7 @@ static Object* _ai_danger_source(Object* a1)
|
|||||||
// Check if we can attack it. No ammo and out of
|
// Check if we can attack it. No ammo and out of
|
||||||
// range are ok results, since we can reload weapon
|
// range are ok results, since we can reload weapon
|
||||||
// move closer if necessary.
|
// move closer if necessary.
|
||||||
CombatBadShot badShot = _combat_check_bad_shot(a1, critter, HIT_MODE_RIGHT_WEAPON_PRIMARY, false);
|
int badShot = _combat_check_bad_shot(a1, critter, HIT_MODE_RIGHT_WEAPON_PRIMARY, false);
|
||||||
if (badShot != COMBAT_BAD_SHOT_OK
|
if (badShot != COMBAT_BAD_SHOT_OK
|
||||||
&& badShot != COMBAT_BAD_SHOT_NO_AMMO
|
&& badShot != COMBAT_BAD_SHOT_NO_AMMO
|
||||||
&& badShot != COMBAT_BAD_SHOT_OUT_OF_RANGE) {
|
&& badShot != COMBAT_BAD_SHOT_OUT_OF_RANGE) {
|
||||||
@@ -1975,13 +1975,13 @@ static Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x4298EC
|
// 0x4298EC
|
||||||
static bool _ai_can_use_weapon(Object* critter, Object* weapon, HitMode hitMode)
|
static bool _ai_can_use_weapon(Object* critter, Object* weapon, int hitMode)
|
||||||
{
|
{
|
||||||
bool result = critterCanUseWeapon(critter, weapon, hitMode);
|
bool result = critterCanUseWeapon(critter, weapon, hitMode);
|
||||||
|
|
||||||
AiPacket* ai = aiGetPacket(critter);
|
AiPacket* ai = aiGetPacket(critter);
|
||||||
if (result) {
|
if (result) {
|
||||||
Skill skill = weaponGetSkillForHitMode(weapon, hitMode);
|
int skill = weaponGetSkillForHitMode(weapon, hitMode);
|
||||||
if (skillGetValue(critter, skill) < ai->min_to_hit) {
|
if (skillGetValue(critter, skill) < ai->min_to_hit) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
@@ -1998,7 +1998,7 @@ static bool _ai_can_use_weapon(Object* critter, Object* weapon, HitMode hitMode)
|
|||||||
// 0x4299A0
|
// 0x4299A0
|
||||||
Object* _ai_search_inven_weap(Object* critter, bool checkRequiredActionPoints, Object* defender)
|
Object* _ai_search_inven_weap(Object* critter, bool checkRequiredActionPoints, Object* defender)
|
||||||
{
|
{
|
||||||
BodyType bodyType = critterGetBodyType(critter);
|
int bodyType = critterGetBodyType(critter);
|
||||||
if (bodyType != BODY_TYPE_BIPED
|
if (bodyType != BODY_TYPE_BIPED
|
||||||
&& bodyType != BODY_TYPE_ROBOTIC
|
&& bodyType != BODY_TYPE_ROBOTIC
|
||||||
&& critter->pid != PROTO_ID_GORIS) {
|
&& critter->pid != PROTO_ID_GORIS) {
|
||||||
@@ -2062,7 +2062,7 @@ Object* _ai_search_inven_armor(Object* critter)
|
|||||||
if (armor != nullptr) {
|
if (armor != nullptr) {
|
||||||
armorScore = armorGetArmorClass(armor);
|
armorScore = armorGetArmorClass(armor);
|
||||||
|
|
||||||
for (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
for (int damageType = 0; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
||||||
armorScore += armorGetDamageResistance(armor, damageType);
|
armorScore += armorGetDamageResistance(armor, damageType);
|
||||||
armorScore += armorGetDamageThreshold(armor, damageType);
|
armorScore += armorGetDamageThreshold(armor, damageType);
|
||||||
}
|
}
|
||||||
@@ -2081,7 +2081,7 @@ Object* _ai_search_inven_armor(Object* critter)
|
|||||||
|
|
||||||
if (armor != candidate) {
|
if (armor != candidate) {
|
||||||
int candidateScore = armorGetArmorClass(candidate);
|
int candidateScore = armorGetArmorClass(candidate);
|
||||||
for (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
for (int damageType = 0; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
||||||
candidateScore += armorGetDamageResistance(candidate, damageType);
|
candidateScore += armorGetDamageResistance(candidate, damageType);
|
||||||
candidateScore += armorGetDamageThreshold(candidate, damageType);
|
candidateScore += armorGetDamageThreshold(candidate, damageType);
|
||||||
}
|
}
|
||||||
@@ -2128,7 +2128,7 @@ static bool aiCanUseItem(Object* critter, Object* item)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
KillType killType = critterGetKillType(critter);
|
int killType = critterGetKillType(critter);
|
||||||
if (killType != KILL_TYPE_MAN
|
if (killType != KILL_TYPE_MAN
|
||||||
&& killType != KILL_TYPE_WOMAN
|
&& killType != KILL_TYPE_WOMAN
|
||||||
&& killType != KILL_TYPE_SUPER_MUTANT
|
&& killType != KILL_TYPE_SUPER_MUTANT
|
||||||
@@ -2260,7 +2260,7 @@ static Object* _ai_retrieve_object(Object* critter, Object* item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x429DB4
|
// 0x429DB4
|
||||||
static HitMode _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender)
|
static int _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender)
|
||||||
{
|
{
|
||||||
if (weapon == nullptr) {
|
if (weapon == nullptr) {
|
||||||
return HIT_MODE_PUNCH;
|
return HIT_MODE_PUNCH;
|
||||||
@@ -2302,19 +2302,19 @@ static HitMode _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defen
|
|||||||
break;
|
break;
|
||||||
case AREA_ATTACK_MODE_BE_SURE:
|
case AREA_ATTACK_MODE_BE_SURE:
|
||||||
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 85
|
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 85
|
||||||
&& !_combat_safety_invalidate_weapon(attacker, weapon, HIT_MODE_RIGHT_WEAPON_SECONDARY, defender, nullptr)) {
|
&& !_combat_safety_invalidate_weapon(attacker, weapon, 3, defender, nullptr)) {
|
||||||
useSecondaryMode = true;
|
useSecondaryMode = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AREA_ATTACK_MODE_BE_CAREFUL:
|
case AREA_ATTACK_MODE_BE_CAREFUL:
|
||||||
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 50
|
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 50
|
||||||
&& !_combat_safety_invalidate_weapon(attacker, weapon, HIT_MODE_RIGHT_WEAPON_SECONDARY, defender, nullptr)) {
|
&& !_combat_safety_invalidate_weapon(attacker, weapon, 3, defender, nullptr)) {
|
||||||
useSecondaryMode = true;
|
useSecondaryMode = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AREA_ATTACK_MODE_BE_ABSOLUTELY_SURE:
|
case AREA_ATTACK_MODE_BE_ABSOLUTELY_SURE:
|
||||||
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 95
|
if (_determine_to_hit(attacker, defender, HIT_LOCATION_TORSO, HIT_MODE_RIGHT_WEAPON_SECONDARY) >= 95
|
||||||
&& !_combat_safety_invalidate_weapon(attacker, weapon, HIT_MODE_RIGHT_WEAPON_SECONDARY, defender, nullptr)) {
|
&& !_combat_safety_invalidate_weapon(attacker, weapon, 3, defender, nullptr)) {
|
||||||
useSecondaryMode = true;
|
useSecondaryMode = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2574,7 +2574,7 @@ static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetDa
|
|||||||
// 0x42A518
|
// 0x42A518
|
||||||
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance)
|
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance)
|
||||||
{
|
{
|
||||||
HitMode hitMode = HIT_MODE_RIGHT_WEAPON_PRIMARY;
|
int hitMode = HIT_MODE_RIGHT_WEAPON_PRIMARY;
|
||||||
bool aiming = false;
|
bool aiming = false;
|
||||||
if (attacker == gDude) {
|
if (attacker == gDude) {
|
||||||
interfaceGetCurrentHitMode(&hitMode, &aiming);
|
interfaceGetCurrentHitMode(&hitMode, &aiming);
|
||||||
@@ -2601,7 +2601,7 @@ static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x42A5B8
|
// 0x42A5B8
|
||||||
static int _ai_switch_weapons(Object* attacker, HitMode* hitMode, Object** weapon, Object* defender)
|
static int _ai_switch_weapons(Object* attacker, int* hitMode, Object** weapon, Object* defender)
|
||||||
{
|
{
|
||||||
*weapon = nullptr;
|
*weapon = nullptr;
|
||||||
*hitMode = HIT_MODE_PUNCH;
|
*hitMode = HIT_MODE_PUNCH;
|
||||||
@@ -2639,9 +2639,9 @@ static int _ai_switch_weapons(Object* attacker, HitMode* hitMode, Object** weapo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x42A670
|
// 0x42A670
|
||||||
static HitLocation _ai_called_shot(Object* attacker, Object* defender, HitMode hitMode)
|
static int _ai_called_shot(Object* attacker, Object* defender, int hitMode)
|
||||||
{
|
{
|
||||||
HitLocation hitLocation = HIT_LOCATION_TORSO;
|
int hitLocation = HIT_LOCATION_TORSO;
|
||||||
|
|
||||||
if (weaponGetActionPointCost(attacker, hitMode, true) <= attacker->data.critter.combat.ap) {
|
if (weaponGetActionPointCost(attacker, hitMode, true) <= attacker->data.critter.combat.ap) {
|
||||||
if (critterCanAim(attacker, hitMode)) {
|
if (critterCanAim(attacker, hitMode)) {
|
||||||
@@ -2661,8 +2661,8 @@ static HitLocation _ai_called_shot(Object* attacker, Object* defender, HitMode h
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (critterGetStat(attacker, STAT_INTELLIGENCE) >= intelligenceRequired) {
|
if (critterGetStat(attacker, STAT_INTELLIGENCE) >= intelligenceRequired) {
|
||||||
hitLocation = static_cast<HitLocation>(randomBetween(HIT_LOCATION_FIRST, HIT_LOCATION_SPECIFIC_COUNT));
|
hitLocation = randomBetween(0, HIT_LOCATION_SPECIFIC_COUNT);
|
||||||
int chanceToHit = _determine_to_hit(attacker, defender, hitLocation, hitMode);
|
int chanceToHit = _determine_to_hit(attacker, defender, hitMode, hitLocation);
|
||||||
if (chanceToHit < ai->min_to_hit) {
|
if (chanceToHit < ai->min_to_hit) {
|
||||||
hitLocation = HIT_LOCATION_TORSO;
|
hitLocation = HIT_LOCATION_TORSO;
|
||||||
}
|
}
|
||||||
@@ -2675,7 +2675,7 @@ static HitLocation _ai_called_shot(Object* attacker, Object* defender, HitMode h
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 0x42A748
|
// 0x42A748
|
||||||
static int _ai_attack(Object* attacker, Object* defender, HitMode hitMode)
|
static int _ai_attack(Object* attacker, Object* defender, int hitMode)
|
||||||
{
|
{
|
||||||
if (attacker->data.critter.combat.maneuver & CRITTER_MANUEVER_FLEEING) {
|
if (attacker->data.critter.combat.maneuver & CRITTER_MANUEVER_FLEEING) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -2686,7 +2686,7 @@ static int _ai_attack(Object* attacker, Object* defender, HitMode hitMode)
|
|||||||
reg_anim_end();
|
reg_anim_end();
|
||||||
_combat_turn_run();
|
_combat_turn_run();
|
||||||
|
|
||||||
HitLocation hitLocation = _ai_called_shot(attacker, defender, hitMode);
|
int hitLocation = _ai_called_shot(attacker, defender, hitMode);
|
||||||
if (_combat_attack(attacker, defender, hitMode, hitLocation)) {
|
if (_combat_attack(attacker, defender, hitMode, hitLocation)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2709,7 +2709,7 @@ static int _ai_try_attack(Object* attacker, Object* defender)
|
|||||||
weapon = nullptr;
|
weapon = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HitMode hitMode = _ai_pick_hit_mode(attacker, weapon, defender);
|
int hitMode = _ai_pick_hit_mode(attacker, weapon, defender);
|
||||||
int minToHit = aiGetPacket(attacker)->min_to_hit;
|
int minToHit = aiGetPacket(attacker)->min_to_hit;
|
||||||
|
|
||||||
int actionPoints = attacker->data.critter.combat.ap;
|
int actionPoints = attacker->data.critter.combat.ap;
|
||||||
@@ -2736,7 +2736,7 @@ static int _ai_try_attack(Object* attacker, Object* defender)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CombatBadShot reason = _combat_check_bad_shot(attacker, defender, hitMode, false);
|
int reason = _combat_check_bad_shot(attacker, defender, hitMode, false);
|
||||||
if (reason == COMBAT_BAD_SHOT_NO_AMMO) {
|
if (reason == COMBAT_BAD_SHOT_NO_AMMO) {
|
||||||
// If the secondary attack (for example, burst fire) does not have enough ammo,
|
// If the secondary attack (for example, burst fire) does not have enough ammo,
|
||||||
// try the primary attack, which may have a lower ammo cost.
|
// try the primary attack, which may have a lower ammo cost.
|
||||||
@@ -2821,6 +2821,9 @@ static int _ai_try_attack(Object* attacker, Object* defender)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (reason == COMBAT_BAD_SHOT_NOT_ENOUGH_AP || reason == COMBAT_BAD_SHOT_ARM_CRIPPLED || reason == COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED) {
|
} else if (reason == COMBAT_BAD_SHOT_NOT_ENOUGH_AP || reason == COMBAT_BAD_SHOT_ARM_CRIPPLED || reason == COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED) {
|
||||||
|
// 3 - not enough action points
|
||||||
|
// 6 - crippled one arm for two-handed weapon
|
||||||
|
// 7 - both hands crippled
|
||||||
if (_ai_switch_weapons(attacker, &hitMode, &weapon, defender) == -1) {
|
if (_ai_switch_weapons(attacker, &hitMode, &weapon, defender) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "obj_types.h"
|
#include "obj_types.h"
|
||||||
#include "sfall_script_hooks.h"
|
#include "sfall_script_hooks.h"
|
||||||
#include "skill_defs.h"
|
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
|
|||||||
+34
-119
@@ -5,66 +5,20 @@
|
|||||||
|
|
||||||
#define EXPLOSION_TARGET_COUNT (6)
|
#define EXPLOSION_TARGET_COUNT (6)
|
||||||
|
|
||||||
|
#define CRTICIAL_EFFECT_COUNT (6)
|
||||||
|
|
||||||
#define WEAPON_CRITICAL_FAILURE_TYPE_COUNT (7)
|
#define WEAPON_CRITICAL_FAILURE_TYPE_COUNT (7)
|
||||||
#define WEAPON_CRITICAL_FAILURE_EFFECT_COUNT (5)
|
#define WEAPON_CRITICAL_FAILURE_EFFECT_COUNT (5)
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
enum CriticalEffect : int {
|
typedef enum CombatState {
|
||||||
CRITICAL_EFFECT_1 = 0,
|
|
||||||
CRITICAL_EFFECT_2 = 1,
|
|
||||||
CRITICAL_EFFECT_3 = 2,
|
|
||||||
CRITICAL_EFFECT_4 = 3,
|
|
||||||
CRITICAL_EFFECT_5 = 4,
|
|
||||||
CRITICAL_EFFECT_6 = 5,
|
|
||||||
CRITICAL_EFFECT_COUNT = 6,
|
|
||||||
CRITICAL_EFFECT_FIRST = CRITICAL_EFFECT_1
|
|
||||||
};
|
|
||||||
|
|
||||||
inline CriticalEffect operator++(CriticalEffect& e, int)
|
|
||||||
{
|
|
||||||
CriticalEffect result = e;
|
|
||||||
e = static_cast<CriticalEffect>(static_cast<int>(e) + 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool criticalEffectIsValid(int effect)
|
|
||||||
{
|
|
||||||
return effect >= CRITICAL_EFFECT_FIRST && effect < CRITICAL_EFFECT_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CombatState : unsigned int {
|
|
||||||
COMBAT_STATE_OUT_COMBAT = 0x00,
|
|
||||||
COMBAT_STATE_IN_COMBAT = 0x01,
|
COMBAT_STATE_IN_COMBAT = 0x01,
|
||||||
COMBAT_STATE_PLAYER_TURN = 0x02,
|
COMBAT_STATE_PLAYER_TURN = 0x02,
|
||||||
COMBAT_STATE_EXIT_REQUESTED = 0x08,
|
COMBAT_STATE_EXIT_REQUESTED = 0x08,
|
||||||
};
|
} CombatState;
|
||||||
|
|
||||||
inline fallout::CombatState& operator&=(fallout::CombatState& lhs, unsigned int rhs)
|
typedef enum HitMode {
|
||||||
{
|
|
||||||
lhs = static_cast<fallout::CombatState>(static_cast<unsigned int>(lhs) & rhs);
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline constexpr CombatState operator~(CombatState rhs)
|
|
||||||
{
|
|
||||||
return static_cast<CombatState>(~static_cast<unsigned int>(rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CombatState& operator&=(CombatState& lhs, CombatState rhs)
|
|
||||||
{
|
|
||||||
lhs = static_cast<CombatState>(static_cast<unsigned int>(lhs) & static_cast<unsigned int>(rhs));
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CombatState& operator|=(CombatState& lhs, CombatState rhs)
|
|
||||||
{
|
|
||||||
lhs = static_cast<CombatState>(static_cast<unsigned int>(lhs) | static_cast<unsigned int>(rhs));
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum HitMode : int {
|
|
||||||
HIT_MODE_INVALID = -1,
|
|
||||||
HIT_MODE_LEFT_WEAPON_PRIMARY = 0,
|
HIT_MODE_LEFT_WEAPON_PRIMARY = 0,
|
||||||
HIT_MODE_LEFT_WEAPON_SECONDARY = 1,
|
HIT_MODE_LEFT_WEAPON_SECONDARY = 1,
|
||||||
HIT_MODE_RIGHT_WEAPON_PRIMARY = 2,
|
HIT_MODE_RIGHT_WEAPON_PRIMARY = 2,
|
||||||
@@ -116,47 +70,21 @@ enum HitMode : int {
|
|||||||
LAST_ADVANCED_KICK_HIT_MODE = HIT_MODE_PIERCING_KICK,
|
LAST_ADVANCED_KICK_HIT_MODE = HIT_MODE_PIERCING_KICK,
|
||||||
FIRST_ADVANCED_UNARMED_HIT_MODE = FIRST_ADVANCED_PUNCH_HIT_MODE,
|
FIRST_ADVANCED_UNARMED_HIT_MODE = FIRST_ADVANCED_PUNCH_HIT_MODE,
|
||||||
LAST_ADVANCED_UNARMED_HIT_MODE = LAST_ADVANCED_KICK_HIT_MODE,
|
LAST_ADVANCED_UNARMED_HIT_MODE = LAST_ADVANCED_KICK_HIT_MODE,
|
||||||
HIT_MODE_FIRST = HIT_MODE_LEFT_WEAPON_PRIMARY,
|
} HitMode;
|
||||||
};
|
|
||||||
|
|
||||||
inline static bool hitModeIsValid(int hitMode)
|
typedef enum HitLocation {
|
||||||
{
|
HIT_LOCATION_HEAD,
|
||||||
return hitMode >= HIT_MODE_FIRST && hitMode < HIT_MODE_COUNT;
|
HIT_LOCATION_LEFT_ARM,
|
||||||
}
|
HIT_LOCATION_RIGHT_ARM,
|
||||||
|
HIT_LOCATION_TORSO,
|
||||||
inline HitMode operator++(HitMode& e, int)
|
HIT_LOCATION_RIGHT_LEG,
|
||||||
{
|
HIT_LOCATION_LEFT_LEG,
|
||||||
HitMode result = e;
|
HIT_LOCATION_EYES,
|
||||||
e = static_cast<HitMode>(static_cast<int>(e) + 1);
|
HIT_LOCATION_GROIN,
|
||||||
return result;
|
HIT_LOCATION_UNCALLED,
|
||||||
}
|
HIT_LOCATION_COUNT,
|
||||||
|
|
||||||
enum HitLocation : int {
|
|
||||||
HIT_LOCATION_HEAD = 0,
|
|
||||||
HIT_LOCATION_LEFT_ARM = 1,
|
|
||||||
HIT_LOCATION_RIGHT_ARM = 2,
|
|
||||||
HIT_LOCATION_TORSO = 3,
|
|
||||||
HIT_LOCATION_RIGHT_LEG = 4,
|
|
||||||
HIT_LOCATION_LEFT_LEG = 5,
|
|
||||||
HIT_LOCATION_EYES = 6,
|
|
||||||
HIT_LOCATION_GROIN = 7,
|
|
||||||
HIT_LOCATION_UNCALLED = 8,
|
|
||||||
HIT_LOCATION_COUNT = 9,
|
|
||||||
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
|
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
|
||||||
HIT_LOCATION_FIRST = HIT_LOCATION_HEAD,
|
} HitLocation;
|
||||||
};
|
|
||||||
|
|
||||||
inline static bool hitLocationIsValid(int hitLocation)
|
|
||||||
{
|
|
||||||
return hitLocation >= HIT_LOCATION_FIRST && hitLocation < HIT_LOCATION_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline HitLocation operator++(HitLocation& e, int)
|
|
||||||
{
|
|
||||||
HitLocation result = e;
|
|
||||||
e = static_cast<HitLocation>(static_cast<int>(e) + 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct CombatStartData {
|
typedef struct CombatStartData {
|
||||||
Object* attacker;
|
Object* attacker;
|
||||||
@@ -173,16 +101,16 @@ typedef struct CombatStartData {
|
|||||||
|
|
||||||
typedef struct Attack {
|
typedef struct Attack {
|
||||||
Object* attacker;
|
Object* attacker;
|
||||||
HitMode hitMode;
|
int hitMode;
|
||||||
Object* weapon;
|
Object* weapon;
|
||||||
HitLocation attackHitLocation; // UNUSED?
|
int attackHitLocation; // UNUSED?
|
||||||
int attackerDamage;
|
int attackerDamage;
|
||||||
int attackerFlags;
|
int attackerFlags;
|
||||||
int ammoQuantity;
|
int ammoQuantity;
|
||||||
int criticalMessageId;
|
int criticalMessageId;
|
||||||
Object* defender;
|
Object* defender;
|
||||||
int tile;
|
int tile;
|
||||||
HitLocation defenderHitLocation;
|
int defenderHitLocation;
|
||||||
int defenderDamage;
|
int defenderDamage;
|
||||||
int defenderFlags;
|
int defenderFlags;
|
||||||
int defenderKnockback;
|
int defenderKnockback;
|
||||||
@@ -195,29 +123,16 @@ typedef struct Attack {
|
|||||||
int extrasKnockback[EXPLOSION_TARGET_COUNT];
|
int extrasKnockback[EXPLOSION_TARGET_COUNT];
|
||||||
} Attack;
|
} Attack;
|
||||||
|
|
||||||
enum CriticalHitDataMember : int {
|
typedef enum CriticalHitDescriptionDataMember {
|
||||||
CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER = 0,
|
CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER,
|
||||||
CRIT_DATA_MEMBER_FLAGS = 1,
|
CRIT_DATA_MEMBER_FLAGS,
|
||||||
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_STAT = 2,
|
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_STAT,
|
||||||
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_STAT_MODIFIER = 3,
|
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_STAT_MODIFIER,
|
||||||
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_FLAGS = 4,
|
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_FLAGS,
|
||||||
CRIT_DATA_MEMBER_MESSAGE_ID = 5,
|
CRIT_DATA_MEMBER_MESSAGE_ID,
|
||||||
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_MESSAGE_ID = 6,
|
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_MESSAGE_ID,
|
||||||
CRIT_DATA_MEMBER_COUNT = 7,
|
CRIT_DATA_MEMBER_COUNT,
|
||||||
CRIT_DATA_MEMBER_FIRST = CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER,
|
} CriticalHitDescriptionDataMember;
|
||||||
};
|
|
||||||
|
|
||||||
inline static bool criticalHitDataMemberIsValid(int criticalHitDataMember)
|
|
||||||
{
|
|
||||||
return criticalHitDataMember >= CRIT_DATA_MEMBER_FIRST && criticalHitDataMember < CRIT_DATA_MEMBER_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CriticalHitDataMember operator++(CriticalHitDataMember& e, int)
|
|
||||||
{
|
|
||||||
CriticalHitDataMember result = e;
|
|
||||||
e = static_cast<CriticalHitDataMember>(static_cast<int>(e) + 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provides metadata about critical hit effect.
|
// Provides metadata about critical hit effect.
|
||||||
typedef union CriticalHitDescription {
|
typedef union CriticalHitDescription {
|
||||||
@@ -245,7 +160,7 @@ typedef union CriticalHitDescription {
|
|||||||
int values[CRIT_DATA_MEMBER_COUNT];
|
int values[CRIT_DATA_MEMBER_COUNT];
|
||||||
} CriticalHitDescription;
|
} CriticalHitDescription;
|
||||||
|
|
||||||
enum CombatBadShot : int {
|
typedef enum CombatBadShot {
|
||||||
COMBAT_BAD_SHOT_OK = 0,
|
COMBAT_BAD_SHOT_OK = 0,
|
||||||
COMBAT_BAD_SHOT_NO_AMMO = 1,
|
COMBAT_BAD_SHOT_NO_AMMO = 1,
|
||||||
COMBAT_BAD_SHOT_OUT_OF_RANGE = 2,
|
COMBAT_BAD_SHOT_OUT_OF_RANGE = 2,
|
||||||
@@ -253,8 +168,8 @@ enum CombatBadShot : int {
|
|||||||
COMBAT_BAD_SHOT_ALREADY_DEAD = 4,
|
COMBAT_BAD_SHOT_ALREADY_DEAD = 4,
|
||||||
COMBAT_BAD_SHOT_AIM_BLOCKED = 5,
|
COMBAT_BAD_SHOT_AIM_BLOCKED = 5,
|
||||||
COMBAT_BAD_SHOT_ARM_CRIPPLED = 6,
|
COMBAT_BAD_SHOT_ARM_CRIPPLED = 6,
|
||||||
COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED = 7
|
COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED = 7,
|
||||||
};
|
} CombatBadShot;
|
||||||
|
|
||||||
} // namespace fallout
|
} // namespace fallout
|
||||||
|
|
||||||
|
|||||||
+15
-32
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
#define CONFIG_FILE_MAX_LINE_LENGTH (2048)
|
#define CONFIG_FILE_MAX_LINE_LENGTH (1024)
|
||||||
|
|
||||||
// The initial number of sections (or key-value) pairs in the config.
|
// The initial number of sections (or key-value) pairs in the config.
|
||||||
#define CONFIG_INITIAL_CAPACITY (10)
|
#define CONFIG_INITIAL_CAPACITY (10)
|
||||||
@@ -32,10 +32,9 @@ struct CaseInsensitiveLess {
|
|||||||
typedef std::set<std::string, CaseInsensitiveLess> StringSet;
|
typedef std::set<std::string, CaseInsensitiveLess> StringSet;
|
||||||
|
|
||||||
static bool configParseLine(Config* config, char* string);
|
static bool configParseLine(Config* config, char* string);
|
||||||
static bool configParseKeyValue(char* string, std::string& key, std::string& value);
|
static bool configParseKeyValue(char* string, char* key, char* value);
|
||||||
static bool configEnsureSectionExists(Config* config, const char* sectionKey);
|
static bool configEnsureSectionExists(Config* config, const char* sectionKey);
|
||||||
static bool configTrimString(char* string);
|
static bool configTrimString(char* string);
|
||||||
static std::string configGetTrimmedString(const char* string);
|
|
||||||
|
|
||||||
static bool configWriteDb(Config* config, const char* filePath);
|
static bool configWriteDb(Config* config, const char* filePath);
|
||||||
static bool configWriteStandard(Config* config, const char* filePath);
|
static bool configWriteStandard(Config* config, const char* filePath);
|
||||||
@@ -121,10 +120,10 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
|
|||||||
|
|
||||||
*pch = '\0';
|
*pch = '\0';
|
||||||
|
|
||||||
std::string key;
|
char key[260];
|
||||||
std::string value;
|
char value[260];
|
||||||
if (configParseKeyValue(pch + 1, key, value)) {
|
if (configParseKeyValue(pch + 1, key, value)) {
|
||||||
if (!configSetString(config, sectionKey, key.c_str(), value.c_str())) {
|
if (!configSetString(config, sectionKey, key, value)) {
|
||||||
*pch = ']';
|
*pch = ']';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -684,13 +683,13 @@ static bool configParseLine(Config* config, char* string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string key;
|
char key[260];
|
||||||
std::string value;
|
char value[260];
|
||||||
if (!configParseKeyValue(string, key, value)) {
|
if (!configParseKeyValue(string, key, value)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return configSetString(config, gConfigLastSectionKey, key.c_str(), value.c_str());
|
return configSetString(config, gConfigLastSectionKey, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits "key=value" pair from [string] and copy appropriate parts into [key]
|
// Splits "key=value" pair from [string] and copy appropriate parts into [key]
|
||||||
@@ -699,9 +698,9 @@ static bool configParseLine(Config* config, char* string)
|
|||||||
// Both key and value are trimmed.
|
// Both key and value are trimmed.
|
||||||
//
|
//
|
||||||
// 0x42C594
|
// 0x42C594
|
||||||
static bool configParseKeyValue(char* string, std::string& key, std::string& value)
|
static bool configParseKeyValue(char* string, char* key, char* value)
|
||||||
{
|
{
|
||||||
if (string == nullptr) {
|
if (string == nullptr || key == nullptr || value == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,11 +712,14 @@ static bool configParseKeyValue(char* string, std::string& key, std::string& val
|
|||||||
|
|
||||||
*pch = '\0';
|
*pch = '\0';
|
||||||
|
|
||||||
key = configGetTrimmedString(string);
|
strcpy(key, string);
|
||||||
value = configGetTrimmedString(pch + 1);
|
strcpy(value, pch + 1);
|
||||||
|
|
||||||
*pch = '=';
|
*pch = '=';
|
||||||
|
|
||||||
|
configTrimString(key);
|
||||||
|
configTrimString(value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,25 +791,6 @@ static bool configTrimString(char* string)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string configGetTrimmedString(const char* string)
|
|
||||||
{
|
|
||||||
if (string == nullptr) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* start = string;
|
|
||||||
while (isspace(static_cast<unsigned char>(*start))) {
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* end = start + strlen(start);
|
|
||||||
while (end > start && isspace(static_cast<unsigned char>(*(end - 1)))) {
|
|
||||||
end--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0x42C718
|
// 0x42C718
|
||||||
bool configGetDouble(Config* config, const char* sectionKey, const char* key, double* valuePtr)
|
bool configGetDouble(Config* config, const char* sectionKey, const char* key, double* valuePtr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ namespace fallout {
|
|||||||
#define CONTENT_CONFIG_START_SECTION "start"
|
#define CONTENT_CONFIG_START_SECTION "start"
|
||||||
#define CONTENT_CONFIG_KARMA_SECTION "karma"
|
#define CONTENT_CONFIG_KARMA_SECTION "karma"
|
||||||
#define CONTENT_CONFIG_ITEMS_SECTION "items"
|
#define CONTENT_CONFIG_ITEMS_SECTION "items"
|
||||||
#define CONTENT_CONFIG_MAPS_SECTION "maps"
|
|
||||||
#define CONTENT_CONFIG_DIALOG_SECTION "dialog"
|
#define CONTENT_CONFIG_DIALOG_SECTION "dialog"
|
||||||
#define CONTENT_CONFIG_MAIN_MENU_SECTION "main_menu"
|
#define CONTENT_CONFIG_MAIN_MENU_SECTION "main_menu"
|
||||||
#define CONTENT_CONFIG_MOVIES_SECTION "movies"
|
#define CONTENT_CONFIG_MOVIES_SECTION "movies"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user