4#include "sprite/npc/WorldLakilester.h"
5#include "sprite/player.h"
7#define NAMESPACE world_lakilester
9BSS s32 N(PutAwayState);
10BSS b32 N(LockingPlayerInput);
11BSS b32 N(PlayerCollisionDisabled);
13BSS b32 N(UpdatePushingWall);
14BSS s32 N(AbilityState);
15BSS s32 N(PlayerBounceOffset);
16BSS s32 N(MoveSoundsTime);
17BSS s32 N(MovePitchAdjustment);
18BSS s32 N(MountingDeltaY);
19BSS f32 N(CurrentGroundPitch);
71 playerStatus->
pos.
x = lakilester->
pos.
x;
72 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f + abs(N(PlayerBounceOffset)) * 0.34f;
73 playerStatus->
pos.
z = lakilester->
pos.
z;
78 lakilester->collisionHeight = 38;
79 lakilester->collisionDiameter = 36;
81 N(PlayerBounceOffset) = 0;
82 N(LockingPlayerInput) = FALSE;
83 N(PlayerCollisionDisabled) = FALSE;
85 N(UpdatePushingWall) = TRUE;
86 N(MoveSoundsTime) = 0;
87 N(MovePitchAdjustment) = 0;
88 N(MountingDeltaY) = 0;
89 N(CurrentGroundPitch) = 0;
90 lakilester->moveToPos.x = lakilester->pos.x;
91 lakilester->moveToPos.y = lakilester->pos.y;
92 lakilester->moveToPos.z = lakilester->pos.z;
95API_CALLABLE(N(TakeOut)) {
96 Npc* lakilester = script->owner2.npc;
118API_CALLABLE(N(Update)) {
120 Npc* lakilester = script->owner2.npc;
121 f32 sinAngle, cosAngle, liftoffVelocity;
134 if (entity == NULL) {
140 switch (N(TweesterPhysicsPtr)->state) {
142 N(TweesterPhysicsPtr)->state++;
143 N(TweesterPhysicsPtr)->prevFlags = lakilester->
flags;
145 N(TweesterPhysicsPtr)->angle =
atan2(entity->
pos.
x, entity->
pos.
z, lakilester->
pos.
x, lakilester->
pos.
z);
146 N(TweesterPhysicsPtr)->angularVel = 6.0f;
147 N(TweesterPhysicsPtr)->liftoffVelPhase = 50.0f;
148 N(TweesterPhysicsPtr)->countdown = 120;
150 lakilester->
flags &= ~NPC_FLAG_GRAVITY;
153 lakilester->
pos.
x = entity->
pos.
x + (sinAngle * N(TweesterPhysicsPtr)->radius);
154 lakilester->
pos.
z = entity->
pos.
z - (cosAngle * N(TweesterPhysicsPtr)->radius);
155 N(TweesterPhysicsPtr)->angle =
clamp_angle(N(TweesterPhysicsPtr)->angle - N(TweesterPhysicsPtr)->angularVel);
157 if (N(TweesterPhysicsPtr)->radius > 20.0f) {
158 N(TweesterPhysicsPtr)->radius--;
159 }
else if (N(TweesterPhysicsPtr)->radius < 19.0f) {
160 N(TweesterPhysicsPtr)->radius++;
163 liftoffVelocity =
sin_rad(
DEG_TO_RAD(N(TweesterPhysicsPtr)->liftoffVelPhase)) * 3.0f;
164 N(TweesterPhysicsPtr)->liftoffVelPhase += 3.0f;
166 if (N(TweesterPhysicsPtr)->liftoffVelPhase > 150.0f) {
167 N(TweesterPhysicsPtr)->liftoffVelPhase = 150.0f;
170 lakilester->
pos.
y += liftoffVelocity;
172 N(TweesterPhysicsPtr)->angularVel += 0.8;
174 if (N(TweesterPhysicsPtr)->angularVel > 40.0f) {
175 N(TweesterPhysicsPtr)->angularVel = 40.0f;
178 if (--N(TweesterPhysicsPtr)->countdown == 0) {
179 N(TweesterPhysicsPtr)->state++;
183 lakilester->
flags = N(TweesterPhysicsPtr)->prevFlags;
184 N(TweesterPhysicsPtr)->countdown = 30;
185 N(TweesterPhysicsPtr)->state++;
191 if (--N(TweesterPhysicsPtr)->countdown == 0) {
209 lakilester->
flags = N(TweesterPhysicsPtr)->prevFlags;
217 f32 stickX = partnerStatus->
stickX;
218 f32 stickY = partnerStatus->
stickY;
220 f32 moveSpeed = 0.0f;
222 if (
dist2D(0.0f, 0.0f, stickX, -stickY) >= 1.0) {
224 if (
SQ(stickX) +
SQ(stickY) >
SQ(55)) {
229 *outAngle = moveAngle;
230 *outSpeed = moveSpeed;
236 f32 hitDirX, hitDirZ;
238 f32 outX, outY, outZ, outLength;
246 playerStatus->
animFlags &= ~PA_FLAG_DISMOUNTING_ALLOWED;
253 outX = playerStatus->
pos.
x;
254 outZ = playerStatus->
pos.
z;
288 f32 hitDirX, hitDirZ;
291 N(MountingDeltaY) = 0;
296 deltaY = y - lakilester->moveToPos.y;
297 if (deltaY != 0.0f) {
298 if (
fabs(deltaY) < 10.0) {
299 N(MountingDeltaY) = deltaY;
300 lakilester->moveToPos.y = y;
313 f32 radius = lakilester->collisionDiameter * 0.8f;
317 #define TEST_MOVE_AT_ANGLE(testFunc, angle) \
319 yaw = clamp_angle(angle), \
320 x = lakilester->pos.x, \
321 y = lakilester->moveToPos.y, \
322 z = lakilester->pos.z, \
323 testFunc(lakilester->collisionChannel, &x, &y, &z, 0.0f, yaw, lakilester->collisionHeight, radius) \
329 lakilester->pos.x = x;
330 lakilester->pos.z = z;
336 lakilester->pos.x = x;
337 lakilester->pos.z = z;
340 lakilester->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
344 lakilester->pos.x = x;
345 lakilester->pos.z = z;
348 lakilester->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
353 lakilester->pos.x = x;
354 lakilester->pos.z = z;
356 lakilester->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
361 lakilester->pos.x = x;
362 lakilester->pos.z = z;
364 lakilester->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
372 f32 hitDepth, sp40, sp44, sp48, sp4C, sinAngle, cosAngle;
373 f32 moveAngle, moveSpeed;
376 s32 raycastBelowResult;
377 s32 currentSurfaceType;
378 s32 belowSurfaceType;
391 if (N(CurrentGroundPitch) >= 20.0f) {
395 lakilester->moveSpeed = moveSpeed;
397 if (moveSpeed != 0.0f) {
399 N(MovePitchAdjustment)++;
400 if (N(MoveSoundsTime) % 8 == 0) {
401 if (N(MovePitchAdjustment) >= 120) {
402 N(MovePitchAdjustment) = 0;
405 if (N(MovePitchAdjustment) < 60) {
415 x = lakilester->pos.x;
416 y = lakilester->moveToPos.y;
417 z = lakilester->pos.z;
420 lakilester->collisionDiameter, lakilester->yaw, lakilester->collisionHeight, lakilester->collisionDiameter))
425 if (moveSpeed != 0.0f) {
426 lakilester->yaw = moveAngle;
427 x = lakilester->pos.x;
428 y = lakilester->moveToPos.y;
429 z = lakilester->pos.z;
431 lakilester->moveSpeed, lakilester->yaw, lakilester->collisionHeight, lakilester->collisionDiameter))
433 if (N(UpdatePushingWall)) {
436 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
437 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
440 if (N(UpdatePushingWall)) {
446 x = lakilester->pos.x;
447 y = lakilester->moveToPos.y;
448 z = lakilester->pos.z;
450 lakilester->moveSpeed, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
452 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
453 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
457 x = lakilester->pos.x;
458 y = lakilester->moveToPos.y;
459 z = lakilester->pos.z;
461 lakilester->moveSpeed, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
463 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
464 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
471 x = lakilester->pos.x;
472 y = lakilester->moveToPos.y;
473 z = lakilester->pos.z;
475 4.0f, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
477 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
478 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
482 x = lakilester->pos.x;
483 y = lakilester->moveToPos.y;
484 z = lakilester->pos.z;
486 4.0f, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
488 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
489 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
494 lakilester->moveToPos.y -= lakilester->jumpScale;
495 hitDepth = lakilester->collisionHeight + 2;
496 y = lakilester->moveToPos.y + 12.0f;
497 x = playerStatus->
pos.
x;
498 z = playerStatus->
pos.
z;
501 &sp44, &sp48, &sp4C);
505 if (N(CurrentGroundPitch) != 0.0f) {
509 if (N(CurrentGroundPitch) > 0.0f && raycastBelowResult >= 0) {
511 lakilester->pos.y = (lakilester->pos.y +
fabs((sinAngle / cosAngle) * playerStatus->
runSpeed));
514 if (hitDepth <= height && raycastBelowResult >
NO_COLLIDER) {
518 collisionStatus->
curFloor = raycastBelowResult;
520 lakilester->curFloor = raycastBelowResult;
521 lakilester->moveToPos.y = y;
522 lakilester->moveToPos.x = x;
523 lakilester->moveToPos.z = z;
524 lakilester->jumpScale = 0.0f;
529 lakilester->curAnim = ANIM_WorldLakilester_StrainWalk;
530 lakilester->moveSpeed = moveSpeed * 0.5f;
532 lakilester->curAnim = ANIM_WorldLakilester_Walk;
533 lakilester->moveSpeed = moveSpeed;
541 lakilester->jumpScale += 1.8;
543 if (lakilester->jumpScale > 12.0f) {
544 lakilester->jumpScale = 12.0f;
555 f32 hitDirX, hitDirZ;
558 N(MountingDeltaY) = 0;
561 lakilester->yaw, lakilester->collisionDiameter))
563 deltaY = y - lakilester->moveToPos.y;
564 if (deltaY != 0.0f) {
565 if (
fabs(deltaY) < 10.0) {
566 N(MountingDeltaY) = deltaY;
567 lakilester->moveToPos.y = y;
581 f32 hitDirX, hitDirZ;
590 &colliderHeight, &hitRx, &hitRz, &hitDirX, &hitDirZ);
593API_CALLABLE(N(UseAbility)) {
597 Npc* lakilester = script->owner2.npc;
602 playerStatus->
animFlags &= ~PA_FLAG_RIDING_PARTNER;
607 lakilester->
flags = lakilester->
flags & ~PA_FLAG_PULSE_STONE_VISIBLE;
616 playerStatus->
animFlags &= ~PA_FLAG_PARTNER_USAGE_FORCED;
638 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
643 lakilester->
curAnim = ANIM_WorldLakilester_Walk;
650 lakilester->
pos.
x = playerStatus->
pos.
x;
652 lakilester->
pos.
z = playerStatus->
pos.
z;
653 lakilester->
curAnim = ANIM_WorldLakilester_Walk;
654 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f;
661 N(PlayerCollisionDisabled) = TRUE;
663 if (!N(LockingPlayerInput)) {
665 N(LockingPlayerInput) = TRUE;
668 N(PlayerBounceOffset) = 0;
677 switch (N(AbilityState)) {
684 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
687 script->functionTemp[1] = 3;
689 N(LockingPlayerInput) = TRUE;
695 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
696 if (N(LockingPlayerInput)) {
698 N(LockingPlayerInput) = FALSE;
707 N(LockingPlayerInput) = FALSE;
709 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
713 if (script->functionTemp[1] == 0) {
716 N(LockingPlayerInput) = FALSE;
717 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
723 script->functionTemp[1]--;
727 switch (N(AbilityState)) {
730 N(PlayerCollisionDisabled) = TRUE;
732 if (!N(LockingPlayerInput)) {
734 N(LockingPlayerInput) = TRUE;
737 lakilester->
flags &= ~NPC_FLAG_FLYING;
747 for (i = 0; i < 4; i++) {
761 lakilester->
curAnim = ANIM_WorldLakilester_Walk;
783 playerStatus->
pos.
y += N(MountingDeltaY);
784 lakilester->
pos.
y += N(MountingDeltaY);
787 if (lakilester->
jumpVel <= 0.0f) {
799 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f;
809 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
811 N(PlayerBounceOffset) = 0;
854 N(PlayerBounceOffset)++;
855 if (N(PlayerBounceOffset) >= 10) {
856 N(PlayerBounceOffset) -= 18;
873 playerStatus->
animFlags &= ~PA_FLAG_FORCED_PARTNER_ABILITY_END;
878 lakilester->
flags &= ~NPC_FLAG_IGNORE_WORLD_COLLISION;
883 yaw = (180.0f + camYaw) - 90.0f;
885 yaw = (0.0f + camYaw) - 90.0f;
887 lakilester->
yaw = yaw;
914 x = playerStatus->
pos.
x;
916 z = playerStatus->
pos.
z;
931 playerStatus->
pos.
y = y;
944 if (N(PlayerCollisionDisabled)) {
945 N(PlayerCollisionDisabled) = FALSE;
956 if (N(LockingPlayerInput)) {
957 N(LockingPlayerInput) = FALSE;
963 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
977 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
978 if (N(LockingPlayerInput)) {
979 N(LockingPlayerInput) = FALSE;
998API_CALLABLE(N(PutAway)) {
1002 Npc* lakilester = script->owner2.npc;
1003 f32 sp20, sp24, sp28, sp2C;
1006 if (isInitialCall) {
1010 playerStatus->
animFlags &= ~PA_FLAG_RIDING_PARTNER;
1014 switch (N(PutAwayState)) {
1019 lakilester->
yaw = (yaw + 180.0f) - 90.0f;
1021 lakilester->
yaw = (yaw + 0.0f) - 90.0f;
1049 if (lakilester->
jumpVel <= 0.0f) {
1051 if (lakilester->
jumpVel < -10.0) {
1055 sp20 = playerStatus->
pos.
x;
1057 sp28 = playerStatus->
pos.
z;
1063 playerStatus->
pos.
y = sp24;
1072 switch (N(PutAwayState)) {
1076 if (N(PlayerCollisionDisabled)) {
1077 N(PlayerCollisionDisabled) = FALSE;
1086 if (N(LockingPlayerInput)) {
1087 N(LockingPlayerInput) = FALSE;
1110 playerStatus->
flags &= ~PS_FLAG_PAUSE_DISABLED;
1112 if (N(LockingPlayerInput)) {
1113 N(LockingPlayerInput) = FALSE;
1140 partnerStatus->
npc = *lakilester;
1149 N(PlayerBounceOffset) = 0;
1157 *lakilester = partnerStatus->
npc;
1175API_CALLABLE(N(EnterMap)) {
1179 f32 temp_f0, temp_f2, temp_f4;
1183 if (isInitialCall) {
1184 script->functionTemp[0] = 0;
1187 switch (script->functionTemp[0]) {
1189 if (!script->varTable[12]) {
1190 temp_f0 = playerStatus->
pos.
x;
1191 lakilester->
pos.
x = temp_f0;
1193 temp_f4 = playerStatus->
pos.
z;
1194 lakilester->
pos.
z = temp_f4;
1196 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f;
1205 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f;
1208 script->functionTemp[1] = script->varTable[4];
1209 temp_s0_2 = (f32*)&script->varTable[5];
1210 temp_f2 =
atan2(lakilester->
pos.
x, lakilester->
pos.
z, script->varTable[1], script->varTable[3]);
1211 lakilester->
yaw = temp_f2;
1213 if (script->varTable[12]) {
1214 if (temp_f2 >= 0.0f && temp_f2 <= 180.0f) {
1221 playerStatus->
anim = ANIM_MarioW2_RideLaki;
1229 N(UpdatePushingWall) = FALSE;
1230 N(PlayerBounceOffset) = 0;
1231 script->functionTemp[0] = 1;
1236 playerStatus->
pos.
x = lakilester->
pos.
x;
1237 playerStatus->
pos.
y = lakilester->
pos.
y + 10.0f;
1238 playerStatus->
pos.
z = lakilester->
pos.
z;
1241 script->functionTemp[1] -= 1;
1243 if (script->functionTemp[1] == 0) {
1244 if (script->varTable[12]) {
s32 partner_use_ability(void)
b8 keepUsingPartnerOnMapChange
@ TWEESTER_PARTNER_ATTRACT
@ TWEESTER_PARTNER_RELEASE
@ PS_FLAG_ENTERING_BATTLE
@ PS_FLAG_CUTSCENE_MOVEMENT
@ PARTNER_ACTION_LAKILESTER_1
@ COLLIDER_FLAG_IGNORE_PLAYER
@ COLLIDER_FLAGS_SURFACE_TYPE_MASK
@ ENTITY_TYPE_SCRIPT_SPRING
@ ENTITY_TYPE_SIMPLE_SPRING
@ PA_FLAG_DISMOUNTING_ALLOWED
@ PA_FLAG_PARTNER_USAGE_FORCED
@ PA_FLAG_FORCED_PARTNER_ABILITY_END
@ SOUND_QUICK_PLAYER_JUMP
@ ACTION_STATE_HIT_FIRE
Causes Mario to fly up and take damage. Used for fire bars.
@ CAMERA_MOVE_IGNORE_PLAYER_Y
@ NPC_FLAG_TOUCHES_GROUND
@ NPC_FLAG_IGNORE_WORLD_COLLISION
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
@ NPC_FLAG_IGNORE_CAMERA_FOR_YAW
@ NPC_FLAG_COLLDING_WITH_WORLD
f32 update_lerp(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration)
b32 npc_raycast_down_around(s32, f32 *, f32 *, f32 *, f32 *, f32, f32)
HitID player_raycast_below_cam_relative(PlayerStatus *playerStatus, f32 *outX, f32 *outY, f32 *outZ, f32 *outLength, f32 *hitRx, f32 *hitRz, f32 *hitDirX, f32 *hitDirZ)
s32 npc_test_move_complex_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void suggest_player_anim_always_forward(AnimID anim)
void partner_clear_player_tracking(Npc *partner)
void partner_flying_update_player_tracking(Npc *partner)
s32 disable_player_input(void)
s32 get_collider_flags(s32 colliderID)
s32 disable_player_static_collisions(void)
s32 enable_player_input(void)
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
void partner_kill_ability_script(void)
void phys_main_collision_below(void)
void gravity_use_fall_parms(void)
u32 get_entity_type(s32 arg0)
void enable_player_shadow(void)
b32 npc_test_move_simple_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void set_action_state(s32 actionState)
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
HitID player_raycast_up_corners(PlayerStatus *, f32 *, f32 *, f32 *, f32 *, f32)
void suggest_player_anim_allow_backward(AnimID anim)
void partner_flying_update_motion(Npc *partner)
void partner_flying_enable(Npc *partner, s32 val)
f32 get_player_normal_pitch(void)
s32 enable_player_static_collisions(void)
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
void func_800E4AD8(s32 arg0)
void disable_player_shadow(void)
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Npc * get_npc_unsafe(s32 npcID)
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
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)
void sfx_play_sound_at_npc(s32 soundID, s32 arg1, s32 npcID)
void sfx_play_sound_with_params(s32 soundID, u8 volume, u8 pan, s16 pitchShift)
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
#define COLLISION_WITH_ENTITY_BIT
#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
CollisionStatus gCollisionStatus
PartnerStatus gPartnerStatus
GameStatus * gGameStatusPtr
s32 NpcHitQueryColliderID
PlayerStatus gPlayerStatus
s32 N test_dismount_height(f32 *posY)
void N try_cancel_tweester(Npc *lakilester)
EvtScript EVS_WorldLakilester_PutAway
@ RIDE_STATE_START_RIDING
void N pre_battle(Npc *lakilester)
#define TEST_MOVE_AT_ANGLE(testFunc, angle)
void N post_battle(Npc *lakilester)
EvtScript EVS_WorldLakilester_TakeOut
EvtScript EVS_WorldLakilester_UseAbility
s32 N test_mounting_height_adjustment(Npc *lakilester, f32 height, f32 dist)
void N sync_player_position(void)
void N get_movement_from_input(f32 *outAngle, f32 *outSpeed)
@ MOUNT_STATE_IN_PROGRESS
void N update_riding_physics(Npc *lakilester)
void N apply_riding_static_collisions(Npc *lakilester)
void N offset_player_from_camera(f32 arg0)
EvtScript EVS_WorldLakilester_Update
void N init(Npc *lakilester)
EvtScript EVS_WorldLakilester_EnterMap