3#include "../src/world/partners.h"
5#include "sprite/npc/WorldWatt.h"
7#include "sprite/player.h"
9#define NAMESPACE world_watt
16BSS s32 N(AbilityState);
34 if (N(StaticEffect) == NULL) {
35 N(StaticEffect) = fx_static_status(0, npc->pos.x, npc->pos.y + 13.0f, npc->pos.z, 0.9f, 5, 0);
41 if (N(StaticEffect) != NULL) {
42 N(StaticEffect)->data.staticStatus->timeLeft = 1;
43 N(StaticEffect) = NULL;
47s32 N(EffectAnimLengths)[] = { 24, 6 };
57 invisTime = N(EffectAnimLengths)[type] * 0.5f;
61 for (i = 1; i < count; i++, part++) {
62 part->
frame = -1.0f - (invisTime * (i & 1));
67 npc->collisionHeight = 24;
68 npc->collisionDiameter = 24;
69 N(D_802BE308) = FALSE;
70 N(D_802BE300) = FALSE;
71 N(IsPlayerHolding) = FALSE;
73 N(StaticEffect) = NULL;
76API_CALLABLE(N(TakeOut)) {
77 Npc* watt = script->owner2.npc;
99b32 N(WattIsMoving) = FALSE;
101API_CALLABLE(N(Update)) {
103 Npc* watt = script->owner2.npc;
104 f32 sinAngle, cosAngle, liftoffVelocity;
117 if (entity == NULL) {
122 if (!N(WattIsMoving)) {
123 N(WattIsMoving) = TRUE;
125 watt->
curAnim = ANIM_WorldWatt_Run;
128 if (N(WattIsMoving)) {
129 N(WattIsMoving) = FALSE;
131 watt->
curAnim = ANIM_WorldWatt_Idle;
134 if (N(StaticEffect) != NULL) {
135 N(StaticEffect)->data.staticStatus->pos.x = watt->
pos.
x;
136 N(StaticEffect)->data.staticStatus->pos.y = watt->
pos.
y + 13.0f;
137 N(StaticEffect)->data.staticStatus->pos.z = watt->
pos.
z;
142 switch (N(TweesterPhysicsPtr)->state) {
144 N(TweesterPhysicsPtr)->state++;
145 N(TweesterPhysicsPtr)->prevFlags = watt->
flags;
148 N(TweesterPhysicsPtr)->angularVel = 6.0f;
149 N(TweesterPhysicsPtr)->liftoffVelPhase = 50.0f;
150 N(TweesterPhysicsPtr)->countdown = 120;
152 watt->
flags &= ~NPC_FLAG_GRAVITY;
155 watt->
pos.
x = entity->
pos.
x + (sinAngle * N(TweesterPhysicsPtr)->radius);
156 watt->
pos.
z = entity->
pos.
z - (cosAngle * N(TweesterPhysicsPtr)->radius);
157 N(TweesterPhysicsPtr)->angle =
clamp_angle(N(TweesterPhysicsPtr)->angle - N(TweesterPhysicsPtr)->angularVel);
159 if (N(TweesterPhysicsPtr)->radius > 20.0f) {
160 N(TweesterPhysicsPtr)->radius--;
161 }
else if (N(TweesterPhysicsPtr)->radius < 19.0f) {
162 N(TweesterPhysicsPtr)->radius++;
165 liftoffVelocity =
sin_rad(
DEG_TO_RAD(N(TweesterPhysicsPtr)->liftoffVelPhase)) * 3.0f;
166 N(TweesterPhysicsPtr)->liftoffVelPhase += 3.0f;
168 if (N(TweesterPhysicsPtr)->liftoffVelPhase > 150.0f) {
169 N(TweesterPhysicsPtr)->liftoffVelPhase = 150.0f;
172 watt->
pos.
y += liftoffVelocity;
174 N(TweesterPhysicsPtr)->angularVel += 0.8;
176 if (N(TweesterPhysicsPtr)->angularVel > 40.0f) {
177 N(TweesterPhysicsPtr)->angularVel = 40.0f;
180 if (--N(TweesterPhysicsPtr)->countdown == 0) {
181 N(TweesterPhysicsPtr)->state++;
185 watt->
flags = N(TweesterPhysicsPtr)->prevFlags;
186 N(TweesterPhysicsPtr)->countdown = 30;
187 N(TweesterPhysicsPtr)->state++;
192 if (--N(TweesterPhysicsPtr)->countdown == 0) {
199 if (N(StaticEffect) != NULL) {
200 N(StaticEffect)->data.staticStatus->pos.x = watt->
pos.
x;
201 N(StaticEffect)->data.staticStatus->pos.y = watt->
pos.
y + 13.0f;
202 N(StaticEffect)->data.staticStatus->pos.z = watt->
pos.
z;
217 watt->
flags = N(TweesterPhysicsPtr)->prevFlags;
223API_CALLABLE(N(UseAbility)) {
226 Npc* npc = script->owner2.npc;
256 npc->
curAnim = ANIM_WorldWatt_Idle;
258 script->functionTemp[1] = 2;
262 switch (N(AbilityState)) {
267 script->functionTemp[1] = 3;
272 if (script->functionTemp[1] == 0) {
283 script->functionTemp[1]--;
287 switch (N(AbilityState)) {
291 N(IsPlayerHolding) = TRUE;
300 npc->
curAnim = ANIM_WorldWatt_Walk;
303 npc->
curAnim = ANIM_WorldWatt_Idle;
307 script->functionTemp[1] = 2;
311 N(IsPlayerHolding) = TRUE;
320 npc->
curAnim = ANIM_WorldWatt_Walk;
334 npc->
curAnim = ANIM_WorldWatt_Idle;
338 script->functionTemp[1] = 2;
346 if (script->functionTemp[1] != 0) {
347 script->functionTemp[1]--;
364 npc->
curAnim = ANIM_WorldWatt_Idle;
366 N(IsPlayerHolding) = FALSE;
389 if (script->functionTemp[1] != 0) {
390 script->functionTemp[1]--;
410 npc->
curAnim = ANIM_WorldWatt_Idle;
412 N(IsPlayerHolding) = FALSE;
425 if (N(StaticEffect) != NULL) {
426 N(StaticEffect)->data.staticStatus->pos.x = npc->
pos.
x;
427 N(StaticEffect)->data.staticStatus->pos.y = npc->
pos.
y + 13.0f;
428 N(StaticEffect)->data.staticStatus->pos.z = npc->
pos.
z;
439API_CALLABLE(N(PutAway)) {
442 Npc* watt = script->owner2.npc;
470 if (N(IsPlayerHolding)) {
471 partnerStatus->
npc = *watt;
483 *watt = partnerStatus->
npc;
489API_CALLABLE(N(EnterMap)) {
495 script->functionTemp[0] = 0;
498 switch (script->functionTemp[0]) {
500 if (script->varTable[12] == 0) {
507 script->functionTemp[1] = script->varTable[4];
509 script->varTable[1], script->varTable[3]);
513 watt->
flags &= ~NPC_FLAG_GRAVITY;
519 N(D_802BE308) = FALSE;
520 script->functionTemp[0]++;
524 script->functionTemp[1]--;
525 if (script->functionTemp[1] == 0) {
526 if (script->varTable[12]) {
539 f32 currentSpeed = playerStatus->
curSpeed;
542 if (playerStatus->
runSpeed <= currentSpeed) {
543 anim = ANIM_MarioW1_CarryRun;
544 }
else if (playerStatus->
walkSpeed <= currentSpeed) {
545 anim = ANIM_MarioW1_CarryWalk;
547 anim = ANIM_MarioW1_CarryIdle;
557 f32 offsetScale, angle;
558 f32 spriteFacingAngle;
563 if ((spriteFacingAngle < 90.0f) || (spriteFacingAngle > 270.0f)) {
589 partnerNPC = new_var2;
s32 partner_use_ability(void)
b8 keepUsingPartnerOnMapChange
AnimID trueAnimation
Encoding back-facing sprite.
struct StaticStatusFXData * staticStatus
@ TWEESTER_PARTNER_ATTRACT
@ TWEESTER_PARTNER_RELEASE
@ NPC_PAL_ADJUST_WATT_IDLE
@ PARTNER_ACTION_WATT_SHINE
@ ACTION_STATE_USE_SPINNING_FLOWER
@ NPC_FLAG_IGNORE_WORLD_COLLISION
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
@ NPC_FLAG_IGNORE_CAMERA_FOR_YAW
void partner_clear_player_tracking(Npc *partner)
void partner_flying_update_player_tracking(Npc *partner)
void move_player(s32 duration, f32 heading, f32 speed)
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
void partner_kill_ability_script(void)
s32 is_starting_conversation(void)
void set_action_state(s32 actionState)
void suggest_player_anim_allow_backward(AnimID anim)
void partner_flying_update_motion(Npc *partner)
void partner_flying_enable(Npc *partner, s32 val)
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Npc * get_npc_unsafe(s32 npcID)
void npc_set_palswap_mode_A(Npc *npc, s32 arg1)
s32 func_800EA52C(s32 partnerID)
s32 partner_init_get_out(Npc *npc)
s32 partner_init_put_away(Npc *partner)
s32 partner_put_away(Npc *partner)
s32 partner_force_player_flip_done(void)
s32 partner_get_out(Npc *partner)
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
#define Return
Kills the current EVT thread.
Entity * TweesterTouchingPartner
PlayerStatus * gPlayerStatusPtr
PartnerStatus gPartnerStatus
GameStatus * gGameStatusPtr
PlayerStatus gPlayerStatus
void N try_cancel_tweester(Npc *watt)
EvtScript EVS_WorldWatt_PutAway
void N pre_battle(Npc *watt)
void N post_battle(Npc *watt)
void N update_player_carry_anim(void)
void N reset_static_effect(s32 type)
EvtScript EVS_WorldWatt_EnterMap
EvtScript EVS_WorldWatt_Update
EvtScript EVS_WorldWatt_UseAbility
void N sync_held_position(void)
void N dispose_static_effect(void)
EvtScript EVS_WorldWatt_TakeOut
void N create_static_effect(Npc *npc)
void force_player_anim(AnimID)