papermario/src/evt/npc_api.c

1092 lines
31 KiB
C

#include "common.h"
#include "map.h"
#include "npc.h"
extern s32 D_802DAE40;
extern s32 D_802DAE44;
Npc* resolve_npc(Evt* script, NpcID npcIdOrPtr) {
if (npcIdOrPtr == NPC_SELF) {
return get_npc_safe(script->owner2.npcID);
} else if (npcIdOrPtr >= -270000000) {
return get_npc_safe(npcIdOrPtr);
} else {
return (Npc*) npcIdOrPtr;
}
}
void set_npc_animation(Npc* npc, u32 arg1) {
PlayerData* playerData = &gPlayerData;
if (arg1 - 0x101 < 9) {
npc->currentAnim.w = gPartnerAnimations[playerData->currentPartner].anims[arg1 - 0x101];
} else if ((arg1 - 0x201) < 0x10) {
npc->currentAnim.w = get_enemy(npc->npcID)->animList[arg1 - 0x201];
} else {
npc->currentAnim.w = arg1;
}
}
ApiStatus CreateNpc(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
s32 initialAnim = get_variable(script, *args++);
NpcBlueprint blueprint;
Npc *npc;
blueprint.flags = 0;
blueprint.initialAnim = initialAnim;
blueprint.onUpdate = NULL;
blueprint.onRender = NULL;
npc = get_npc_by_index(_create_npc_basic(&blueprint));
npc->npcID = npcID;
disable_npc_shadow(npc);
return ApiStatus_DONE2;
}
ApiStatus DeleteNpc(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
Npc* npc = get_npc_unsafe(get_variable(script, *args++));
if (npc == NULL) {
return ApiStatus_DONE2;
}
free_npc(npc);
return ApiStatus_DONE2;
}
ApiStatus GetNpcPointer(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
Bytecode varNPC = *args++;
set_variable(script, varNPC, (s32)get_npc_safe(npcID));
return ApiStatus_DONE2;
}
ApiStatus SetNpcPos(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
f32 x = get_variable(script, *args++);
f32 y = get_variable(script, *args++);
f32 z = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->pos.x = x;
npc->pos.y = y;
npc->pos.z = z;
npc->colliderPos.x = npc->pos.x;
npc->colliderPos.y = npc->pos.y;
npc->colliderPos.z = npc->pos.z;
npc->flags |= 0x10000;
return ApiStatus_DONE2;
}
ApiStatus SetNpcRotation(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
f32 rotX = get_float_variable(script, *args++);
f32 rotY = get_float_variable(script, *args++);
f32 rotZ = get_float_variable(script, *args++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->rotation.x = rotX;
npc->rotation.y = rotY;
npc->rotation.z = rotZ;
return ApiStatus_DONE2;
}
ApiStatus func_802CDE68(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
f32 var1 = get_float_variable(script, *args++);
Npc* npc;
npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->rotationVerticalPivotOffset = var1;
return ApiStatus_DONE2;
}
ApiStatus SetNpcScale(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
f32 sizeX = get_float_variable(script, *ptrReadPos++);
f32 sizeY = get_float_variable(script, *ptrReadPos++);
f32 sizeZ = get_float_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->scale.x = sizeX;
npc->scale.y = sizeY;
npc->scale.z = sizeZ;
return ApiStatus_DONE2;
}
ApiStatus SetNpcCollisionSize(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
s32 height = get_variable(script, *ptrReadPos++);
s32 radius = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->collisionHeight = height;
npc->collisionRadius = radius;
return ApiStatus_DONE2;
}
ApiStatus SetNpcSpeed(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
f32 speed = get_float_variable(script, *ptrReadPos);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->moveSpeed = speed;
return ApiStatus_DONE2;
}
ApiStatus SetNpcJumpscale(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
f32 jumpScale = get_float_variable(script, *ptrReadPos);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->jumpScale = jumpScale;
return ApiStatus_DONE2;
}
ApiStatus SetNpcAnimation(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
s32 animation = get_variable(script, *ptrReadPos);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_npc_animation(npc, animation);
return ApiStatus_DONE2;
}
ApiStatus GetNpcAnimation(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
Bytecode outVar = *ptrReadPos++;
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_variable(script, outVar, npc->currentAnim.w);
return ApiStatus_DONE2;
}
ApiStatus SetNpcAnimationSpeed(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
f32 animationSpeed = get_float_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->animationSpeed = animationSpeed;
return ApiStatus_DONE2;
}
ApiStatus NpcMoveTo(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
Npc* npc;
f32 dist;
f32 moveSpeed;
if (isInitialCall) {
script->functionTemp[0] = 0;
}
if (script->functionTemp[0] == 0) {
NpcID npcID = get_variable(script, *args++);
f32 targetX = get_variable(script, *args++);
f32 targetZ = get_variable(script, *args++);
s32 duration = get_variable(script, *args++);
npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
script->functionTemp[1] = (s32)npc;
npc->moveToPos.x = targetX;
npc->moveToPos.z = targetZ;
npc->duration = duration;
dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
if (npc->duration == 0) {
npc->duration = dist / npc->moveSpeed;
} else {
npc->moveSpeed = dist / npc->duration;
}
if (npc->duration == 0) {
npc->duration = 1;
}
script->functionTemp[0] = 1;
}
npc = (Npc*)script->functionTemp[1];
npc->yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
npc_move_heading(npc, npc->moveSpeed, npc->yaw);
if (npc->moveSpeed < 4.0) {
func_8003D660(npc, 0);
} else {
func_8003D660(npc, 1);
}
dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
moveSpeed = npc->moveSpeed;
if (moveSpeed < 1.0) {
moveSpeed = 1.0f;
}
if (dist <= moveSpeed) {
return ApiStatus_DONE1;
}
return ApiStatus_BLOCK;
}
ApiStatus _npc_jump_to(Evt* script, s32 isInitialCall, s32 snapYaw) {
Bytecode* args = script->ptrReadPos;
f32* yaw = (f32*) &script->functionTemp[2];
Npc* npc;
if (isInitialCall) {
script->functionTemp[0] = 0;
}
if (script->functionTemp[0] == 0) {
NpcID npcID = get_variable(script, *args++);
f32 xTemp = get_variable(script, *args++);
f32 yTemp = get_variable(script, *args++);
f32 zTemp = get_variable(script, *args++);
s32 duration = get_variable(script, *args++);
f32 dist;
npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
script->functionTemp[1] = (s32)npc;
npc->moveToPos.x = xTemp;
npc->moveToPos.y = yTemp;
npc->moveToPos.z = zTemp;
npc->duration = duration;
dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
*yaw = 0.0f;
if (dist > 2.0) {
*yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
if (snapYaw == 0) {
npc->yaw = *yaw;
}
}
yTemp = npc->moveToPos.y - npc->pos.y;
if (npc->duration == 0) {
npc->duration = dist / npc->moveSpeed;
} else {
npc->moveSpeed = dist / npc->duration;
}
npc->flags |= 0x800;
npc->jumpVelocity = (npc->jumpScale * npc->duration * 0.5f) + (yTemp / npc->duration);
script->functionTemp[0] =1;
}
npc = (Npc*)script->functionTemp[1];
npc_move_heading(npc, npc->moveSpeed, *yaw);
npc->pos.y += npc->jumpVelocity;
npc->jumpVelocity -= npc->jumpScale;
npc->duration--;
if (npc->duration < 0) {
npc->jumpVelocity = 0.0f;
npc->pos.x = npc->moveToPos.x;
npc->pos.y = npc->moveToPos.y;
npc->pos.z = npc->moveToPos.z;
npc->flags &= ~0x800;
func_8003D660(npc, 2);
return ApiStatus_DONE1;
}
return ApiStatus_BLOCK;
}
ApiStatus NpcJump0(Evt* script, s32 isInitialCall) {
return _npc_jump_to(script, isInitialCall, 0);
}
ApiStatus NpcJump1(Evt* script, s32 isInitialCall) {
return _npc_jump_to(script, isInitialCall, 1);
}
ApiStatus NpcFlyTo(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
f32* outX = (f32*)&script->varTable[3];
f32* outY = (f32*)&script->varTable[4];
f32* outZ = (f32*)&script->varTable[5];
Npc* npc;
f32 dist;
f32 yDelta;
if (isInitialCall) {
npc = resolve_npc(script, get_variable(script, *args++));
if (npc == NULL) {
return ApiStatus_DONE2;
}
script->functionTemp[1] = (s32)npc;
npc->moveToPos.x = get_float_variable(script, *args++);
npc->moveToPos.y = get_float_variable(script, *args++);
npc->moveToPos.z = get_float_variable(script, *args++);
script->varTable[6] = get_variable(script, *args++);
script->functionTemp[2] = get_variable(script, *args++);
script->functionTemp[3] = get_variable(script, *args++);
npc->duration = 0;
*outX = npc->pos.x;
*outY = npc->pos.y;
*outZ = npc->pos.z;
npc->yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
npc->planarFlyDist = dist;
if (script->varTable[6] == 0) {
script->varTable[6] = (dist / npc->moveSpeed);
} else {
npc->moveSpeed = dist / script->varTable[6];
}
}
npc = (Npc*)script->functionTemp[1];
npc->pos.x = update_lerp(script->functionTemp[3], *outX, npc->moveToPos.x, npc->duration, script->varTable[6]);
npc->pos.y = update_lerp(script->functionTemp[3], *outY, npc->moveToPos.y, npc->duration, script->varTable[6]);
npc->pos.z = update_lerp(script->functionTemp[3], *outZ, npc->moveToPos.z, npc->duration, script->varTable[6]);
npc->duration++;
if (npc->duration >= script->varTable[6]) {
npc->pos.x = npc->moveToPos.x;
npc->pos.y = npc->moveToPos.y;
npc->pos.z = npc->moveToPos.z;
return ApiStatus_DONE2;
}
dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
if (dist == 0.0f) {
dist = 1.0f;
}
if (npc->planarFlyDist == 0.0f) {
npc->planarFlyDist = 1.0f;
}
yDelta = sin_deg((1.0 - (dist / npc->planarFlyDist)) * 180.0);
if (script->functionTemp[2] == 0) {
yDelta = 0.0f;
}
if (script->functionTemp[2] < 0) {
yDelta = -yDelta * -script->functionTemp[2];
}
if (script->functionTemp[2] > 0) {
yDelta *= script->functionTemp[2];
}
npc->pos.y += yDelta;
return ApiStatus_BLOCK;
}
ApiStatus GetNpcYaw(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
Bytecode outVar = *ptrReadPos++;
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_variable(script, outVar, clamp_angle(npc->yaw));
return ApiStatus_DONE2;
}
ApiStatus SetNpcYaw(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_npc_yaw(npc, get_variable(script, *ptrReadPos++));
return ApiStatus_DONE2;
}
ApiStatus InterpNpcYaw(Evt* script, s32 isInitialCall) {
PlayerStatus* playerStatus = &gPlayerStatus;
Bytecode* args = script->ptrReadPos;
f32* t1 = (f32*) &script->functionTemp[1];
f32* t2 = (f32*) &script->functionTemp[2];
s32* t3 = &script->functionTemp[3];
Npc* npc;
if (isInitialCall) {
NpcID npcID = get_variable(script, *args++);
npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
*t1 = npc->yaw;
*t2 = get_variable(script, *args++) - *t1;
script->functionTemp[0] = (s32)npc;
*t3 = get_variable(script, *args++);
if (*t3 == 0) {
npc->yaw += *t2;
return ApiStatus_DONE2;
}
npc->duration = 0;
if (*t2 < -180.0f) {
*t2 += 360.0f;
}
if (*t2 > 180.0f) {
*t2 -= 360.0f;
}
}
npc = (Npc*)script->functionTemp[0];
if (*t3 > 0) {
npc->duration++;
npc->yaw = *t1 + ((*t2 * npc->duration) / *t3);
npc->yaw = clamp_angle(npc->yaw);
return !(npc->duration < *t3) * ApiStatus_DONE1;
}
npc->yaw += *t2;
return ApiStatus_DONE2;
}
ApiStatus NpcFacePlayer(Evt* script, s32 isInitialCall) {
PlayerStatus* playerStatus = &gPlayerStatus;
Bytecode* args = script->ptrReadPos;
f32* t1 = (f32*) &script->functionTemp[1];
f32* t2 = (f32*) &script->functionTemp[2];
s32* t3 = &script->functionTemp[3];
Npc* npc;
if (isInitialCall) {
NpcID npcID = get_variable(script, *args++);
npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
*t1 = npc->yaw;
*t2 = atan2(npc->pos.x, npc->pos.z, playerStatus->position.x, playerStatus->position.z) - *t1;
script->functionTemp[0] = (s32)npc;
*t3 = get_variable(script, *args++);
npc->duration = 0;
if (*t2 < -180.0f) {
*t2 += 360.0f;
}
if (*t2 > 180.0f) {
*t2 -= 360.0f;
}
}
npc = (Npc*)script->functionTemp[0];
if (*t3 > 0) {
npc->duration++;
npc->yaw = *t1 + ((*t2 * npc->duration) / *t3);
npc->yaw = clamp_angle(npc->yaw);
return !(npc->duration < *t3) * ApiStatus_DONE1;
}
npc->yaw += *t2;
return ApiStatus_DONE2;
}
ApiStatus NpcFaceNpc(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
f32* t1 = (f32*) &script->functionTemp[1];
f32* t2 = (f32*) &script->functionTemp[2];
s32* t3 = &script->functionTemp[3];
Npc* npc;
Npc* npc2;
if (isInitialCall) {
NpcID npcID = get_variable(script, *args++);
NpcID npcID2 = get_variable(script, *args++);
npc = resolve_npc(script, npcID2);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc2 = resolve_npc(script, npcID);
if (npc2 == NULL) {
return ApiStatus_DONE2;
}
*t1 = npc2->yaw;
*t2 = atan2(npc2->pos.x, npc2->pos.z, npc->pos.x, npc->pos.z) - *t1;
script->functionTemp[0] = (s32)npc2;
*t3 = get_variable(script, *args++);
npc2->duration = 0;
if (*t2 < -180.0f) {
*t2 += 360.0f;
}
if (*t2 > 180.0f) {
*t2 -= 360.0f;
}
}
npc2 = (Npc*)script->functionTemp[0];
if (*t3 > 0) {
npc2->duration++;
npc2->yaw = *t1 + ((*t2 * npc2->duration) / *t3);
npc2->yaw = clamp_angle(npc2->yaw);
return !(npc2->duration < *t3) * ApiStatus_DONE1;
}
npc2->yaw += *t2;
return ApiStatus_DONE2;
}
ApiStatus SetNpcFlagBits(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
s32 flagBits = *args++;
s32 enable = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
if (enable) {
npc->flags |= flagBits;
} else {
npc->flags &= ~flagBits;
}
return ApiStatus_DONE2;
}
ApiStatus GetNpcPos(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcID = get_variable(script, *args++);
s32 a1 = *args++;
s32 a2 = *args++;
s32 a3 = *args++;
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_variable(script, a1, npc->pos.x);
set_variable(script, a2, npc->pos.y);
set_variable(script, a3, npc->pos.z);
return ApiStatus_DONE2;
}
ApiStatus func_802CF1B4(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode arg1 = *args;
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->unk_80 = arg1;
return ApiStatus_DONE2;
}
ApiStatus SetNpcSprite(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode arg1 = *args;
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_npc_sprite(npc, arg1, NULL);
return ApiStatus_DONE2;
}
ApiStatus EnableNpcShadow(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
s32 enableShadow = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
if (enableShadow) {
enable_npc_shadow(npc);
} else {
disable_npc_shadow(npc);
}
return ApiStatus_DONE2;
}
ApiStatus EnableNpcBlur(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
s32 enableBlur = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
if (enableBlur) {
enable_npc_blur(npc);
} else {
disable_npc_blur(npc);
}
return ApiStatus_DONE2;
}
ApiStatus ClearPartnerMoveHistory(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
partner_clear_player_tracking(npc);
return ApiStatus_DONE2;
}
ApiStatus NpcSetHomePosToCurrent(Evt* script, s32 isInitialCall) {
Npc* npc = resolve_npc(script, get_variable(script, *script->ptrReadPos));
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->homePos.x = npc->pos.x;
npc->homePos.y = npc->pos.y;
npc->homePos.z = npc->pos.z;
return ApiStatus_DONE2;
}
ApiStatus GetPartnerPos(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
Bytecode posX = *ptrReadPos++;
Bytecode posY = *ptrReadPos++;
Bytecode posZ = *ptrReadPos++;
Npc* npc = get_npc_unsafe(-4);
if (npc == NULL) {
return ApiStatus_DONE2;
}
set_variable(script, posX, npc->pos.x);
set_variable(script, posY, npc->pos.y);
set_variable(script, posZ, npc->pos.z);
return ApiStatus_DONE2;
}
ApiStatus DisablePartnerAI(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
if (get_variable(script, *ptrReadPos++) == 0) {
func_800EF314();
} else {
func_800EF300();
}
return ApiStatus_DONE2;
}
ApiStatus EnablePartnerAI(Evt* script, s32 isInitialCall) {
enable_partner_ai();
return ApiStatus_DONE2;
}
ApiStatus func_802CF54C(Evt* script, s32 isInitialCall) {
func_800EF43C();
return ApiStatus_DONE2;
}
ApiStatus func_802CF56C(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
s32 value = get_variable(script, *ptrReadPos++);
if (value == 2) {
func_800EF3E4();
} else {
func_800EF3D4(value);
}
return ApiStatus_DONE2;
}
s32 BringPartnerOut(Evt *script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcBlueprint bp;
NpcBlueprint* bpPointer = &bp;
PlayerData* playerData = &gPlayerData;
PlayerStatus* playerStatus = &gPlayerStatus;
Npc* partner;
Npc* npc;
f32 duration;
f32 playerZ;
f32 targetZ;
f32 playerX;
f32 targetX;
f32 targetY;
f32 playerY;
if (isInitialCall) {
D_802DAE40 = get_variable(script, *args++);
if (playerData->currentPartner == D_802DAE40) {
D_802DAE40 = 0;
return ApiStatus_DONE2;
}
partner = get_npc_unsafe(NPC_PARTNER);
partner->npcID = -5;
bpPointer->flags = NPC_FLAG_100;
bpPointer->initialAnim = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_FLY];
bpPointer->onUpdate = NULL;
bpPointer->onRender = NULL;
D_802DAE44 = _create_npc_basic(bpPointer);
npc = get_npc_by_index(D_802DAE44);
npc->collisionRadius = 10;
npc->collisionHeight = 10;
npc->npcID = NPC_PARTNER;
npc->scale.x = 0.0f;
npc->scale.y = 0.0f;
npc->scale.z = 0.0f;
npc->moveToPos.x = targetX = partner->pos.x;
playerY = playerStatus->position.y;
npc->moveToPos.y = playerStatus->position.y;
npc->moveToPos.z = targetZ = partner->pos.z + 30.0f;
npc->pos.x = playerX = playerStatus->position.x;
npc->pos.y = targetY = playerStatus->position.y + (playerStatus->colliderHeight / 2);
playerZ = playerStatus->position.z;
npc->moveSpeed = 4.0f;
npc->jumpScale = 1.6f;
npc->pos.z = playerZ;
npc->planarFlyDist = dist2D(playerX, npc->pos.z, targetX, targetZ);
npc->yaw = atan2(playerX, playerZ, targetX, targetZ);
npc->duration = npc->planarFlyDist / npc->moveSpeed;
if (npc->duration < 10) {
npc->duration = 10;
npc->moveSpeed = npc->planarFlyDist / npc->duration;
}
npc->jumpVelocity = ((playerY - targetY) + (npc->jumpScale * npc->duration * npc->duration * 0.5f)) / npc->duration;
npc->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_WALK];
return ApiStatus_BLOCK;
}
npc = get_npc_by_index(D_802DAE44);
npc->jumpVelocity -= npc->jumpScale;
npc->pos.y += npc->jumpVelocity;
if (npc->jumpVelocity <= 0.0f) {
npc->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_JUMP];
}
npc_move_heading(npc, npc->moveSpeed, npc->yaw);
duration = npc->duration;
if (duration > 10.0f) {
duration = 10.0f;
}
npc->scale.x = (10.0f - duration) / 10.0f;
npc->scale.y = npc->scale.x;
npc->scale.z = npc->scale.x;
npc->duration--;
if (npc->duration < 0) {
npc->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_IDLE];
npc->jumpVelocity = 0.0f;
npc->pos.y = npc->moveToPos.y;
npc->scale.x = 1.0f;
npc->scale.y = 1.0f;
npc->scale.z = 1.0f;
npc->yaw = clamp_angle(npc->yaw + 180.0f);
return ApiStatus_DONE2;
}
return ApiStatus_BLOCK;
}
ApiStatus PutPartnerAway(Evt* script, s32 isInitialCall) {
Npc* partner = get_npc_unsafe(NPC_PARTNER);
PlayerStatus* playerStatus = &gPlayerStatus;
f32 scale;
f32 targetX;
f32 targetY;
f32 targetZ;
f32 partnerX;
f32 partnerY;
f32 partnerZ;
if (isInitialCall) {
if (D_802DAE40 != 0) {
partner->flags &= ~0x200;
partner->flags &= ~8;
targetX = playerStatus->position.x;
partner->moveToPos.x = targetX;
partnerX = partner->pos.x;
targetY = playerStatus->position.y + (playerStatus->colliderHeight / 2);
partner->moveToPos.y = targetY;
partnerY = partner->pos.y;
targetZ = playerStatus->position.z;
partner->moveToPos.z = targetZ;
partnerZ = partner->pos.z;
partner->moveSpeed = 4.0f;
partner->jumpScale = 2.6f;
partner->planarFlyDist = dist2D(partnerX, partnerZ, targetX, targetZ);
partner->yaw = atan2(partnerX, partnerZ, targetX, targetZ);
partner->duration = partner->planarFlyDist / partner->moveSpeed;
if (partner->duration < 10) {
partner->duration = 10;
partner->moveSpeed = partner->planarFlyDist / partner->duration;
}
partnerY = targetY - partnerY;
partner->jumpVelocity = (partnerY + (partner->jumpScale * partner->duration * partner->duration * 0.5f)) / partner->duration;
partner->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_WALK];
return ApiStatus_BLOCK;
} else {
return ApiStatus_DONE2;
}
}
partner->jumpVelocity -= partner->jumpScale;
partner->pos.y += partner->jumpVelocity;
if (partner->jumpVelocity <= 0.0f) {
partner->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_JUMP];
}
npc_move_heading(partner, partner->moveSpeed, partner->yaw);
scale = partner->duration;
if (scale > 10.0f) {
scale = 10.0f;
}
partner->scale.x = scale / 10.0f;
partner->scale.y = partner->scale.x;
partner->scale.z = partner->scale.x;
partner->duration--;
if (partner->duration < 0) {
partner->currentAnim.w = gPartnerAnimations[D_802DAE40].anims[PARTNER_ANIM_FALL];
partner->jumpVelocity = 0.0f;
partner->pos.y = partner->moveToPos.y;
free_npc_by_index(D_802DAE44);
get_npc_unsafe(-5)->npcID = NPC_PARTNER;
return ApiStatus_DONE2;
}
return ApiStatus_BLOCK;
}
ApiStatus GetCurrentPartnerID(Evt* script, s32 isInitialCall) {
set_variable(script, *script->ptrReadPos, gPlayerData.currentPartner);
return ApiStatus_DONE2;
}
ApiStatus PartnerCanUseAbility(Evt* script, s32 isInitialCall) {
Bytecode arg0 = *script->ptrReadPos;
set_variable(script, arg0, partner_can_use_ability());
return ApiStatus_DONE2;
}
ApiStatus PartnerIsFlying(Evt* script, s32 isInitialCall) {
Bytecode arg0 = *script->ptrReadPos;
set_variable(script, arg0, partner_is_flying());
return ApiStatus_DONE2;
}
ApiStatus func_802CFD30(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode var1 = get_variable(script, *args++);
Bytecode var2 = get_variable(script, *args++);
Bytecode var3 = get_variable(script, *args++);
Bytecode var4 = get_variable(script, *args++);
Bytecode var5 = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
func_8003D624(npc, var1, var2, var3, var4, var5, npc->unk_A2);
return ApiStatus_DONE2;
}
ApiStatus func_802CFE2C(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode arg1 = *args;
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc->unk_A2 = arg1;
return ApiStatus_DONE2;
}
ApiStatus SetNpcPaletteSwapMode(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode var1 = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc_set_palswap_mode_A(npc, var1);
return ApiStatus_DONE2;
}
ApiStatus SetNpcPaletteSwapLower(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode var1 = get_variable(script, *args++);
Bytecode var2 = get_variable(script, *args++);
Bytecode var3 = get_variable(script, *args++);
Bytecode var4 = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc_set_palswap_1(npc, var1, var2, var3, var4);
return ApiStatus_DONE2;
}
ApiStatus SetNpcPaletteSwapping(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
NpcID npcId = get_variable(script, *args++);
Bytecode var1 = get_variable(script, *args++);
Bytecode var2 = get_variable(script, *args++);
Bytecode var3 = get_variable(script, *args++);
Bytecode var4 = get_variable(script, *args++);
Bytecode var5 = get_variable(script, *args++);
Bytecode var6 = get_variable(script, *args++);
Bytecode var7 = get_variable(script, *args++);
Bytecode var8 = get_variable(script, *args++);
Npc* npc = resolve_npc(script, npcId);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc_set_palswap_1(npc, var1, var2, var3, var4);
npc_set_palswap_2(npc, var5, var6, var7, var8);
return ApiStatus_DONE2;
}
ApiStatus SetNpcDecoration(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
s32 value1 = get_variable(script, *ptrReadPos++);
s32 value2 = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
npc_set_decoration(npc, value1, value2);
return ApiStatus_DONE2;
}
ApiStatus PlaySoundAtNpc(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
SoundID soundID = get_variable(script, *ptrReadPos++);
s32 value2 = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
if (npc == NULL) {
return ApiStatus_DONE2;
}
sfx_play_sound_at_position(soundID, value2, npc->pos.x, npc->pos.y, npc->pos.z);
return ApiStatus_DONE2;
}
ApiStatus func_802D0244(Evt* script, s32 isInitialCall) {
Bytecode* ptrReadPos = script->ptrReadPos;
NpcID npcID = get_variable(script, *ptrReadPos++);
u8 renderMode = get_variable(script, *ptrReadPos++);
Npc* npc = resolve_npc(script, npcID);
npc->renderMode = renderMode;
return ApiStatus_DONE2;
}