Compare commits

...
Author SHA1 Message Date
jirik2077 3d5fbe061c fix -Wswitch warnings 2026-07-27 22:33:16 +02:00
jirik2077 c33eeb0342 premade character enum usage hardened 2026-07-27 22:25:33 +02:00
jirik2077 d8df3cdd73 editor folder, editor derived stat to be named enums 2026-07-27 22:19:17 +02:00
jirik2077 8663fe5b60 pcstat enum usage hardened 2026-07-27 22:08:02 +02:00
jirik2077 4720ce1b7d stat enum usage hardened 2026-07-27 21:51:30 +02:00
Mike Klaas cd38c82514 Remove 100 hard cap on outlined objects (#612)
Fixes odd highlighting behaviour in https://github.com/fallout2-ce/fallout2-ce/pull/603
2026-07-27 08:37:07 -07:00
alpacacommunist-cmd 552505e3f5 fixes party_member.cc memory leaks (#601)
updates functions:

--- File: src/party_member.cc ---
661 | static int _partyMemberRecoverLoadInstance(PartyMemberListItem* a1)
--- File: src/party_member.cc ---
710 | int partyMembersLoad(File* stream)
2026-07-27 13:09:37 +03:00
alpacacommunist-cmd b9dd399457 adds OBJECT_HIDDEN flag check for exit grids in objectSetLocation (#588) 2026-07-27 12:45:31 +03:00
5f544ca985 Change body replacement with the blood stains so the dropped items are on top (#602)
* change the body replacement sequence with the blood stains so that items are dropped after the blood is created

* chore: auto-format with clang-format

* typo

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

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-27 08:39:26 +02:00
jirik2077andgithub-actions[bot] 0c7752fd33 Type safe usages of DamageType, KillType, BodyType, Editor, Skill, CriticalEffect, RaceType enums. (#599)
* type safe usages or DamageType, KillType, BodyType, Editor, Skill, CriticalEffect, RaceType enums...
replaced numeric constants to Editor enum in character_editor.cc

* chore: auto-format with clang-format

* added defaults to the switches to satisfy -Wswitch

* chore: auto-format with clang-format

* copilot review fixes

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-27 06:20:57 +02:00
Mike Klaas 0a5364972c [Et tu] DisableSpecialMapIDs=1 (#611) 2026-07-26 21:03:46 -07:00
48 changed files with 1918 additions and 1656 deletions
+1
View File
@@ -48,6 +48,7 @@ The following settings were moved into [`<DAT>/config/game.cfg`](files/ce.dat/co
| `Misc` | `ViewXPos` | `start` | `worldmap_view_x` |
| `Misc` | `ViewYPos` | `start` | `worldmap_view_y` |
| `Misc` | `StartGDialogFix` | `dialog` | `start_gdialog_fix` |
| `Misc` | `DisableSpecialMapIDs` | `maps` | `disable_special_map_ids` |
## Opcodes / Metarules
+5
View File
@@ -26,6 +26,11 @@ model_female_default=hfjmps
; Set to 2 to make the pipboy available by only skipping the vault suit movie check.
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]
; 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
+9 -9
View File
@@ -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 _talk_to(Object* _, Object* critter);
static int _report_dmg(Attack* attack, Object* _);
static int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType);
static int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, DamageType damageType);
static int hideProjectile(void* _, void* projectile);
@@ -200,7 +200,7 @@ int pickDeathAnim(Object* attacker, Object* defender, Object* weapon, int damage
int normalViolenceLevelDamageThreshold = 15;
int maximumBloodViolenceLevelDamageThreshold = 45;
int damageType = weaponGetDamageType(attacker, weapon);
DamageType damageType = weaponGetDamageType(attacker, weapon);
if (weapon != nullptr && weapon->pid == PROTO_ID_MOLOTOV_COCKTAIL) {
normalViolenceLevelDamageThreshold = 5;
@@ -729,7 +729,7 @@ int _action_ranged(Attack* attack, int anim)
weaponGetRange(attack->attacker, attack->hitMode);
int damageType = weaponGetDamageType(attack->attacker, attack->weapon);
DamageType damageType = weaponGetDamageType(attack->attacker, attack->weapon);
tileGetTileInDirection(attack->attacker->tile, attack->attacker->rotation, 1);
@@ -1306,7 +1306,7 @@ int actionLootCritter(Object* critter, Object* target)
}
// 0x4124E0
int _action_skill_use(int skill)
int _action_skill_use(Skill skill)
{
if (skill == SKILL_SNEAK) {
reg_anim_clear(gDude);
@@ -1336,7 +1336,7 @@ static int _action_use_skill_in_combat_error(Object* critter)
// skill_use
// 0x41255C
int actionUseSkill(Object* user, Object* target, int skill)
int actionUseSkill(Object* user, Object* target, Skill skill)
{
UseSkillOnHookResult hookResult = scriptHooks_UseSkillOn(&user, target, skill);
if (!hookResult.shouldContinue) {
@@ -1907,7 +1907,7 @@ int _talk_to(Object* _, Object* critter)
}
// 0x413494
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor)
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, DamageType damageType, bool animated, bool bypassArmor)
{
Attack* attack = (Attack*)internal_malloc(sizeof(*attack));
if (attack == nullptr) {
@@ -1988,15 +1988,15 @@ int _report_dmg(Attack* attack, Object* _)
// Calculate damage by applying threshold and resistances.
//
// 0x413660
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType)
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, DamageType damageType)
{
if (!critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
knockbackDistancePtr = nullptr;
}
int damage = randomBetween(min, max) - critterGetStat(obj, STAT_DAMAGE_THRESHOLD + damageType);
int damage = randomBetween(min, max) - critterGetStat(obj, static_cast<Stat>(STAT_DAMAGE_THRESHOLD + damageType));
if (damage > 0) {
damage -= critterGetStat(obj, STAT_DAMAGE_RESISTANCE + damageType) * damage / 100;
damage -= critterGetStat(obj, static_cast<Stat>(STAT_DAMAGE_RESISTANCE + damageType)) * damage / 100;
}
if (damage < 0) {
+5 -3
View File
@@ -3,6 +3,8 @@
#include "combat_defs.h"
#include "obj_types.h"
#include "proto_types.h"
#include "skill_defs.h"
namespace fallout {
@@ -13,14 +15,14 @@ int _action_use_an_item_on_object(Object* user, Object* targetObj, Object* item)
int _action_use_an_object(Object* user, Object* targetObj);
int actionPickUp(Object* critter, Object* item);
int actionLootCritter(Object* critter, Object* target);
int _action_skill_use(int skill);
int actionUseSkill(Object* user, Object* target, int skill);
int _action_skill_use(Skill skill);
int actionUseSkill(Object* user, Object* target, Skill skill);
bool _is_hit_from_front(const Object* attacker, const Object* defender);
bool _can_see(Object* source, Object* target);
bool _action_explode_running();
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* sourceObj, bool animate);
int actionTalk(Object* obj, Object* critter);
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, DamageType damageType, bool animated, bool bypassArmor);
bool actionCheckPush(Object* obj, Object* target);
int actionPush(Object* obj, Object* target);
int _action_can_talk_to(Object* obj, Object* critter);
+1 -1
View File
@@ -1736,7 +1736,7 @@ static bool canUseDoor(Object* critter, Object* door)
return false;
}
int bodyType = critterGetBodyType(critter);
BodyType bodyType = critterGetBodyType(critter);
if (bodyType != BODY_TYPE_BIPED && bodyType != BODY_TYPE_ROBOTIC) {
return false;
}
+239 -210
View File
File diff suppressed because it is too large Load Diff
+24 -9
View File
@@ -67,12 +67,27 @@ namespace fallout {
#define CS_WINDOW_SECONDARY_STAT_MID_X (379)
#define CS_WINDOW_BIO_X (438)
typedef enum PremadeCharacter {
enum PremadeCharacter : int {
PREMADE_CHARACTER_NARG,
PREMADE_CHARACTER_CHITSA,
PREMADE_CHARACTER_MINGUN,
PREMADE_CHARACTER_COUNT,
} PremadeCharacter;
PREMADE_CHARACTER_FIRST = PREMADE_CHARACTER_NARG
};
inline PremadeCharacter operator++(PremadeCharacter& e, int)
{
PremadeCharacter result = e;
e = static_cast<PremadeCharacter>(static_cast<int>(e) + 1);
return result;
}
inline PremadeCharacter operator--(PremadeCharacter& e, int)
{
PremadeCharacter result = e;
e = static_cast<PremadeCharacter>(static_cast<int>(e) - 1);
return result;
}
typedef struct PremadeCharacterDescription {
char fileName[20];
@@ -91,7 +106,7 @@ static bool characterSelectorWindowFatalError(bool result);
static void premadeCharactersLocalizePath(char* path);
// 0x51C84C premade_index
static int gCurrentPremadeCharacter = PREMADE_CHARACTER_NARG;
static PremadeCharacter gCurrentPremadeCharacter = PREMADE_CHARACTER_NARG;
// 0x51C850 premade_characters
static PremadeCharacterDescription gPremadeCharacterDescriptions[PREMADE_CHARACTER_COUNT] = {
@@ -223,9 +238,9 @@ int characterSelectorOpen()
soundPlayFile("ib2p1xx1");
// FALLTHROUGH
case 500:
gCurrentPremadeCharacter -= 1;
if (gCurrentPremadeCharacter < 0) {
gCurrentPremadeCharacter = gPremadeCharacterCount - 1;
gCurrentPremadeCharacter--;
if (gCurrentPremadeCharacter < PREMADE_CHARACTER_FIRST) {
gCurrentPremadeCharacter--;
}
characterSelectorWindowRefresh();
@@ -234,9 +249,9 @@ int characterSelectorOpen()
soundPlayFile("ib2p1xx1");
// FALLTHROUGH
case 501:
gCurrentPremadeCharacter += 1;
gCurrentPremadeCharacter++;
if (gCurrentPremadeCharacter >= gPremadeCharacterCount) {
gCurrentPremadeCharacter = 0;
gCurrentPremadeCharacter = PREMADE_CHARACTER_FIRST;
}
characterSelectorWindowRefresh();
@@ -827,7 +842,7 @@ static bool characterSelectorWindowRenderStats()
y += vh; // blank line
// SKILLS
int skills[DEFAULT_TAGGED_SKILLS];
Skill skills[DEFAULT_TAGGED_SKILLS];
skillsGetTagged(skills, DEFAULT_TAGGED_SKILLS);
for (int index = 0; index < DEFAULT_TAGGED_SKILLS; index++) {
+860 -858
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -59,9 +59,9 @@ void _combat_delete_critter(Object* obj);
void _combatKillCritterOutsideCombat(Object* critter_obj, char* msg);
int combatGetTargetHighlight();
int criticalsGetValue(int killType, HitLocation hitLocation, int effect, CriticalHitDataMember dataMember);
void criticalsSetValue(int killType, HitLocation hitLocation, int effect, CriticalHitDataMember dataMember, int value);
void criticalsResetValue(int killType, HitLocation hitLocation, int effect, CriticalHitDataMember dataMember);
int criticalsGetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember);
void criticalsSetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember, int value);
void criticalsResetValue(KillType killType, HitLocation hitLocation, CriticalEffect effect, CriticalHitDataMember dataMember);
bool criticalsNoTimeLimits();
int unarmedGetDamage(HitMode hitMode, int* minDamagePtr, int* maxDamagePtr);
int unarmedGetBonusCriticalChance(HitMode hitMode);
+8 -8
View File
@@ -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.end)) == -1) return -1;
for (int index = 0; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
for (int index = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
AiMessageRange* range = &(ai->hit[index]);
if (fileReadInt32(stream, &(range->start)) == -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.end) == -1) return -1;
for (int index = 0; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
for (int index = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
AiMessageRange* range = &(ai->hit[index]);
if (fileWriteInt32(stream, range->start) == -1) return -1;
if (fileWriteInt32(stream, range->end) == -1) return -1;
@@ -1981,7 +1981,7 @@ static bool _ai_can_use_weapon(Object* critter, Object* weapon, HitMode hitMode)
AiPacket* ai = aiGetPacket(critter);
if (result) {
int skill = weaponGetSkillForHitMode(weapon, hitMode);
Skill skill = weaponGetSkillForHitMode(weapon, hitMode);
if (skillGetValue(critter, skill) < ai->min_to_hit) {
result = false;
}
@@ -1998,7 +1998,7 @@ static bool _ai_can_use_weapon(Object* critter, Object* weapon, HitMode hitMode)
// 0x4299A0
Object* _ai_search_inven_weap(Object* critter, bool checkRequiredActionPoints, Object* defender)
{
int bodyType = critterGetBodyType(critter);
BodyType bodyType = critterGetBodyType(critter);
if (bodyType != BODY_TYPE_BIPED
&& bodyType != BODY_TYPE_ROBOTIC
&& critter->pid != PROTO_ID_GORIS) {
@@ -2062,7 +2062,7 @@ Object* _ai_search_inven_armor(Object* critter)
if (armor != nullptr) {
armorScore = armorGetArmorClass(armor);
for (int damageType = 0; damageType < DAMAGE_TYPE_COUNT; damageType++) {
for (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
armorScore += armorGetDamageResistance(armor, damageType);
armorScore += armorGetDamageThreshold(armor, damageType);
}
@@ -2081,7 +2081,7 @@ Object* _ai_search_inven_armor(Object* critter)
if (armor != candidate) {
int candidateScore = armorGetArmorClass(candidate);
for (int damageType = 0; damageType < DAMAGE_TYPE_COUNT; damageType++) {
for (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
candidateScore += armorGetDamageResistance(candidate, damageType);
candidateScore += armorGetDamageThreshold(candidate, damageType);
}
@@ -2128,7 +2128,7 @@ static bool aiCanUseItem(Object* critter, Object* item)
return false;
}
int killType = critterGetKillType(critter);
KillType killType = critterGetKillType(critter);
if (killType != KILL_TYPE_MAN
&& killType != KILL_TYPE_WOMAN
&& killType != KILL_TYPE_SUPER_MUTANT
@@ -2661,7 +2661,7 @@ static HitLocation _ai_called_shot(Object* attacker, Object* defender, HitMode h
}
if (critterGetStat(attacker, STAT_INTELLIGENCE) >= intelligenceRequired) {
hitLocation = static_cast<HitLocation>(randomBetween(HIT_LOCATION_HEAD, HIT_LOCATION_SPECIFIC_COUNT));
hitLocation = static_cast<HitLocation>(randomBetween(HIT_LOCATION_FIRST, HIT_LOCATION_SPECIFIC_COUNT));
int chanceToHit = _determine_to_hit(attacker, defender, hitLocation, hitMode);
if (chanceToHit < ai->min_to_hit) {
hitLocation = HIT_LOCATION_TORSO;
+1
View File
@@ -6,6 +6,7 @@
#include "db.h"
#include "obj_types.h"
#include "sfall_script_hooks.h"
#include "skill_defs.h"
namespace fallout {
+31 -6
View File
@@ -2,16 +2,38 @@
#define COMBAT_DEFS_H
#include "obj_types.h"
#include "stat_defs.h"
#define EXPLOSION_TARGET_COUNT (6)
#define CRTICIAL_EFFECT_COUNT (6)
#define WEAPON_CRITICAL_FAILURE_TYPE_COUNT (7)
#define WEAPON_CRITICAL_FAILURE_EFFECT_COUNT (5)
namespace fallout {
enum CriticalEffect : int {
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,
@@ -95,11 +117,12 @@ enum HitMode : int {
LAST_ADVANCED_KICK_HIT_MODE = HIT_MODE_PIERCING_KICK,
FIRST_ADVANCED_UNARMED_HIT_MODE = FIRST_ADVANCED_PUNCH_HIT_MODE,
LAST_ADVANCED_UNARMED_HIT_MODE = LAST_ADVANCED_KICK_HIT_MODE,
HIT_MODE_FIRST = HIT_MODE_LEFT_WEAPON_PRIMARY,
};
inline static bool hitModeIsValid(int hitMode)
{
return hitMode >= HIT_MODE_LEFT_WEAPON_PRIMARY && hitMode < HIT_MODE_COUNT;
return hitMode >= HIT_MODE_FIRST && hitMode < HIT_MODE_COUNT;
}
inline HitMode operator++(HitMode& e, int)
@@ -121,11 +144,12 @@ enum HitLocation : int {
HIT_LOCATION_UNCALLED = 8,
HIT_LOCATION_COUNT = 9,
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
HIT_LOCATION_FIRST = HIT_LOCATION_HEAD,
};
inline static bool hitLocationIsValid(int hitLocation)
{
return hitLocation >= HIT_LOCATION_HEAD && hitLocation < HIT_LOCATION_COUNT;
return hitLocation >= HIT_LOCATION_FIRST && hitLocation < HIT_LOCATION_COUNT;
}
inline HitLocation operator++(HitLocation& e, int)
@@ -181,11 +205,12 @@ enum CriticalHitDataMember : int {
CRIT_DATA_MEMBER_MESSAGE_ID = 5,
CRIT_DATA_MEMBER_MASSIVE_CRITICAL_MESSAGE_ID = 6,
CRIT_DATA_MEMBER_COUNT = 7,
CRIT_DATA_MEMBER_FIRST = CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER,
};
inline static bool criticalHitDataMemberIsValid(int criticalHitDataMember)
{
return criticalHitDataMember >= CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER && criticalHitDataMember < CRIT_DATA_MEMBER_COUNT;
return criticalHitDataMember >= CRIT_DATA_MEMBER_FIRST && criticalHitDataMember < CRIT_DATA_MEMBER_COUNT;
}
inline CriticalHitDataMember operator++(CriticalHitDataMember& e, int)
@@ -205,7 +230,7 @@ typedef union CriticalHitDescription {
// Stat to check to upgrade this critical hit to massive critical hit or
// -1 if there is no massive critical hit.
int massiveCriticalStat;
Stat massiveCriticalStat;
// Bonus/penalty to massive critical stat.
int massiveCriticalStatModifier;
+1
View File
@@ -8,6 +8,7 @@ namespace fallout {
#define CONTENT_CONFIG_START_SECTION "start"
#define CONTENT_CONFIG_KARMA_SECTION "karma"
#define CONTENT_CONFIG_ITEMS_SECTION "items"
#define CONTENT_CONFIG_MAPS_SECTION "maps"
#define CONTENT_CONFIG_DIALOG_SECTION "dialog"
#define CONTENT_CONFIG_MAIN_MENU_SECTION "main_menu"
#define CONTENT_CONFIG_MOVIES_SECTION "movies"
+36 -44
View File
@@ -80,7 +80,7 @@ static int _critterClearObjDrugs(Object* obj, void* data);
static char _aCorpse[] = "corpse";
// 0x501494
static char byte_501494[] = "";
static char empty[] = "";
// 0x51833C name_critter
static char* _name_critter = _aCorpse;
@@ -107,7 +107,7 @@ static const int gRadiationEnduranceModifiers[RADIATION_LEVEL_COUNT] = {
// [RADIATION_EFFECT_PRIMARY_STAT_COUNT] for more info.
//
// 0x518358 rad_stat
static const int gRadiationEffectStats[RADIATION_EFFECT_COUNT] = {
static const Stat gRadiationEffectStats[RADIATION_EFFECT_COUNT] = {
STAT_STRENGTH,
STAT_PERCEPTION,
STAT_ENDURANCE,
@@ -152,7 +152,7 @@ static char gDudeName[DUDE_NAME_MAX_LENGTH];
static int _sneak_working;
// 0x56D780 pc_kill_counts
static int gKillsByType[KILL_TYPE_COUNT];
static int gKillsByType[KILL_TYPE_DEFAULT_COUNT];
// Something with radiation.
//
@@ -679,15 +679,15 @@ int radiationEventWrite(File* stream, void* data)
}
// 0x42D82C critter_get_base_damage_type
int critterGetDamageType(Object* obj)
DamageType critterGetDamageType(Object* obj)
{
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
return 0;
return DAMAGE_TYPE_NORMAL;
}
Proto* proto;
if (protoGetProto(obj->pid, &proto) == -1) {
return 0;
return DAMAGE_TYPE_NORMAL;
}
return proto->critter.data.damageType;
@@ -703,9 +703,9 @@ static int critter_kill_count_clear()
}
// 0x42D878 critter_kill_count_inc
int killsIncByType(int killType)
int killsIncByType(KillType killType)
{
if (killType != -1 && killType < KILL_TYPE_COUNT) {
if (killTypeIsValid(killType)) {
gKillsByType[killType]++;
return 0;
}
@@ -714,9 +714,9 @@ int killsIncByType(int killType)
}
// 0x42D8A8 critter_kill_count
int killsGetByType(int killType)
int killsGetByType(KillType killType)
{
if (killType != -1 && killType < KILL_TYPE_COUNT) {
if (killTypeIsValid(killType)) {
return gKillsByType[killType];
}
@@ -726,7 +726,7 @@ int killsGetByType(int killType)
// 0x42D8C0 critter_kill_count_load
int killsLoad(File* stream)
{
if (fileReadInt32List(stream, gKillsByType, KILL_TYPE_COUNT) == -1) {
if (fileReadInt32List(stream, gKillsByType, KILL_TYPE_DEFAULT_COUNT) == -1) {
fileClose(stream);
return -1;
}
@@ -737,7 +737,7 @@ int killsLoad(File* stream)
// 0x42D8F0 critter_kill_count_save
int killsSave(File* stream)
{
if (fileWriteInt32List(stream, gKillsByType, KILL_TYPE_COUNT) == -1) {
if (fileWriteInt32List(stream, gKillsByType, KILL_TYPE_DEFAULT_COUNT) == -1) {
fileClose(stream);
return -1;
}
@@ -746,7 +746,7 @@ int killsSave(File* stream)
}
// 0x42D920 critter_kill_count_type
int critterGetKillType(Object* obj)
KillType critterGetKillType(Object* obj)
{
if (obj == gDude) {
int gender = critterGetStat(obj, STAT_GENDER);
@@ -757,7 +757,7 @@ int critterGetKillType(Object* obj)
}
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
return -1;
return KILL_TYPE_INVALID;
}
Proto* proto;
@@ -767,33 +767,25 @@ int critterGetKillType(Object* obj)
}
// 0x42D974 critter_kill_name
char* killTypeGetName(int killType)
char* killTypeGetName(KillType killType)
{
if (killType != -1 && killType < KILL_TYPE_COUNT) {
if (killType >= 0 && killType < KILL_TYPE_COUNT) {
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1450 + killType);
} else {
return nullptr;
}
} else {
return byte_501494;
if (killTypeIsValid(killType)) {
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1450 + killType);
}
return empty;
}
// 0x42D9B4 critter_kill_info
char* killTypeGetDescription(int killType)
char* killTypeGetDescription(KillType killType)
{
if (killType != -1 && killType < KILL_TYPE_COUNT) {
if (killType >= 0 && killType < KILL_TYPE_COUNT) {
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1469 + killType);
} else {
return nullptr;
}
} else {
return byte_501494;
if (killTypeIsValid(killType)) {
MessageListItem messageListItem;
return getmsg(&gProtoMessageList, &messageListItem, 1469 + killType);
}
return empty;
}
// 0x42D9F4 critter_heal_hours
@@ -1008,15 +1000,15 @@ bool critterIsProne(Object* critter)
// critter_body_type
// 0x42DDC4 critter_body_type
int critterGetBodyType(Object* critter)
BodyType critterGetBodyType(Object* critter)
{
if (critter == nullptr) {
debugPrint("\nError: critter_body_type: pobj was NULL!");
return 0;
return BODY_TYPE_BIPED;
}
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
return 0;
return BODY_TYPE_BIPED;
}
Proto* proto;
@@ -1091,9 +1083,9 @@ int gcdLoad(const char* path)
}
proto->critter.data.baseStats[STAT_DAMAGE_RESISTANCE_EMP] = 100;
proto->critter.data.bodyType = 0;
proto->critter.data.bodyType = BODY_TYPE_BIPED;
proto->critter.data.experience = 0;
proto->critter.data.killType = 0;
proto->critter.data.killType = KILL_TYPE_MAN;
fileClose(stream);
return 0;
@@ -1105,10 +1097,10 @@ int protoCritterDataRead(File* stream, CritterProtoData* critterData)
if (fileReadInt32(stream, &(critterData->flags)) == -1) return -1;
if (fileReadInt32List(stream, critterData->baseStats, SAVEABLE_STAT_COUNT) == -1) return -1;
if (fileReadInt32List(stream, critterData->bonusStats, SAVEABLE_STAT_COUNT) == -1) return -1;
if (fileReadInt32List(stream, critterData->skills, SKILL_COUNT) == -1) return -1;
if (fileReadInt32(stream, &(critterData->bodyType)) == -1) return -1;
if (fileReadInt32List(stream, reinterpret_cast<int*>(critterData->skills), SKILL_COUNT) == -1) return -1;
if (fileReadInt32(stream, reinterpret_cast<int*>(&(critterData->bodyType))) == -1) return -1;
if (fileReadInt32(stream, &(critterData->experience)) == -1) return -1;
if (fileReadInt32(stream, &(critterData->killType)) == -1) return -1;
if (fileReadInt32(stream, reinterpret_cast<int*>(&(critterData->killType))) == -1) return -1;
// NOTE: For unknown reason damage type is not present in two protos: Sentry
// Bot and Weak Brahmin. These two protos are 412 bytes, not 416.
@@ -1122,7 +1114,7 @@ int protoCritterDataRead(File* stream, CritterProtoData* critterData)
//
// Regardless of the reason, damage type is considered optional by original
// code as seen at 0x42E01B.
if (fileReadInt32(stream, &(critterData->damageType)) == -1) {
if (fileReadInt32(stream, reinterpret_cast<int*>(&(critterData->damageType))) == -1) {
critterData->damageType = DAMAGE_TYPE_NORMAL;
}
@@ -1172,7 +1164,7 @@ int protoCritterDataWrite(File* stream, CritterProtoData* critterData)
if (fileWriteInt32(stream, critterData->flags) == -1) return -1;
if (fileWriteInt32List(stream, critterData->baseStats, SAVEABLE_STAT_COUNT) == -1) return -1;
if (fileWriteInt32List(stream, critterData->bonusStats, SAVEABLE_STAT_COUNT) == -1) return -1;
if (fileWriteInt32List(stream, critterData->skills, SKILL_COUNT) == -1) return -1;
if (fileWriteInt32List(stream, reinterpret_cast<int*>(critterData->skills), SKILL_COUNT) == -1) return -1;
if (fileWriteInt32(stream, critterData->bodyType) == -1) return -1;
if (fileWriteInt32(stream, critterData->experience) == -1) return -1;
if (fileWriteInt32(stream, critterData->killType) == -1) return -1;
+7 -7
View File
@@ -39,14 +39,14 @@ void radiationProcess(Object* obj, int radiationLevel, bool direction);
int radiationEventProcess(Object* obj, void* data);
int radiationEventRead(File* stream, void** dataPtr);
int radiationEventWrite(File* stream, void* data);
int critterGetDamageType(Object* critter);
int killsIncByType(int killType);
int killsGetByType(int killType);
DamageType critterGetDamageType(Object* critter);
int killsIncByType(KillType killType);
int killsGetByType(KillType killType);
int killsLoad(File* stream);
int killsSave(File* stream);
int critterGetKillType(Object* critter);
char* killTypeGetName(int killType);
char* killTypeGetDescription(int killType);
KillType critterGetKillType(Object* critter);
char* killTypeGetName(KillType killType);
char* killTypeGetDescription(KillType killType);
int critterHealByHours(Object* obj, int hours);
void critterKill(Object* critter, int anim, bool refreshRect);
int critterGetExp(Object* critter);
@@ -54,7 +54,7 @@ bool critterIsActive(Object* critter);
bool critterIsDead(Object* critter);
bool critterIsCrippled(Object* critter);
bool critterIsProne(Object* critter);
int critterGetBodyType(Object* critter);
BodyType critterGetBodyType(Object* critter);
// Checks physical/art capability only. Callers that expose weapon usability
// decisions must still call scriptHooks_CanUseWeapon with the final result.
bool critterCanUseWeapon(Object* critter, Object* weapon, HitMode hitMode);
+2
View File
@@ -184,6 +184,8 @@ namespace {
{ kSfallMisc, "FemaleStartModel", CONTENT_CONFIG_START_SECTION, "model_female", "hfprim" },
{ kSfallMisc, "FemaleDefaultModel", CONTENT_CONFIG_START_SECTION, "model_female_default", "hfjmps" },
{ kSfallMisc, "PipBoyAvailableAtGameStart", CONTENT_CONFIG_START_SECTION, "pipboy", "0" },
// [maps]
{ kSfallMisc, "DisableSpecialMapIDs", CONTENT_CONFIG_MAPS_SECTION, "disable_special_map_ids", "0" },
// [karma]
{ kSfallMisc, "KarmaFRMs", CONTENT_CONFIG_KARMA_SECTION, "frms" },
{ kSfallMisc, "KarmaPoints", CONTENT_CONFIG_KARMA_SECTION, "points" },
+1 -1
View File
@@ -3789,7 +3789,7 @@ void partyMemberControlWindowUpdate()
fontDrawText(windowBuffer + windowWidth * 96 + 240, formattedText, 115, windowWidth, COLOR_GREEN);
// Render best skill.
int bestSkill = partyMemberGetBestSkill(gGameDialogSpeaker);
Skill bestSkill = partyMemberGetBestSkill(gGameDialogSpeaker);
text = skillGetName(bestSkill);
snprintf(formattedText, sizeof(formattedText), "%s", text);
fontDrawText(windowBuffer + windowWidth * 113 + 240, formattedText, 115, windowWidth, COLOR_GREEN);
+3 -3
View File
@@ -264,7 +264,7 @@ static int gGameMouseModeFrmIds[GAME_MOUSE_MODE_COUNT] = {
};
// 0x518D68 gmouse_skill_table
static const int gGameMouseModeSkills[GAME_MOUSE_MODE_SKILL_COUNT] = {
static const Skill gGameMouseModeSkills[GAME_MOUSE_MODE_SKILL_COUNT] = {
SKILL_FIRST_AID,
SKILL_DOCTOR,
SKILL_LOCKPICK,
@@ -1258,7 +1258,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
break;
case GAME_MOUSE_ACTION_MENU_ITEM_USE_SKILL:
if (1) {
int skill = -1;
Skill skill = SKILL_INVALID;
int rc = skilldexOpen();
switch (rc) {
@@ -1288,7 +1288,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
break;
}
if (skill != -1) {
if (skill != SKILL_INVALID) {
actionUseSkill(gDude, targetObj, skill);
}
}
+1 -1
View File
@@ -1390,7 +1390,7 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, HitMode hitMode, Object
soundVariant = 1;
}
int damageType = weaponGetDamageType(nullptr, weapon);
DamageType damageType = weaponGetDamageType(nullptr, weapon);
// SFALL
if (effectTypeCode != 'H' || target == nullptr || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
+57
View File
@@ -3,6 +3,8 @@
#include "combat_defs.h"
#include "object.h"
#include "proto_types.h"
#include "stat_defs.h"
#include <setjmp.h>
#include <vector>
@@ -289,6 +291,61 @@ inline CriticalHitDataMember programStackPopEnum(Program* program)
return static_cast<CriticalHitDataMember>(criticalHitDataMember);
}
template <>
inline CriticalEffect programStackPopEnum(Program* program)
{
int effect = programStackPopInteger(program);
if (!criticalEffectIsValid(effect)) {
programPrintError("invalid critical effect %d", effect);
}
return static_cast<CriticalEffect>(effect);
}
template <>
inline KillType programStackPopEnum(Program* program)
{
int killType = programStackPopInteger(program);
if (!killTypeOverrideIsValid(killType)) {
programPrintError("invalid kill type %d", killType);
}
return static_cast<KillType>(killType);
}
template <>
inline Skill programStackPopEnum(Program* program)
{
int skill = programStackPopInteger(program);
if (!skillIsValid(skill)) {
programPrintError("invalid skill %d", skill);
}
return static_cast<Skill>(skill);
}
template <>
inline Stat programStackPopEnum(Program* program)
{
int stat = programStackPopInteger(program);
if (!statIsValid(stat)) {
programPrintError("invalid stat %d", stat);
}
return static_cast<Stat>(stat);
}
template <>
inline PcStat programStackPopEnum(Program* program)
{
int pcStat = programStackPopInteger(program);
if (!pcStatIsValid(pcStat)) {
programPrintError("invalid pc stat %d", pcStat);
}
return static_cast<PcStat>(pcStat);
}
void programReturnStackPushValue(Program* program, ProgramValue& programValue);
void programReturnStackPushInteger(Program* program, int value);
void programReturnStackPushPointer(Program* program, void* value);

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