diff --git a/src/SB/Core/x/xModel.h b/src/SB/Core/x/xModel.h index 885667b0a..9af789f0d 100644 --- a/src/SB/Core/x/xModel.h +++ b/src/SB/Core/x/xModel.h @@ -151,6 +151,8 @@ void xModel_SceneExit(RpWorld* world); xSphere* xModelGetLocalSBound(xModelInstance* model); void xModelGetBoneMat(xMat4x3& mat, const xModelInstance& model, size_t index); void xModelInstanceUpgradeBrotherShared(xModelInstance* inst, U32 flags); +xVec3 xModelGetBoneLocation(const xModelInstance& model, + size_t index); // Based off the usage in zNPCTypeDutchman inline void xModelSetFrame(xModelInstance* modelInst, const xMat4x3* frame) { diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index b2ed0f2b3..4b3b5b714 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -10,6 +10,8 @@ #include "xSFX.h" #include "xstransvc.h" #include "xDraw.h" +#include "xstransvc.h" +#include "xDraw.h" #include "zNPCSndTable.h" #include "zMovePoint.h" diff --git a/src/SB/Game/zNPCTypeDutchman.cpp b/src/SB/Game/zNPCTypeDutchman.cpp index 0dd9152cd..8a049ef2f 100644 --- a/src/SB/Game/zNPCTypeDutchman.cpp +++ b/src/SB/Game/zNPCTypeDutchman.cpp @@ -34,6 +34,8 @@ static U32 dutchman_count; +extern NPCSndTrax g_sndTrax_Dutchman; + namespace { @@ -159,6 +161,7 @@ namespace tweak_callback cb_sound; void register_tweaks(bool init, xModelAssetParam* ap, U32 apsize, const char*); + void load(xModelAssetParam*, U32); }; struct sound_data_type @@ -181,6 +184,7 @@ namespace F32 scale; }; + static delay_goal sequence[3][16]; static sound_data_type sound_data[6]; static sound_asset sound_assets[6]; static xBinaryCamera boss_cam; @@ -229,8 +233,9 @@ namespace static tweak_group tweak; - static void set_volume(S32 which, U32, F32 new_vol) + static void set_volume(S32 which, U32 unk, F32 new_vol) { + xSndSetVol(tweak.sound->volume * unk, new_vol); } void tweak_group::register_tweaks(bool init, xModelAssetParam* ap, U32 apsize, const char*) @@ -1275,6 +1280,16 @@ void zNPCDutchman::RenderExtra() RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)&oldcmp); } +void zNPCDutchman::ParseINI() +{ + zNPCCommon::ParseINI(); + cfg_npc->snd_traxShare = &g_sndTrax_Dutchman; + NPCS_SndTablePrepare(&g_sndTrax_Dutchman); + cfg_npc->snd_trax = &g_sndTrax_Dutchman; + NPCS_SndTablePrepare(&g_sndTrax_Dutchman); + tweak.load(parmdata, pdatsize); +} + void zNPCDutchman::SelfSetup() { xBehaveMgr* bmgr = xBehaveMgr_GetSelf(); @@ -1352,14 +1367,13 @@ U32 zNPCDutchman::AnimPick(S32 rawgoal, en_NPC_GOAL_SPOT gspot, xGoal* goal) void zNPCDutchman::LassoNotify(en_LASSO_EVENT event) { - if ((event != 3) && (event < 3) && (event > 1)) + if ((event != 3) && (event < 3) && (event < 2)) { - // xPsyche::GoalSet(NPC_GOAL_DUTCHMANCAUGHT, 1); + psy_instinct->GoalSet('NGMF', 1); } zNPCCommon::LassoNotify(event); } -//NPC_GOAL_DUTCHMANCAUGHT // double zNPCDutchman::goal_delay() // { @@ -1393,6 +1407,16 @@ void zNPCDutchman::update_round() stage = -1; } +S32 zNPCDutchman::next_goal() +{ + return 0; +} + +F32 zNPCDutchman::goal_delay() +{ + return 0; +} + void zNPCDutchman::decompose() { if (flag.fighting != 0) @@ -1402,7 +1426,7 @@ void zNPCDutchman::decompose() disable_emitter(*fadein_emitter); disable_emitter(*fadeout_emitter); zCameraEnableTracking(CO_BOSS); - boss_cam.stop; + boss_cam.stop(); } } @@ -1410,8 +1434,17 @@ void zNPCDutchman::render_debug() { } -void zNPCDutchman::update_animation(float) +void zNPCDutchman::update_animation(F32) +{ +} + +void zNPCDutchman::update_camera(F32 dt) { + zCameraDisableTracking(CO_BOSS); + if ((zCameraIsTrackingDisabled() & -9) == 0) + { + boss_cam.update(dt); + } } void zNPCDutchman::kill_wave(zNPCDutchman::wave_data& wave) @@ -1450,7 +1483,7 @@ void zNPCDutchman::stop_hand_trail() void zNPCDutchman::dissolve(F32 delay) { F32 volume; - if (delay == 0.0f) + if (delay <= 0.0f) { flag.fade = FADE_TELEPORT; disable_emitter(*fadeout_emitter); @@ -1483,15 +1516,140 @@ void zNPCDutchman::dissolve(F32 delay) } } +void zNPCDutchman::coalesce(F32 delay) +{ + reappear(); + if (delay <= 0.0f) + { + flag.fade = FADE_NONE; + disable_emitter(*fadein_emitter); + disable_emitter(*dissolve_emitter); + set_alpha(1.0f); + stop_eye_glow(); + stop_hand_trail(); + if (fade.sound_handle != 0) + { + kill_sound(2, fade.sound_handle); + fade.sound_handle = 0; + } + } + else + { + flag.fade = FADE_COALESCE; + fade.time = 0.0f; + fade.duration = delay; + fade.iduration = 1.0f / fade.duration; + enable_emitter(*fadein_emitter); + enable_emitter(*dissolve_emitter); + set_alpha(0.0f); + start_eye_glow(); + start_hand_trail(); + if (fade.sound_handle != 0) + { + set_volume(2, fade.sound_handle, 1.0f); + } + } +} + +void zNPCDutchman::reset_blob_mat() +{ + // Decomp.me says 90% + F32 temp; + F32 temp2; + + temp = isin(tweak.flame.blob_pitch); + temp2 = icos(tweak.flame.blob_pitch); + flames.blob_mat.right.assign(1.0f, 0.0f, 0.0f); + flames.blob_mat.up.assign(0.0f, temp2, temp); + flames.blob_mat.at.assign(0.0f, -temp, temp2); +} + void zNPCDutchman::reset_lasso_anim() { xAnimPlaySetState(0, lassdata->holdGuideAnim, 0); } +void zNPCDutchman::update_fade(F32 delay) +{ + F32 frac; + if (flag.fade != FADE_TELEPORT) + { + if (flag.fade < 1) + { + if (flag.fade < 4) + { + fade.time = fade.time + delay; + if (fade.time >= fade.duration) + { + flag.fade = FADE_TELEPORT; + disable_emitter(*fadeout_emitter); + set_alpha(0.0f); + vanish(); + set_volume(2, fade.sound_handle, 1.0f); + } + else + { + frac = fade.time * fade.iduration; + set_alpha(1.0f - frac); + set_volume(2, fade.sound_handle, frac); + } + } + } + else if (flag.fade < 4) + { + fade.time = fade.time + delay; + if (fade.time >= fade.duration) + { + flag.fade = FADE_NONE; + disable_emitter(*fadein_emitter); + disable_emitter(*dissolve_emitter); + set_alpha(1.0f); + stop_eye_glow(); + stop_hand_trail(); + reappear(); + kill_sound(2, fade.sound_handle); + fade.sound_handle = 0; + } + else + { + frac = fade.time * fade.iduration; + set_alpha(frac); + set_volume(2, fade.sound_handle, 1.0f - frac); + } + } + } +} + void zNPCDutchman::add_splash(const xVec3&, float) { } +void zNPCDutchman::start_fight() +{ + if (flag.fighting == 0 && life <= 0) + { + flag.fighting = 1; + psy_instinct->GoalSet(0, 0); + zCameraDisableTracking(CO_BOSS); + boss_cam.start(globals.camera); + boss_cam.set_targets((xVec3&)globals.player.ent.model->Mat->pos, (xVec3&)model->Mat->pos, + 2.0f); + } +} + +void zNPCDutchman::set_life(S32 lf) +{ + life = range_limit(life, 0, 3); + if (life < lf) + { + flag.hurting = 1; + for (S32 i = life; i < life; i++) + { + zEntEvent((xBase*)lf, (xBase*)lf, 0x1d7); // Haven't found 0x1d7. only 0x1d8 and 0x1d4 + } + } +} + void zNPCDutchman::start_beam() { if ((flag.beaming) != 0) @@ -1532,6 +1690,21 @@ void zNPCDutchman::stop_flames() flag.flaming = false; } +void zNPCDutchman::get_eye_loc(S32 idx) const +{ + // Not sure if this is correct. + static size_t lookup; + xModelGetBoneLocation(*model, lookup << 2 + idx); +} + +void zNPCDutchman::get_hand_loc(S32) const +{ +} + +void zNPCDutchman::get_splash_loc() const +{ +} + void zNPCDutchman::vanish() { old.moreFlags = moreFlags; @@ -1555,13 +1728,25 @@ void zNPCDutchman::reset_speed() { } +void zNPCDutchman::render_beam() +{ +} + xFactoryInst* zNPCGoalDutchmanInitiate::create(S32 who, RyzMemGrow* grow, void* info) { return new (who, grow) zNPCGoalDutchmanInitiate(who, (zNPCDutchman&)*info); } +S32 zNPCGoalDutchmanInitiate::Enter(F32 dt, void* updCtxt) +{ + owner.get_orbit(); + owner.face_player(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + S32 zNPCGoalDutchmanInitiate::Exit(F32 dt, void* updCtxt) { + owner.turn.accel = tweak.turn_accel; return xGoal::Exit(dt, updCtxt); } @@ -1581,12 +1766,12 @@ S32 zNPCGoalDutchmanIdle::Exit(F32 dt, void* updCtxt) return xGoal::Exit(dt, updCtxt); } -S32 zNPCGoalDutchmanIdle::Process(en_trantype* trantype, float dt, void* updCtxt, xScene* xscn) +S32 zNPCGoalDutchmanIdle::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn) { - owner.goal_delay(); - if (owner.delay == owner.delay) + F32 tmpFlt = owner.goal_delay(); + if (owner.delay >= tmpFlt) { - owner.delay = 1; + owner.delay = 0; owner.next_goal(); } @@ -1650,6 +1835,10 @@ S32 zNPCGoalDutchmanBeam::Exit(F32 dt, void* updCtxt) return xGoal::Exit(dt, updCtxt); } +void zNPCGoalDutchmanBeam::update_stop(F32 dt) +{ +} + xFactoryInst* zNPCGoalDutchmanFlame::create(S32 who, RyzMemGrow* grow, void* info) { return new (who, grow) zNPCGoalDutchmanFlame(who, (zNPCDutchman&)*info); diff --git a/src/SB/Game/zNPCTypeDutchman.h b/src/SB/Game/zNPCTypeDutchman.h index a2de6e5ae..ef3fd80b6 100644 --- a/src/SB/Game/zNPCTypeDutchman.h +++ b/src/SB/Game/zNPCTypeDutchman.h @@ -124,10 +124,10 @@ struct zNPCDutchman : zNPCSubBoss { xVec2 dir; //0x2d4 F32 vel; //0x2dc - F32 accel; //0x2e0 - F32 max_vel; //0x2e4 + F32 accel; //0x2e4 + F32 max_vel; //0x2e8 } turn; - move_info move; //0x2e8 + move_info move; struct { U8 moreFlags; //0x31c @@ -181,6 +181,7 @@ struct zNPCDutchman : zNPCSubBoss S32* handled); void Render(); void RenderExtra(); + void ParseINI(); void SelfSetup(); void render_debug(); void update_turn(F32); @@ -202,12 +203,15 @@ struct zNPCDutchman : zNPCSubBoss void start_flames(); void stop_flames(); U8 check_player_damage(); + void get_eye_loc(S32) const; void get_hand_loc(S32) const; + void get_splash_loc() const; void start_hand_trail(); void stop_hand_trail(); void refresh_reticle(); void update_hand_trail(F32); void dissolve(F32); + void coalesce(F32); void reset_lasso_anim(); void update_fade(F32); void update_slime(F32); @@ -218,8 +222,8 @@ struct zNPCDutchman : zNPCSubBoss S32 LassoSetup(); void update_round(); void decompose(); - void next_goal(); - void goal_delay(); + S32 next_goal(); + F32 goal_delay(); void start_eye_glow(); void stop_eye_glow(); void update_eye_glow(F32); @@ -231,6 +235,8 @@ struct zNPCDutchman : zNPCSubBoss void enable_emitter(zParEmitter&) const; void disable_emitter(zParEmitter&) const; + void turning() const; // Not sure this is the correct return type + void turning(F32) const; // Not sure this is the correct return type U8 PhysicsFlags() const; U8 ColPenByFlags() const; U8 ColChkByFlags() const; @@ -251,6 +257,7 @@ struct zNPCGoalDutchmanInitiate : zNPCGoalCommon { } + S32 Enter(float, void*); S32 Exit(float, void*); static xFactoryInst* create(S32 who, RyzMemGrow* grow, void* info); @@ -344,6 +351,7 @@ struct zNPCGoalDutchmanBeam : zNPCGoalCommon } S32 Exit(float, void*); + void update_stop(F32 dt); static xFactoryInst* create(S32 who, RyzMemGrow* grow, void* info); };