Files
banjo-kazooie/src/BGS/ch/yumblie.c
mariob92 c8598c2677 documentations:
- various particle system functions/structs
- more in src/fight
- beehive
- added prototypes (reduced compiler warnings)
2024-09-07 12:52:35 +02:00

218 lines
6.7 KiB
C

#include <ultra64.h>
#include "functions.h"
#include "variables.h"
#include "prop.h"
extern void actor_predrawMethod(Actor *);
extern void actor_postdrawMethod(ActorMarker *);
extern f32 randf (void);
extern BKModelBin *chvilegame_get_grumblie_model(ActorMarker *marker);
enum chyumblie_state_e{
YUMBLIE_STATE_1_UNDER_GROUND = 1,
YUMBLIE_STATE_2_APPEAR,
YUMBLIE_STATE_3_ABOVE_GROUND,
YUMBLIE_STATE_4_DISAPPEAR,
YUMBLIE_STATE_5_BEING_EATEN
};
typedef struct chyumblie_s{
f32 unk0;
u8 unk4;
u8 pad7[3];
f32 unk8; //wait_timer
ActorMarker *game_marker;
} ActorLocal_Yumblie;
void chyumblie_set_state(Actor*, enum chyumblie_state_e);
void chyumblie_update(Actor *);
Actor *chyumblie_draw(ActorMarker *this, Gfx **gfx, Mtx** mtx, Vtx **vtx);
/* .data */
ActorInfo D_80390A40 = {MARKER_C7_YUMBLIE, ACTOR_139_YUMBLIE, ASSET_3F6_MODEL_YUMBLIE, 0x00, NULL,
chyumblie_update, NULL, chyumblie_draw,
0, 0, 0.0f, 0
};
/* .code */
bool func_8038B160(Actor *this){
ActorLocal_Yumblie *local;
s32 temp_v0;
local = (ActorLocal_Yumblie *)&this->local;
temp_v0 = func_8038A9E0(local->game_marker);
if ((temp_v0 == 1) || (temp_v0 == 4))
return FALSE;
if ((temp_v0 == 2) || (temp_v0 == 5))
return (0.7 <= randf ()) ? TRUE : FALSE;
return (randf () >= 0.5)? TRUE : FALSE;
}
void chyumblie_set_state(Actor* this, enum chyumblie_state_e next_state){
ActorLocal_Yumblie *s0;
s0 = (ActorLocal_Yumblie *)&this->local;
s0->unk8 = 0;
if(next_state == 1){
s0->unk8 = randf2(1.0f, 10.0f);
}
if(next_state == 2){
this->yaw = randf2(0.0f, 360.0f);
s0->unk4 = func_8038B160(this);
chvilegame_new_piece(s0->game_marker, this->marker, this->position, s0->unk4);
skeletalAnim_set(this->unk148, (s0->unk4)? ASSET_128_ANIM_GRUMBLIE_APPEAR : ASSET_125_ANIM_YUMBLIE_APPEAR, 0.0f, 1.5f);
skeletalAnim_setBehavior(this->unk148, SKELETAL_ANIM_2_ONCE);
}
if(next_state == 3){
s0->unk8 = randf2(5.0f, 10.0f);
skeletalAnim_set(this->unk148, (s0->unk4)? ASSET_12A_ANIM_GRUMBLIE_IDLE : ASSET_127_ANIM_YUMBLIE_IDLE, 0.1f, randf2(0.5f, 1.0f));
skeletalAnim_setBehavior(this->unk148, SKELETAL_ANIM_1_LOOP);
if(s0->unk4){
func_8030E6A4(SFX_C4_TWINKLY_MUNCHER_GRR,randf2(1.0f, 1.2), 30000);
}else{
func_8030E878(SFX_C3_HEGH,randf2(1.0f, 1.2), 30000, this->position, 500.0f, 3000.0f);
}
}
if(next_state == 4){
chvilegame_remove_piece(s0->game_marker, this->marker);
skeletalAnim_set(this->unk148, (s0->unk4)? ASSET_129_ANIM_GRUMBLIE_HIDE : ASSET_126_ANIM_YUMBLIE_HIDE, 0.1f, 0.5f);
skeletalAnim_setBehavior(this->unk148, SKELETAL_ANIM_2_ONCE);
}
if(next_state == 5){
s0->unk8 = randf2(10.0f, 20.0f);
chvilegame_remove_piece(s0->game_marker, this->marker);
func_8030E878((s0->unk4)? SFX_C4_TWINKLY_MUNCHER_GRR: SFX_C3_HEGH, 1.4f, 32000, this->position, 500.0f, 3000.0f);
}
this->state = next_state;
}
bool chyumblie_is_edible(ActorMarker * arg0){
volatile Actor* actPtr;
actPtr = marker_getActor(arg0);
return (actPtr->state >= 2) && (actPtr->state < 5);
}
Actor *chyumblie_draw(ActorMarker *this, Gfx **gfx, Mtx** mtx, Vtx **vtx){
Actor *thisActor;
ActorLocal_Yumblie *sp40;
f32 sp44[3];
f32 sp38[3];
thisActor = marker_getActor(this);
sp40 = (ActorLocal_Yumblie *)&thisActor->local;
if ( thisActor->state < 2 || thisActor->state > 4){
thisActor->marker->unk14_21 = 0;
return thisActor;
}
modelRender_preDraw((GenFunction_1) actor_predrawMethod, (s32)thisActor);
modelRender_postDraw((GenFunction_1) actor_postdrawMethod, (s32)this);
sp44[0] = thisActor->position_x;
sp44[1] = thisActor->position_y + sp40->unk0*75.0f;
sp44[2] = thisActor->position_z;
sp38[0] = thisActor->pitch;
sp38[1] = thisActor->yaw;
sp38[2] = thisActor->roll;
if(sp40->unk4 && sp40->game_marker){
modelRender_draw(gfx, mtx, sp44, sp38, 1.0f, NULL, chvilegame_get_grumblie_model(sp40->game_marker));
}
else{
modelRender_draw(gfx, mtx, sp44, sp38, 1.0f, NULL, marker_loadModelBin(this));
}
return thisActor;
}
bool func_8038B684(ActorMarker * arg0){
Actor* actPtr = marker_getActor(arg0);
if( actPtr->state < 5){
chyumblie_set_state(actPtr, YUMBLIE_STATE_5_BEING_EATEN);
return TRUE;
}
return FALSE;
}
void chyumblie_update(Actor *this){
ActorLocal_Yumblie *s0;
f32 sp50;
f32 sp4C;
f32 sp48;
s32 pad44;
f32 tmp;
s0 = (ActorLocal_Yumblie *)&this->local;
sp4C = time_getDelta();
if(!this->unk16C_4){
this->unk16C_4 = 1;
s0->unk0 = 0.0f;
s0->unk4 = 0;
s0->game_marker = NULL;
chyumblie_set_state(this, YUMBLIE_STATE_1_UNDER_GROUND);
return;
}
if(s0->game_marker == NULL){
s0->game_marker = actorArray_findClosestActorFromActorId(this->position, ACTOR_138_VILE_GAME_CTRL, -1, &sp48)->marker;
}
sp50 = skeletalAnim_getProgress(this->unk148);
if(this->state == YUMBLIE_STATE_1_UNDER_GROUND){
if(ml_timer_update(&s0->unk8, sp4C)){
if(mapSpecificFlags_get(6) && (12 > chvilegame_get_piece_count(s0->game_marker))){
chyumblie_set_state(this, YUMBLIE_STATE_2_APPEAR);
}
else{
chyumblie_set_state(this, YUMBLIE_STATE_1_UNDER_GROUND);
}
}
}
if(this->state == YUMBLIE_STATE_2_APPEAR){
tmp = s0->unk0;
if(s0->unk4){
if(sp50 <= 0.3){
s0->unk0 = sp50/0.3;
}
}else{
if(sp50 <= 0.6){
s0->unk0 = sp50/0.6;
}
}
if((tmp < 0.5) && (0.5 <= s0->unk0)){
func_8030E878(SFX_C5_TWINKLY_POP, randf2(1.0f, 1.2f), 30000, this->position, 500.0f, 3000.0f);
}
if( 0 < skeletalAnim_getLoopCount(this->unk148)){
s0->unk0 = 1.0f;
chyumblie_set_state(this,YUMBLIE_STATE_3_ABOVE_GROUND);
}
}
if(this->state == YUMBLIE_STATE_3_ABOVE_GROUND){
if( ml_timer_update(&s0->unk8,sp4C) || !mapSpecificFlags_get(6) ){
chyumblie_set_state(this,YUMBLIE_STATE_4_DISAPPEAR);
}
}
if(this->state == YUMBLIE_STATE_4_DISAPPEAR){
if(sp50 >= 0.25 )
s0->unk0 -= 2.0f*(f64)sp4C;
if(0.0f >= s0->unk0){
s0->unk0 = 0.0f;
chyumblie_set_state(this,YUMBLIE_STATE_1_UNDER_GROUND);
}
}
if(this->state == YUMBLIE_STATE_5_BEING_EATEN){
if( ml_timer_update(&s0->unk8,sp4C)){
chyumblie_set_state(this,YUMBLIE_STATE_1_UNDER_GROUND);
}
}
}