diff --git a/src/SB/Game/zNPCGoalStd.h b/src/SB/Game/zNPCGoalStd.h index 3658dadf..0c9e0ed9 100644 --- a/src/SB/Game/zNPCGoalStd.h +++ b/src/SB/Game/zNPCGoalStd.h @@ -75,7 +75,11 @@ struct zNPCGoalLoopAnim : zNPCGoalCommon U32 origAnimFlags; U32 animWeMolested; - // void* __ct(S32 myType); + zNPCGoalLoopAnim(S32 myType) : zNPCGoalCommon(myType) + { + SetFlags(1 << 1); + } + void LoopCountSet(S32 unk); // return type might be wrong }; @@ -194,7 +198,11 @@ struct zNPCGoalPushAnim : zNPCGoalCommon S32 flg_pushanim; F32 lastAnimTime; - // void* __ct(S32 myType); + zNPCGoalPushAnim(S32 myType) : zNPCGoalCommon(myType) + { + SetFlags((1 << 2) | (1 << 1)); + } + S32 Enter(F32 dt, void* updCtxt); }; diff --git a/src/SB/Game/zNPCGoalVillager.cpp b/src/SB/Game/zNPCGoalVillager.cpp index 4e11d38c..0ac14683 100644 --- a/src/SB/Game/zNPCGoalVillager.cpp +++ b/src/SB/Game/zNPCGoalVillager.cpp @@ -1,8 +1,62 @@ #include +#include "xMath.h" +#include "xutil.h" +#include "zEntPickup.h" +#include "zGameExtras.h" #include "zGlobals.h" #include "zNPCGoalVillager.h" #include "zNPCTypeVillager.h" +#include "zNPCGoals.h" +#include "zGoo.h" +#include "zSurface.h" + +xFactoryInst* GOALCreate_Villager(S32 who, RyzMemGrow* grow, void*) +{ + xGoal* goal = NULL; + + switch (who) + { + case NPC_GOAL_PLAYERNEAR: + goal = new (who, grow) zNPCGoalPlayerNear(who); + break; + case NPC_GOAL_TALK: + goal = new (who, grow) zNPCGoalTalk(who); + break; + case NPC_GOAL_CHATTER: + goal = new (who, grow) zNPCGoalChatter(who); + break; + case NPC_GOAL_SPEAK: + goal = new (who, grow) zNPCGoalSpeak(who); + break; + case NPC_GOAL_CHEER: + goal = new (who, grow) zNPCGoalCheer(who); + break; + case NPC_GOAL_HURT: + goal = new (who, grow) zNPCGoalHurt(who); + break; + case NPC_GOAL_BALLOON: + goal = new (who, grow) zNPCGoalBalloon(who); + break; + case NPC_GOAL_BOYRIDE: + goal = new (who, grow) zNPCGoalBoyRide(who); + break; + case NPC_GOAL_BOYFALL: + goal = new (who, grow) zNPCGoalBoyFall(who); + break; + case NPC_GOAL_BOYWEEP: + goal = new (who, grow) zNPCGoalBoyWeep(who); + break; + case NPC_GOAL_BOYSWIM: + goal = new (who, grow) zNPCGoalBoySwim(who); + break; + default: + xUtil_idtag2string(who, 0); + break; + } + + return goal; +} void zNPCGoalPlayerNear::DoCheatPanHandle() { @@ -12,47 +66,58 @@ void zNPCGoalPlayerNear::DoCheatPanHandle() } } +void zNPCGoalHurt::ChkRewardCheat() +{ + static const U32 shinies[] = { 4, 2, 1 }; + + if (zGameExtras_CheatFlags() & (1 << 20)) + { + zNPCCommon* npc = (zNPCCommon*)psyche->clt_owner; + zEntPickup_SpawnNRewards((U32*)shinies, 3, npc->Center()); + } +} + S32 zNPCGoalBalloon::Enter(F32 dt, void* updCtxt) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; - bboy->specialBalloon = 1; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + npc->specialBalloon = 1; - zNPCGoalCommon::Enter(dt, updCtxt); + return zNPCGoalCommon::Enter(dt, updCtxt); } S32 zNPCGoalBalloon::Exit(F32 dt, void* updCtxt) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; - bboy->specialBalloon = 0; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + npc->specialBalloon = 0; - xGoal::Exit(dt, updCtxt); + return xGoal::Exit(dt, updCtxt); } S32 zNPCGoalBalloon::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; - S32 type; - if (bboy->plat_balloons != NULL) + S32 nextgoal; + if (npc->plat_balloons != NULL) { *trantype = GOAL_TRAN_PUSH; - type = 'NGS?'; + nextgoal = NPC_GOAL_BOYRIDE; } else { *trantype = GOAL_TRAN_SET; - type = 'NGS@'; + nextgoal = NPC_GOAL_BOYFALL; } // This is always true if (*trantype != GOAL_TRAN_NONE) { - return type; + return nextgoal; } - if (type != 0) + if (nextgoal != 0) { - return type; + return nextgoal; } return xGoal::Process(trantype, dt, updCtxt, NULL); @@ -84,72 +149,149 @@ S32 zNPCGoalBalloon::NPCMessage(NPCMsg* mail) S32 zNPCGoalBoyRide::Enter(F32 dt, void* updCtxt) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; - bboy->flags2.flg_colCheck = 0; - bboy->flags2.flg_penCheck = 0; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + npc->flags2.flg_colCheck = 0; + npc->flags2.flg_penCheck = 0; - zNPCGoalCommon::Enter(dt, updCtxt); + return zNPCGoalCommon::Enter(dt, updCtxt); } S32 zNPCGoalBoyRide::Exit(F32 dt, void* updCtxt) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; - bboy->RestoreColFlags(); + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + npc->RestoreColFlags(); - xGoal::Exit(dt, updCtxt); + return xGoal::Exit(dt, updCtxt); } S32 zNPCGoalBoyRide::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) { - S32 type = 0; - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; - if (bboy->plat_balloons == NULL) + S32 nextgoal = 0; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + if (npc->plat_balloons == NULL) { *trantype = GOAL_TRAN_SWAP; - type = 'NGS@'; + nextgoal = NPC_GOAL_BOYFALL; } - if (type != 0) + if (nextgoal != 0) { - return type; + return nextgoal; } - xVec3* pos = xEntGetPos(bboy->plat_balloons); - xVec3Copy(&bboy->frame->mat.pos, pos); - xMat3x3Copy((xMat3x3*)&bboy->frame->mat, (xMat3x3*)bboy->plat_balloons->model->Mat); + xVec3Copy(&npc->frame->mat.pos, xEntGetPos(npc->plat_balloons)); + xMat3x3Copy((xMat3x3*)&npc->frame->mat, (xMat3x3*)npc->plat_balloons->model->Mat); - bboy->frame->mode |= 0x41; + npc->frame->mode |= 0x41; - bboy->PlatAnimSync(); + npc->PlatAnimSync(); return xGoal::Process(trantype, dt, updCtxt, NULL); } S32 zNPCGoalBoyRide::NPCMessage(NPCMsg* mail) { - zNPCBalloonBoy* bboy = (zNPCBalloonBoy*)psyche->clt_owner; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; S32 handled = 1; switch (mail->msgid) { - case NPC_MID_SYSEVENT: - if (mail->sysevent.toEvent == eEventNPCSpecial_PlatformFall) - { - bboy->plat_balloons = NULL; - } - else - { - handled = 0; - } - break; - case NPC_MID_DAMAGE: - DoAutoAnim(NPC_GSPOT_ALTA, 0); - bboy->PlatAnimSet(BBOY_PLATANIM_HIT); - break; - default: + case NPC_MID_SYSEVENT: + if (mail->sysevent.toEvent == eEventNPCSpecial_PlatformFall) + { + npc->plat_balloons = NULL; + } + else + { handled = 0; - break; + } + break; + case NPC_MID_DAMAGE: + DoAutoAnim(NPC_GSPOT_ALTA, 0); + npc->PlatAnimSet(BBOY_PLATANIM_HIT); + break; + default: + handled = 0; + break; } return handled; } + +S32 zNPCGoalBoyFall::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) +{ + S32 nextgoal = 0; + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + + if (hitGround != 0) + { + xAnimState* anim_state = npc->AnimCurState(); + if (npc->AnimTimeRemain(anim_state) < dt + 0.001f) + { + *trantype = GOAL_TRAN_SET; + nextgoal = NPC_GOAL_BOYWEEP; + } + else if (anim_state->ID != anid_played) + { + *trantype = GOAL_TRAN_SET; + nextgoal = NPC_GOAL_BOYWEEP; + } + } + + if (nextgoal != 0) + { + return nextgoal; + } + + // Nonmatching + xEntFrame* frame = npc->frame; + F32 fVar2 = (frame->vel.y - dt * 10.0f); + F32 fVar1 = (fVar2 > -4.0f) ? -4.0f : fVar2; + frame->vel.y = fVar1; + + npc->colFreq = (npc->colFreq < 0) ? npc->colFreq : 0; + + return xGoal::Process(trantype, dt, updCtxt, NULL); +} + +// Nonmatching: not finished +U8 zNPCGoalBoyFall::CollReview(void*) +{ + if (hitGround != 0) + { + return 0; + } + + zNPCBalloonBoy* npc = (zNPCBalloonBoy*)psyche->clt_owner; + xEntCollis* collis = npc->collis; + if (collis->colls[0].flags & 1) + { + return 0; + } + + zSurfaceGetSurface(&collis->colls[0]); + F32 meme[1]; + meme[0] = 0.0f; + xEnt* ent = (xEnt*)collis->colls[0].optr; + if (ent == NULL) + { + hitGround = 1; + } + else if (zGooIs(ent, (F32&)*meme, 0)) + { + hitGround = 2; + } + else + { + hitGround = 1; + } + DoAutoAnim(NPC_GSPOT_ALTA, 0); + return 1; +} + +S32 zNPCGoalBoyWeep::Enter(F32 dt, void* updCtxt) +{ + tmr_weep = 300.0f * (0.25f * (xurand() - 0.5f)) + 300.0f; + ang_spinrate = 0.0f; + return zNPCGoalCommon::Enter(dt, updCtxt); +} diff --git a/src/SB/Game/zNPCGoalVillager.h b/src/SB/Game/zNPCGoalVillager.h index 8241edbd..a1d418d8 100644 --- a/src/SB/Game/zNPCGoalVillager.h +++ b/src/SB/Game/zNPCGoalVillager.h @@ -1,30 +1,151 @@ #ifndef ZNPCGOALVILLAGER_H #define ZNPCGOALVILLAGER_H +#include "xSFX.h" +#include "zNPCGlyph.h" #include "zNPCGoalCommon.h" +#include "zNPCGoalStd.h" -class zNPCGoalPlayerNear : zNPCGoalCommon +struct zNPCGoalCheer : zNPCGoalLoopAnim { -public: + zNPCGoalCheer(S32 goalID) : zNPCGoalLoopAnim(goalID) + { + SetFlags(1 << 1); + } +}; + +struct zNPCGoalHurt : zNPCGoalPushAnim +{ + zNPCGoalHurt(S32 goalID) : zNPCGoalPushAnim(goalID) + { + SetFlags(1 << 1); + } + + void ChkRewardCheat(); +}; + +// FIXME: Put this in somewhere. +struct NPCWidget; + +struct zNPCGoalPlayerNear : zNPCGoalCommon +{ + S32 flg_plyrnear; + NPCGlyph* talk_glyph; + NPCWidget* talk_font; + F32 tmr_actBored; + + zNPCGoalPlayerNear(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags((1 << 3) | (1 << 2)); + } + void DoCheatPanHandle(); }; -class zNPCGoalBalloon : zNPCGoalCommon +struct zNPCGoalTalk : zNPCGoalCommon { - virtual S32 Enter(F32 ft, void* updCtxt); - virtual S32 Exit(F32 ft, void* updCtxt); + F32 tmr_cycleAnim; + F32 tmr_minTalk; + S32 stopTalking; + S32 killAndExit; + xSFX* sfx_curTalk; + U32 aid_curSound; + xVec3 pos_maintain; + void* jawdata; + F32 jawtime; + + zNPCGoalTalk(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + } +}; + +struct zNPCGoalChatter : zNPCGoalCommon +{ + U32 sid_played; + U32 playThisSound; + + zNPCGoalChatter(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + } +}; + +struct zNPCGoalSpeak : zNPCGoalCommon +{ + F32 tmr_cycleAnim; + xVec3 pos_maintain; + void* jawdata; + F32 jawtime; + + zNPCGoalSpeak(S32 goalID) : zNPCGoalCommon(goalID) + { + } +}; + +struct zNPCGoalBalloon : zNPCGoalCommon +{ + zNPCGoalBalloon(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags((1 << 3) | (1 << 2)); + AddFlags(1 << 17); + } + + virtual S32 Enter(F32 dt, void* updCtxt); + virtual S32 Exit(F32 dt, void* updCtxt); virtual S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); virtual S32 NPCMessage(NPCMsg* mail); }; -class zNPCGoalBoyRide : zNPCGoalCommon +struct zNPCGoalBoyRide : zNPCGoalCommon { - virtual S32 Enter(F32 ft, void* updCtxt); - virtual S32 Exit(F32 ft, void* updCtxt); + zNPCGoalBoyRide(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + } + + virtual S32 Enter(F32 dt, void* updCtxt); + virtual S32 Exit(F32 dt, void* updCtxt); virtual S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); virtual S32 NPCMessage(NPCMsg* mail); }; +struct zNPCGoalBoyFall : zNPCGoalCommon +{ + S32 hitGround; + + zNPCGoalBoyFall(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + flg_npcgable |= (1 << 0); + } + + virtual S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); + virtual U8 CollReview(void*); +}; + +struct zNPCGoalBoyWeep : zNPCGoalCommon +{ + F32 tmr_weep; + F32 ang_spinrate; + + zNPCGoalBoyWeep(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + } + + virtual S32 Enter(F32 dt, void* updCtxt); + virtual S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); +}; + +struct zNPCGoalBoySwim : zNPCGoalCommon +{ + zNPCGoalBoySwim(S32 goalID) : zNPCGoalCommon(goalID) + { + SetFlags(1 << 1); + } +}; + xFactoryInst* GOALCreate_Villager(S32 who, RyzMemGrow* grow, void*); #endif diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index 74dc4dfe..c23cd528 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -405,6 +405,7 @@ struct zNPCCommon : xNPCBasic void ModelScaleSet(F32 unk); void ModelScaleSet(const xVec3* vec); S32 AnimStart(U32 animID, S32 forceRestart); + xAnimState* AnimCurState(); U32 AnimCurStateID(); void GiveReward(); S32 SndPlayRandom(en_NPC_SOUND sndtype); diff --git a/src/SB/Game/zSurface.h b/src/SB/Game/zSurface.h index d2f5a3a5..a6fe2cca 100644 --- a/src/SB/Game/zSurface.h +++ b/src/SB/Game/zSurface.h @@ -121,7 +121,7 @@ struct xScene; void zSurfaceRegisterMapper(U32 assetId); void zSurfaceExit(); xSurface* zSurfaceGetSurface(U32 mat_id); -// xSurface* zSurfaceGetSurface(const xCollis* coll); +xSurface* zSurfaceGetSurface(const xCollis* coll); U32 zSurfaceGetStandOn(const xSurface* surf); void zSurfaceSave(xSurface* ent, xSerial* s); void zSurfaceLoad(xSurface* ent, xSerial* s);