Files
banjo-kazooie/src/BGS/ch/mrvile.c
2024-09-09 19:51:23 +02:00

449 lines
13 KiB
C

#include <ultra64.h>
#include "functions.h"
#include "variables.h"
#include "prop.h"
#include "core2/modelRender.h"
Actor *chvile_draw(ActorMarker*, Gfx **, Mtx **, Vtx **);
void chvile_update(Actor *);
void func_8038BB40(ActorMarker *);
extern bool func_80320C94(f32[3], f32[3], f32, f32[3], s32, u32);
extern bool chvilegame_find_closest_piece(ActorMarker *, f32[3], f32, f32[3]);
typedef struct chmrvile_s{
u8 unk0;
// u8 pad1[0x3];
BKModelBin *unk4; //yumblie_model
ActorMarker *game_marker; //game_marker
u8 unkC;
// u8 padD[0x3];
f32 unk10; //movement_speed
f32 unk14; //yumblie_eating_timer
f32 target_position[3]; //target_position
f32 unk24;
f32 unk28[3]; //target_rotation?
} ActorLocal_MrVile;
/* .data */
ActorInfo D_80390A70 = {MARKER_C8_MR_VILE, ACTOR_13A_MR_VILE, ASSET_373_MODEL_MR_VILE, 0x00, NULL,
chvile_update, NULL, chvile_draw,
0, 0, 0.0f, 0
};
f32 D_80390A94[7] = {0.0f, 0.8f, 0.9f, 1.0f, 0.9f, 0.95f, 1.0f};
/* .code */
void func_8038B9F0(f32 arg0[3], f32 arg1[3], f32 arg2, f32 arg3, s32 arg4) {
f32 sp64[3];
f32 pad60;
f32 sp54[3];
f32 pad50;
f32 sp44[3];
f32 sp38[3];
f32 sp2C[3];
f32 var_f0;
sp44[0] = arg0[0];
sp44[1] = arg0[1] + arg2;
sp44[2] = arg0[2];
sp38[0] = arg1[0];
sp38[1] = arg1[1] + arg2;
sp38[2] = arg1[2];
sp2C[0] = sp38[0];
sp2C[1] = sp38[1];
sp2C[2] = sp38[2];
if (func_80320C94(sp44, sp38, arg3, sp54, 3, arg4)) {
sp64[0] = sp38[0] - sp2C[0];
sp64[1] = sp38[1] - sp2C[1];
sp64[2] = sp38[2] - sp2C[2];
var_f0 = sp54[0]*sp64[0] + sp54[1]*sp64[1] + sp54[2]*sp64[2];
if (var_f0 < 1.0f) {
var_f0 = 1.0f;
}
ml_vec3f_set_length(sp54, var_f0);
arg1[0] = arg1[0] + sp54[0];
arg1[1] = arg1[1] + sp54[1];
arg1[2] = arg1[2] + sp54[2];
}
}
void func_8038BB40(ActorMarker * arg0){
Actor *this;
ActorLocal_MrVile *local;
this = marker_getActor(arg0);
local = (ActorLocal_MrVile *)&this->local;
if(func_8038A9E0(local->game_marker) >= 3){
item_set(ITEM_14_HEALTH, 0);
func_8028F66C(BS_INTR_F);
}
else{
item_dec(ITEM_14_HEALTH);
func_8028F590(4, arg0);
}
}
void BGS_func_8038BBA0(Actor *this, s32 arg1){
ActorLocal_MrVile *local;
local = (ActorLocal_MrVile *)&this->local;
local->unk14 = 0.0f;
if(arg1 == 101){
local->unk24 = 0.0f;
local->unk28[0] = local->unk28[1] = local->unk28[2] = 0.0f;
skeletalAnim_set(this->unk148, 0xe1, 0.10000000149f, 1.0f); //0xe1 = croc_idle
}
if(arg1 == 102){
if(local->unk24 < 100.0f){
local->unk24 = 100.0f;
};
skeletalAnim_swap(this->unk148, 0xe0, 0.1f, 0.5f); //0xe1 = croc_walk
}
if(arg1 == 103){
skeletalAnim_swap(this->unk148, 0x124, 0.1f, 0.5f); //0x124 = croc_munch
if(this->state == 4){
timed_playSfx(0.31f, SFX_4C_LIP_SMACK, 0.90f, 25000);
timedFunc_set_1(0.31f, (GenFunction_1)func_8038BB40, reinterpret_cast(s32, this->marker));
}
else{
timed_playSfx(0.31f, SFX_4C_LIP_SMACK, 0.90f, 25000);
timed_playSfx(0.81f, SFX_4C_LIP_SMACK, 0.93f, 25000);
timed_playSfx(1.31f, SFX_4C_LIP_SMACK, 0.91f, 25000);
}
}
if(arg1 == 104){
local->unk14 = 1.0f;
timed_playSfx(randf2(1.2f, 1.3f), SFX_97_BLUBBER_BURPS, randf2(0.8f, 1.1f), randi2(25000, 32000));
}
local->unkC = arg1;
}
void func_8038BD84(Actor *this){
ActorLocal_MrVile *local;
local = (ActorLocal_MrVile *)&this->local;
local->unkC = 100;
local->unk10 = 0.0f;
local->unk14 = 0.0f;
local->unk24 = 0.0f;
local->target_position[0] = 0.0f;
local->target_position[1] = 0.0f;
local->target_position[2] = 0.0f;
local->unk28[0] = 0.0f;
local->unk28[1] = 0.0f;
local->unk28[2] = 0.0f;
BGS_func_8038BBA0(this, 101);
}
void func_8038BDD4(Actor *this) {
ActorLocal_MrVile *local;
f32 start_position[3];
f32 sp5C;
f32 sp58;
f32 sp54;
f32 sp50;
f32 sp44[3];
f32 temp_f0_3;
local = (ActorLocal_MrVile *)&this->local;
sp5C = time_getDelta();
start_position[0] = this->position[0];
start_position[1] = this->position[1];
start_position[2] = this->position[2];
ml_timer_update(&local->unk14, sp5C);
if ((local->unkC == 102) || (local->unkC == 103) || (local->unkC == 104)) {
sp44[0] = 0.0f;
sp44[1] = 0.0f;
sp44[2] = local->unk24 * sp5C;
ml_vec3f_yaw_rotate_copy(sp44, sp44, this->yaw);
this->position[0] = this->position[0] + sp44[0];
this->position[1] = this->position[1] + sp44[1];
this->position[2] = this->position[2] + sp44[2];
this->pitch += local->unk28[0] * sp5C;
this->yaw += local->unk28[1] * sp5C;
this->roll += local->unk28[2] * sp5C;
func_80258A4C(this->position, this->yaw - 90.0f, local->target_position, &sp58, &sp54, &sp50);
if ((sp54 > 0.0f) && (sp58 > 200.0f)) {
local->unk24 += 100.0f * sp5C;
}
if ((sp54 < 0.0f) && (sp58 > 100.0f)) {
local->unk24 -= 100.0f * sp5C;
}
local->unk24 = (local->unk24 < 10.0f) ? 10.0f
: (local->unk10 < local->unk24) ? local->unk10
: local->unk24;
skeletalAnim_setDuration(this->unk148, (200.0f / local->unk24) * 0.5);
local->unk28[1] = sp50 * 200.0f;
temp_f0_3 = mapModel_getFloorY(this->position);
if (temp_f0_3 > 125.0f) {
this->position[1] = 125.0f;
} else if (temp_f0_3 > 80.0f) {
this->position[1] = temp_f0_3;
} else {
this->position[1] = 0.0f;
}
}
if (this->position[1] > 100.0f) {
func_8038B9F0(start_position, this->position, 90.0f, 70.0f, 0);
}
}
void func_8038C0C8(Actor * this, s32 next_state){
ActorLocal_MrVile *local;
local = (ActorLocal_MrVile *)&this->local;
if(next_state == 1)
BGS_func_8038BBA0(this, 101);
if(next_state == 2)
BGS_func_8038BBA0(this, 101);
if(next_state == 3)
BGS_func_8038BBA0(this, 102);
if(next_state == 4)
BGS_func_8038BBA0(this, 102);
if(next_state == 5){
local->target_position[0] = local->target_position[1] = local->target_position[2] = 0.0f;
BGS_func_8038BBA0(this, 102);
}
if(next_state == 6){
local->target_position[0] = local->target_position[1] = local->target_position[2] = 0.0f;
local->unk24 = 300.0f;
BGS_func_8038BBA0(this, 102);
}
this->state = next_state;
}
Actor *chvile_draw(ActorMarker *marker, Gfx **gfx, Mtx** mtx, Vtx **vtx){
Actor *this;
ActorLocal_MrVile *local;
f32 position[3];
this = actor_draw(marker, gfx, mtx, vtx);
local = (ActorLocal_MrVile *)&this->local;
if (
(local->unkC == 104) &&
(local->unk14 > 0.0f)
&& (this->marker->unk14_21)
) {
func_8034A174(func_80329934(), 5, position);
position[1] -= 30.0f;
modelRender_setDepthMode(MODEL_RENDER_DEPTH_FULL);
modelRender_draw(gfx, mtx, position, 0, local->unk14, 0, local->unk4);
}
return this;
}
f32 *chVile_getPostion(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
return this->position;
}
bool func_8038C2A8(ActorMarker *marker) {
f32 player_position[3];
Actor *this;
ActorLocal_MrVile *local;
this = marker_getActor(marker);
local = (ActorLocal_MrVile *)&this->local;
player_getPosition(player_position);
if (this->state == 6) {
return ml_distance_vec3f(this->position, player_position) < 150.0f;
}
return local->unk0 == 1;
}
bool BGS_func_8038C338(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
return this->state == 1;
}
void chvile_free(Actor *this){
ActorLocal_MrVile *local;
local = (ActorLocal_MrVile *)&this->local;
assetcache_release(local->unk4);
}
void func_8038C384(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
func_8038C0C8(this, 4);
}
void func_8038C3B0(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
func_8038C0C8(this, 2);
}
void func_8038C3DC(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
func_8038C0C8(this, 3);
}
void func_8038C408(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
func_8038C0C8(this, 5);
}
void BGS_func_8038C434(ActorMarker *marker){
Actor *this;
this = marker_getActor(marker);
func_8038C0C8(this, 6);
}
void BGS_func_8038C460(ActorMarker *arg0){
func_8038C0C8(marker_getActor(arg0), 1);
}
void chvile_update(Actor *this) {
f32 player_position[3];
f32 sp90;
f32 temp_a0;
bool var_v1;
f32 sp84;
f32 sp80;
f32 sp7C;
s32 temp_v0;
s32 i;
f32 sp70;
f32 sp6C;
f32 sp68;
ActorLocal_MrVile *local;
f32 random_position[3];
local = (ActorLocal_MrVile *)&this->local;
if (!this->unk16C_4) {
this->unk16C_4 = TRUE;
this->marker->actorFreeFunc = chvile_free;
local->unk0 = 0;
local->unk4 = assetcache_get(0x3F6);
local->game_marker = NULL;
func_8038BD84(this);
func_8038C0C8(this, 1);
return;
}
if (local->game_marker == NULL) {
local->game_marker = actorArray_findClosestActorFromActorId(this->position, 0x138, -1, &sp90)->marker;
}
player_getPosition(player_position);
sp90 = ml_distance_vec3f(this->position, player_position);
if (sp90 <= 300.0f) {
local->unk0 = (local->unk0 == 0) ? 1 : 2;
} else if (sp90 > 300.0f) {
local->unk0 = 0U;
}
if (this->state == 2) {
func_80258A4C(this->position, this->yaw - 90.0f, player_position, &sp84, &sp80, &sp7C);
if (((sp84 > 50.0f) && (0.05 < sp7C)) || (sp7C < -0.05)) {
this->yaw += sp7C * 20.0f;
} else {
func_8038C0C8(this, 1);
}
}
if (this->state == 3) {
var_v1 = chvilegame_find_closest_piece(local->game_marker, this->position, this->yaw, local->target_position) && mapSpecificFlags_get(6);
if (!var_v1) {
local->target_position[0] = 0.0f;
local->target_position[1] = 0.0f;
local->target_position[2] = 0.0f;
}
if (local->game_marker != NULL) {
temp_v0 = chvilegame_get_score_difference(local->game_marker);
if (temp_v0 >= 2) {
local->unk10 = 200.0f;
} else if (temp_v0 >= 0) {
local->unk10 = 310.0f;
} else if (temp_v0 >= -2) {
local->unk10 = 350.0f;
} else {
local->unk10 = 450.0f;
}
local->unk10 *= D_80390A94[func_8038A9E0(local->game_marker)];
}
if (func_8038A9E0(local->game_marker) < 7) {
func_80258A4C(this->position, this->yaw - 90.0f, local->target_position, &sp70, &sp6C, &sp68);
if (local->unkC == 102) {
if ((-0.8 < sp68) && (sp68 < 0.8) && (sp70 <= 150.0f) && var_v1) {
BGS_func_8038BBA0(this, 103);
}
}
if (local->unkC == 103) {
if (sp70 <= 50.0f) {
if (chvilegame_cpu_consume_piece(local->game_marker, local->target_position)) {
BGS_func_8038BBA0(this, 104);
} else {
BGS_func_8038BBA0(this, 102);
}
} else if (skeletalAnim_getLoopCount(this->unk148) >= 3) {
BGS_func_8038BBA0(this, 102);
}
}
if ((local->unkC == 104) && (skeletalAnim_getLoopCount(this->unk148) >= 3)) {
BGS_func_8038BBA0(this, 102);
}
}
}
if (this->state == 4) {
player_getPosition(local->target_position);
local->unk10 = 500.0f;
if ((local->unkC == 102) && (ml_distance_vec3f(this->position, local->target_position) < 200.0f)) {
BGS_func_8038BBA0(this, 103);
}
if ((local->unkC == 103) && (skeletalAnim_getLoopCount(this->unk148) >= 2)) {
func_8038C0C8(this, 1);
}
}
if (this->state == 5) {
local->unk10 = 200.0f;
if (ml_distance_vec3f(this->position, local->target_position) < 100.0f) {
local->target_position[0] = randf2(-500.0f, 500.0f);
local->target_position[1] = 0.0f;
local->target_position[2] = randf2(-500.0f, 500.0f);
}
}
if ((this->state == 6)){
local->unk10 = 400.0f;
if((ml_distance_vec3f(this->position, local->target_position) < 100.0f) || (ml_distance_vec3f(player_position, local->target_position) < 300.0f)) {
for(i = 0; i < 10; i++){
random_position[0] = randf2(-500.0f, 500.0f);
random_position[1] = 0.0f;
random_position[2] = randf2(-500.0f, 500.0f);
if ((i == 0) || (ml_distance_vec3f(player_position, random_position) > ml_distance_vec3f(player_position, local->target_position))) {
local->target_position[0] = random_position[0];
local->target_position[1] = random_position[1];
local->target_position[2] = random_position[2];
}
};
}
}
func_8038BDD4(this);
if (this->state != 4) {
func_8028E668(this->position, 100.0f, -50.0f, 120.0f);
}
}