mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a3b3fe8a5 |
@@ -48,7 +48,12 @@ 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` |
|
||||
| `Sound` | `MainMenuMusic` | `sound` | `main_menu_music` |
|
||||
| `Sound` | `WorldMapMusic` | `sound` | `worldmap_music` |
|
||||
| `Sound` | `WorldMapCarMusic` | `sound` | `worldmap_car_music` |
|
||||
| `Sound` | `EndGameMovieMusic0` | `sound` | `endgame_movie_music0` |
|
||||
| `Sound` | `EndGameMovieMusic1` | `sound` | `endgame_movie_music1` |
|
||||
| `Sound` | `MapLoadingSound` | `sound` | `map_loading_sound` |
|
||||
|
||||
## Opcodes / Metarules
|
||||
|
||||
|
||||
@@ -26,11 +26,6 @@ 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
|
||||
@@ -70,6 +65,18 @@ offset_y=0
|
||||
credits_offset_x=0
|
||||
credits_offset_y=0
|
||||
|
||||
[sound]
|
||||
; Background music played on the main menu.
|
||||
main_menu_music=07desert
|
||||
; Background music played while viewing the world map on foot or in the car.
|
||||
worldmap_music=03wrldmp
|
||||
worldmap_car_music=20car
|
||||
; Music played before and during the end-game credits/movie sequence.
|
||||
endgame_movie_music0=maybe
|
||||
endgame_movie_music1=10labone
|
||||
; Music file played as looping ambience while maps are loading.
|
||||
map_loading_sound=wind2
|
||||
|
||||
[movies]
|
||||
; Number of days after game start when each Hakunin dream sequence becomes available.
|
||||
artimer1=90
|
||||
|
||||
+9
-9
@@ -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, DamageType damageType);
|
||||
static int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int 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;
|
||||
|
||||
DamageType damageType = weaponGetDamageType(attacker, weapon);
|
||||
int 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);
|
||||
|
||||
DamageType damageType = weaponGetDamageType(attack->attacker, attack->weapon);
|
||||
int 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(Skill skill)
|
||||
int _action_skill_use(int 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, Skill skill)
|
||||
int actionUseSkill(Object* user, Object* target, int 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, 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));
|
||||
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, DamageType damageType)
|
||||
int _compute_dmg_damage(int min, int max, Object* obj, int* knockbackDistancePtr, int damageType)
|
||||
{
|
||||
if (!critterFlagCheck(obj->pid, CRITTER_NO_KNOCKBACK)) {
|
||||
knockbackDistancePtr = nullptr;
|
||||
}
|
||||
|
||||
int damage = randomBetween(min, max) - critterGetStat(obj, static_cast<Stat>(STAT_DAMAGE_THRESHOLD + damageType));
|
||||
int damage = randomBetween(min, max) - critterGetStat(obj, STAT_DAMAGE_THRESHOLD + damageType);
|
||||
if (damage > 0) {
|
||||
damage -= critterGetStat(obj, static_cast<Stat>(STAT_DAMAGE_RESISTANCE + damageType)) * damage / 100;
|
||||
damage -= critterGetStat(obj, STAT_DAMAGE_RESISTANCE + damageType) * damage / 100;
|
||||
}
|
||||
|
||||
if (damage < 0) {
|
||||
|
||||
+3
-5
@@ -3,8 +3,6 @@
|
||||
|
||||
#include "combat_defs.h"
|
||||
#include "obj_types.h"
|
||||
#include "proto_types.h"
|
||||
#include "skill_defs.h"
|
||||
|
||||
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 actionPickUp(Object* critter, Object* item);
|
||||
int actionLootCritter(Object* critter, Object* target);
|
||||
int _action_skill_use(Skill skill);
|
||||
int actionUseSkill(Object* user, Object* target, Skill skill);
|
||||
int _action_skill_use(int skill);
|
||||
int actionUseSkill(Object* user, Object* target, int 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, 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);
|
||||
int actionPush(Object* obj, Object* target);
|
||||
int _action_can_talk_to(Object* obj, Object* critter);
|
||||
|
||||
+1
-1
@@ -1736,7 +1736,7 @@ static bool canUseDoor(Object* critter, Object* door)
|
||||
return false;
|
||||
}
|
||||
|
||||
BodyType bodyType = critterGetBodyType(critter);
|
||||
int bodyType = critterGetBodyType(critter);
|
||||
if (bodyType != BODY_TYPE_BIPED && bodyType != BODY_TYPE_ROBOTIC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+210
-239
File diff suppressed because it is too large
Load Diff
@@ -67,27 +67,12 @@ namespace fallout {
|
||||
#define CS_WINDOW_SECONDARY_STAT_MID_X (379)
|
||||
#define CS_WINDOW_BIO_X (438)
|
||||
|
||||
enum PremadeCharacter : int {
|
||||
typedef enum PremadeCharacter {
|
||||
PREMADE_CHARACTER_NARG,
|
||||
PREMADE_CHARACTER_CHITSA,
|
||||
PREMADE_CHARACTER_MINGUN,
|
||||
PREMADE_CHARACTER_COUNT,
|
||||
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;
|
||||
}
|
||||
} PremadeCharacter;
|
||||
|
||||
typedef struct PremadeCharacterDescription {
|
||||
char fileName[20];
|
||||
@@ -106,7 +91,7 @@ static bool characterSelectorWindowFatalError(bool result);
|
||||
static void premadeCharactersLocalizePath(char* path);
|
||||
|
||||
// 0x51C84C premade_index
|
||||
static PremadeCharacter gCurrentPremadeCharacter = PREMADE_CHARACTER_NARG;
|
||||
static int gCurrentPremadeCharacter = PREMADE_CHARACTER_NARG;
|
||||
|
||||
// 0x51C850 premade_characters
|
||||
static PremadeCharacterDescription gPremadeCharacterDescriptions[PREMADE_CHARACTER_COUNT] = {
|
||||
@@ -238,9 +223,9 @@ int characterSelectorOpen()
|
||||
soundPlayFile("ib2p1xx1");
|
||||
// FALLTHROUGH
|
||||
case 500:
|
||||
gCurrentPremadeCharacter--;
|
||||
if (gCurrentPremadeCharacter < PREMADE_CHARACTER_FIRST) {
|
||||
gCurrentPremadeCharacter--;
|
||||
gCurrentPremadeCharacter -= 1;
|
||||
if (gCurrentPremadeCharacter < 0) {
|
||||
gCurrentPremadeCharacter = gPremadeCharacterCount - 1;
|
||||
}
|
||||
|
||||
characterSelectorWindowRefresh();
|
||||
@@ -249,9 +234,9 @@ int characterSelectorOpen()
|
||||
soundPlayFile("ib2p1xx1");
|
||||
// FALLTHROUGH
|
||||
case 501:
|
||||
gCurrentPremadeCharacter++;
|
||||
gCurrentPremadeCharacter += 1;
|
||||
if (gCurrentPremadeCharacter >= gPremadeCharacterCount) {
|
||||
gCurrentPremadeCharacter = PREMADE_CHARACTER_FIRST;
|
||||
gCurrentPremadeCharacter = 0;
|
||||
}
|
||||
|
||||
characterSelectorWindowRefresh();
|
||||
@@ -842,7 +827,7 @@ static bool characterSelectorWindowRenderStats()
|
||||
y += vh; // blank line
|
||||
|
||||
// SKILLS
|
||||
Skill skills[DEFAULT_TAGGED_SKILLS];
|
||||
int skills[DEFAULT_TAGGED_SKILLS];
|
||||
skillsGetTagged(skills, DEFAULT_TAGGED_SKILLS);
|
||||
|
||||
for (int index = 0; index < DEFAULT_TAGGED_SKILLS; index++) {
|
||||
|
||||
+858
-860
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -59,9 +59,9 @@ void _combat_delete_critter(Object* obj);
|
||||
void _combatKillCritterOutsideCombat(Object* critter_obj, char* msg);
|
||||
|
||||
int combatGetTargetHighlight();
|
||||
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);
|
||||
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);
|
||||
bool criticalsNoTimeLimits();
|
||||
int unarmedGetDamage(HitMode hitMode, int* minDamagePtr, int* maxDamagePtr);
|
||||
int unarmedGetBonusCriticalChance(HitMode hitMode);
|
||||
|
||||
+8
-8
@@ -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 = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
||||
for (int index = 0; 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 = HIT_LOCATION_FIRST; index < HIT_LOCATION_SPECIFIC_COUNT; index++) {
|
||||
for (int index = 0; 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) {
|
||||
Skill skill = weaponGetSkillForHitMode(weapon, hitMode);
|
||||
int 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)
|
||||
{
|
||||
BodyType bodyType = critterGetBodyType(critter);
|
||||
int 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 (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
||||
for (int damageType = 0; 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 (DamageType damageType = DAMAGE_TYPE_FIRST; damageType < DAMAGE_TYPE_COUNT; damageType++) {
|
||||
for (int damageType = 0; 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;
|
||||
}
|
||||
|
||||
KillType killType = critterGetKillType(critter);
|
||||
int 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_FIRST, HIT_LOCATION_SPECIFIC_COUNT));
|
||||
hitLocation = static_cast<HitLocation>(randomBetween(HIT_LOCATION_HEAD, HIT_LOCATION_SPECIFIC_COUNT));
|
||||
int chanceToHit = _determine_to_hit(attacker, defender, hitLocation, hitMode);
|
||||
if (chanceToHit < ai->min_to_hit) {
|
||||
hitLocation = HIT_LOCATION_TORSO;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "db.h"
|
||||
#include "obj_types.h"
|
||||
#include "sfall_script_hooks.h"
|
||||
#include "skill_defs.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
|
||||
+6
-31
@@ -2,38 +2,16 @@
|
||||
#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,
|
||||
@@ -117,12 +95,11 @@ 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_FIRST && hitMode < HIT_MODE_COUNT;
|
||||
return hitMode >= HIT_MODE_LEFT_WEAPON_PRIMARY && hitMode < HIT_MODE_COUNT;
|
||||
}
|
||||
|
||||
inline HitMode operator++(HitMode& e, int)
|
||||
@@ -144,12 +121,11 @@ 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_FIRST && hitLocation < HIT_LOCATION_COUNT;
|
||||
return hitLocation >= HIT_LOCATION_HEAD && hitLocation < HIT_LOCATION_COUNT;
|
||||
}
|
||||
|
||||
inline HitLocation operator++(HitLocation& e, int)
|
||||
@@ -205,12 +181,11 @@ 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_FIRST && criticalHitDataMember < CRIT_DATA_MEMBER_COUNT;
|
||||
return criticalHitDataMember >= CRIT_DATA_MEMBER_DAMAGE_MULTIPLIER && criticalHitDataMember < CRIT_DATA_MEMBER_COUNT;
|
||||
}
|
||||
|
||||
inline CriticalHitDataMember operator++(CriticalHitDataMember& e, int)
|
||||
@@ -230,7 +205,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.
|
||||
Stat massiveCriticalStat;
|
||||
int massiveCriticalStat;
|
||||
|
||||
// Bonus/penalty to massive critical stat.
|
||||
int massiveCriticalStatModifier;
|
||||
|
||||
@@ -8,9 +8,9 @@ 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_SOUND_SECTION "sound"
|
||||
#define CONTENT_CONFIG_MOVIES_SECTION "movies"
|
||||
#define CONTENT_CONFIG_COMBAT_SECTION "combat"
|
||||
#define CONTENT_CONFIG_EXPLOSIONS_SECTION "explosions"
|
||||
|
||||
+44
-36
@@ -80,7 +80,7 @@ static int _critterClearObjDrugs(Object* obj, void* data);
|
||||
static char _aCorpse[] = "corpse";
|
||||
|
||||
// 0x501494
|
||||
static char empty[] = "";
|
||||
static char byte_501494[] = "";
|
||||
|
||||
// 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 Stat gRadiationEffectStats[RADIATION_EFFECT_COUNT] = {
|
||||
static const int 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_DEFAULT_COUNT];
|
||||
static int gKillsByType[KILL_TYPE_COUNT];
|
||||
|
||||
// Something with radiation.
|
||||
//
|
||||
@@ -679,15 +679,15 @@ int radiationEventWrite(File* stream, void* data)
|
||||
}
|
||||
|
||||
// 0x42D82C critter_get_base_damage_type
|
||||
DamageType critterGetDamageType(Object* obj)
|
||||
int critterGetDamageType(Object* obj)
|
||||
{
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return DAMAGE_TYPE_NORMAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Proto* proto;
|
||||
if (protoGetProto(obj->pid, &proto) == -1) {
|
||||
return DAMAGE_TYPE_NORMAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return proto->critter.data.damageType;
|
||||
@@ -703,9 +703,9 @@ static int critter_kill_count_clear()
|
||||
}
|
||||
|
||||
// 0x42D878 critter_kill_count_inc
|
||||
int killsIncByType(KillType killType)
|
||||
int killsIncByType(int killType)
|
||||
{
|
||||
if (killTypeIsValid(killType)) {
|
||||
if (killType != -1 && killType < KILL_TYPE_COUNT) {
|
||||
gKillsByType[killType]++;
|
||||
return 0;
|
||||
}
|
||||
@@ -714,9 +714,9 @@ int killsIncByType(KillType killType)
|
||||
}
|
||||
|
||||
// 0x42D8A8 critter_kill_count
|
||||
int killsGetByType(KillType killType)
|
||||
int killsGetByType(int killType)
|
||||
{
|
||||
if (killTypeIsValid(killType)) {
|
||||
if (killType != -1 && killType < KILL_TYPE_COUNT) {
|
||||
return gKillsByType[killType];
|
||||
}
|
||||
|
||||
@@ -726,7 +726,7 @@ int killsGetByType(KillType killType)
|
||||
// 0x42D8C0 critter_kill_count_load
|
||||
int killsLoad(File* stream)
|
||||
{
|
||||
if (fileReadInt32List(stream, gKillsByType, KILL_TYPE_DEFAULT_COUNT) == -1) {
|
||||
if (fileReadInt32List(stream, gKillsByType, KILL_TYPE_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_DEFAULT_COUNT) == -1) {
|
||||
if (fileWriteInt32List(stream, gKillsByType, KILL_TYPE_COUNT) == -1) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ int killsSave(File* stream)
|
||||
}
|
||||
|
||||
// 0x42D920 critter_kill_count_type
|
||||
KillType critterGetKillType(Object* obj)
|
||||
int critterGetKillType(Object* obj)
|
||||
{
|
||||
if (obj == gDude) {
|
||||
int gender = critterGetStat(obj, STAT_GENDER);
|
||||
@@ -757,7 +757,7 @@ KillType critterGetKillType(Object* obj)
|
||||
}
|
||||
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return KILL_TYPE_INVALID;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Proto* proto;
|
||||
@@ -767,25 +767,33 @@ KillType critterGetKillType(Object* obj)
|
||||
}
|
||||
|
||||
// 0x42D974 critter_kill_name
|
||||
char* killTypeGetName(KillType killType)
|
||||
char* killTypeGetName(int killType)
|
||||
{
|
||||
if (killTypeIsValid(killType)) {
|
||||
MessageListItem messageListItem;
|
||||
return getmsg(&gProtoMessageList, &messageListItem, 1450 + 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;
|
||||
}
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
// 0x42D9B4 critter_kill_info
|
||||
char* killTypeGetDescription(KillType killType)
|
||||
char* killTypeGetDescription(int killType)
|
||||
{
|
||||
if (killTypeIsValid(killType)) {
|
||||
MessageListItem messageListItem;
|
||||
return getmsg(&gProtoMessageList, &messageListItem, 1469 + 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;
|
||||
}
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
// 0x42D9F4 critter_heal_hours
|
||||
@@ -1000,15 +1008,15 @@ bool critterIsProne(Object* critter)
|
||||
|
||||
// critter_body_type
|
||||
// 0x42DDC4 critter_body_type
|
||||
BodyType critterGetBodyType(Object* critter)
|
||||
int critterGetBodyType(Object* critter)
|
||||
{
|
||||
if (critter == nullptr) {
|
||||
debugPrint("\nError: critter_body_type: pobj was NULL!");
|
||||
return BODY_TYPE_BIPED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return BODY_TYPE_BIPED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Proto* proto;
|
||||
@@ -1083,9 +1091,9 @@ int gcdLoad(const char* path)
|
||||
}
|
||||
|
||||
proto->critter.data.baseStats[STAT_DAMAGE_RESISTANCE_EMP] = 100;
|
||||
proto->critter.data.bodyType = BODY_TYPE_BIPED;
|
||||
proto->critter.data.bodyType = 0;
|
||||
proto->critter.data.experience = 0;
|
||||
proto->critter.data.killType = KILL_TYPE_MAN;
|
||||
proto->critter.data.killType = 0;
|
||||
|
||||
fileClose(stream);
|
||||
return 0;
|
||||
@@ -1097,10 +1105,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, reinterpret_cast<int*>(critterData->skills), SKILL_COUNT) == -1) return -1;
|
||||
if (fileReadInt32(stream, reinterpret_cast<int*>(&(critterData->bodyType))) == -1) return -1;
|
||||
if (fileReadInt32List(stream, critterData->skills, SKILL_COUNT) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(critterData->bodyType)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(critterData->experience)) == -1) return -1;
|
||||
if (fileReadInt32(stream, reinterpret_cast<int*>(&(critterData->killType))) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(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.
|
||||
@@ -1114,7 +1122,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, reinterpret_cast<int*>(&(critterData->damageType))) == -1) {
|
||||
if (fileReadInt32(stream, &(critterData->damageType)) == -1) {
|
||||
critterData->damageType = DAMAGE_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
@@ -1164,7 +1172,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, reinterpret_cast<int*>(critterData->skills), SKILL_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, 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
@@ -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);
|
||||
DamageType critterGetDamageType(Object* critter);
|
||||
int killsIncByType(KillType killType);
|
||||
int killsGetByType(KillType killType);
|
||||
int critterGetDamageType(Object* critter);
|
||||
int killsIncByType(int killType);
|
||||
int killsGetByType(int killType);
|
||||
int killsLoad(File* stream);
|
||||
int killsSave(File* stream);
|
||||
KillType critterGetKillType(Object* critter);
|
||||
char* killTypeGetName(KillType killType);
|
||||
char* killTypeGetDescription(KillType killType);
|
||||
int critterGetKillType(Object* critter);
|
||||
char* killTypeGetName(int killType);
|
||||
char* killTypeGetDescription(int 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);
|
||||
BodyType critterGetBodyType(Object* critter);
|
||||
int 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);
|
||||
|
||||
+11
-2
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "art.h"
|
||||
#include "color.h"
|
||||
#include "content_config.h"
|
||||
#include "credits.h"
|
||||
#include "cycle.h"
|
||||
#include "db.h"
|
||||
@@ -78,6 +79,7 @@ static void _endgame_voiceover_callback();
|
||||
static int endgameEndingSubtitlesLoad(const char* filePath);
|
||||
static void endgameEndingRefreshSubtitles();
|
||||
static void endgameEndingSubtitlesFree();
|
||||
static const char* endgameGetSoundConfig(const char* key, const char* defaultValue);
|
||||
static void _endgame_movie_callback();
|
||||
static void _endgame_movie_bk_process();
|
||||
static int endgameEndingInit();
|
||||
@@ -239,7 +241,7 @@ void endgamePlayMovie()
|
||||
_endgame_maybe_done = 0;
|
||||
tickersAdd(_endgame_movie_bk_process);
|
||||
backgroundSoundSetEndCallback(_endgame_movie_callback);
|
||||
backgroundSoundLoad("akiss", GSOUND_LIMIT_AFTER, GSOUND_STREAM, GSOUND_NO_LOOP);
|
||||
backgroundSoundLoad(endgameGetSoundConfig("endgame_movie_music0", "maybe"), GSOUND_LIMIT_AFTER, GSOUND_STREAM, GSOUND_NO_LOOP);
|
||||
inputPauseForTocks(3000);
|
||||
|
||||
// NOTE: Result is ignored. I guess there was some kind of switch for male
|
||||
@@ -872,6 +874,13 @@ static void endgameEndingSubtitlesFree()
|
||||
gEndgameEndingSubtitlesLength = 0;
|
||||
}
|
||||
|
||||
static const char* endgameGetSoundConfig(const char* key, const char* defaultValue)
|
||||
{
|
||||
char* value = nullptr;
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_SOUND_SECTION, key, &value, nullptr);
|
||||
return value != nullptr && value[0] != '\0' ? value : defaultValue;
|
||||
}
|
||||
|
||||
// 0x440728 endgame_movie_callback
|
||||
static void _endgame_movie_callback()
|
||||
{
|
||||
@@ -882,7 +891,7 @@ static void _endgame_movie_callback()
|
||||
static void _endgame_movie_bk_process()
|
||||
{
|
||||
if (_endgame_maybe_done) {
|
||||
backgroundSoundLoad("10labone", GSOUND_LIMIT_BEFORE, GSOUND_STREAM, GSOUND_LOOP);
|
||||
backgroundSoundLoad(endgameGetSoundConfig("endgame_movie_music1", "10labone"), GSOUND_LIMIT_BEFORE, GSOUND_STREAM, GSOUND_LOOP);
|
||||
backgroundSoundSetEndCallback(nullptr);
|
||||
tickersRemove(_endgame_movie_bk_process);
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ namespace {
|
||||
|
||||
constexpr char kSfallMisc[] = "Misc";
|
||||
constexpr char kSfallInterface[] = "Interface";
|
||||
constexpr char kSfallSound[] = "Sound";
|
||||
|
||||
struct SfallMigrationEntry {
|
||||
const char* sfallSection;
|
||||
@@ -184,8 +185,6 @@ 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" },
|
||||
@@ -201,6 +200,13 @@ namespace {
|
||||
{ kSfallMisc, "MainMenuOffsetY", CONTENT_CONFIG_MAIN_MENU_SECTION, "offset_y", "0" },
|
||||
{ kSfallMisc, "MainMenuCreditsOffsetX", CONTENT_CONFIG_MAIN_MENU_SECTION, "credits_offset_x", "0" },
|
||||
{ kSfallMisc, "MainMenuCreditsOffsetY", CONTENT_CONFIG_MAIN_MENU_SECTION, "credits_offset_y", "0" },
|
||||
// [sound]
|
||||
{ kSfallSound, "MainMenuMusic", CONTENT_CONFIG_SOUND_SECTION, "main_menu_music", "07desert" },
|
||||
{ kSfallSound, "WorldMapMusic", CONTENT_CONFIG_SOUND_SECTION, "worldmap_music", "03wrldmp" },
|
||||
{ kSfallSound, "WorldMapCarMusic", CONTENT_CONFIG_SOUND_SECTION, "worldmap_car_music", "20car" },
|
||||
{ kSfallSound, "EndGameMovieMusic0", CONTENT_CONFIG_SOUND_SECTION, "endgame_movie_music0", "maybe" },
|
||||
{ kSfallSound, "EndGameMovieMusic1", CONTENT_CONFIG_SOUND_SECTION, "endgame_movie_music1", "10labone" },
|
||||
{ kSfallSound, "MapLoadingSound", CONTENT_CONFIG_SOUND_SECTION, "map_loading_sound", "wind2" },
|
||||
// [movies]
|
||||
{ kSfallMisc, "MovieTimer_artimer1", CONTENT_CONFIG_MOVIES_SECTION, "artimer1", "90" },
|
||||
{ kSfallMisc, "MovieTimer_artimer2", CONTENT_CONFIG_MOVIES_SECTION, "artimer2", "180" },
|
||||
|
||||
+1
-1
@@ -3789,7 +3789,7 @@ void partyMemberControlWindowUpdate()
|
||||
fontDrawText(windowBuffer + windowWidth * 96 + 240, formattedText, 115, windowWidth, COLOR_GREEN);
|
||||
|
||||
// Render best skill.
|
||||
Skill bestSkill = partyMemberGetBestSkill(gGameDialogSpeaker);
|
||||
int bestSkill = partyMemberGetBestSkill(gGameDialogSpeaker);
|
||||
text = skillGetName(bestSkill);
|
||||
snprintf(formattedText, sizeof(formattedText), "%s", text);
|
||||
fontDrawText(windowBuffer + windowWidth * 113 + 240, formattedText, 115, windowWidth, COLOR_GREEN);
|
||||
|
||||
+3
-3
@@ -264,7 +264,7 @@ static int gGameMouseModeFrmIds[GAME_MOUSE_MODE_COUNT] = {
|
||||
};
|
||||
|
||||
// 0x518D68 gmouse_skill_table
|
||||
static const Skill gGameMouseModeSkills[GAME_MOUSE_MODE_SKILL_COUNT] = {
|
||||
static const int 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) {
|
||||
Skill skill = SKILL_INVALID;
|
||||
int skill = -1;
|
||||
|
||||
int rc = skilldexOpen();
|
||||
switch (rc) {
|
||||
@@ -1288,7 +1288,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
break;
|
||||
}
|
||||
|
||||
if (skill != SKILL_INVALID) {
|
||||
if (skill != -1) {
|
||||
actionUseSkill(gDude, targetObj, skill);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1390,7 +1390,7 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, HitMode hitMode, Object
|
||||
soundVariant = 1;
|
||||
}
|
||||
|
||||
DamageType damageType = weaponGetDamageType(nullptr, weapon);
|
||||
int damageType = weaponGetDamageType(nullptr, weapon);
|
||||
|
||||
// SFALL
|
||||
if (effectTypeCode != 'H' || target == nullptr || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user