document core2/ch/snowball.c

This commit is contained in:
Banjo Kazooie
2023-01-22 21:11:24 -06:00
parent c403098315
commit 99b2cad21d
5 changed files with 122 additions and 118 deletions

172
src/core2/ch/snowball.c Normal file
View File

@@ -0,0 +1,172 @@
#include <ultra64.h>
#include "functions.h"
#include "variables.h"
extern void func_80329904(ActorMarker *, s32, f32 *);
extern int func_80320C94(f32 (*)[3], f32(*)[3], f32, s32, s32, u32);
extern f32 func_8033229C(ActorMarker *);
typedef struct{
s32 unk0;
s32 unk4;
}ActorLocal_chSnowball;
Actor *chSnowball_draw(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx);
void chSnowball_update(Actor *this);
/* .data */
ActorInfo chSnowball = {
MARKER_B2_SNOWBALL, ACTOR_125_SNOWBALL, ASSET_378_MODEL_SNOWBALL,
0x1, NULL,
chSnowball_update, func_80326224, chSnowball_draw,
0, 0x800, 0.8f, 0
};
/* .bss */
f32 D_8037E640[3];
/* .code */
Actor *chSnowball_draw(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
Actor *this;
this = func_80325888(marker, gfx, mtx, vtx);
if (marker->unk14_21 && this->state != 2) {
func_8033E73C(marker, 5, func_80329904);
func_8033E3F0(0xD, marker->unk14_21);
}
return this;
}
void __chSnowball_spawnPieces(f32 position[3]) {
static struct31s D_80368734 = {{0.65f, 1.1}, {0.0f, 0.0f}, {0.0f, 0.01f}, {0.8f, 0.8f}, 0.0f, 0.5f};
static struct43s D_8036875C = {
{{-220.0f, 210.0f, -220.0f}, {280.0f, 460.0f, 280.0f}},
{{ 0.0f, -800.0f, 0.0f}, { 0.0f, -800.0f, 0.0f}},
{{ -20.0f, -20.0f, -20.0f}, { 20.0f, 20.0f, 20.0f}}
};
ParticleEmitter *pCtrl;
pCtrl = partEmitList_pushNew(8);
particleEmitter_setModel(pCtrl, ASSET_37A_MODEL_TINY_SNOWBALL);
particleEmitter_setPosition(pCtrl, position);
particleEmitter_setPositionVelocityAndAccelerationRanges(pCtrl, &D_8036875C);
func_802EFE24(pCtrl, -300.0f, -300.0f, -300.0f, 300.0f, 300.0f, 300.0f);
func_802EFB98(pCtrl, &D_80368734);
particleEmitter_emitN(pCtrl, 8);
}
void __chSnowball_collisionCallback(Actor *this, bool water_collision) {
static f32 D_803687A4[4] = {0.2f, 0.3f, 1.0f, 1.2f};
if (water_collision) {
D_8037E640[0] = this->position[0];
D_8037E640[1] = this->position[1];
D_8037E640[2] = this->position[2];
D_8037E640[1] -= 40.0f;
func_80359A40(D_8037E640, D_803687A4, 3);
func_802F4200(D_8037E640);
func_802F3FE4(D_8037E640);
func_8030E878(SFX_2F_ORANGE_SPLAT, 1.0f, 10000, this->position, 1250.0f, 2500.0f);
func_8030E878(SFX_F_SMALL_WATER_SPLASH, randf2(0.8f, 1.2f), 32000, this->position, 1250.0f, 2500.0f);
actor_collisionOff(this);
func_80326310(this);
func_80328A84(this, 2U);
}
else{
func_8030E878(SFX_2F_ORANGE_SPLAT, 1.0f, 32000, this->position, 1250.0f, 2500.0f);
__chSnowball_spawnPieces(this->position);
marker_despawn(this->marker);
}
}
void __chSnowball_actorCollisionCallback(ActorMarker *marker, ActorMarker *other_marker){
Actor *this;
this = marker_getActor(marker);
__chSnowball_collisionCallback(this, 0);
}
void chSnowball_update(Actor *this) {
f32 sp7C[3];
f32 sp70[3];
f32 sp64[3];
f32 sp58[3];
ActorLocal_chSnowball *local = (ActorLocal_chSnowball *)&this->local;
BKCollisionTri *temp_v0_3;
s32 phi_a1;
s32 i;
if(this->unk38_31 == 0 && func_80329530(this, 500)){
FUNC_8030E8B4(SFX_C_TAKING_FLIGHT_LIFTOFF, 0.85f, 32000, this->position, 1250, 2500);
this->unk38_31 = 1;
}
if(!this->initialized){
marker_setCollisionScripts(this->marker, NULL, NULL, __chSnowball_actorCollisionCallback);
if(local->unk0 == 0){
player_getPosition(this->unk1C);
local->unk0 = 1;
return;
}
this->initialized = TRUE;
player_getPosition(sp7C);
sp7C[1] += 1.0f;
phi_a1 = (func_8023DB5C() & 1) ? 0x15 : 0x2B;
for(i = 0; i < 3; i++){
sp58[i] = sp7C[i] + (sp7C[i] - this->unk1C[i]) * phi_a1;
}
this->velocity[0] = (sp58[0] - this->position[0])/32;
this->velocity[1] = (sp58[1] - this->position[1])/32 - -32.0f;
this->velocity[2] = (sp58[2] - this->position[2])/32;
local->unk4 = 0;
this->unk60 = 6.0f;
}
switch (this->state) {
case 1:
sp64[0] = this->position[0];
sp64[1] = this->position[1];
sp64[2] = this->position[2];
this->position[0] = this->position[0] + this->velocity[0];
this->position[1] = this->position[1] + this->velocity[1];
this->position[2] = this->position[2] + this->velocity[2];
this->velocity_y -= 2.0f;
this->pitch += 10.0f;
this->yaw += 10.0f;
if(this->pitch > 360.0f){
this->pitch -= 360.0f;
}
if (this->yaw > 360.0f) {
this->yaw -= 360.0f;
}
if (local->unk4 >= 6) {
temp_v0_3 = func_80320C94(sp64, this->position, func_8033229C(this->marker) * 1.2, sp70, 5, 0);
if (temp_v0_3 != 0) {
__chSnowball_collisionCallback(this, *((u32*)temp_v0_3 + 2) & 0x20000);
return;
}
}
local->unk4++;
if (this->unk60 > 0.0) {
this->unk60 -= time_getDelta();
} else {
marker_despawn(this->marker);
}
if (this->position_y < -1000.0f) {
marker_despawn(this->marker);
}
break;
case 2:
this->marker->unk40_22 = NOT(func_8028F170());
this->velocity[0] *= 0.7;
this->velocity[1] *= 0.7;
this->velocity[2] *= 0.7;
this->position[0] = this->position[0] + this->velocity[0];\
this->position[1] = this->position[1] + this->velocity[1];\
this->position[2] = this->position[2] + this->velocity[2];
break;
}
}

View File

@@ -18,42 +18,32 @@ typedef struct {
u8 unkB;
} ActorLocal_chSirSlush;
Actor *func_802E1AC0(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx); //chSirSlush_draw
void func_802E20E8(Actor *this); //chSirSlush_update
Actor *chSnowman_draw(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx); //chSirSlush_draw
void chSnowman_update(Actor *this); //chSirSlush_update
/* .data */
ActorAnimationInfo D_80368650[] = {
ActorAnimationInfo chSnowmanAnimations[] = {
{0, 0.0f},
{ASSET_108_ANIM_SIR_SLUSH_IDLE, 0.8f},
{ASSET_109_ANIM_SIR_SLUSH_ATTACK, 4.0f},
{ASSET_220_ANIM_SIR_SLUSH_DIE, 1.6f}
};
ActorInfo D_80368670 = {
enum chsnowman_state_e{
CHSNOWMAN_STATE_1_IDLE = 1,
CHSNOWMAN_STATE_2_ATTACK,
CHSNOWMAN_STATE_3_DIE
};
ActorInfo chSnowman = {
MARKER_B1_SIR_SLUSH, ACTOR_124_SIR_SLUSH, ASSET_377_MODEL_SIR_SLUSH,
1, D_80368650,
func_802E20E8, func_80326224, func_802E1AC0,
CHSNOWMAN_STATE_1_IDLE, chSnowmanAnimations,
chSnowman_update, func_80326224, chSnowman_draw,
0, 0x199, 0.0f, 0
};
struct31s D_80368694 = {
{0.4f, 1.55f},
{0.0f, 0.0f},
{0.0f, 0.01f},
{4.0f, 4.0f},
0.0f, 0.3f
};
struct43s D_803686BC = {
{{-250.0f, 600.0f, -250.0f}, {350.0f, 960.0f, 350.0f}},
{{0.0f, -1200.0f, 0.0f}, {0.0f, -1200.0f, 0.0f}},
{{-80.0f, 0.0f, -80.0f}, {80.0f, 200.0f, 80.0f}}
};
f32 D_80368704[3] = {350.0f, 600.0f, 65.0f};
/* .code */
Actor *func_802E1AC0(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx){
Actor *chSnowman_draw(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx){
Actor *actor;
ActorLocal_chSirSlush *local;
@@ -64,29 +54,29 @@ Actor *func_802E1AC0(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx){
func_80325888(marker, gfx, mtx, vtx);
}
void func_802E1B24(ActorMarker *marker){
void __chSnowman_spawnSnowball(ActorMarker *marker){
Actor *actor;
Actor *other;
f32 sp1C[3];
f32 player_position[3];
ActorMarker *m = *(ActorMarker **)&marker;
actor = marker_getActor(m);
other = spawn_child_actor(ACTOR_125_SNOWBALL, &actor);
if(m->unk14_21){
func_8034A174(m->unk44, 5, sp1C);
func_8034A174(m->unk44, 5, player_position);
}
else{
sp1C[0] = actor->position[0];
sp1C[1] = actor->position[1];
sp1C[2] = actor->position[2];
sp1C[1] += 150.0f;
player_position[0] = actor->position[0];
player_position[1] = actor->position[1];
player_position[2] = actor->position[2];
player_position[1] += 150.0f;
}
other->position[0] = sp1C[0];
other->position[1] = sp1C[1];
other->position[2] = sp1C[2];
other->position[0] = player_position[0];
other->position[1] = player_position[1];
other->position[2] = player_position[2];
}
void func_802E1BD0(ActorMarker *marker){
void __chSnowman_spawnHat(ActorMarker *marker){
Actor *actor;
Actor *other;
f32 sp2C[3];
@@ -113,7 +103,20 @@ void func_802E1BD0(ActorMarker *marker){
other->velocity[1] = 30.0f;
}
void func_802E1CB8(f32 position[3], s32 count){
void __chSnowman_spawnSnowballParticles(f32 position[3], s32 count){
static struct31s D_80368694 = {
{0.4f, 1.55f},
{0.0f, 0.0f},
{0.0f, 0.01f},
{4.0f, 4.0f},
0.0f, 0.3f
};
static struct43s D_803686BC = {
{{-250.0f, 600.0f, -250.0f}, {350.0f, 960.0f, 350.0f}},
{{0.0f, -1200.0f, 0.0f}, {0.0f, -1200.0f, 0.0f}},
{{-80.0f, 0.0f, -80.0f}, {80.0f, 200.0f, 80.0f}}
};
ParticleEmitter *particleSpawner = partEmitList_pushNew(count);
particleEmitter_setModel(particleSpawner, ASSET_378_MODEL_SNOWBALL);
@@ -128,91 +131,91 @@ void func_802E1CB8(f32 position[3], s32 count){
particleEmitter_emitN(particleSpawner, count);
}
void func_802E1DA0(Actor *this){
void __chSnowman_enterIdle(Actor *this){
ActorLocal_chSirSlush *local = (ActorLocal_chSirSlush *) &this->local;
func_80328B8C(this, 1, 0.01f, 1);
func_80328B8C(this, CHSNOWMAN_STATE_1_IDLE, 0.01f, 1);
actor_loopAnimation(this);
local->unk4 = 0.4f;
}
void func_802E1DE8(Actor *this){
func_80328B8C(this, 3, 0.01f, 1);
void __chSnowman_enterDeath(Actor *this){
func_80328B8C(this, CHSNOWMAN_STATE_3_DIE, 0.01f, 1);
actor_playAnimationOnce(this);
}
void func_802E1E20(Actor *this, f32 arg1){
void __chSnowman_setYawTarget(Actor *this, f32 max_rotation){
this->yaw_ideal = func_80329784(this);
func_80328FB0(this, 6.0f);
}
int func_802E1E5C(Actor *this, s32 arg1){
f32 f0;
f0 = this->yaw - this->yaw_ideal;
if((f0 < arg1) && (-arg1 < f0)){
return 1;
bool __chSnowman_isYawNearYawTarget(Actor *this, s32 max_angle_degree){
f32 dYaw;
dYaw = this->yaw - this->yaw_ideal;
if((dYaw < max_angle_degree) && (-max_angle_degree < dYaw)){
return TRUE;
}
return 0;
return FALSE;
}
int func_802E1EB4(Actor *this, s32 arg1, s32 arg2){
f32 sp1C[3];
int __chSnowman_isPlayerInAttackRange(Actor *this, s32 min_distance, s32 max_distance){
f32 player_position[3];
if(this->unkF4_8 == 0x33){
player_getPosition(sp1C);
if( (this->position[1] + 500.0f < sp1C[1]) || (sp1C[1] < this->position[1] - 500.0f))
player_getPosition(player_position);
if( (this->position[1] + 500.0f < player_position[1]) || (player_position[1] < this->position[1] - 500.0f))
return 0;
}//L802E1F28
if(func_80329530(this, arg2) && !func_80329530(this, arg1)){
if(func_80329530(this, max_distance) && !func_80329530(this, min_distance)){
return 1;
}
return 0;
}
int func_802E1F70(ActorMarker *marker, s32 arg1){
int __chSnowman_func_802E1F70(ActorMarker *marker, s32 arg1){
if(marker->unk40_31 == 0xB){
marker->unk14_20 = 0x287;
}
else{
marker->unk14_20 = 0xB1;
marker->unk14_20 = MARKER_B1_SIR_SLUSH;
}
return 1;
return TRUE;
}
void func_802E1FD0(ActorMarker *marker, ActorMarker *other_marker){
void __chSnowman_deathCallback(ActorMarker *marker, ActorMarker *other_marker){
Actor *actor = marker_getActor(marker);
FUNC_8030E8B4(SFX_15_METALLIC_HIT_2, 1.0f, 30000, actor->position, 1500, 4500);
FUNC_8030E8B4(SFX_3EA_UNKNOWN, 1.0f, 30000, actor->position, 1500, 4500);
FUNC_8030E8B4(SFX_2F_ORANGE_SPLAT, 1.0f, 30000, actor->position, 1500, 4500);
__spawnQueue_add_1((GenMethod_1)func_802E1BD0, (s32)actor->marker);
__spawnQueue_add_1((GenMethod_1)__chSnowman_spawnHat, (s32)actor->marker);
if(map_get() == MAP_27_FP_FREEZEEZY_PEAK)
func_8038A978();
func_802E1CB8(actor->position, 0xC);
__chSnowman_spawnSnowballParticles(actor->position, 0xC);
marker_despawn(actor->marker);
}
int func_802E208C(void){
f32 sp1C[3];
int __chSnowman_CCW_playerInProtectedZone(void){
static f32 ccw_no_attack_zone[3] = {350.0f, 600.0f, 65.0f};
f32 player_position[3];
if(map_get() == MAP_46_CCW_WINTER){
player_getPosition(sp1C);
if(func_802592C4(sp1C, D_80368704, 900.0f))
player_getPosition(player_position);
if(func_802592C4(player_position, ccw_no_attack_zone, 900.0f))
return 1;
}
return 0;
}
//chSirSlush_update
void func_802E20E8(Actor *this){
void chSnowman_update(Actor *this){
ActorLocal_chSirSlush *local = (ActorLocal_chSirSlush *) &this->local;
f32 sp38;
f32 dt;
sp38 = time_getDelta();
dt = time_getDelta();
if(!this->unk16C_4){
this->unk16C_4 = TRUE;
this->marker->propPtr->unk8_3 = 0;
actor_collisionOn(this);
marker_setCollisionScripts(this->marker, NULL, NULL, func_802E1FD0);
func_803300C0(this->marker, func_802E1F70);
marker_setCollisionScripts(this->marker, NULL, NULL, __chSnowman_deathCallback);
func_803300C0(this->marker, __chSnowman_func_802E1F70);
local->unk9 = 0;
local->unkA = 1;
local->unkB = 0;
@@ -244,12 +247,12 @@ void func_802E20E8(Actor *this){
local->unkB = 1;
}//L802E2280
switch(this->state){
case 1://L802E22B0
case CHSNOWMAN_STATE_1_IDLE://L802E22B0
local->unk9 = FALSE;
local->unkA = 1;
func_802E1E20(this, 6.0f);
if(!func_80329530(this, 0xC4E)){
func_802E1DE8(this);
__chSnowman_setYawTarget(this, 6.0f);
if(!func_80329530(this, 3150)){
__chSnowman_enterDeath(this);
}
else if(
map_get() != MAP_27_FP_FREEZEEZY_PEAK
@@ -260,36 +263,36 @@ void func_802E20E8(Actor *this){
if( (func_8023DB5C() & 1)
|| func_8028ECAC() == BSGROUP_A_FLYING
){//L802E236C
local->unk4 -= sp38;
local->unk4 -= dt;
}
}
else{//L802E2380
if( func_802E1EB4(this, 0x1f4, 0xabe)
&& func_802E1E5C(this, 3)
if( __chSnowman_isPlayerInAttackRange(this, 500, 2750)
&& __chSnowman_isYawNearYawTarget(this, 3)
&& func_8028EE84() != BSWATERGROUP_2_UNDERWATER
&& !func_802E208C()
&& !__chSnowman_CCW_playerInProtectedZone()
){
func_80328B8C(this, 2, 0.01f, 1);
func_80328B8C(this, CHSNOWMAN_STATE_2_ATTACK, 0.01f, 1);
actor_playAnimationOnce(this);
}
}
}
break;
case 2://L802E23E8
if(!func_80329530(this, 0xC4E)){
func_802E1DE8(this);
case CHSNOWMAN_STATE_2_ATTACK://L802E23E8
if(!func_80329530(this, 3150)){
__chSnowman_enterDeath(this);
}//L802E240C
else if(
0.98 < animctrl_getAnimTimer(this->animctrl)
|| !func_802E1EB4(this, 0x1f4, 0xabe)
|| !__chSnowman_isPlayerInAttackRange(this, 500, 2750)
|| func_8028EE84() == BSWATERGROUP_2_UNDERWATER
|| func_802E208C()
|| __chSnowman_CCW_playerInProtectedZone()
){
func_802E1DA0(this);
__chSnowman_enterIdle(this);
}
else{
if(animctrl_getAnimTimer(this->animctrl) < 0.45){
func_802E1E20(this, 6.0f);
__chSnowman_setYawTarget(this, 6.0f);
}
if( actor_animationIsAt(this, 0.19f)
|| actor_animationIsAt(this, 0.28f)
@@ -309,15 +312,15 @@ void func_802E20E8(Actor *this){
&& local->unkB
){
func_8030E878(SFX_8F_SNOWBALL_FLYING, randf2(0.95f, 1.05f), 30000, this->position, 800.0f, 3050.0f);
__spawnQueue_add_1((GenMethod_1)func_802E1B24, (s32)this->marker);
__spawnQueue_add_1((GenMethod_1)__chSnowman_spawnSnowball, (s32)this->marker);
local->unk9 = FALSE;
}
}
break;
case 3://L802E2604
if(func_80329530(this, 0xC4E)){
func_802E1DA0(this);
case CHSNOWMAN_STATE_3_DIE://L802E2604
if(func_80329530(this, 3150)){
__chSnowman_enterIdle(this);
}
break;
}