Match calc partner damage enemy (#695)

* match calc_partner_damage_enemy

* run coverage

* some var name changes

* remove typedef from enum

* fix warning

* remove casts

* saw a target flag in a comment

* Assert and script enums

Co-authored-by: ThreeMustyFears <>
This commit is contained in:
ThreeMustyFears 2022-04-18 05:56:44 -03:00 committed by GitHub
parent cfe089af10
commit 41108b78b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 664 additions and 1598 deletions

View File

@ -1009,7 +1009,7 @@ typedef struct BattleStatus {
/* 0x195 */ s8 statusDuration; /* 0x195 */ s8 statusDuration;
/* 0x196 */ char unk_196; /* 0x196 */ char unk_196;
/* 0x197 */ u8 targetHomeIndex; /* some sort of home idnex used for target list construction */ /* 0x197 */ u8 targetHomeIndex; /* some sort of home idnex used for target list construction */
/* 0x198 */ u8 powerBounceCounter; /* 0x198 */ s8 powerBounceCounter;
/* 0x199 */ s8 wasStatusInflicted; /* during last attack */ /* 0x199 */ s8 wasStatusInflicted; /* during last attack */
/* 0x19A */ u8 unk_19A; /* 0x19A */ u8 unk_19A;
/* 0x19B */ char unk_19B[5]; /* 0x19B */ char unk_19B[5];

View File

@ -1811,6 +1811,7 @@ enum StatusFlags {
STATUS_FLAG_SHRINK = 0x00080000, STATUS_FLAG_SHRINK = 0x00080000,
STATUS_FLAG_STONE = 0x00100000, STATUS_FLAG_STONE = 0x00100000,
STATUS_FLAG_STOP = 0x00200000, STATUS_FLAG_STOP = 0x00200000,
STATUS_FLAG_400000 = 0x00400000,
STATUS_FLAG_KO = 0x01000000, STATUS_FLAG_KO = 0x01000000,
STATUS_FLAG_GLOWING = 0x02000000, STATUS_FLAG_GLOWING = 0x02000000,
STATUS_FLAG_TRANSPARENT = 0x04000000, STATUS_FLAG_TRANSPARENT = 0x04000000,
@ -1869,6 +1870,15 @@ enum PartnerIDs {
PARTNER_TWINK = 0x0000000B, PARTNER_TWINK = 0x0000000B,
}; };
enum AttackEventFlags {
ATTACK_EVENT_FLAG_1 = 0x1,
ATTACK_EVENT_FLAG_2 = 0x2,
ATTACK_EVENT_FLAG_4 = 0x4,
ATTACK_EVENT_FLAG_8 = 0x8,
ATTACK_EVENT_FLAG_10 = 0x10,
ATTACK_EVENT_FLAG_80 = 0x80,
};
enum PartnerActions { enum PartnerActions {
PARTNER_ACTION_NONE = 0, // genetic state PARTNER_ACTION_NONE = 0, // genetic state
PARTNER_ACTION_USE = 1, // generic state PARTNER_ACTION_USE = 1, // generic state

View File

@ -1,6 +1,10 @@
#include "common.h" #include "common.h"
#include "battle/battle.h" #include "battle/battle.h"
#include "script_api/battle.h"
#include "effects.h"
s32 calc_partner_damage_enemy(void); s32 calc_partner_damage_enemy(void);
s32 dispatch_damage_event_partner_1(s32, s32);
void dispatch_event_partner(s32 lastEventType) { void dispatch_event_partner(s32 lastEventType) {
BattleStatus* battleStatus = &gBattleStatus; BattleStatus* battleStatus = &gBattleStatus;
@ -141,8 +145,650 @@ s32 calc_partner_test_enemy(void) {
INCLUDE_ASM(s32, "1AC760", calc_partner_test_enemy); INCLUDE_ASM(s32, "1AC760", calc_partner_test_enemy);
#endif #endif
s32 calc_partner_damage_enemy(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* partner = battleStatus->partnerActor;
s32 currentTargetID = battleStatus->currentTargetID;
s32 currentTargetPartID = battleStatus->currentTargetPart;
s32 retVal;
s32 sp2C = FALSE;
s32 isFireDamage = FALSE;
s32 isElectricDamage = FALSE;
s32 isIceDamage = FALSE;
s32 tempBinary = FALSE;
s32 wasStatusInflicted = FALSE;
Actor* target;
ActorPart* targetPart;
ActorState* state;
Evt* evt;
s32 statusChanceOrDefense;
s32 damageDealt;
s32 dispatchEvent;
INCLUDE_ASM(s32, "1AC760", calc_partner_damage_enemy); battleStatus->wasStatusInflicted = FALSE;
battleStatus->lastAttackDamage = FALSE;
battleStatus->attackerActorID = partner->actorID;
battleStatus->currentTargetID2 = battleStatus->currentTargetID;
battleStatus->currentTargetPart2 = battleStatus->currentTargetPart;
target = get_actor(currentTargetID);
state = &partner->state;
if (target == NULL) {
return 0;
}
targetPart = get_actor_part(target, currentTargetPartID);
ASSERT(targetPart != NULL);
target->lastDamageTaken = 0;
if (gBattleStatus.flags1 & BS_FLAGS1_800) {
retVal = 2;
dispatchEvent = EVENT_UNKNOWN_TRIGGER;
sfx_play_sound_at_position(SOUND_IMMUNE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
if (targetPart->eventFlags & ACTOR_EVENT_FLAG_ILLUSORY || target->transStatus == STATUS_E ||
targetPart->eventFlags & ACTOR_EVENT_FLAG_800 && !(battleStatus->currentAttackElement & DAMAGE_TYPE_QUAKE)) {
return 6;
}
if (target->stoneStatus == STATUS_STONE) {
sfx_play_sound_at_position(SOUND_IMMUNE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
func_8024EFE0(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, 1);
show_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 0);
return (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) ? 1 : 0;
}
if (targetPart->partFlags3 & battleStatus->currentAttackElement) {
sp2C = 1;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_JUMP && targetPart->eventFlags & ACTOR_EVENT_FLAG_SPIKY_TOP) {
sfx_play_sound_at_position(SOUND_108, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_SPIKE_CONTACT);
dispatch_event_actor(target, EVENT_SPIKE_TAUNT);
return -1;
} else if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) && targetPart->eventFlags & ACTOR_EVENT_FLAG_8000) {
dispatch_event_actor(target, EVENT_EXPLODE_TRIGGER);
if (!(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_2)) {
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_BURN_CONTACT);
return -1;
}
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
return (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) ? 1 : 0;
} else if (!(battleStatus->currentAttackElement & (DAMAGE_TYPE_NO_CONTACT | DAMAGE_TYPE_SMASH)) &&
targetPart->eventFlags & ACTOR_EVENT_FLAG_FIREY && !(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_10)) {
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_BURN_CONTACT);
dispatch_event_actor(target, EVENT_BURN_TAUNT);
return -1;
} else if (!(battleStatus->currentAttackElement & (DAMAGE_TYPE_NO_CONTACT | DAMAGE_TYPE_JUMP)) &&
targetPart->eventFlags & ACTOR_EVENT_FLAG_SPIKY_FRONT && !(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_4)) {
sfx_play_sound_at_position(SOUND_108, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_SPIKE_CONTACT);
dispatch_event_actor(target, EVENT_SPIKE_TAUNT);
return -1;
} else if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE && battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE &&
targetPart->eventFlags & (ACTOR_EVENT_FLAG_400 | ACTOR_EVENT_FLAG_EXPLOSIVE)) {
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_event_actor(target, EVENT_EXPLODE_TRIGGER);
return (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) ? 1 : 0;
} else if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) && targetPart->eventFlags & ACTOR_EVENT_FLAG_200000 &&
!(target->flags & ACTOR_FLAG_HP_OFFSET_BELOW) && !(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_80)) {
sfx_play_sound_at_position(SOUND_108, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_SPIKE_CONTACT);
dispatch_event_actor(target, EVENT_SPIKE_TAUNT);
return -1;
} else if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) && targetPart->eventFlags & ACTOR_EVENT_FLAG_SPIKY_TOP &&
!(target->flags & ACTOR_FLAG_HP_OFFSET_BELOW) && !(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_1)) {
sfx_play_sound_at_position(SOUND_108, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_damage_event_partner_1(1, EVENT_SPIKE_CONTACT);
dispatch_event_actor(target, EVENT_SPIKE_TAUNT);
return -1;
} else if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE && battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE &&
targetPart->eventFlags & (ACTOR_EVENT_FLAG_400 | ACTOR_EVENT_FLAG_EXPLOSIVE)) {
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_event_actor(target, EVENT_EXPLODE_TRIGGER);
return (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) ? 1 : 0;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_AIR_LIFT) {
if (partner->staticStatus != STATUS_STATIC && (target->staticStatus == STATUS_STATIC ||
targetPart->eventFlags & ACTOR_EVENT_FLAG_ELECTRIFIED) && !(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) &&
!(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_8)) {
sfx_play_sound_at_position(SOUND_HIT_SHOCK, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
func_80251474(partner);
dispatch_damage_event_partner_1(1, EVENT_SHOCK_HIT);
return -1;
}
return 0;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE) {
fx_ring_blast(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f, 1.0f, 0x18);
isFireDamage = TRUE;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_ELECTRIC) {
func_80251474(target);
isElectricDamage = TRUE;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_WATER) {
fx_water_splash(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f, 1.0f, 0x18);
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_ICE) {
fx_big_snowflakes(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f);
isIceDamage = TRUE;
}
if (partner->staticStatus != STATUS_STATIC && (target->staticStatus == STATUS_STATIC ||
targetPart->eventFlags & ACTOR_EVENT_FLAG_ELECTRIFIED) &&
!(battleStatus->currentAttackElement & (DAMAGE_TYPE_NO_CONTACT | DAMAGE_TYPE_ELECTRIC)) &&
!(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_8)) {
gBattleStatus.flags1 |= BS_FLAGS1_SP_EVT_ACTIVE;
}
if (targetPart->eventFlags & (ACTOR_EVENT_FLAG_80000 | ACTOR_EVENT_FLAG_ENCHANTED)) {
battleStatus->currentAttackElement &= ~DAMAGE_TYPE_IGNORE_DEFENSE;
}
statusChanceOrDefense = get_defense(target, targetPart->defenseTable, battleStatus->currentAttackElement);
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_IGNORE_DEFENSE)) {
statusChanceOrDefense += target->defenseBoost;
}
damageDealt = battleStatus->currentAttackDamage + partner->attackBoost;
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_BLAST) {
if (targetPart->eventFlags & ACTOR_EVENT_FLAG_EXPLOSIVE) {
statusChanceOrDefense = 0;
damageDealt = target->currentHP;
}
}
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS) {
statusChanceOrDefense = 0;
damageDealt = 0;
}
if (partner->debuff == STATUS_SHRINK) {
if (damageDealt != 0) {
damageDealt /= 2;
if (damageDealt == 0) {
damageDealt = 1;
}
}
}
if (damageDealt >= 100) {
damageDealt = 99;
}
if (damageDealt < 0) {
statusChanceOrDefense = 0;
}
damageDealt -= statusChanceOrDefense;
target->hpChangeCounter = 0;
if (damageDealt < 0) {
damageDealt = 0;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_POWER_BOUNCE && damageDealt > 0) {
damageDealt += battleStatus->powerBounceCounter;
if (damageDealt <= 0) {
damageDealt = 1;
}
}
battleStatus->lastAttackDamage = 0;
if (damageDealt <= 0) {
target->hpChangeCounter = 0;
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS)) {
retVal = 2;
dispatchEvent = EVENT_UNKNOWN_TRIGGER;
sfx_play_sound_at_position(SOUND_IMMUNE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
retVal = 2;
dispatchEvent = (target->currentHP <= 0) ? EVENT_DEATH : EVENT_UNKNOWN_TRIGGER;
}
battleStatus->lastAttackDamage = 0;
} else {
target->damageCounter += damageDealt;
target->hpChangeCounter -= damageDealt;
battleStatus->lastAttackDamage = 0;
dispatchEvent = EVENT_HIT_COMBO;
retVal = 0;
if (!(targetPart->flags & ACTOR_PART_FLAG_2000) && !(gBattleStatus.flags1 & BS_FLAGS1_2000000) && !sp2C && !(targetPart->targetFlags & ACTOR_PART_FLAG_4)) {
target->currentHP -= damageDealt;
if (target->currentHP <= 0) {
target->currentHP = 0;
dispatchEvent = EVENT_DEATH;
}
}
battleStatus->lastAttackDamage += damageDealt;
target->lastDamageTaken = battleStatus->lastAttackDamage;
target->hpChangeCounter = 0;
}
if (targetPart->flags & ACTOR_PART_FLAG_2000) {
if (partner->staticStatus == STATUS_STATIC || (target->staticStatus != STATUS_STATIC &&
!(targetPart->eventFlags & ACTOR_EVENT_FLAG_ELECTRIFIED)) || battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT ||
battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_8) {
dispatchEvent = (!(gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE)) ? EVENT_UNKNOWN_TRIGGER : EVENT_IMMUNE;
sfx_play_sound_at_position(SOUND_IMMUNE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
dispatch_event_actor(target, dispatchEvent);
func_8024EFE0(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, 3);
return (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) ? 1 : 0;
}
sfx_play_sound_at_position(SOUND_HIT_SHOCK, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
func_80251474(partner);
dispatch_damage_event_partner_1(1, EVENT_SHOCK_HIT);
return -1;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (dispatchEvent == EVENT_HIT_COMBO) {
dispatchEvent = EVENT_HIT;
}
if (dispatchEvent == EVENT_UNKNOWN_TRIGGER) {
dispatchEvent = EVENT_IMMUNE;
}
if (target->currentHP <= 0) {
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_DEATH;
}
}
} else if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_HIT_COMBO;
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE ||
(func_80266E14(targetPart), gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE)) { // TODO remove func_80266E14 from conditional
if (battleStatus->currentAttackElement & DAMAGE_TYPE_SPIN_SMASH) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_SPIN_SMASH_HIT;
}
if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_SPIN_SMASH_DEATH;
}
tempBinary = TRUE;
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) && targetPart->eventFlags & ACTOR_EVENT_FLAG_POWER_BOUNCE) {
if (dispatchEvent == EVENT_HIT_COMBO) {
dispatchEvent = EVENT_POWER_BOUNCE_HIT;
}
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_POWER_BOUNCE_HIT;
}
if (dispatchEvent == EVENT_UNKNOWN_TRIGGER) {
dispatchEvent = EVENT_POWER_BOUNCE_HIT;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_POWER_BOUNCE_HIT;
}
if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_POWER_BOUNCE_DEATH;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_JUMP && targetPart->eventFlags & ACTOR_EVENT_FLAG_GROUNDABLE) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
tempBinary = TRUE;
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_JUMP && targetPart->eventFlags & ACTOR_EVENT_FLAG_FLIPABLE) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
if (!(target->flags & ACTOR_FLAG_400)) {
tempBinary = TRUE;
}
}
}
}
}
}
if (!(gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) && battleStatus->currentAttackElement & DAMAGE_TYPE_JUMP &&
targetPart->eventFlags & ACTOR_EVENT_FLAG_FLIPABLE) {
if (dispatchEvent == EVENT_HIT_COMBO) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
if (dispatchEvent == EVENT_UNKNOWN_TRIGGER) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
if (!(target->flags & ACTOR_FLAG_400)) {
tempBinary = TRUE;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_BLAST && targetPart->eventFlags & ACTOR_EVENT_FLAG_EXPLOSIVE) {
if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_EXPLODE_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_EXPLODE_TRIGGER;
}
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_EXPLODE_TRIGGER;
}
tempBinary = TRUE;
isFireDamage = TRUE;
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & (DAMAGE_TYPE_BLAST | DAMAGE_TYPE_FIRE)) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_BURN_HIT;
}
if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_BURN_DEATH;
}
isFireDamage = TRUE;
}
do { // TODO remove this do while
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE && battleStatus->lastAttackDamage >= 0 && dispatchEvent != EVENT_DEATH &&
dispatchEvent != EVENT_SPIN_SMASH_DEATH &&
dispatchEvent != EVENT_EXPLODE_TRIGGER && !(targetPart->targetFlags & ACTOR_PART_FLAG_4)) {
#define INFLICT_STATUS(STATUS_TYPE) \
if ((battleStatus->currentAttackStatus & STATUS_FLAG_##STATUS_TYPE) && \
try_inflict_status(target, STATUS_##STATUS_TYPE, STATUS_##STATUS_TYPE##_TURN_MOD)) { \
tempBinary = TRUE; \
wasStatusInflicted = TRUE; \
} \
INFLICT_STATUS(SHRINK);
INFLICT_STATUS(POISON);
INFLICT_STATUS(STONE);
INFLICT_STATUS(SLEEP);
INFLICT_STATUS(STOP);
INFLICT_STATUS(STATIC);
INFLICT_STATUS(FEAR);
INFLICT_STATUS(PARALYZE);
INFLICT_STATUS(DIZZY);
#undef INFLICT_STATUS
statusChanceOrDefense = target->actorBlueprint->baseStatusChance;
if (statusChanceOrDefense > 0) {
statusChanceOrDefense = 100;
}
statusChanceOrDefense = (battleStatus->statusChance * statusChanceOrDefense) / 100;
if (battleStatus->currentAttackStatus & STATUS_FLAG_400000) {
if (rand_int(99) < statusChanceOrDefense) {
if (!(target->debuff == STATUS_FEAR ||
target->debuff == STATUS_DIZZY ||
target->debuff == STATUS_PARALYZE ||
target->debuff == STATUS_SLEEP ||
target->debuff == STATUS_FROZEN ||
target->debuff == STATUS_STOP) && !(target->flags & ACTOR_FLAG_400)) {
dispatchEvent = EVENT_SCARE_AWAY;
wasStatusInflicted = TRUE;
retVal = 0;
tempBinary = TRUE;
gBattleStatus.flags1 |= (BS_FLAGS1_40 | BS_FLAGS1_SP_EVT_ACTIVE | BS_FLAGS1_10 | BS_FLAGS1_8 | BS_FLAGS1_1);
sfx_play_sound_at_position(SOUND_231, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
dispatchEvent = EVENT_IMMUNE;
retVal = 2;
}
} else {
dispatchEvent = EVENT_IMMUNE;
retVal = 2;
}
}
if (wasStatusInflicted) {
if (dispatchEvent == EVENT_UNKNOWN_TRIGGER) {
dispatchEvent = EVENT_HIT_COMBO;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_HIT;
}
}
}
} while (0);
}
}
statusChanceOrDefense = target->actorBlueprint->baseStatusChance;
statusChanceOrDefense = (battleStatus->statusChance * statusChanceOrDefense) / 100;
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_FEAR) {
if (rand_int(99) < statusChanceOrDefense) {
if (!(target->debuff == STATUS_FEAR ||
target->debuff == STATUS_DIZZY ||
target->debuff == STATUS_PARALYZE ||
target->debuff == STATUS_SLEEP ||
target->debuff == STATUS_FROZEN ||
target->debuff == STATUS_STOP) && !(target->flags & ACTOR_FLAG_400)) {
dispatchEvent = EVENT_SCARE_AWAY;
wasStatusInflicted = TRUE;
retVal = 0;
tempBinary = TRUE;
gBattleStatus.flags1 |= (BS_FLAGS1_40 | BS_FLAGS1_SP_EVT_ACTIVE | BS_FLAGS1_10 | BS_FLAGS1_8 | BS_FLAGS1_1);
sfx_play_sound_at_position(SOUND_231, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
dispatchEvent = EVENT_IMMUNE;
retVal = 2;
}
} else {
dispatchEvent = EVENT_IMMUNE;
retVal = 2;
}
}
}
battleStatus->wasStatusInflicted = wasStatusInflicted;
dispatch_event_actor(target, dispatchEvent);
if (!(target->flags & ACTOR_FLAG_NO_DMG_POPUP)) {
if (battleStatus->lastAttackDamage == 0) {
if (!tempBinary) {
if (!wasStatusInflicted) {
func_8024EFE0(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, 3);
}
}
} else if (!sp2C) {
if (battleStatus->currentAttackElement & (DAMAGE_TYPE_NO_OTHER_DAMAGE_POPUPS | DAMAGE_TYPE_SMASH)) {
show_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
} else {
func_802664DC(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
}
if (!(targetPart->targetFlags & ACTOR_PART_FLAG_4)) {
func_802666E4(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
}
}
}
if (tempBinary && gBattleStatus.flags1 & (BS_FLAGS1_200 | BS_FLAGS1_40) || gBattleStatus.flags1 & (BS_FLAGS1_200 | BS_FLAGS1_40) &&
!(gBattleStatus.flags1 & BS_FLAGS1_80)) {
if ((battleStatus->lastAttackDamage > 0 &&
((sfx_play_sound_at_position(SOUND_231, 0, state->goalPos.x, state->goalPos.y,
state->goalPos.z), //TODO remove sfx_play from conditional
battleStatus->lastAttackDamage > 0))) || (battleStatus->currentAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS && tempBinary)) {
if (gBattleStatus.flags1 & BS_FLAGS1_40) {
func_802667F0(0, target, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
func_802667F0(3, target, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
func_80266970(target);
}
if (battleStatus->lastAttackDamage > 0) {
if (sp2C == 0) {
if (partner->actorTypeData1[5] != 0) {
sfx_play_sound_at_position(partner->actorTypeData1[5], 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
func_80267018(target, 1);
if (isFireDamage) {
sfx_play_sound_at_position(SOUND_HIT_FIRE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else if (isElectricDamage) {
sfx_play_sound_at_position(SOUND_HIT_SHOCK, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else if (isIceDamage) {
sfx_play_sound_at_position(SOUND_HIT_ICE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
} else {
sfx_play_sound_at_position(SOUND_HIT_NORMAL, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
}
}
if (battleStatus->lastAttackDamage <= 0 && !tempBinary && !wasStatusInflicted || targetPart->flags & ACTOR_PART_FLAG_2000) {
sfx_play_sound_at_position(SOUND_IMMUNE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_SLEEP && wasStatusInflicted) {
evt = start_script((EvtScript*) DoSleepHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_SLEEP, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_DIZZY && wasStatusInflicted) {
evt = start_script((EvtScript*) DoDizzyHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_PARALYZE && wasStatusInflicted) {
evt = start_script((EvtScript*) DoParalyzeHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_POISON && wasStatusInflicted) {
evt = start_script((EvtScript*) DoPoisonHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_STOP && wasStatusInflicted) {
evt = start_script((EvtScript*) DoStopHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_FROZEN && wasStatusInflicted) {
evt = start_script((EvtScript*) DoFreezeHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
evt->varTablePtr[3] = target;
sfx_play_sound_at_position(SOUND_HIT_ICE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_SHRINK && wasStatusInflicted) {
evt = start_script((EvtScript*) DoShrinkHit, EVT_PRIORITY_A, 0);
evt->varTable[0] = state->goalPos.x;
evt->varTable[1] = state->goalPos.y;
evt->varTable[2] = state->goalPos.z;
evt->varTablePtr[3] = target;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_SMASH && target->actorType == ACTOR_TYPE_GOOMNUT_TREE) {
sfx_play_sound_at_position(SOUND_SMASH_GOOMNUT_TREE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
func_80266ADC(target);
if (gBattleStatus.flags1 & (BS_FLAGS1_200 | BS_FLAGS1_40)) {
if (retVal == 0) {
retVal = 1;
}
if (retVal == 2) {
retVal = 3;
}
}
if (partner->staticStatus != STATUS_STATIC && (target->staticStatus == STATUS_STATIC ||
targetPart->eventFlags & ACTOR_EVENT_FLAG_ELECTRIFIED) && !(battleStatus->currentAttackElement & DAMAGE_TYPE_NO_CONTACT) &&
!(battleStatus->currentAttackEventSuppression & ATTACK_EVENT_FLAG_8)) {
sfx_play_sound_at_position(SOUND_HIT_SHOCK, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
func_80251474(partner);
dispatch_damage_event_partner_1(1, EVENT_SHOCK_HIT);
return -1;
}
return retVal;
}
//Some slight stack / ordering issues at the beginning //Some slight stack / ordering issues at the beginning
#ifdef NON_EQUIVALENT #ifdef NON_EQUIVALENT

File diff suppressed because it is too large Load Diff