From b18b2471c3a4e1ad386d7776317d04ce076deb54 Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Thu, 6 Jul 2023 23:41:04 +0200 Subject: [PATCH] Code readability: _determine_to_hit, sfxBuildWeaponName --- src/animation.cc | 1 + src/combat.cc | 197 ++++++++++++++++++++++------------------------ src/combat.h | 12 +-- src/combat_ai.cc | 183 +++++++++++++++++++++--------------------- src/game_sound.cc | 10 +-- 5 files changed, 200 insertions(+), 203 deletions(-) diff --git a/src/animation.cc b/src/animation.cc index bc472c7..e813728 100644 --- a/src/animation.cc +++ b/src/animation.cc @@ -1711,6 +1711,7 @@ int _make_path(Object* object, int from, int to, unsigned char* rotations, int a return pathfinderFindPath(object, from, to, rotations, a5, _obj_blocking_at); } +// TODO: move pathfinding into another unit // 0x415EFC int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback) { diff --git a/src/combat.cc b/src/combat.cc index 4e84fda..70098c0 100644 --- a/src/combat.cc +++ b/src/combat.cc @@ -116,7 +116,7 @@ static int attackComputeCriticalHit(Attack* a1); static int _attackFindInvalidFlags(Object* a1, Object* a2); static int attackComputeCriticalFailure(Attack* attack); static void _do_random_cripple(int* flagsPtr); -static int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode, bool a6); +static int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode, bool useDistance); static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3); static void _check_for_death(Object* a1, int a2, int* a3); static void _set_new_results(Object* a1, int a2); @@ -3476,16 +3476,16 @@ void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode, } // 0x422F3C -int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) +int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocation) { - if (a1 != gDude && hitMode == HIT_MODE_PUNCH && randomBetween(1, 4) == 1) { - int fid = buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28); + if (attacker != gDude && hitMode == HIT_MODE_PUNCH && randomBetween(1, 4) == 1) { + int fid = buildFid(OBJ_TYPE_CRITTER, attacker->fid & 0xFFF, ANIM_KICK_LEG, (attacker->fid & 0xF000) >> 12, (attacker->fid & 0x70000000) >> 28); if (artExists(fid)) { hitMode = HIT_MODE_KICK; } } - attackInit(&_main_ctd, a1, a2, hitMode, hitLocation); + attackInit(&_main_ctd, attacker, defender, hitMode, hitLocation); debugPrint("computing attack...\n"); if (attackCompute(&_main_ctd) == -1) { @@ -3513,7 +3513,7 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) bool aiming; if (_main_ctd.defenderHitLocation == HIT_LOCATION_TORSO || _main_ctd.defenderHitLocation == HIT_LOCATION_UNCALLED) { - if (a1 == gDude) { + if (attacker == gDude) { interfaceGetCurrentHitMode(&hitMode, &aiming); } else { aiming = false; @@ -3522,22 +3522,22 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) aiming = true; } - int actionPoints = weaponGetActionPointCost(a1, _main_ctd.hitMode, aiming); + int actionPoints = weaponGetActionPointCost(attacker, _main_ctd.hitMode, aiming); debugPrint("sequencing attack...\n"); if (_action_attack(&_main_ctd) == -1) { return -1; } - if (actionPoints > a1->data.critter.combat.ap) { - a1->data.critter.combat.ap = 0; + if (actionPoints > attacker->data.critter.combat.ap) { + attacker->data.critter.combat.ap = 0; } else { - a1->data.critter.combat.ap -= actionPoints; + attacker->data.critter.combat.ap -= actionPoints; } - if (a1 == gDude) { - interfaceRenderActionPoints(a1->data.critter.combat.ap, _combat_free_move); - _critter_set_who_hit_me(a1, a2); + if (attacker == gDude) { + interfaceRenderActionPoints(attacker->data.critter.combat.ap, _combat_free_move); + _critter_set_who_hit_me(attacker, defender); } // SFALL @@ -3545,19 +3545,19 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) _combat_call_display = 1; _combat_cleanup_enabled = 1; - aiInfoSetLastTarget(a1, a2); + aiInfoSetLastTarget(attacker, defender); debugPrint("running attack...\n"); return 0; } -// Returns tile one step closer from [a1] to [a2] +// Returns tile one step closer from [attacker] to [target] // // 0x423104 -int _combat_bullet_start(const Object* a1, const Object* a2) +int _combat_bullet_start(const Object* attacker, const Object* target) { - int rotation = tileGetRotationTo(a1->tile, a2->tile); - return tileGetTileInDirection(a1->tile, rotation, 1); + int rotation = tileGetRotationTo(attacker->tile, target->tile); + return tileGetTileInDirection(attacker->tile, rotation, 1); } // 0x423128 @@ -4282,26 +4282,26 @@ static void _do_random_cripple(int* flagsPtr) } // 0x42436C -int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode) +int _determine_to_hit(Object* attacker, Object* defender, int hitLocation, int hitMode) { - return attackDetermineToHit(a1, a1->tile, a2, hitLocation, hitMode, true); + return attackDetermineToHit(attacker, attacker->tile, defender, hitLocation, hitMode, true); } // 0x424380 -int _determine_to_hit_no_range(Object* a1, Object* a2, int hitLocation, int hitMode, unsigned char* a5) +int _determine_to_hit_no_range(Object* attacker, Object* defender, int hitLocation, int hitMode, unsigned char* a5) { - return attackDetermineToHit(a1, a1->tile, a2, hitLocation, hitMode, false); + return attackDetermineToHit(attacker, attacker->tile, defender, hitLocation, hitMode, false); } // 0x424394 -int _determine_to_hit_from_tile(Object* a1, int tile, Object* a3, int hitLocation, int hitMode) +int _determine_to_hit_from_tile(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode) { - return attackDetermineToHit(a1, tile, a3, hitLocation, hitMode, true); + return attackDetermineToHit(attacker, tile, defender, hitLocation, hitMode, true); } // determine_to_hit // 0x4243A8 -static int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode, bool a6) +static int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode, bool useDistance) { Object* weapon = critterGetWeaponForHitMode(attacker, hitMode); @@ -4311,32 +4311,30 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in bool isRangedWeapon = false; - int accuracy; + int toHit; if (weapon == NULL || isUnarmedHitMode(hitMode)) { - accuracy = skillGetValue(attacker, SKILL_UNARMED); + toHit = skillGetValue(attacker, SKILL_UNARMED); } else { - accuracy = weaponGetSkillValue(attacker, hitMode); - - int modifier = 0; + toHit = weaponGetSkillValue(attacker, hitMode); int attackType = weaponGetAttackTypeForHitMode(weapon, hitMode); if (attackType == ATTACK_TYPE_RANGED || attackType == ATTACK_TYPE_THROW) { isRangedWeapon = true; - int v29 = 0; - int v25 = 0; + int perceptionBonusMult = 0; + int minEffectiveDist = 0; int weaponPerk = weaponGetPerk(weapon); switch (weaponPerk) { case PERK_WEAPON_LONG_RANGE: - v29 = 4; + perceptionBonusMult = 4; break; case PERK_WEAPON_SCOPE_RANGE: - v29 = 5; - v25 = 8; + perceptionBonusMult = 5; + minEffectiveDist = 8; break; default: - v29 = 2; + perceptionBonusMult = 2; break; } @@ -4347,71 +4345,72 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in perception += 2 * perkGetRank(gDude, PERK_SHARPSHOOTER); } + int distanceMod = 0; // SFALL: Fix for `determine_to_hit_func` function taking distance // into account when called from `determine_to_hit_no_range`. - if (defender != NULL && a6) { - modifier = objectGetDistanceBetweenTiles(attacker, tile, defender, defender->tile); + if (defender != NULL && useDistance) { + distanceMod = objectGetDistanceBetweenTiles(attacker, tile, defender, defender->tile); } else { - modifier = 0; + distanceMod = 0; } - if (modifier >= v25) { - int penalty = attacker == gDude - ? v29 * (perception - 2) - : v29 * perception; + if (distanceMod >= minEffectiveDist) { + int perceptionBonus = attacker == gDude + ? perceptionBonusMult * (perception - 2) + : perceptionBonusMult * perception; - modifier -= penalty; + distanceMod -= perceptionBonus; } else { - modifier += v25; + distanceMod += minEffectiveDist; } - if (-2 * perception > modifier) { - modifier = -2 * perception; + if (distanceMod < -2 * perception) { + distanceMod = -2 * perception; } - if (modifier >= 0) { + if (distanceMod >= 0) { if ((attacker->data.critter.combat.results & DAM_BLIND) != 0) { - modifier *= -12; + distanceMod *= -12; } else { - modifier *= -4; + distanceMod *= -4; } } else { - modifier *= -4; + distanceMod *= -4; } - if (a6 || modifier > 0) { - accuracy += modifier; + if (useDistance || distanceMod > 0) { + toHit += distanceMod; } - modifier = 0; + int numCrittersInLof = 0; - if (defender != NULL && a6) { - _combat_is_shot_blocked(attacker, tile, defender->tile, defender, &modifier); + if (defender != NULL && useDistance) { + _combat_is_shot_blocked(attacker, tile, defender->tile, defender, &numCrittersInLof); } - accuracy -= 10 * modifier; + toHit -= 10 * numCrittersInLof; } if (attacker == gDude && traitIsSelected(TRAIT_ONE_HANDER)) { if (weaponIsTwoHanded(weapon)) { - accuracy -= 40; + toHit -= 40; } else { - accuracy += 20; + toHit += 20; } } int minStrength = weaponGetMinStrengthRequired(weapon); - modifier = minStrength - critterGetStat(attacker, STAT_STRENGTH); + int minStrengthMod = minStrength - critterGetStat(attacker, STAT_STRENGTH); if (attacker == gDude && perkGetRank(gDude, PERK_WEAPON_HANDLING) != 0) { - modifier -= 3; + minStrengthMod -= 3; } - if (modifier > 0) { - accuracy -= 20 * modifier; + if (minStrengthMod > 0) { + toHit -= 20 * minStrengthMod; } if (weaponGetPerk(weapon) == PERK_WEAPON_ACCURATE) { - accuracy += 20; + toHit += 20; } } @@ -4422,17 +4421,17 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in armorClass = 0; } - accuracy -= armorClass; + toHit -= armorClass; } if (isRangedWeapon) { - accuracy += hit_location_penalty[hitLocation]; + toHit += hit_location_penalty[hitLocation]; } else { - accuracy += hit_location_penalty[hitLocation] / 2; + toHit += hit_location_penalty[hitLocation] / 2; } if (defender != NULL && (defender->flags & OBJECT_MULTIHEX) != 0) { - accuracy += 15; + toHit += 15; } if (attacker == gDude) { @@ -4447,45 +4446,45 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in } if (lightIntensity <= 26214) - accuracy -= 40; + toHit -= 40; else if (lightIntensity <= 39321) - accuracy -= 25; + toHit -= 25; else if (lightIntensity <= 52428) - accuracy -= 10; + toHit -= 10; } if (_gcsd != NULL) { - accuracy += _gcsd->accuracyBonus; + toHit += _gcsd->accuracyBonus; } if ((attacker->data.critter.combat.results & DAM_BLIND) != 0) { - accuracy -= 25; + toHit -= 25; } if (targetIsCritter && defender != NULL && (defender->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0) { - accuracy += 40; + toHit += 40; } if (attacker->data.critter.combat.team != gDude->data.critter.combat.team) { switch (settings.preferences.combat_difficulty) { case 0: - accuracy -= 20; + toHit -= 20; break; case 2: - accuracy += 20; + toHit += 20; break; } } - if (accuracy > 95) { - accuracy = 95; + if (toHit > 95) { + toHit = 95; } - if (accuracy < -100) { + if (toHit < -100) { debugPrint("Whoa! Bad skill value in determine_to_hit!\n"); } - return accuracy; + return toHit; } // 0x4247B8 @@ -5880,39 +5879,35 @@ void _combat_highlight_change() _combat_highlight = targetHighlight; } -// Probably calculates line of sight or determines if object can see other object. +// Checks if line of fire to the target object is blocked or not. Optionally calculate number of critters on the line of fire. // // 0x426CC4 -bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5) +bool _combat_is_shot_blocked(Object* sourceObj, int from, int to, Object* targetObj, int* numCrittersOnLof) { - if (a5 != NULL) { - *a5 = 0; + if (numCrittersOnLof != NULL) { + *numCrittersOnLof = 0; } - Object* obstacle = a1; + Object* obstacle = sourceObj; int current = from; while (obstacle != NULL && current != to) { - _make_straight_path_func(a1, current, to, 0, &obstacle, 32, _obj_shoot_blocking_at); + _make_straight_path_func(sourceObj, current, to, 0, &obstacle, 32, _obj_shoot_blocking_at); if (obstacle != NULL) { - if (FID_TYPE(obstacle->fid) != OBJ_TYPE_CRITTER && obstacle != a4) { + if (FID_TYPE(obstacle->fid) != OBJ_TYPE_CRITTER && obstacle != targetObj) { return true; } - if (a5 != NULL) { - if (obstacle != a4) { - if (a4 != NULL) { - // SFALL: Fix for combat_is_shot_blocked_ engine - // function not taking the flags of critters in the - // line of fire into account when calculating the hit - // chance penalty of ranged attacks in - // determine_to_hit_func_ engine function. - if ((obstacle->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_DOWN | DAM_KNOCKED_OUT)) == 0) { - *a5 += 1; + if (numCrittersOnLof != NULL && obstacle != targetObj && targetObj != NULL) { + // SFALL: Fix for combat_is_shot_blocked_ engine + // function not taking the flags of critters in the + // line of fire into account when calculating the hit + // chance penalty of ranged attacks in + // determine_to_hit_func_ engine function. + if ((obstacle->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_DOWN | DAM_KNOCKED_OUT)) == 0) { + *numCrittersOnLof += 1; - if ((obstacle->flags & OBJECT_MULTIHEX) != 0) { - *a5 += 1; - } - } + if ((obstacle->flags & OBJECT_MULTIHEX) != 0) { + *numCrittersOnLof += 1; } } } diff --git a/src/combat.h b/src/combat.h index 9ce73d9..2438b37 100644 --- a/src/combat.h +++ b/src/combat.h @@ -34,13 +34,13 @@ void _combat_over_from_load(); void _combat_give_exps(int exp_points); void _combat_turn_run(); void _combat(STRUCT_664980* attack); -void attackInit(Attack* attack, Object* a2, Object* a3, int a4, int a5); -int _combat_attack(Object* a1, Object* a2, int a3, int a4); -int _combat_bullet_start(const Object* a1, const Object* a2); +void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode, int hitLocation); +int _combat_attack(Object* attacker, Object* defender, int hitMode, int hitLocation); +int _combat_bullet_start(const Object* attacker, const Object* target); void _compute_explosion_on_extras(Attack* attack, bool isFromAttacker, bool isGrenade, bool noDamage); int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode); -int _determine_to_hit_no_range(Object* a1, Object* a2, int a3, int a4, unsigned char* a5); -int _determine_to_hit_from_tile(Object* a1, int a2, Object* a3, int a4, int 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, int hitLocation, int hitMode); void attackComputeDeathFlags(Attack* attack); void _apply_damage(Attack* attack, bool animated); void _combat_display(Attack* attack); @@ -52,7 +52,7 @@ void _combat_attack_this(Object* a1); void _combat_outline_on(); void _combat_outline_off(); void _combat_highlight_change(); -bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5); +bool _combat_is_shot_blocked(Object* sourceObj, int from, int to, Object* targetObj, int* numCrittersOnLof); int _combat_player_knocked_out_by(); int _combat_explode_scenery(Object* a1, Object* a2); void _combat_delete_critter(Object* obj); diff --git a/src/combat_ai.cc b/src/combat_ai.cc index 797d9e0..3ee2082 100644 --- a/src/combat_ai.cc +++ b/src/combat_ai.cc @@ -2327,61 +2327,61 @@ static int _ai_pick_hit_mode(Object* attacker, Object* weapon, Object* defender) } // 0x429FC8 -static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, bool taunt) +static int _ai_move_steps_closer(Object* critter, Object* target, int actionPoints, bool taunt) { if (actionPoints <= 0) { return -1; } - int distance = aiGetDistance(a1); + int distance = aiGetDistance(critter); if (distance == DISTANCE_STAY) { return -1; } if (distance == DISTANCE_STAY_CLOSE) { - if (a2 != gDude) { - int currentDistance = objectGetDistanceBetween(a1, gDude); + if (target != gDude) { + int currentDistance = objectGetDistanceBetween(critter, gDude); if (currentDistance > 5 - && objectGetDistanceBetween(a2, gDude) > 5 + && objectGetDistanceBetween(target, gDude) > 5 && currentDistance + actionPoints > 5) { return -1; } } } - if (objectGetDistanceBetween(a1, a2) <= 1) { + if (objectGetDistanceBetween(critter, target) <= 1) { return -1; } reg_anim_begin(ANIMATION_REQUEST_RESERVED); if (taunt) { - _combatai_msg(a1, NULL, AI_MESSAGE_TYPE_MOVE, 0); + _combatai_msg(critter, NULL, AI_MESSAGE_TYPE_MOVE, 0); } - Object* v18 = a2; + Object* initialTarget = target; bool shouldUnhide; - if ((a2->flags & OBJECT_MULTIHEX) != 0) { + if ((target->flags & OBJECT_MULTIHEX) != 0) { shouldUnhide = true; - a2->flags |= OBJECT_HIDDEN; + target->flags |= OBJECT_HIDDEN; } else { shouldUnhide = false; } - if (pathfinderFindPath(a1, a1->tile, a2->tile, NULL, 0, _obj_blocking_at) == 0) { + if (pathfinderFindPath(critter, critter->tile, target->tile, NULL, 0, _obj_blocking_at) == 0) { _moveBlockObj = NULL; - if (pathfinderFindPath(a1, a1->tile, a2->tile, NULL, 0, _obj_ai_blocking_at) == 0 + if (pathfinderFindPath(critter, critter->tile, target->tile, NULL, 0, _obj_ai_blocking_at) == 0 && _moveBlockObj != NULL && PID_TYPE(_moveBlockObj->pid) == OBJ_TYPE_CRITTER) { if (shouldUnhide) { - a2->flags &= ~OBJECT_HIDDEN; + target->flags &= ~OBJECT_HIDDEN; } - a2 = _moveBlockObj; - if ((a2->flags & OBJECT_MULTIHEX) != 0) { + target = _moveBlockObj; + if ((target->flags & OBJECT_MULTIHEX) != 0) { shouldUnhide = true; - a2->flags |= OBJECT_HIDDEN; + target->flags |= OBJECT_HIDDEN; } else { shouldUnhide = false; } @@ -2389,25 +2389,25 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, bool } if (shouldUnhide) { - a2->flags &= ~OBJECT_HIDDEN; + target->flags &= ~OBJECT_HIDDEN; } - int tile = a2->tile; - if (a2 == v18) { - _cai_retargetTileFromFriendlyFire(a1, a2, &tile); + int tile = target->tile; + if (target == initialTarget) { + _cai_retargetTileFromFriendlyFire(critter, target, &tile); } - if (actionPoints >= critterGetStat(a1, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(a1->fid)) { - if ((a2->flags & OBJECT_MULTIHEX) != 0) { - animationRegisterRunToObject(a1, a2, actionPoints, 0); + if (actionPoints >= critterGetStat(critter, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(critter->fid)) { + if ((target->flags & OBJECT_MULTIHEX) != 0) { + animationRegisterRunToObject(critter, target, actionPoints, 0); } else { - animationRegisterRunToTile(a1, tile, a1->elevation, actionPoints, 0); + animationRegisterRunToTile(critter, tile, critter->elevation, actionPoints, 0); } } else { - if ((a2->flags & OBJECT_MULTIHEX) != 0) { - animationRegisterMoveToObject(a1, a2, actionPoints, 0); + if ((target->flags & OBJECT_MULTIHEX) != 0) { + animationRegisterMoveToObject(critter, target, actionPoints, 0); } else { - animationRegisterMoveToTile(a1, tile, a1->elevation, actionPoints, 0); + animationRegisterMoveToTile(critter, tile, critter->elevation, actionPoints, 0); } } @@ -2665,35 +2665,35 @@ static int _ai_attack(Object* attacker, Object* defender, int hitMode) } // 0x42A7D8 -static int _ai_try_attack(Object* a1, Object* a2) +static int _ai_try_attack(Object* attacker, Object* defender) { - _critter_set_who_hit_me(a1, a2); + _critter_set_who_hit_me(attacker, defender); - CritterCombatData* combatData = &(a1->data.critter.combat); + CritterCombatData* combatData = &(attacker->data.critter.combat); bool taunt = true; - Object* weapon = critterGetItem2(a1); + Object* weapon = critterGetItem2(attacker); if (weapon != NULL && itemGetType(weapon) != ITEM_TYPE_WEAPON) { weapon = NULL; } - int hitMode = _ai_pick_hit_mode(a1, weapon, a2); - int minToHit = aiGetPacket(a1)->min_to_hit; + int hitMode = _ai_pick_hit_mode(attacker, weapon, defender); + int minToHit = aiGetPacket(attacker)->min_to_hit; - int actionPoints = a1->data.critter.combat.ap; + int actionPoints = attacker->data.critter.combat.ap; int safeDistance = 0; - int v42 = 0; + int actionPointsToUse = 0; if (weapon != NULL - || (critterGetBodyType(a2) == BODY_TYPE_BIPED - && ((a2->fid & 0xF000) >> 12 == 0) - && artExists(buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_THROW_PUNCH, 0, a1->rotation + 1)))) { + || (critterGetBodyType(defender) == BODY_TYPE_BIPED + && ((defender->fid & 0xF000) >> 12 == 0) + && artExists(buildFid(OBJ_TYPE_CRITTER, attacker->fid & 0xFFF, ANIM_THROW_PUNCH, 0, attacker->rotation + 1)))) { // SFALL: Check the safety of weapons based on the selected attack mode // instead of always the primary weapon hit mode. - if (_combat_safety_invalidate_weapon(a1, weapon, hitMode, a2, &safeDistance)) { - _ai_switch_weapons(a1, &hitMode, &weapon, a2); + if (_combat_safety_invalidate_weapon(attacker, weapon, hitMode, defender, &safeDistance)) { + _ai_switch_weapons(attacker, &hitMode, &weapon, defender); } } else { - _ai_switch_weapons(a1, &hitMode, &weapon, a2); + _ai_switch_weapons(attacker, &hitMode, &weapon, defender); } unsigned char rotations[800]; @@ -2704,37 +2704,37 @@ static int _ai_try_attack(Object* a1, Object* a2) break; } - int reason = _combat_check_bad_shot(a1, a2, hitMode, false); + int reason = _combat_check_bad_shot(attacker, defender, hitMode, false); if (reason == COMBAT_BAD_SHOT_NO_AMMO) { // out of ammo - if (aiHaveAmmo(a1, weapon, &ammo)) { + if (aiHaveAmmo(attacker, weapon, &ammo)) { int remainingAmmoQuantity = weaponReload(weapon, ammo); if (remainingAmmoQuantity == 0 && ammo != NULL) { _obj_destroy(ammo); } if (remainingAmmoQuantity != -1) { - int volume = _gsound_compute_relative_volume(a1); + int volume = _gsound_compute_relative_volume(attacker); const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_READY, weapon, hitMode, NULL); _gsound_play_sfx_file_volume(sfx, volume); - _ai_magic_hands(a1, weapon, 5002); + _ai_magic_hands(attacker, weapon, 5002); // SFALL: Fix incorrect AP cost when AI reloads a weapon. // CE: There is a commented out code which checks // available action points before performing reload. Not // sure why it was commented, probably needs additional // testing. - int actionPointsRequired = weaponGetActionPointCost(a1, HIT_MODE_RIGHT_WEAPON_RELOAD, false); - if (a1->data.critter.combat.ap >= actionPointsRequired) { - a1->data.critter.combat.ap -= actionPointsRequired; + int actionPointsRequired = weaponGetActionPointCost(attacker, HIT_MODE_RIGHT_WEAPON_RELOAD, false); + if (attacker->data.critter.combat.ap >= actionPointsRequired) { + attacker->data.critter.combat.ap -= actionPointsRequired; } else { - a1->data.critter.combat.ap = 0; + attacker->data.critter.combat.ap = 0; } } } else { - ammo = _ai_search_environ(a1, ITEM_TYPE_AMMO); + ammo = _ai_search_environ(attacker, ITEM_TYPE_AMMO); if (ammo != NULL) { - ammo = _ai_retrieve_object(a1, ammo); + ammo = _ai_retrieve_object(attacker, ammo); if (ammo != NULL) { int remainingAmmoQuantity = weaponReload(weapon, ammo); if (remainingAmmoQuantity == 0) { @@ -2742,62 +2742,63 @@ static int _ai_try_attack(Object* a1, Object* a2) } if (remainingAmmoQuantity != -1) { - int volume = _gsound_compute_relative_volume(a1); + int volume = _gsound_compute_relative_volume(attacker); const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_READY, weapon, hitMode, NULL); _gsound_play_sfx_file_volume(sfx, volume); - _ai_magic_hands(a1, weapon, 5002); + _ai_magic_hands(attacker, weapon, 5002); // SFALL: Fix incorrect AP cost when AI reloads a // weapon. // CE: See note above, probably need to check // available action points before performing // reload. - int actionPointsRequired = weaponGetActionPointCost(a1, HIT_MODE_RIGHT_WEAPON_RELOAD, false); - if (a1->data.critter.combat.ap >= actionPointsRequired) { - a1->data.critter.combat.ap -= actionPointsRequired; + int actionPointsRequired = weaponGetActionPointCost(attacker, HIT_MODE_RIGHT_WEAPON_RELOAD, false); + if (attacker->data.critter.combat.ap >= actionPointsRequired) { + attacker->data.critter.combat.ap -= actionPointsRequired; } else { - a1->data.critter.combat.ap = 0; + attacker->data.critter.combat.ap = 0; } } } } else { - int volume = _gsound_compute_relative_volume(a1); + int volume = _gsound_compute_relative_volume(attacker); const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_OUT_OF_AMMO, weapon, hitMode, NULL); _gsound_play_sfx_file_volume(sfx, volume); - _ai_magic_hands(a1, weapon, 5001); + _ai_magic_hands(attacker, weapon, 5001); - if (_inven_unwield(a1, 1) == 0) { + if (_inven_unwield(attacker, 1) == 0) { _combat_turn_run(); } - _ai_switch_weapons(a1, &hitMode, &weapon, a2); + _ai_switch_weapons(attacker, &hitMode, &weapon, defender); } } } 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(a1, &hitMode, &weapon, a2) == -1) { + if (_ai_switch_weapons(attacker, &hitMode, &weapon, defender) == -1) { return -1; } } else if (reason == COMBAT_BAD_SHOT_OUT_OF_RANGE) { // target out of range - int accuracy = _determine_to_hit_no_range(a1, a2, HIT_LOCATION_UNCALLED, hitMode, rotations); - if (accuracy < minToHit) { - debugPrint("%s: FLEEING: Can't possibly Hit Target!", critterGetName(a1)); - _ai_run_away(a1, a2); + int toHitNoRange = _determine_to_hit_no_range(attacker, defender, HIT_LOCATION_UNCALLED, hitMode, rotations); + if (toHitNoRange < minToHit) { + // hit chance is too low even at point blank range (not taking range into account) + debugPrint("%s: FLEEING: Can't possibly Hit Target!", critterGetName(attacker)); + _ai_run_away(attacker, defender); return 0; } if (weapon != NULL) { - if (_ai_move_steps_closer(a1, a2, actionPoints, taunt) == -1) { + if (_ai_move_steps_closer(attacker, defender, actionPoints, taunt) == -1) { return -1; } taunt = false; } else { - if (_ai_switch_weapons(a1, &hitMode, &weapon, a2) == -1 || weapon == NULL) { + if (_ai_switch_weapons(attacker, &hitMode, &weapon, defender) == -1 || weapon == NULL) { // NOTE: Uninline. - if (_ai_move_closer(a1, a2, taunt) == -1) { + if (_ai_move_closer(attacker, defender, taunt) == -1) { return -1; } } @@ -2805,66 +2806,66 @@ static int _ai_try_attack(Object* a1, Object* a2) } } else if (reason == COMBAT_BAD_SHOT_AIM_BLOCKED) { // aim is blocked - if (_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, taunt) == -1) { + if (_ai_move_steps_closer(attacker, defender, attacker->data.critter.combat.ap, taunt) == -1) { return -1; } taunt = false; } else if (reason == COMBAT_BAD_SHOT_OK) { - int accuracy = _determine_to_hit(a1, a2, HIT_LOCATION_UNCALLED, hitMode); + int accuracy = _determine_to_hit(attacker, defender, HIT_LOCATION_UNCALLED, hitMode); if (safeDistance != 0) { - if (_ai_move_away(a1, a2, safeDistance) == -1) { + if (_ai_move_away(attacker, defender, safeDistance) == -1) { return -1; } } if (accuracy < minToHit) { - int accuracyNoRange = _determine_to_hit_no_range(a1, a2, HIT_LOCATION_UNCALLED, hitMode, rotations); - if (accuracyNoRange < minToHit) { - debugPrint("%s: FLEEING: Can't possibly Hit Target!", critterGetName(a1)); - _ai_run_away(a1, a2); + int toHitNoRange = _determine_to_hit_no_range(attacker, defender, HIT_LOCATION_UNCALLED, hitMode, rotations); + if (toHitNoRange < minToHit) { + debugPrint("%s: FLEEING: Can't possibly Hit Target!", critterGetName(attacker)); + _ai_run_away(attacker, defender); return 0; } if (actionPoints > 0) { - int v24 = pathfinderFindPath(a1, a1->tile, a2->tile, rotations, 0, _obj_blocking_at); - if (v24 == 0) { - v42 = actionPoints; + int pathLength = pathfinderFindPath(attacker, attacker->tile, defender->tile, rotations, 0, _obj_blocking_at); + if (pathLength == 0) { + actionPointsToUse = actionPoints; } else { - if (v24 < actionPoints) { - actionPoints = v24; + if (pathLength < actionPoints) { + actionPoints = pathLength; } - int tile = a1->tile; + int tile = attacker->tile; int index; for (index = 0; index < actionPoints; index++) { tile = tileGetTileInDirection(tile, rotations[index], 1); - v42++; + actionPointsToUse++; - int v27 = _determine_to_hit_from_tile(a1, tile, a2, HIT_LOCATION_UNCALLED, hitMode); - if (v27 >= minToHit) { + int toHit = _determine_to_hit_from_tile(attacker, tile, defender, HIT_LOCATION_UNCALLED, hitMode); + if (toHit >= minToHit) { break; } } if (index == actionPoints) { - v42 = actionPoints; + actionPointsToUse = actionPoints; } } } - if (_ai_move_steps_closer(a1, a2, v42, taunt) == -1) { - debugPrint("%s: FLEEING: Can't possibly get closer to Target!", critterGetName(a1)); - _ai_run_away(a1, a2); + if (_ai_move_steps_closer(attacker, defender, actionPointsToUse, taunt) == -1) { + debugPrint("%s: FLEEING: Can't possibly get closer to Target!", critterGetName(attacker)); + _ai_run_away(attacker, defender); return 0; } taunt = false; - if (_ai_attack(a1, a2, hitMode) == -1 || weaponGetActionPointCost(a1, hitMode, 0) > a1->data.critter.combat.ap) { + if (_ai_attack(attacker, defender, hitMode) == -1 || weaponGetActionPointCost(attacker, hitMode, 0) > attacker->data.critter.combat.ap) { return -1; } } else { - if (_ai_attack(a1, a2, hitMode) == -1 || weaponGetActionPointCost(a1, hitMode, 0) > a1->data.critter.combat.ap) { + if (_ai_attack(attacker, defender, hitMode) == -1 || weaponGetActionPointCost(attacker, hitMode, 0) > attacker->data.critter.combat.ap) { return -1; } } diff --git a/src/game_sound.cc b/src/game_sound.cc index 618457b..f1dc99b 100644 --- a/src/game_sound.cc +++ b/src/game_sound.cc @@ -1370,7 +1370,7 @@ char* gameSoundBuildInterfaceName(const char* a1) // 0x451760 char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* target) { - int v6; + int soundVariant; char weaponSoundCode; char effectTypeCode; char materialCode; @@ -1384,12 +1384,12 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta if (hitMode != HIT_MODE_LEFT_WEAPON_PRIMARY && hitMode != HIT_MODE_RIGHT_WEAPON_PRIMARY && hitMode != HIT_MODE_PUNCH) { - v6 = 2; + soundVariant = 2; } else { - v6 = 1; + soundVariant = 1; } } else { - v6 = 1; + soundVariant = 1; } int damageType = weaponGetDamageType(NULL, weapon); @@ -1438,7 +1438,7 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta } } - snprintf(_sfx_file_name, sizeof(_sfx_file_name), "W%c%c%1d%cXX%1d", effectTypeCode, weaponSoundCode, v6, materialCode, 1); + snprintf(_sfx_file_name, sizeof(_sfx_file_name), "W%c%c%1d%cXX%1d", effectTypeCode, weaponSoundCode, soundVariant, materialCode, 1); compat_strupr(_sfx_file_name); return _sfx_file_name; }