Player action hooks (#93)
Some checks failed
GenerateBuilds / generate-port-otr (push) Has been cancelled
GenerateBuilds / build-windows (push) Has been cancelled
GenerateBuilds / build-macos (push) Has been cancelled
GenerateBuilds / build-linux (push) Has been cancelled

* Create Player Action and Player Movement event types

* Call Boost/Brake events

* Change some event types

* Make Boost/Brake events cancellable

* Use new dynamic hooks

* Use separate events for each player action

* Add shoot events

* Return early on cancel

* Add Bomb and Charged Shot Events

* Remove movement event hooks, add player param to action hooks

* Fix whitespace

* Register player action events
This commit is contained in:
Kiloku 2024-12-30 01:47:42 -03:00 committed by GitHub
parent dbf9b0378f
commit ad7bc7c691
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 249 additions and 165 deletions

View File

@ -3145,6 +3145,7 @@ void Player_SetupTankShot(Player* player, PlayerShot* shot, PlayerShotId shotId,
void Player_TankCannon(Player* player) { void Player_TankCannon(Player* player) {
s32 i; s32 i;
CALL_CANCELLABLE_EVENT(PlayerActionPreShootEvent, player, gLaserStrength[gPlayerNum]) {
for (i = 0; i < ARRAY_COUNT(gPlayerShots) - 1; i++) { for (i = 0; i < ARRAY_COUNT(gPlayerShots) - 1; i++) {
if (gPlayerShots[i].obj.status == SHOT_FREE) { if (gPlayerShots[i].obj.status == SHOT_FREE) {
Player_SetupTankShot(player, &gPlayerShots[i], PLAYERSHOT_TANK, 100.0f); Player_SetupTankShot(player, &gPlayerShots[i], PLAYERSHOT_TANK, 100.0f);
@ -3153,6 +3154,10 @@ void Player_TankCannon(Player* player) {
break; break;
} }
} }
}
if (!PlayerActionPreShootEvent_.event.cancelled){
CALL_EVENT(PlayerActionPostShootEvent, player, gLaserStrength[gPlayerNum]);
}
} }
void Player_ArwingLaser(Player* player) { void Player_ArwingLaser(Player* player) {
@ -3164,6 +3169,11 @@ void Player_ArwingLaser(Player* player) {
laser = LASERS_SINGLE; laser = LASERS_SINGLE;
} }
CALL_EVENT(PlayerActionPreShootEvent, player, laser);
if (PlayerActionPreShootEvent_.event.cancelled){
return;
}
switch (laser) { switch (laser) {
case LASERS_SINGLE: case LASERS_SINGLE:
for (i = 0; i < ARRAY_COUNT(gPlayerShots) - 1; i++) { for (i = 0; i < ARRAY_COUNT(gPlayerShots) - 1; i++) {
@ -3175,6 +3185,7 @@ void Player_ArwingLaser(Player* player) {
break; break;
} }
} }
break; break;
case LASERS_TWIN: case LASERS_TWIN:
case LASERS_HYPER: case LASERS_HYPER:
@ -3194,11 +3205,19 @@ void Player_ArwingLaser(Player* player) {
} }
break; break;
} }
CALL_EVENT(PlayerActionPostShootEvent, player, laser);
} }
void Player_SmartBomb(Player* player) { void Player_SmartBomb(Player* player) {
if ((gBombCount[player->num] != 0) && (gBombButton[player->num] & gInputPress->button) && if ((gBombCount[player->num] != 0) && (gBombButton[player->num] & gInputPress->button) &&
(gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].obj.status == SHOT_FREE)) { (gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].obj.status == SHOT_FREE)) {
CALL_EVENT(PlayerActionPreBombEvent, player);
if (PlayerActionPreBombEvent_.event.cancelled)
{
return;
}
if (gVersusMode) { if (gVersusMode) {
gBombCount[player->num] = 0; gBombCount[player->num] = 0;
} else { } else {
@ -3218,6 +3237,7 @@ void Player_SmartBomb(Player* player) {
gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].unk_60 = 0; gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].unk_60 = 0;
Audio_InitBombSfx(player->num, 1); Audio_InitBombSfx(player->num, 1);
Audio_PlayBombFlightSfx(player->num, gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].sfxSource); Audio_PlayBombFlightSfx(player->num, gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].sfxSource);
CALL_EVENT(PlayerActionPostBombEvent, player);
} }
} }
@ -3350,6 +3370,7 @@ bool Player_UpdateLockOn(Player* player) {
(gPlayerShots[14 - player->num].obj.id != PLAYERSHOT_LOCK_ON) || (gPlayerShots[14 - player->num].obj.id != PLAYERSHOT_LOCK_ON) ||
((gPlayerShots[14 - player->num].obj.id == PLAYERSHOT_LOCK_ON) && ((gPlayerShots[14 - player->num].obj.id == PLAYERSHOT_LOCK_ON) &&
(gPlayerShots[14 - player->num].unk_60 != 0))) { (gPlayerShots[14 - player->num].unk_60 != 0))) {
CALL_CANCELLABLE_EVENT(PlayerActionPreShootChargedEvent, player){
if (player->form == FORM_ARWING) { if (player->form == FORM_ARWING) {
Player_SetupArwingShot(player, &gPlayerShots[14 - player->num], 0.0f, 0.0f, PLAYERSHOT_LOCK_ON, Player_SetupArwingShot(player, &gPlayerShots[14 - player->num], 0.0f, 0.0f, PLAYERSHOT_LOCK_ON,
70.0f); 70.0f);
@ -3360,6 +3381,8 @@ bool Player_UpdateLockOn(Player* player) {
gControllerRumbleTimers[player->num] = 5; gControllerRumbleTimers[player->num] = 5;
return true; return true;
} }
CALL_EVENT(PlayerActionPostShootChargedEvent, player);
}
break; break;
} }
} }
@ -3369,6 +3392,7 @@ bool Player_UpdateLockOn(Player* player) {
(gPlayerShots[14 - player->num].obj.id != PLAYERSHOT_LOCK_ON) || (gPlayerShots[14 - player->num].obj.id != PLAYERSHOT_LOCK_ON) ||
((gPlayerShots[14 - player->num].obj.id == PLAYERSHOT_LOCK_ON) && ((gPlayerShots[14 - player->num].obj.id == PLAYERSHOT_LOCK_ON) &&
(gPlayerShots[14 - player->num].scale > 1.0f))) { (gPlayerShots[14 - player->num].scale > 1.0f))) {
CALL_CANCELLABLE_EVENT(PlayerActionPreShootChargedEvent, player){
if (player->form == FORM_ARWING) { if (player->form == FORM_ARWING) {
Player_SetupArwingShot(player, &gPlayerShots[14 - player->num], 0.0f, 0.0f, PLAYERSHOT_LOCK_ON, Player_SetupArwingShot(player, &gPlayerShots[14 - player->num], 0.0f, 0.0f, PLAYERSHOT_LOCK_ON,
70.0f); 70.0f);
@ -3381,6 +3405,8 @@ bool Player_UpdateLockOn(Player* player) {
return true; return true;
} }
} }
CALL_EVENT(PlayerActionPostShootChargedEvent, player);
}
gChargeTimers[player->num] = 0; gChargeTimers[player->num] = 0;
} }
@ -3401,6 +3427,7 @@ bool Player_UpdateLockOn(Player* player) {
} }
if (hasBombTarget && (gBombCount[player->num] != 0) && if (hasBombTarget && (gBombCount[player->num] != 0) &&
(gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].obj.status == SHOT_FREE)) { (gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].obj.status == SHOT_FREE)) {
CALL_CANCELLABLE_EVENT(PlayerActionPreBombEvent, player){
gBombCount[player->num]--; gBombCount[player->num]--;
if (player->form == FORM_ARWING) { if (player->form == FORM_ARWING) {
Player_SetupArwingShot(player, &gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1], 0.0f, 0.0f, Player_SetupArwingShot(player, &gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1], 0.0f, 0.0f,
@ -3414,6 +3441,8 @@ bool Player_UpdateLockOn(Player* player) {
Audio_PlayBombFlightSfx(player->num, gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].sfxSource); Audio_PlayBombFlightSfx(player->num, gPlayerShots[ARRAY_COUNT(gPlayerShots) - 1].sfxSource);
return true; return true;
} }
CALL_EVENT(PlayerActionPostBombEvent, player);
}
} }
return false; return false;
} }
@ -5136,6 +5165,7 @@ void Player_ArwingBoost(Player* player) {
} }
if ((gInputHold->button & gBoostButton[player->num]) && !(gInputHold->button & gBrakeButton[player->num]) && if ((gInputHold->button & gBoostButton[player->num]) && !(gInputHold->button & gBrakeButton[player->num]) &&
(player->state != PLAYERSTATE_U_TURN) && !player->boostCooldown) { (player->state != PLAYERSTATE_U_TURN) && !player->boostCooldown) {
CALL_CANCELLABLE_EVENT(PlayerActionBoostEvent, player) {
if (player->boostMeter == 0.0f) { if (player->boostMeter == 0.0f) {
Player_PlaySfx(player->sfxSource, NA_SE_ARWING_BOOST, player->num); Player_PlaySfx(player->sfxSource, NA_SE_ARWING_BOOST, player->num);
player->unk_194 = 5.0f; player->unk_194 = 5.0f;
@ -5168,6 +5198,7 @@ void Player_ArwingBoost(Player* player) {
Math_SmoothStepToF(&player->camDist, -400.0f, 0.1f, 30.0f, 0.0f); Math_SmoothStepToF(&player->camDist, -400.0f, 0.1f, 30.0f, 0.0f);
player->sfx.boost = 1; player->sfx.boost = 1;
Math_SmoothStepToF(&D_ctx_801779A8[player->num], 50.0f, 1.0f, 10.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[player->num], 50.0f, 1.0f, 10.0f, 0.0f);
}
} else { } else {
if (player->boostMeter > 0.0f) { if (player->boostMeter > 0.0f) {
player->boostMeter -= sp2C; player->boostMeter -= sp2C;
@ -5239,6 +5270,7 @@ void Player_ArwingBrake(Player* player) {
if ((gInputHold->button & gBrakeButton[player->num]) && !(gInputHold->button & gBoostButton[player->num]) && if ((gInputHold->button & gBrakeButton[player->num]) && !(gInputHold->button & gBoostButton[player->num]) &&
(player->state != PLAYERSTATE_U_TURN) && !player->boostCooldown) { (player->state != PLAYERSTATE_U_TURN) && !player->boostCooldown) {
CALL_CANCELLABLE_EVENT(PlayerActionBrakeEvent, player) {
if (player->boostMeter == 0.0f) { if (player->boostMeter == 0.0f) {
Player_PlaySfx(player->sfxSource, NA_SE_ARWING_BRAKE, player->num); Player_PlaySfx(player->sfxSource, NA_SE_ARWING_BRAKE, player->num);
if ((gLevelMode == LEVELMODE_ALL_RANGE) && (gInputPress->button & gBrakeButton[player->num])) { if ((gLevelMode == LEVELMODE_ALL_RANGE) && (gInputPress->button & gBrakeButton[player->num])) {
@ -5267,6 +5299,7 @@ void Player_ArwingBrake(Player* player) {
Math_SmoothStepToF(&player->camDist, 180.0f, 0.1f, 10.0f, 0.0f); Math_SmoothStepToF(&player->camDist, 180.0f, 0.1f, 10.0f, 0.0f);
player->sfx.brake = true; player->sfx.brake = true;
Math_SmoothStepToF(&D_ctx_801779A8[player->num], 25.0f, 1.0f, 5.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[player->num], 25.0f, 1.0f, 5.0f, 0.0f);
}
} else if (player->boostMeter > 0.0f) { } else if (player->boostMeter > 0.0f) {
player->boostMeter -= sp34; player->boostMeter -= sp34;
if (player->boostMeter <= 0.0f) { if (player->boostMeter <= 0.0f) {

View File

@ -1,6 +1,7 @@
#include "global.h" #include "global.h"
#include "assets/ast_landmaster.h" #include "assets/ast_landmaster.h"
#include "assets/ast_titania.h" #include "assets/ast_titania.h"
#include "port/hooks/Events.h"
void func_tank_80047754(Player* player); void func_tank_80047754(Player* player);
void func_tank_80047D38(Player* player, f32); void func_tank_80047D38(Player* player, f32);
@ -550,6 +551,7 @@ void func_tank_80045348(Player* player) {
if (player->unk_19C >= 0) { if (player->unk_19C >= 0) {
if ((gBoostButton[player->num] & gInputHold->button) && !player->boostCooldown) { if ((gBoostButton[player->num] & gInputHold->button) && !player->boostCooldown) {
CALL_CANCELLABLE_EVENT(PlayerActionBoostEvent, player) {
D_800C9F14++; D_800C9F14++;
sp2E = true; sp2E = true;
if (D_800C9F24 == 0.0f) { if (D_800C9F24 == 0.0f) {
@ -569,16 +571,19 @@ void func_tank_80045348(Player* player) {
} }
Math_SmoothStepToF(&D_ctx_801779A8[player->num], 50.0f, 1.0f, 10.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[player->num], 50.0f, 1.0f, 10.0f, 0.0f);
}
} else { } else {
D_800C9F24 = 0.0f; D_800C9F24 = 0.0f;
} }
if ((gBrakeButton[player->num] & gInputHold->button) && !player->boostCooldown && !sp2E) { if ((gBrakeButton[player->num] & gInputHold->button) && !player->boostCooldown && !sp2E) {
CALL_CANCELLABLE_EVENT(PlayerActionBrakeEvent, player) {
D_800C9F14++; D_800C9F14++;
baseSpeedTarget = 5.0f; baseSpeedTarget = 5.0f;
sp40 = 100.0f; sp40 = 100.0f;
sp3C = 0.2f; sp3C = 0.2f;
D_800C9F28 += 1.0f; D_800C9F28 += 1.0f;
Math_SmoothStepToF(&D_ctx_801779A8[player->num], 25.0f, 1.0f, 5.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[player->num], 25.0f, 1.0f, 5.0f, 0.0f);
}
} else { } else {
D_800C9F28 = 0.0f; D_800C9F28 = 0.0f;
} }

View File

@ -1212,6 +1212,10 @@ void Aquas_BlueMarineTorpedo(Player* player) {
for (i = 15, shot = &gPlayerShots[15]; i < ARRAY_COUNT(gPlayerShots); i++, shot++) { for (i = 15, shot = &gPlayerShots[15]; i < ARRAY_COUNT(gPlayerShots); i++, shot++) {
if (shot->obj.status == SHOT_FREE) { if (shot->obj.status == SHOT_FREE) {
CALL_EVENT(PlayerActionPreBombEvent, player)
if (PlayerActionPreBombEvent_.event.cancelled){
return;
}
Player_SetupArwingShot(player, shot, 0.0f, 0.0f, PLAYERSHOT_LOCK_ON, 50.0f); Player_SetupArwingShot(player, shot, 0.0f, 0.0f, PLAYERSHOT_LOCK_ON, 50.0f);
AUDIO_PLAY_SFX(NA_SE_MAR_BOMB_SHOT, shot->sfxSource, 0); AUDIO_PLAY_SFX(NA_SE_MAR_BOMB_SHOT, shot->sfxSource, 0);
D_i3_801C4190[5] = i + 1; D_i3_801C4190[5] = i + 1;
@ -1219,6 +1223,7 @@ void Aquas_BlueMarineTorpedo(Player* player) {
D_i3_801C4458 = -100.0f; D_i3_801C4458 = -100.0f;
D_i3_801C445C = 0.1f; D_i3_801C445C = 0.1f;
gLight3Brightness = 1.0f; gLight3Brightness = 1.0f;
CALL_EVENT(PlayerActionPostBombEvent, player);
break; break;
} }
} }
@ -1227,6 +1232,7 @@ void Aquas_BlueMarineTorpedo(Player* player) {
void Aquas_BlueMarineLaser(Player* player) { void Aquas_BlueMarineLaser(Player* player) {
s32 i; s32 i;
CALL_CANCELLABLE_EVENT(PlayerActionPreShootEvent, player, gLaserStrength[gPlayerNum]) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (gPlayerShots[i].obj.status == SHOT_FREE) { if (gPlayerShots[i].obj.status == SHOT_FREE) {
Player_SetupArwingShot(player, &gPlayerShots[i], 0.0f, -10.0f, PLAYERSHOT_SINGLE_LASER, 120.0f); Player_SetupArwingShot(player, &gPlayerShots[i], 0.0f, -10.0f, PLAYERSHOT_SINGLE_LASER, 120.0f);
@ -1238,6 +1244,10 @@ void Aquas_BlueMarineLaser(Player* player) {
break; break;
} }
} }
}
if (!PlayerActionPreShootEvent_.event.cancelled){
CALL_EVENT(PlayerActionPostShootEvent, player, gLaserStrength[gPlayerNum]);
}
} }
void Aquas_BlueMarineShoot(Player* player) { void Aquas_BlueMarineShoot(Player* player) {
@ -1514,10 +1524,12 @@ void Aquas_BlueMarineBoost(Player* player) {
if ((gBoostButton[player->num] & gInputHold->button) && (player->unk_230 == 0) && if ((gBoostButton[player->num] & gInputHold->button) && (player->unk_230 == 0) &&
(player->state != PLAYERSTATE_U_TURN) && (player->boostCooldown == 0)) { (player->state != PLAYERSTATE_U_TURN) && (player->boostCooldown == 0)) {
CALL_CANCELLABLE_EVENT(PlayerActionBoostEvent, player){
if (player->boostMeter == 0) { if (player->boostMeter == 0) {
AUDIO_PLAY_SFX(NA_SE_MARINE_BOOST, player->sfxSource, 4); AUDIO_PLAY_SFX(NA_SE_MARINE_BOOST, player->sfxSource, 4);
} }
if (!CVarGetInteger("gInfiniteBoost", 0)) { if (!CVarGetInteger("gInfiniteBoost", 0)) {
player->boostMeter += 3.0f; player->boostMeter += 3.0f;
if (player->boostMeter > 90.0f) { if (player->boostMeter > 90.0f) {
@ -1537,6 +1549,7 @@ void Aquas_BlueMarineBoost(Player* player) {
player->sfx.boost = 1; player->sfx.boost = 1;
Math_SmoothStepToF(&D_ctx_801779A8[0], 50.0f, 1.0f, 10.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[0], 50.0f, 1.0f, 10.0f, 0.0f);
}
} else { } else {
D_i3_801C41B8[27] = 0.0f; D_i3_801C41B8[27] = 0.0f;
@ -1564,6 +1577,7 @@ void Aquas_BlueMarineBrake(Player* player) {
if ((gInputHold->button & gBrakeButton[player->num]) && (player->unk_230 == 0) && if ((gInputHold->button & gBrakeButton[player->num]) && (player->unk_230 == 0) &&
(player->state != PLAYERSTATE_U_TURN) && (player->boostCooldown == 0)) { (player->state != PLAYERSTATE_U_TURN) && (player->boostCooldown == 0)) {
CALL_CANCELLABLE_EVENT(PlayerActionBrakeEvent, player){
if (player->boostMeter == 0) { if (player->boostMeter == 0) {
AUDIO_PLAY_SFX(NA_SE_MARINE_BRAKE, player->sfxSource, 4); AUDIO_PLAY_SFX(NA_SE_MARINE_BRAKE, player->sfxSource, 4);
} }
@ -1587,6 +1601,7 @@ void Aquas_BlueMarineBrake(Player* player) {
player->sfx.brake = true; player->sfx.brake = true;
Math_SmoothStepToF(&D_ctx_801779A8[0], 25.0f, 1.0f, 5.0f, 0.0f); Math_SmoothStepToF(&D_ctx_801779A8[0], 25.0f, 1.0f, 5.0f, 0.0f);
}
} else { } else {
if (player->boostMeter > 0.0f) { if (player->boostMeter > 0.0f) {
player->boostMeter -= 0.5f; player->boostMeter -= 0.5f;

View File

@ -3,3 +3,4 @@
#include "list/EngineEvent.h" #include "list/EngineEvent.h"
#include "list/ActorEvent.h" #include "list/ActorEvent.h"
#include "list/ItemEvent.h" #include "list/ItemEvent.h"
#include "list/ActionEvent.h"

View File

@ -0,0 +1,17 @@
#pragma once
#include "sf64player.h"
#include "port/hooks/impl/EventSystem.h"
DEFINE_EVENT(PlayerActionBoostEvent, Player* player;);
DEFINE_EVENT(PlayerActionBrakeEvent, Player* player;);
DEFINE_EVENT(PlayerActionPreShootEvent, Player* player; LaserStrength laser;);
DEFINE_EVENT(PlayerActionPostShootEvent, Player* player; LaserStrength laser;);
DEFINE_EVENT(PlayerActionPreShootChargedEvent, Player* player;);
DEFINE_EVENT(PlayerActionPostShootChargedEvent, Player* player;);
DEFINE_EVENT(PlayerActionPreBombEvent, Player* player;);
DEFINE_EVENT(PlayerActionPostBombEvent, Player* player;);

View File

@ -193,6 +193,19 @@ void PortEnhancements_Register() {
REGISTER_EVENT(ObjectUpdateEvent); REGISTER_EVENT(ObjectUpdateEvent);
REGISTER_EVENT(ObjectDrawEvent); REGISTER_EVENT(ObjectDrawEvent);
REGISTER_EVENT(ObjectDestroyEvent); REGISTER_EVENT(ObjectDestroyEvent);
// Register player action events
REGISTER_EVENT(PlayerActionBoostEvent);
REGISTER_EVENT(PlayerActionBrakeEvent);
REGISTER_EVENT(PlayerActionPreShootEvent);
REGISTER_EVENT(PlayerActionPostShootEvent);
REGISTER_EVENT(PlayerActionPreShootChargedEvent);
REGISTER_EVENT(PlayerActionPostShootChargedEvent);
REGISTER_EVENT(PlayerActionPreBombEvent);
REGISTER_EVENT(PlayerActionPostBombEvent);
} }
void PortEnhancements_Exit() { void PortEnhancements_Exit() {