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; tile = defender->tile;
range = objectGetDistanceBetween(attacker, defender); range = objectGetDistanceBetween(attacker, defender);
if ((defender->data.critter.combat.results & DAM_DEAD) != 0) { 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 (weapon != NULL) {
if ((attacker->data.critter.combat.results & DAM_CRIP_ARM_LEFT) != 0 if ((attacker->data.critter.combat.results & DAM_CRIP_ARM_LEFT) != 0
&& (attacker->data.critter.combat.results & DAM_CRIP_ARM_RIGHT) != 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 ((attacker->data.critter.combat.results & DAM_CRIP_ARM_ANY) != 0) {
if (weaponIsTwoHanded(weapon)) { 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) { 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) { if (weaponGetRange(attacker, hitMode) < range) {
return 2; // target out of range return COMBAT_BAD_SHOT_OUT_OF_RANGE;
} }
int attackType = weaponGetAttackTypeForHitMode(weapon, hitMode); int attackType = weaponGetAttackTypeForHitMode(weapon, hitMode);
if (ammoGetCapacity(weapon) > 0) { if (ammoGetCapacity(weapon) > 0) {
if (ammoGetQuantity(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 || attackType == ATTACK_TYPE_THROW
|| weaponGetRange(attacker, hitMode) > 1) { || weaponGetRange(attacker, hitMode) > 1) {
if (_combat_is_shot_blocked(attacker, attacker->tile, tile, defender, NULL)) { 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 // 0x426744
@ -5638,7 +5638,7 @@ bool _combat_to_hit(Object* target, int* accuracy)
return false; 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; return false;
} }
@ -5671,7 +5671,7 @@ void _combat_attack_this(Object* a1)
int rc = _combat_check_bad_shot(gDude, a1, hitMode, aiming); int rc = _combat_check_bad_shot(gDude, a1, hitMode, aiming);
switch (rc) { switch (rc) {
case 1: case COMBAT_BAD_SHOT_NO_AMMO:
item = critterGetWeaponForHitMode(gDude, hitMode); item = critterGetWeaponForHitMode(gDude, hitMode);
messageListItem.num = 101; // Out of ammo. messageListItem.num = 101; // Out of ammo.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { 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); sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_OUT_OF_AMMO, item, hitMode, NULL);
soundPlayFile(sfx); soundPlayFile(sfx);
return; return;
case 2: case COMBAT_BAD_SHOT_OUT_OF_RANGE:
messageListItem.num = 102; // Target out of range. messageListItem.num = 102; // Target out of range.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
return; return;
case 3: case COMBAT_BAD_SHOT_NOT_ENOUGH_AP:
item = critterGetWeaponForHitMode(gDude, hitMode); item = critterGetWeaponForHitMode(gDude, hitMode);
messageListItem.num = 100; // You need %d action points. messageListItem.num = 100; // You need %d action points.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
@ -5696,21 +5696,21 @@ void _combat_attack_this(Object* a1)
displayMonitorAddMessage(formattedText); displayMonitorAddMessage(formattedText);
} }
return; return;
case 4: case COMBAT_BAD_SHOT_ALREADY_DEAD:
return; return;
case 5: case COMBAT_BAD_SHOT_AIM_BLOCKED:
messageListItem.num = 104; // Your aim is blocked. messageListItem.num = 104; // Your aim is blocked.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
return; return;
case 6: case COMBAT_BAD_SHOT_ARM_CRIPPLED:
messageListItem.num = 106; // You cannot use two-handed weapons with a crippled arm. messageListItem.num = 106; // You cannot use two-handed weapons with a crippled arm.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
return; return;
case 7: case COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED:
messageListItem.num = 105; // You cannot use weapons with both arms crippled. messageListItem.num = 105; // You cannot use weapons with both arms crippled.
if (messageListGetItem(&gCombatMessageList, &messageListItem)) { if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); 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 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)); debugPrint("\nai_danger_source: %s couldn't attack at target! Picking alternate!", critterGetName(a1));
break; break;
} }
@ -1541,7 +1541,7 @@ static Object* _ai_danger_source(Object* a1)
Object* candidate = targets[index]; Object* candidate = targets[index];
if (candidate != NULL && objectCanHearObject(a1, candidate)) { if (candidate != NULL && objectCanHearObject(a1, candidate)) {
if (pathfinderFindPath(a1, a1->tile, candidate->tile, NULL, 0, _obj_blocking_at) != 0 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; return candidate;
} }
debugPrint("\nai_danger_source: I couldn't get at my target! Picking alternate!"); 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); int reason = _combat_check_bad_shot(a1, a2, hitMode, false);
if (reason == 1) { if (reason == COMBAT_BAD_SHOT_NO_AMMO) {
// out of ammo // out of ammo
if (aiHaveAmmo(a1, weapon, &ammo)) { if (aiHaveAmmo(a1, weapon, &ammo)) {
int v9 = weaponReload(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); _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 // 3 - not enough action points
// 6 - crippled one arm for two-handed weapon // 6 - crippled one arm for two-handed weapon
// 7 - both hands crippled // 7 - both hands crippled
if (_ai_switch_weapons(a1, &hitMode, &weapon, a2) == -1) { if (_ai_switch_weapons(a1, &hitMode, &weapon, a2) == -1) {
return -1; return -1;
} }
} else if (reason == 2) { } else if (reason == COMBAT_BAD_SHOT_OUT_OF_RANGE) {
// target out of range // target out of range
int accuracy = _determine_to_hit_no_range(a1, a2, HIT_LOCATION_UNCALLED, hitMode, v30); int accuracy = _determine_to_hit_no_range(a1, a2, HIT_LOCATION_UNCALLED, hitMode, v30);
if (accuracy < minToHit) { if (accuracy < minToHit) {
@ -2638,13 +2638,13 @@ static int _ai_try_attack(Object* a1, Object* a2)
} }
v38 = 0; v38 = 0;
} }
} else if (reason == 5) { } else if (reason == COMBAT_BAD_SHOT_AIM_BLOCKED) {
// aim is blocked // aim is blocked
if (_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, v38) == -1) { if (_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, v38) == -1) {
return -1; return -1;
} }
v38 = 0; v38 = 0;
} else if (reason == 0) { } else if (reason == COMBAT_BAD_SHOT_OK) {
int accuracy = _determine_to_hit(a1, a2, HIT_LOCATION_UNCALLED, hitMode); int accuracy = _determine_to_hit(a1, a2, HIT_LOCATION_UNCALLED, hitMode);
if (v31) { if (v31) {
if (_ai_move_away(a1, a2, v31) == -1) { if (_ai_move_away(a1, a2, v31) == -1) {

View File

@ -158,4 +158,15 @@ typedef union CriticalHitDescription {
int values[CRIT_DATA_MEMBER_COUNT]; int values[CRIT_DATA_MEMBER_COUNT];
} CriticalHitDescription; } 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 */ #endif /* COMBAT_DEFS_H */