calc_item_damage_enemy (#549)

* setup function

* cleanup parts of calc_item_damage_enemy

* .

* .

* .

* resolve issues

* set function as NON_MATCHING

* npc flags

* resolve issues

* .

* Update include/enums.h

Co-authored-by: Alex Bates <hi@imalex.xyz>

* Update 17FEB0.c

Co-authored-by: Alex Bates <hi@imalex.xyz>
This commit is contained in:
Alexander Faßbender 2021-12-21 23:12:59 +01:00 committed by GitHub
parent a5340e8dce
commit dbde606a86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 491 additions and 45 deletions

View File

@ -505,8 +505,8 @@ enum SoundIDs {
SOUND_E3 = 0x000000E3,
SOUND_E7 = 0x000000E7,
SOUND_E9 = 0x000000E9,
SOUND_FIRE = 0x000000EA,
SOUND_FREEZE = 0x000000EB,
SOUND_FIRE_DAMAGE = 0x000000EA,
SOUND_FREEZE_DAMAGE = 0x000000EB,
SOUND_10C = 0x0000010C,
SOUND_10D = 0x0000010D,
SOUND_STEP1 = 0x00000141,
@ -578,7 +578,7 @@ enum SoundIDs {
SOUND_377 = 0x00000377,
SOUND_379 = 0x00000379,
SOUND_37A = 0x0000037A,
SOUND_ELECTRIC = 0x0000037B,
SOUND_ELECTRIC_DAMAGE = 0x0000037B,
SOUND_GENERAL_WHISTLE = 0x00000395,
SOUND_OPEN_SHELL = 0x000003D4,
SOUND_JUMP_3E2 = 0x000003E2,
@ -1213,6 +1213,7 @@ enum Events {
EVENT_SPIN_SMASH_LAUNCH_HIT = 0x00000011,
EVENT_SHELL_CRACK_HIT = 0x00000012,
EVENT_STAR_BEAM = 0x00000013,
EVENT_14 = 0x00000014,
EVENT_POWER_BOUNCE_HIT = 0x00000015,
EVENT_BLOW_AWAY = 0x00000016,
EVENT_UNKNOWN_TRIGGER = 0x00000017,
@ -1221,6 +1222,7 @@ enum Events {
EVENT_BLOCK = 0x0000001A,
EVENT_SPIKE_TAUNT = 0x0000001B,
EVENT_BURN_TAUNT = 0x0000001C,
EVENT_1D = 0x0000001D,
EVENT_AIR_LIFT_FAILED = 0x0000001F,
EVENT_DEATH = 0x00000020,
EVENT_SPIN_SMASH_DEATH = 0x00000021,
@ -1236,6 +1238,7 @@ enum Events {
EVENT_BURN_CONTACT = 0x0000002C,
EVENT_SHOCK_HIT = 0x0000002F,
EVENT_RECOVER_STATUS = 0x00000031,
EVENT_32 = 0x00000032,
EVENT_34 = 0x00000034,
EVENT_END_FIRST_STRIKE = 0x00000035,
EVENT_LUCKY = 0x00000037,
@ -1620,41 +1623,42 @@ enum Areas {
};
enum NpcFlags {
NPC_FLAG_0 = 0x00000000,
NPC_FLAG_PASSIVE = 0x00000001, ///< Collision does not trigger battle
NPC_FLAG_2 = 0x00000002,
NPC_FLAG_4 = 0x00000004,
NPC_FLAG_ENABLE_HIT_SCRIPT = 0x00000008,
NPC_FLAG_HAS_SHADOW = 0x00000010, ///< Set by default and by enable_npc_shadow
NPC_FLAG_NO_AI = 0x00000020, ///< Disable movement AI and collision (idle animation plays)
NPC_FLAG_40 = 0x00000040,
NPC_FLAG_80 = 0x00000080, // TODO
NPC_FLAG_100 = 0x00000100, // TODO
NPC_FLAG_GRAVITY = 0x00000200, ///< Enables gravity. Does nothing if NPC_FLAG_NO_Y_MOVEMENT is set.
NPC_FLAG_LOCK_ANIMS = 0x00000400, ///< Do not allow scripts to change animation
NPC_FLAG_NO_Y_MOVEMENT = 0x00000800, ///< Causes NpcMoveTo() to ignore stairs
NPC_FLAG_1000 = 0x00001000,
NPC_FLAG_NO_PROJECT_SHADOW = 0x00002000, ///< Draw shadow at base of sprite instead of projecting to ground
NPC_FLAG_4000 = 0x00004000,
NPC_FLAG_8000 = 0x00008000,
NPC_FLAG_DIRTY_SHADOW = 0x00010000, ///< Set if shadow model is dirty (needs to be repositioned etc.)
NPC_FLAG_REFLECT_WALL = 0x00020000, ///< Mirror rendering across z=0
NPC_FLAG_40000 = 0x00040000, ///< Yaw?
NPC_FLAG_REFLECT_FLOOR = 0x00080000, ///< Mirror rendering across y=0
NPC_FLAG_MOTION_BLUR = 0x00100000, ///< Gives motion blur effect as NPC moves. Set by enable_npc_blur
NPC_FLAG_200000 = 0x00200000,
NPC_FLAG_400000 = 0x00400000,
NPC_FLAG_NO_DROPS = 0x00800000, ///< Do not drop hearts, flowers, or coins on defeat
NPC_FLAG_1000000 = 0x01000000, // TODO. fails assert in set_npc_sprite
NPC_FLAG_2000000 = 0x02000000,
NPC_FLAG_0 = 0x00000000,
NPC_FLAG_PASSIVE = 0x00000001, ///< Collision does not trigger battle
NPC_FLAG_2 = 0x00000002,
NPC_FLAG_4 = 0x00000004,
NPC_FLAG_ENABLE_HIT_SCRIPT = 0x00000008,
NPC_FLAG_HAS_SHADOW = 0x00000010, ///< Set by default and by enable_npc_shadow
NPC_FLAG_NO_AI = 0x00000020, ///< Disable movement AI and collision (idle animation plays)
NPC_FLAG_40 = 0x00000040,
NPC_FLAG_UPSIDE_DOWN = 0x00000080, ///< Render NPCs upside-down
NPC_FLAG_100 = 0x00000100, // TODO
NPC_FLAG_GRAVITY = 0x00000200, ///< Enables gravity. Does nothing if NPC_FLAG_NO_Y_MOVEMENT is set.
NPC_FLAG_LOCK_ANIMS = 0x00000400, ///< Do not allow scripts to change animation
NPC_FLAG_NO_Y_MOVEMENT = 0x00000800, ///< Causes NpcMoveTo() to ignore stairs
NPC_FLAG_1000 = 0x00001000,
NPC_FLAG_NO_PROJECT_SHADOW = 0x00002000, ///< Draw shadow at base of sprite instead of projecting to ground
NPC_FLAG_4000 = 0x00004000,
NPC_FLAG_8000 = 0x00008000,
NPC_FLAG_DIRTY_SHADOW = 0x00010000, ///< Set if shadow model is dirty (needs to be repositioned etc.)
NPC_FLAG_REFLECT_WALL = 0x00020000, ///< Mirror rendering across z=0
NPC_FLAG_40000 = 0x00040000, ///< Yaw?
NPC_FLAG_REFLECT_FLOOR = 0x00080000, ///< Mirror rendering across y=0
NPC_FLAG_MOTION_BLUR = 0x00100000, ///< Gives motion blur effect as NPC moves. Set by enable_npc_blur
NPC_FLAG_200000 = 0x00200000,
NPC_FLAG_400000 = 0x00400000,
NPC_FLAG_NO_DROPS = 0x00800000, ///< Do not drop hearts, flowers, or coins on defeat
NPC_FLAG_1000000 = 0x01000000, // TODO. fails assert in set_npc_sprite
NPC_FLAG_SIMPLIFIED_PHYSICS = 0x02000000,
/// Use simpler, faster physics calculations:
/// - Perform only one lateral collision test during motion
/// - Allow falling below Y=-2000 (by default, NPC_FLAG_NO_Y_MOVEMENT is set when an NPC falls out-of-bounds)
NPC_FLAG_PARTICLE = 0x04000000,
NPC_FLAG_8000000 = 0x08000000,
NPC_FLAG_10000000 = 0x10000000,
NPC_FLAG_NO_ANIMS_LOADED = 0x40000000, ///< Npc has no animations loaded
NPC_FLAG_80000000 = 0x80000000,
NPC_FLAG_PARTICLE = 0x04000000,
NPC_FLAG_8000000 = 0x08000000,
NPC_FLAG_10000000 = 0x10000000,
NPC_FLAG_20000000 = 0x20000000,
NPC_FLAG_NO_ANIMS_LOADED = 0x40000000, ///< Npc has no animations loaded
NPC_FLAG_80000000 = 0x80000000,
};
enum PlayerStatusFlags {

View File

@ -40,7 +40,449 @@ s32 calc_item_check_hit(void) {
return HIT_RESULT_HIT;
}
// Almost matching besides the parts that are marked as "TODO"
#ifdef NON_MATCHING
s32 calc_item_damage_enemy(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* playerActor = battleStatus->playerActor;
s32 currentTargetID = battleStatus->currentTargetID;
Actor* partnerActor = battleStatus->partnerActor;
s32 currentTargetPartID = battleStatus->currentTargetPart;
Actor* targetActor;
ActorPart* targetActorPart;
ActorState* actorState;
Evt* attackScript;
s32 sp1C = 0;
s32 isFireDamage = 0;
s32 isElectricDamage = 0;
s32 isIceDamage = 0;
s8 wasStatusInflicted = FALSE;
s32 currentHP;
s32 baseStatusChance;
s32 attackDamage;
s32 targetActorDefense;
s32 dispatchEvent;
u32 sp18;
s32 phi_a0_2;
s32 phi_fp;
battleStatus->wasStatusInflicted = FALSE;
battleStatus->lastAttackDamage = 0;
battleStatus->attackerActorID = playerActor->actorID;
battleStatus->currentTargetID2 = battleStatus->currentTargetID;
battleStatus->currentTargetPart2 = battleStatus->currentTargetPart;
targetActor = get_actor(currentTargetID);
if (targetActor == NULL) {
return 0;
}
targetActorPart = get_actor_part(targetActor, currentTargetPartID);
currentTargetID &= 0x700;
if (targetActorPart == NULL) {
PANIC();
}
targetActor->lastDamageTaken = 0;
if (gBattleStatus.flags1 & BS_FLAGS1_80000) {
actorState = &playerActor->state;
} else {
actorState = &partnerActor->state;
}
phi_a0_2 = 0;
if (battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE) {
playFX_24(0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z + 5.0f, 1.0f, 0x18);
isFireDamage = TRUE;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_ELECTRIC) {
func_80251474(targetActor);
isElectricDamage = TRUE;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_WATER) {
playFX_5F(0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z + 5.0f, 1.0f, 0x18);
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_ICE) {
playFX_30(0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z + 5.0f);
isIceDamage = TRUE;
}
if ((battleStatus->currentAttackElement & DAMAGE_TYPE_REMOVE_BUFFS) == 0) {
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_ILLUSORY) {
return 6;
}
if (targetActor->transStatus == STATUS_E || targetActorPart->eventFlags & ACTOR_EVENT_FLAG_800 && !(battleStatus->currentAttackElement & DAMAGE_TYPE_QUAKE)) {
return 6;
}
}
if (targetActor->stoneStatus == STATUS_STONE) {
sfx_play_sound_at_position(SOUND_10C, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
func_8024EFE0(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, 0, 1, 1);
show_damage_popup(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, 0, 0);
if (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) {
return 1;
} else {
return 0;
}
}
sp18 = (targetActorPart->partFlags3 & battleStatus->currentAttackElement) != 0; // TODO 3a8
if (targetActorPart->eventFlags & (ACTOR_EVENT_FLAG_ENCHANTED | ACTOR_EVENT_FLAG_80000)) {
battleStatus->currentAttackElement &= ~DAMAGE_TYPE_IGNORE_DEFENSE;
}
targetActorDefense = get_defense(targetActor, targetActorPart->defenseTable, battleStatus->currentAttackElement);
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_IGNORE_DEFENSE)) {
targetActorDefense += targetActor->defenseBoost;
}
attackDamage = battleStatus->currentAttackDamage;
if (attackDamage > 99) {
attackDamage = 99;
}
if (attackDamage <= 0) {
targetActorDefense = 0;
}
attackDamage -= targetActorDefense;
targetActor->hpChangeCounter = 0;
if (attackDamage <= 0) { // TODO 434
targetActor->hpChangeCounter = 0;
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS)) {
phi_fp = 2;
dispatchEvent = EVENT_UNKNOWN_TRIGGER;
sfx_play_sound_at_position(SOUND_10C, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
} else {
battleStatus->lastAttackDamage = 0;
dispatchEvent = EVENT_UNKNOWN_TRIGGER;
}
} else {
targetActor->damageCounter += attackDamage;
targetActor->hpChangeCounter -= attackDamage;
battleStatus->lastAttackDamage = 0;
dispatchEvent = EVENT_HIT_COMBO;
phi_fp = 0;
if (!(targetActorPart->flags & ACTOR_PART_FLAG_2000) && sp18 == 0 && !(targetActorPart->targetFlags & ACTOR_PART_FLAG_4)) {
targetActor->currentHP -= attackDamage;
if (targetActor->currentHP <= 0) {
targetActor->currentHP = 0;
dispatchEvent = EVENT_DEATH;
}
}
battleStatus->lastAttackDamage += attackDamage;
targetActor->lastDamageTaken = battleStatus->lastAttackDamage;
targetActor->hpChangeCounter = 0;
}
if (targetActorPart->flags & ACTOR_PART_FLAG_2000) {
dispatch_event_actor(targetActor, dispatchEvent);
func_8024EFE0(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, 0, 1, 3);
sfx_play_sound_at_position(SOUND_10C, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
return 2;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_2000) {
battleStatus->lastAttackDamage = 0;
dispatchEvent = EVENT_DEATH;
phi_fp = 0;
}
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 (targetActor->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) {
if (!(battleStatus->currentAttackElement & DAMAGE_TYPE_REMOVE_BUFFS)) {
goto block_80;
}
dispatchEvent = EVENT_IMMUNE;
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_ENCHANTED) {
dispatchEvent = EVENT_STAR_BEAM;
wasStatusInflicted = TRUE;
}
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_400000) {
dispatchEvent = EVENT_STAR_BEAM;
wasStatusInflicted = TRUE;
}
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_80000) {
dispatchEvent = EVENT_1D;
}
phi_fp = 0;
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_REMOVE_BUFFS
&& gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE
&& targetActor->attackBoost <= 0
&& targetActor->defenseBoost <= 0
&& targetActor->staticStatus == STATUS_END
&& targetActor->transStatus == STATUS_END) {
targetActor->attackBoost = 0;
targetActor->defenseBoost = 0;
targetActor->isGlowing = FALSE;
dispatchEvent = EVENT_HIT; // TODO 660
if (targetActor->staticStatus != STATUS_END) {
targetActor->staticStatus = STATUS_END;
targetActor->staticDuration = 0;
remove_status_static(targetActor->hudElementDataIndex);
}
if (targetActor->transStatus != STATUS_END) {
targetActor->transStatus = STATUS_END;
targetActor->transDuration = 0;
remove_status_transparent(targetActor->hudElementDataIndex);
}
wasStatusInflicted = TRUE;
phi_fp = 0;
}
block_80:
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_PEACH_BEAM) {
dispatchEvent = EVENT_IMMUNE;
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_ENCHANTED) {
dispatchEvent = EVENT_14;
wasStatusInflicted = TRUE;
}
if (targetActorPart->eventFlags & ACTOR_EVENT_FLAG_80000) {
dispatchEvent = EVENT_14;
wasStatusInflicted = TRUE;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
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;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & (DAMAGE_TYPE_JUMP | DAMAGE_TYPE_POW) && targetActorPart->eventFlags & ACTOR_EVENT_FLAG_GROUNDABLE) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_POW && targetActorPart->eventFlags & ACTOR_EVENT_FLAG_800000) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_FALL_TRIGGER;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & (DAMAGE_TYPE_JUMP | DAMAGE_TYPE_POW | DAMAGE_TYPE_QUAKE) && targetActorPart->eventFlags & ACTOR_EVENT_FLAG_FLIPABLE) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_FLIP_TRIGGER;
}
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE) {
if (dispatchEvent == EVENT_HIT) {
dispatchEvent = EVENT_BURN_HIT;
}
if (dispatchEvent == EVENT_DEATH) {
dispatchEvent = EVENT_BURN_DEATH;
}
isFireDamage = 1;
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE
&& battleStatus->lastAttackDamage >= 0
&& dispatchEvent != EVENT_DEATH
&& dispatchEvent != EVENT_SPIN_SMASH_DEATH
&& dispatchEvent != EVENT_EXPLODE_TRIGGER) {
if (battleStatus->currentAttackStatus & STATUS_FLAG_SHRINK && try_inflict_status(targetActor, STATUS_SHRINK, STATUS_SHRINK_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_POISON && try_inflict_status(targetActor, STATUS_POISON, STATUS_POISON_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_STONE && try_inflict_status(targetActor, STATUS_STONE, STATUS_STONE_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_SLEEP && try_inflict_status(targetActor, STATUS_SLEEP, STATUS_SLEEP_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_STOP && try_inflict_status(targetActor, STATUS_STOP, STATUS_STOP_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_STATIC && try_inflict_status(targetActor, STATUS_STATIC, STATUS_STATIC_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_FEAR && try_inflict_status(targetActor, STATUS_FEAR, STATUS_FEAR_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_PARALYZE && try_inflict_status(targetActor, STATUS_PARALYZE, STATUS_PARALYZE_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_DIZZY && try_inflict_status(targetActor, STATUS_DIZZY, STATUS_DIZZY_TURN_MOD)) {
wasStatusInflicted = TRUE;
}
if (wasStatusInflicted != FALSE) {
if (dispatchEvent == EVENT_UNKNOWN_TRIGGER) {
dispatchEvent = EVENT_HIT_COMBO;
}
if (dispatchEvent == EVENT_IMMUNE) {
dispatchEvent = EVENT_HIT;
}
}
}
}
}
}
}
}
}
baseStatusChance = (battleStatus->statusChance * targetActor->staticActorData->baseStatusChance) / 100; // TODO a70
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE && battleStatus->currentAttackElement & DAMAGE_TYPE_FEAR) {
//dispatchEvent = EVENT_IMMUNE;
if (rand_int(99) < baseStatusChance) {
dispatchEvent = EVENT_IMMUNE;
phi_fp = 2;
if (targetActor->debuff - 3 >= 6) {
phi_fp = 2;
if (!(targetActor->flags & ACTOR_FLAG_400)) {
sp1C = 1;
gBattleStatus.flags1 |= (BS_FLAGS1_1 | BS_FLAGS1_8 | BS_FLAGS1_10 | BS_FLAGS1_SP_EVT_ACTIVE | BS_FLAGS1_40);
sfx_play_sound_at_position(SOUND_UNKNOWN_231, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
wasStatusInflicted = TRUE;
dispatchEvent = EVENT_SCARE_AWAY;
phi_fp = 0;
}
}
} else {
phi_fp = 2;
}
}
battleStatus->wasStatusInflicted = wasStatusInflicted; // TODO b8c
if (sp1C != 0 && (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200) || gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200) && gBattleStatus.flags1 & BS_FLAGS1_80 && battleStatus->lastAttackDamage > 0) && (sfx_play_sound_at_position(0x231, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z), battleStatus->lastAttackDamage > 0) || battleStatus->currentAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS && sp1C != 0) {
if (!(gBattleStatus.flags1 & BS_FLAGS1_40)) {
phi_a0_2 = 3;
}
func_802667F0(phi_a0_2, targetActor, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
func_80266970(targetActor);
}
dispatch_event_actor(targetActor, dispatchEvent);
if (currentTargetID == 0x100) {
if (battleStatus->lastAttackDamage > 0 && gBattleStatus.flags1 & BS_FLAGS1_SP_EVT_ACTIVE) {
inflict_status(targetActor, 13, battleStatus->lastAttackDamage);
}
}
if (!(targetActor->flags & ACTOR_FLAG_NO_DMG_POPUP)) {
if (battleStatus->lastAttackDamage == 0) {
if (sp1C == 0 && !wasStatusInflicted) {
func_8024EFE0(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, 0, 1, 3);
}
} else if (sp18 == 0) {
if (battleStatus->currentAttackElement & (DAMAGE_TYPE_SMASH | DAMAGE_TYPE_NO_OTHER_DAMAGE_POPUPS)) {
show_damage_popup(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, battleStatus->lastAttackDamage, 0);
} else {
func_802664DC(actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, battleStatus->lastAttackDamage, 0);
}
if (!(targetActorPart->targetFlags & 4)) {
func_802666E4(targetActor, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, battleStatus->lastAttackDamage);
}
}
}
if (battleStatus->lastAttackDamage > 0) {
if (sp18 == 0) {
func_80267018(targetActor, 1);
if (isFireDamage) {
sfx_play_sound_at_position(SOUND_FIRE_DAMAGE, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
} else if (isElectricDamage) {
sfx_play_sound_at_position(SOUND_ELECTRIC_DAMAGE, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
} else if (isIceDamage) {
sfx_play_sound_at_position(SOUND_FREEZE_DAMAGE, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
} else {
sfx_play_sound_at_position(SOUND_E9, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
}
}
if (battleStatus->lastAttackDamage <= 0 && wasStatusInflicted && targetActorPart->flags & ACTOR_FLAG_2000) {
sfx_play_sound_at_position(SOUND_10C, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_SLEEP && wasStatusInflicted) {
attackScript = start_script(DoSleepHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_SLEEP, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_DIZZY && wasStatusInflicted) {
attackScript = start_script(DoDizzyHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_PARALYZE && wasStatusInflicted) {
attackScript = start_script(DoParalyzeHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_POISON && wasStatusInflicted) {
attackScript = start_script(DoPoisonHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_STOP && wasStatusInflicted) {
attackScript = start_script(DoStopHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_FROZEN && wasStatusInflicted) {
attackScript = start_script(DoFreezeHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
attackScript->varTable[3] = targetActor;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackStatus & STATUS_FLAG_SHRINK && wasStatusInflicted) {
attackScript = start_script(DoShrinkHit, 10, 0);
attackScript->varTable[0] = actorState->goalPos.x;
attackScript->varTable[1] = actorState->goalPos.y;
attackScript->varTable[2] = actorState->goalPos.z;
attackScript->varTable[3] = targetActor;
sfx_play_sound_at_position(SOUND_INFLICT_STATUS, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
if (battleStatus->currentAttackElement & DAMAGE_TYPE_SMASH && targetActor->actorType == 0x93) {
sfx_play_sound_at_position(SOUND_SMASH_GOOMNUT_TREE, 0, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z);
}
func_80266ADC(targetActor);
if (gBattleStatus.flags1 & (BS_FLAGS1_40 | BS_FLAGS1_200)) {
if (phi_fp == 0) {
phi_fp = 1;
}
if (phi_fp == 2) {
phi_fp = 3;
}
}
return phi_fp;
}
#else
INCLUDE_ASM(s32, "17FEB0", calc_item_damage_enemy);
#endif
ApiStatus ItemDamageEnemy(Evt* script, s32 isInitialCall) {
BattleStatus* battleStatus = &gBattleStatus;

View File

@ -72,10 +72,10 @@ void play_hit_sound(Actor* actor, f32 x, f32 y, f32 z, u32 hitSound) {
sfx_play_sound_at_position(SOUND_E2, 0, x, y, z);
break;
case ACTOR_PARTNER:
sfx_play_sound_at_position(SOUND_FIRE, 0, x, y, z);
sfx_play_sound_at_position(SOUND_FIRE_DAMAGE, 0, x, y, z);
break;
case ACTOR_ENEMY0:
sfx_play_sound_at_position(SOUND_FIRE, 0, x, y, z);
sfx_play_sound_at_position(SOUND_FIRE_DAMAGE, 0, x, y, z);
break;
}
break;
@ -85,10 +85,10 @@ void play_hit_sound(Actor* actor, f32 x, f32 y, f32 z, u32 hitSound) {
sfx_play_sound_at_position(SOUND_E3, 0, x, y, z);
break;
case ACTOR_PARTNER:
sfx_play_sound_at_position(SOUND_FREEZE, 0, x, y, z);
sfx_play_sound_at_position(SOUND_FREEZE_DAMAGE, 0, x, y, z);
break;
case ACTOR_ENEMY0:
sfx_play_sound_at_position(SOUND_FREEZE, 0, x, y, z);
sfx_play_sound_at_position(SOUND_FREEZE_DAMAGE, 0, x, y, z);
break;
}
break;
@ -98,10 +98,10 @@ void play_hit_sound(Actor* actor, f32 x, f32 y, f32 z, u32 hitSound) {
sfx_play_sound_at_position(SOUND_37A, 0, x, y, z);
break;
case ACTOR_PARTNER:
sfx_play_sound_at_position(SOUND_ELECTRIC, 0, x, y, z);
sfx_play_sound_at_position(SOUND_ELECTRIC_DAMAGE, 0, x, y, z);
break;
case ACTOR_ENEMY0:
sfx_play_sound_at_position(SOUND_ELECTRIC, 0, x, y, z);
sfx_play_sound_at_position(SOUND_ELECTRIC_DAMAGE, 0, x, y, z);
break;
}
break;
@ -765,7 +765,7 @@ s32 calc_enemy_damage_target(Actor* attacker) {
script->varTable[1] = state->goalPos.y;
script->varTable[2] = state->goalPos.z;
script->varTable[3] = (s32) target;
sfx_play_sound_at_position(SOUND_FREEZE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
sfx_play_sound_at_position(SOUND_FREEZE_DAMAGE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
}
if ((battleStatus->currentAttackStatus & STATUS_FLAG_SHRINK) && statusInflicted) {
script = start_script(&DoShrinkHit, 10, 0);
@ -791,7 +791,7 @@ s32 calc_enemy_damage_target(Actor* attacker) {
&& !has_enchanted_part(attacker)
) {
// enum mismatch? shock vs explode :raised_eyebrow:
sfx_play_sound_at_position(SOUND_ELECTRIC, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
sfx_play_sound_at_position(SOUND_ELECTRIC_DAMAGE, 0, state->goalPos.x, state->goalPos.y, state->goalPos.z);
func_80251474(attacker);
dispatch_damage_event_actor_1(attacker, 1, EVENT_SHOCK_HIT);
return HIT_RESULT_TRIGGERED_EXPLODE;

View File

@ -447,7 +447,7 @@ void appendGfx_npc(Npc* npc) {
f32 temp_f22 = npc_get_render_yaw();
guTranslateF(subroutine_arg6, npc->pos.x, npc->pos.y + npc->unk_AB, npc->pos.z);
if (npc->flags & NPC_FLAG_80) {
if (npc->flags & NPC_FLAG_UPSIDE_DOWN) {
mtx_ident_mirror_y(subroutine_arg16);
guMtxCatF(subroutine_arg16, subroutine_arg6, subroutine_arg6);
}
@ -501,7 +501,7 @@ void appendGfx_npc(Npc* npc) {
if (npc->flags & NPC_FLAG_REFLECT_WALL) {
guTranslateF(subroutine_arg6, npc->pos.x, npc->pos.y + npc->unk_AB, -npc->pos.z);
if (npc->flags & NPC_FLAG_80) {
if (npc->flags & NPC_FLAG_UPSIDE_DOWN) {
mtx_ident_mirror_y(subroutine_arg16);
guMtxCatF(subroutine_arg16, subroutine_arg6, subroutine_arg6);
}