Add CombatBadShot enum

This commit is contained in:
Alexander Batalov 2022-08-31 18:29:46 +03:00
parent 40d6348b09
commit 916bf40602
3 changed files with 34 additions and 23 deletions

View File

@ -5584,7 +5584,7 @@ int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool
tile = defender->tile;
range = objectGetDistanceBetween(attacker, defender);
if ((defender->data.critter.combat.results & DAM_DEAD) != 0) {
return 4; // defender is dead
return COMBAT_BAD_SHOT_ALREADY_DEAD;
}
}
@ -5592,29 +5592,29 @@ int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool
if (weapon != NULL) {
if ((attacker->data.critter.combat.results & DAM_CRIP_ARM_LEFT) != 0
&& (attacker->data.critter.combat.results & DAM_CRIP_ARM_RIGHT) != 0) {
return 7; // both hands crippled
return COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED;
}
if ((attacker->data.critter.combat.results & DAM_CRIP_ARM_ANY) != 0) {
if (weaponIsTwoHanded(weapon)) {
return 6; // crippled one arm for two-handed weapon
return COMBAT_BAD_SHOT_ARM_CRIPPLED;
}
}
}
if (weaponGetActionPointCost(attacker, hitMode, aiming) > attacker->data.critter.combat.ap) {
return 3; // not enough action points
return COMBAT_BAD_SHOT_NOT_ENOUGH_AP;
}
if (weaponGetRange(attacker, hitMode) < range) {
return 2; // target out of range
return COMBAT_BAD_SHOT_OUT_OF_RANGE;
}
int attackType = weaponGetAttackTypeForHitMode(weapon, hitMode);
if (ammoGetCapacity(weapon) > 0) {
if (ammoGetQuantity(weapon) == 0) {
return 1; // out of ammo
return COMBAT_BAD_SHOT_NO_AMMO;
}
}
@ -5622,11 +5622,11 @@ int _combat_check_bad_shot(Object* attacker, Object* defender, int hitMode, bool
|| attackType == ATTACK_TYPE_THROW
|| weaponGetRange(attacker, hitMode) > 1) {
if (_combat_is_shot_blocked(attacker, attacker->tile, tile, defender, NULL)) {
return 5; // Your aim is blocked
return COMBAT_BAD_SHOT_AIM_BLOCKED;
}
}
return 0; // success
return COMBAT_BAD_SHOT_OK;
}
// 0x426744
@ -5638,7 +5638,7 @@ bool _combat_to_hit(Object* target, int* accuracy)
return false;
}
if (_combat_check_bad_shot(gDude, target, hitMode, aiming) != 0) {
if (_combat_check_bad_shot(gDude, target, hitMode, aiming) != COMBAT_BAD_SHOT_OK) {
return false;
}
@ -5671,7 +5671,7 @@ void _combat_attack_this(Object* a1)
int rc = _combat_check_bad_shot(gDude, a1, hitMode, aiming);
switch (rc) {
case 1:
case COMBAT_BAD_SHOT_NO_AMMO:
item = critterGetWeaponForHitMode(gDude, hitMode);
messageListItem.num = 101; // Out of ammo.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
@ -5681,13 +5681,13 @@ void _combat_attack_this(Object* a1)
sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_OUT_OF_AMMO, item, hitMode, NULL);
soundPlayFile(sfx);
return;
case 2:
case COMBAT_BAD_SHOT_OUT_OF_RANGE:
messageListItem.num = 102; // Target out of range.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
return;
case 3:
case COMBAT_BAD_SHOT_NOT_ENOUGH_AP:
item = critterGetWeaponForHitMode(gDude, hitMode);
messageListItem.num = 100; // You need %d action points.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
@ -5696,21 +5696,21 @@ void _combat_attack_this(Object* a1)
displayMonitorAddMessage(formattedText);
}
return;
case 4:
case COMBAT_BAD_SHOT_ALREADY_DEAD:
return;
case 5:
case COMBAT_BAD_SHOT_AIM_BLOCKED:
messageListItem.num = 104; // Your aim is blocked.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
return;
case 6:
case COMBAT_BAD_SHOT_ARM_CRIPPLED:
messageListItem.num = 106; // You cannot use two-handed weapons with a crippled arm.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
return;
case 7:
case COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED:
messageListItem.num = 105; // You cannot use weapons with both arms crippled.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);

View File

@ -1471,7 +1471,7 @@ static Object* _ai_danger_source(Object* a1)
}
if (pathfinderFindPath(a1, a1->tile, gDude->data.critter.combat.whoHitMe->tile, NULL, 0, _obj_blocking_at) == 0
&& _combat_check_bad_shot(a1, candidate, HIT_MODE_RIGHT_WEAPON_PRIMARY, false) != 0) {
&& _combat_check_bad_shot(a1, candidate, HIT_MODE_RIGHT_WEAPON_PRIMARY, false) != COMBAT_BAD_SHOT_OK) {
debugPrint("\nai_danger_source: %s couldn't attack at target! Picking alternate!", critterGetName(a1));
break;
}
@ -1541,7 +1541,7 @@ static Object* _ai_danger_source(Object* a1)
Object* candidate = targets[index];
if (candidate != NULL && objectCanHearObject(a1, candidate)) {
if (pathfinderFindPath(a1, a1->tile, candidate->tile, NULL, 0, _obj_blocking_at) != 0
|| _combat_check_bad_shot(a1, candidate, HIT_MODE_RIGHT_WEAPON_PRIMARY, false) == 0) {
|| _combat_check_bad_shot(a1, candidate, HIT_MODE_RIGHT_WEAPON_PRIMARY, false) == COMBAT_BAD_SHOT_OK) {
return candidate;
}
debugPrint("\nai_danger_source: I couldn't get at my target! Picking alternate!");
@ -2540,7 +2540,7 @@ static int _ai_try_attack(Object* a1, Object* a2)
}
int reason = _combat_check_bad_shot(a1, a2, hitMode, false);
if (reason == 1) {
if (reason == COMBAT_BAD_SHOT_NO_AMMO) {
// out of ammo
if (aiHaveAmmo(a1, weapon, &ammo)) {
int v9 = weaponReload(weapon, ammo);
@ -2608,14 +2608,14 @@ static int _ai_try_attack(Object* a1, Object* a2)
_ai_switch_weapons(a1, &hitMode, &weapon, a2);
}
}
} else if (reason == 3 || reason == 6 || reason == 7) {
} 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) {
return -1;
}
} else if (reason == 2) {
} 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, v30);
if (accuracy < minToHit) {
@ -2638,13 +2638,13 @@ static int _ai_try_attack(Object* a1, Object* a2)
}
v38 = 0;
}
} else if (reason == 5) {
} else if (reason == COMBAT_BAD_SHOT_AIM_BLOCKED) {
// aim is blocked
if (_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, v38) == -1) {
return -1;
}
v38 = 0;
} else if (reason == 0) {
} else if (reason == COMBAT_BAD_SHOT_OK) {
int accuracy = _determine_to_hit(a1, a2, HIT_LOCATION_UNCALLED, hitMode);
if (v31) {
if (_ai_move_away(a1, a2, v31) == -1) {

View File

@ -158,4 +158,15 @@ typedef union CriticalHitDescription {
int values[CRIT_DATA_MEMBER_COUNT];
} CriticalHitDescription;
typedef enum CombatBadShot {
COMBAT_BAD_SHOT_OK = 0,
COMBAT_BAD_SHOT_NO_AMMO = 1,
COMBAT_BAD_SHOT_OUT_OF_RANGE = 2,
COMBAT_BAD_SHOT_NOT_ENOUGH_AP = 3,
COMBAT_BAD_SHOT_ALREADY_DEAD = 4,
COMBAT_BAD_SHOT_AIM_BLOCKED = 5,
COMBAT_BAD_SHOT_ARM_CRIPPLED = 6,
COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED = 7,
} CombatBadShot;
#endif /* COMBAT_DEFS_H */