diff --git a/src/SB/Game/zNPCTypeTiki.cpp b/src/SB/Game/zNPCTypeTiki.cpp index 892e00254..703531b17 100644 --- a/src/SB/Game/zNPCTypeTiki.cpp +++ b/src/SB/Game/zNPCTypeTiki.cpp @@ -6,6 +6,7 @@ #include "xVec3.h" #include "xutil.h" +#include "zEntButton.h" #include "zGlobals.h" #include "zGoo.h" #include "zNPCGoals.h" @@ -62,7 +63,7 @@ void ZNPC_Tiki_Shutdown() void zNPCTiki_InitStacking(zScene* zsc) { - for (int i = 0; i < zsc->num_npcs; i++) + for (S32 i = 0; i < zsc->num_npcs; i++) { xNPCBasic* npc = (xNPCBasic*)zsc->npcs[i]; @@ -73,7 +74,7 @@ void zNPCTiki_InitStacking(zScene* zsc) continue; } - zNPCTiki* tiki = (zNPCTiki*)(npc); + zNPCTiki* tiki = (zNPCTiki*)npc; if (npc->SelfType() != NPC_TYPE_TIKI_LOVEY) { tiki->FindParents(zsc); @@ -150,66 +151,61 @@ void zNPCTiki_InitFX(zScene* scene) void zNPCTiki_ExplodeFX(zNPCTiki* tiki) { + xVec3 shockwavePos; + xVec3 delta; // not in dwarf + NPCHazard* haz; + zScene* zsc; + U32 i; + if (tiki->SelfType() == NPC_TYPE_TIKI_THUNDER) { xScrFXGlareAdd((xVec3*)&tiki->model->Mat->pos, 0.7f, 0.2f, 5.0f, 1.0f, 1.0f, 0.75f, 1.0f, NULL); - xVec3 pos; - xVec3Copy(&pos, (xVec3*)&tiki->model->Mat->pos); - pos.y += 0.35f; + xVec3Copy(&shockwavePos, (xVec3*)&tiki->model->Mat->pos); + shockwavePos.y += 0.35f; - NPCHazard* haz = HAZ_Acquire(); - if (haz) - { - haz->ConfigHelper(NPC_HAZ_THUNDER); - haz->SetNPCOwner(tiki); - haz->Start(xEntGetCenter(tiki), -1.0f); - } + haz = HAZ_Acquire(); + if (!haz) + return; + + haz->ConfigHelper(NPC_HAZ_THUNDER); + haz->SetNPCOwner(tiki); + haz->Start(xEntGetCenter(tiki), -1.0f); - zScene* scene = globals.sceneCur; + zsc = globals.sceneCur; - for (U32 idx = 0; idx < scene->num_npcs; idx++) + for (i = 0; i < zsc->num_npcs; i++) { - zNPCTiki* other = (zNPCTiki*)scene->npcs[idx]; - if (other == tiki || !other->flg_vuln) + if (zsc->npcs[i] == tiki || !((zNPCCommon*)zsc->npcs[i])->flg_vuln) continue; - xVec3 delta; - xVec3Sub(&delta, (xVec3*)&tiki->model->Mat->pos, (xVec3*)&other->model->Mat->pos); + xVec3Sub(&delta, (xVec3*)&tiki->model->Mat->pos, + (xVec3*)&(zsc->npcs[i])->model->Mat->pos); F32 dist2 = xVec3Length2(&delta); - if (dist2 < 25.0f) { - if ((other->SelfType() & ~0xFF) == 'NTT\0') - other->timeToLive = dist2 * 0.012f; - - other->Damage(DMGTYP_THUNDER_TIKI_EXPLOSION, 0, 0); + if ((((zNPCCommon*)zsc->npcs[i])->SelfType() & ~0xFF) == 'NTT\0') + ((zNPCTiki*)zsc->npcs[i])->timeToLive = dist2 * 0.012f; + ((zNPCCommon*)zsc->npcs[i])->Damage(DMGTYP_THUNDER_TIKI_EXPLOSION, 0, 0); } } - for (U32 idx = 0; idx < scene->num_dyns; idx++) + for (i = 0; i < zsc->num_dyns; i++) { - xBase* dyn = (xBase*)scene->dyns[idx]; - if (dyn->baseType != 0x1B) + if ((zsc->dyns[i])->baseType != 0x1B) continue; - xModelInstance* model = *((xModelInstance**)((char*)dyn + 2)); - xVec3 delta; - xVec3Sub(&delta, (xVec3*)&tiki->model->Mat->pos, (xVec3*)&model->Mat->pos); - - if (xVec3Length2(&delta) < 25.0f) - zEntEvent(dyn, 0x3A); - } - - { - xVec3 delta; xVec3Sub(&delta, (xVec3*)&tiki->model->Mat->pos, - (xVec3*)&globals.player.ent.model->Mat->pos); - + (xVec3*)&((xEnt*)zsc->dyns[i])->model->Mat->pos); if (xVec3Length2(&delta) < 25.0f) - zEntEvent((xBase*)&globals.player, 0x3A); + zEntEvent(zsc->dyns[i], 0x3A); } + + xVec3Sub(&delta, (xVec3*)&tiki->model->Mat->pos, + (xVec3*)&globals.player.ent.model->Mat->pos); + if (xVec3Length2(&delta) < 25.0f) + zEntEvent((xBase*)&globals.player, 0x3A); } if (tiki->explosion && tiki->explosion->initCB) @@ -222,16 +218,15 @@ static void zNPCTiki_PickTikisToAnimate() { xCollis* coll = globals.player.ent.collis->colls; xCollis* cend = coll + globals.player.ent.collis->idx; - zNPCTiki* npc; + xNPCBasic* npc; // dwarf says there's 2 `xNPCBasic* npc`s but that causes a register issue for (; coll < cend; coll++) { if ((coll->flags & 1) != 0 && coll->optr != NULL) { - npc = (zNPCTiki*)coll->optr; - + npc = (xNPCBasic*)coll->optr; if (npc->baseType == '+' && (npc->SelfType() & ~0xFF) == 'NTT\0') { - npc->tikiFlag &= ~0xC0; + ((zNPCTiki*)npc)->tikiFlag &= ~0xC0; } } } @@ -252,12 +247,12 @@ static void zNPCTiki_PickTikisToAnimate() } } - npc = (zNPCTiki*)globals.player.carry.grabbed; + npc = (xNPCBasic*)globals.player.carry.grabbed; if (npc != NULL) { if (npc->baseType == '+' && (npc->SelfType() & ~0xFF) == 'NTT\0') { - npc->tikiFlag &= ~0xC0; + ((zNPCTiki*)npc)->tikiFlag &= ~0xC0; } } @@ -375,14 +370,14 @@ void zNPCTiki::Reset() timeToLive = 0.0f; tikiFlag = 0; - for (int i = 0; i < sizeof(parents[0]); i++) + for (S32 i = 0; i < sizeof(parents[0]); i++) { parents[i] = NULL; } numParents = 0; contactParent = ~0x0; - for (int i = 0; i < sizeof(children[0]); i++) + for (S32 i = 0; i < sizeof(children[0]); i++) { children[i] = NULL; } @@ -424,8 +419,6 @@ void zNPCTiki::Setup() void zNPCTiki::Init(xEntAsset* entass) { - int iVar1; - xAnimPlay* pxVar2; xModelInstance* nextModel; zNPCCommon::Init(entass); @@ -470,8 +463,7 @@ void zNPCTiki::Init(xEntAsset* entass) this->nextOrphan = NULL; - iVar1 = this->SelfType(); - if (iVar1 == NPC_TYPE_TIKI_LOVEY) + if (this->SelfType() == NPC_TYPE_TIKI_LOVEY) { this->render = loveyTikiRender; } @@ -480,10 +472,9 @@ void zNPCTiki::Init(xEntAsset* entass) this->render = genericTikiRender; } - pxVar2 = this->model->Anim; - if (pxVar2 != NULL) + if (this->model->Anim != NULL) { - this->tikiAnim = *pxVar2->Single->State->Data->RawData; + this->tikiAnim = *this->model->Anim->Single->State->Data->RawData; this->tikiAnimTime = this->model->Anim->Single->Time; this->model->Anim = NULL; this->tikiFlag &= ~0xC0; @@ -517,87 +508,69 @@ S32 zNPCTiki::SetCarryState(en_NPC_CARRY_STATE cs) return 0; } - if (cs == zNPCCARRY_THROW) - { - return 0; - } - - if (cs >= zNPCCARRY_THROW) + switch (cs) { - if (cs < 4) + case zNPCCARRY_ATTEMPTPICKUP: + if (this->numChildren != 0) { - if (this->numChildren == 0) + // non-matching: lfs for 0.2f only happens once, should be + // showing up multiple times as this gets unrolled + for (S32 i = 0; i < 4; i++) { - return 1; + if (this->children[i] != NULL) + { + if (this->children[i]->bound.box.box.lower.y < + 0.2f + this->bound.box.box.upper.y) + { + return 0; + } + } } + return 1; + } + return 1; - if (this->children[0] != NULL && - this->children[0]->bound.box.box.lower.y < 0.2f + this->bound.box.box.upper.y) - { - return 0; - } + case zNPCCARRY_PICKUP: + this->tikiFlag |= 0x10; + this->landHt = FLOAT_MIN; + RemoveFromFamily(); + return 1; - if (this->children[1] != NULL && - this->children[1]->bound.box.box.lower.y < 0.2f + this->bound.box.box.upper.y) + case zNPCCARRY_NONE: + if ((this->tikiFlag & 0x10)) + { + this->tikiFlag &= ~0x10; + + if (this->frame != NULL) { - return 0; + this->frame->mat.up.x = 0.0f; + this->frame->mat.up.y = 1.0f; + this->frame->mat.up.z = 0.0f; } - if (this->children[2] != NULL && - this->children[2]->bound.box.box.lower.y < 0.2f + this->bound.box.box.upper.y) + this->model->Mat->up.x = 0.0f; + this->model->Mat->up.y = 1.0f; + this->model->Mat->up.z = 0.0f; + + if (this->SelfType() == NPC_TYPE_TIKI_STONE) { - return 0; + this->tikiFlag |= 0x25; + this->bound.type = XBOUND_TYPE_BOX; } - - if (this->children[3] != NULL && - this->children[3]->bound.box.box.lower.y < 0.2f + this->bound.box.box.upper.y) + else { - return 0; + this->Damage(DMGTYP_SIDE, 0, NULL); } return 1; } - return 0; - } - - if (cs != zNPCCARRY_NONE) - { - this->tikiFlag |= 0x10; - this->landHt = FLOAT_MIN; - RemoveFromFamily(); - return 1; - } - - if ((this->tikiFlag & 0x10) == 0) - { - return 0; - } - - this->tikiFlag &= ~0x10; - - if (this->frame != NULL) - { - this->frame->mat.up.x = 0.0f; - this->frame->mat.up.y = 1.0f; - this->frame->mat.up.z = 0.0f; - } - this->model->Mat->up.x = 0.0f; - this->model->Mat->up.y = 1.0f; - this->model->Mat->up.z = 0.0f; - - if (this->SelfType() == NPC_TYPE_TIKI_STONE) - { - this->tikiFlag |= 0x25; - this->bound.type = XBOUND_TYPE_BOX; - } - else - { - this->Damage(DMGTYP_SIDE, 0, NULL); + case zNPCCARRY_THROW: + break; } - return 1; + return 0; } void zNPCTiki::SelfSetup() @@ -661,25 +634,11 @@ void zNPCTiki::ParseINI() } } -// WIP void zNPCTiki::Process(xScene* xscn, F32 dt) { - // The actual local variables from the dwarf: + xVec3* t0; U32 i; - F32 duration; xQuat* q0; - xVec3* t0; - F32 dy; - F32 dh; - // Ghidra-generated: - F32 fVar1; - xVec3 fStack_88; - xVec3 afStack_7c; - xVec3 fStack_70; - xVec3 fStack_64; - F32 local_60; - F32 local_54; - xVec3 afStack_4c; if (!(this->numChildren == NULL || ((this->tikiFlag & 8) != 0))) { @@ -696,7 +655,7 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) if (this->tikiAnim != NULL && ((this->tikiFlag & 0xC0) == 0)) { - duration = iAnimDuration(this->tikiAnim); + F32 duration = iAnimDuration(this->tikiAnim); this->tikiAnimTime += dt; if (this->tikiAnimTime >= duration) @@ -708,18 +667,19 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) else { this->tikiAnimTime = 0.0f; - this->tikiFlag = this->tikiFlag & ~0xC0; - this->tikiFlag = this->tikiFlag | 0x40; + this->tikiFlag &= ~0xC0; + this->tikiFlag |= 0x40; } } q0 = (xQuat*)giAnimScratch; t0 = (xVec3*)(q0 + 0x41); - iAnimEval(this->tikiAnim, this->tikiAnimTime, (U32)0, (xVec3*)t0, (xQuat*)q0); + iAnimEval(this->tikiAnim, this->tikiAnimTime, 0, t0, q0); iModelAnimMatrices(this->model->Data, q0, t0, this->model->Mat + 1); } - xVec3Copy(t0, (xVec3*)&this->model->Mat->pos); + xVec3 pos_save; + xVec3Copy(&pos_save, (xVec3*)&this->model->Mat->pos); if (this->numParents != 0) { @@ -736,8 +696,8 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) if ((this->tikiFlag & 0x300) == 0x100) { this->RemoveFromFamily(); - this->tikiFlag = this->tikiFlag & ~0x300; - this->tikiFlag = this->tikiFlag | 0x200; + this->tikiFlag &= ~0x300; + this->tikiFlag |= 0x200; return; } @@ -766,11 +726,15 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) { for (i = 0; i < 4; i++) { - if (this->parents[i] && i != this->contactParent) + if (i != this->contactParent && this->parents[i]) { S32 p = this->contactParent; - if (p == -1 || this->parents[p]->bound.box.box.upper.y < - this->parents[i]->bound.box.box.upper.y) + if (p == -1) + { + this->contactParent = i; + } + else if (this->parents[i]->bound.box.box.upper.y > + this->parents[p]->bound.box.box.upper.y) { this->contactParent = i; } @@ -781,12 +745,12 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) if (this->tikiFlag & 1) { this->vel -= 10.0f * dt; - fVar1 = dt * this->vel; + F32 dh = dt * this->vel; - this->model->Mat->pos.y += fVar1; - this->bound.box.box.lower.y += fVar1; - this->bound.box.box.upper.y += fVar1; - this->bound.box.center.y += fVar1; + this->model->Mat->pos.y += dh; + this->bound.box.box.lower.y += dh; + this->bound.box.box.upper.y += dh; + this->bound.box.center.y += dh; if (this->numParents != 0) { @@ -801,22 +765,21 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) this->vel = 0.0f; } } - else { if (this->bound.box.box.lower.y < this->landHt) { F32 diff = this->landHt - this->bound.box.box.lower.y; - this->model->Mat->pos.y += diff; this->bound.box.box.lower.y += diff; this->bound.box.box.upper.y += diff; this->bound.box.center.y += diff; + this->model->Mat->pos.y += diff; this->tikiFlag &= ~1; if (this->tikiFlag & 2) { - this->eventFunc(this, 0, 0xE, 0, 0); + this->Damage(DMGTYP_DAMAGE_SURFACE, 0, 0); } if (this->vel < -0.1f) @@ -839,7 +802,7 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) xBound& parentBound = this->parents[this->contactParent]->bound; xBound& bound = this->bound; - dy = parentBound.box.box.upper.y - bound.box.box.lower.y; + F32 dy = parentBound.box.box.upper.y - bound.box.box.lower.y; bound.box.box.lower.y += dy; bound.box.box.upper.y += dy; bound.box.center.y += dy; @@ -858,7 +821,6 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) } else { - RwMatrix& matP = *this->nonTikiParent->model->Mat; xVec3 delta; xVec3Copy(&delta, (xVec3*)&this->nonTikiParent->model->Mat->pos); xVec3AddScaled(&delta, (xVec3*)&this->nonTikiParent->model->Mat->right, @@ -874,14 +836,14 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) delta.y = 0.0f; } - xVec3AddTo(&this->bound.box.box.upper, &delta); xVec3AddTo(&this->bound.box.box.lower, &delta); + xVec3AddTo(&this->bound.box.box.upper, &delta); xVec3AddTo(&this->bound.box.center, &delta); xVec3AddTo((xVec3*)&this->model->Mat->pos, &delta); if (!(this->tikiFlag & 1) && this->nonTikiParent->baseType == eBaseTypeButton) { - //zEntButton_Hold((_zEntButton*)this->nonTikiParent, 0x2000); + zEntButton_Hold((_zEntButton*)this->nonTikiParent, 0x2000); } } } @@ -891,12 +853,13 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) if (!this->isCulled) { - xVec3Sub(&fStack_64, (xVec3*)&globals.player.ent.model->Mat->pos, + xVec3 playerDist; + xVec3Sub(&playerDist, (xVec3*)&globals.player.ent.model->Mat->pos, (xVec3*)&(this->model->Mat->pos)); - //local_60 = 0.01f; - F32 dVar19 = xVec3Length2(&fStack_64); + playerDist.y = 0.0f; + F32 offset = xVec3Length2(&playerDist); - if (dVar19 < 400.0f && !this->isCulled) + if (400.0f > offset && !this->isCulled) { numTikisOnScreen++; if (numTikisOnScreen == whichTikiToAnimate) @@ -907,16 +870,15 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) if (globals.player.drv.odriver != this && globals.player.drv.driver != this) { - if (1.0f > dVar19 && dVar19 < 400.0f) + if (offset > 1.0f && offset < 400.0f) { - xVec3AddScaled((xVec3*)&(this->model->Mat->at), &fStack_64, 0.2f / dVar19); + xVec3AddScaled((xVec3*)&(this->model->Mat->at), &playerDist, 0.2f / offset); xVec3Normalize((xVec3*)&(this->model->Mat->at), (xVec3*)&(this->model->Mat->at)); } - if (dVar19 < 100.0f && g_tmr_talkytiki < 0.0f && (this->tikiFlag & 0x300) == 0) + if (offset < 100.0f && g_tmr_talkytiki < 0.0f && (this->tikiFlag & 0x300) == 0) { this->ISeePlayer(); - F32 offset = (xurand() - 0.5f) * 0.25f * 90.0f; - g_tmr_talkytiki = 90.0f + (90.0f * offset); + g_tmr_talkytiki = 90.0f + 90.0f * ((xurand() - 0.5f) * 0.25f); } } @@ -926,29 +888,35 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) xVec3Copy(&this->lastAt, (xVec3*)&this->model->Mat->at); - dt = this->model->Scale.x; - if (dt != 0.0f) + F32 scale = this->model->Scale.x; + if (scale) { - // clang-format off - xVec3SMul(&fStack_70, &this->origLocalBound.box.center, dt); - xVec3SMul(&afStack_7c, &this->origLocalBound.box.center, (this->model->Scale).x); - xVec3SMul(&fStack_88, &this->origLocalBound.box.center, (this->model->Scale).x); - xVec3Add(&fStack_70, (xVec3*)&(this->model->Mat->pos), &this->bound.box.center); - xVec3Add(&fStack_88, (xVec3*)&(this->model->Mat->pos), &this->bound.box.box.upper); - xVec3Add(&afStack_7c, (xVec3*)&(this->model->Mat->pos), &this->bound.box.box.lower); + xVec3 scaledUpper; + xVec3 scaledLower; + xVec3 scaledCenter; - afStack_7c.x += 0.0001f; - fStack_70.x += 0.00005f; - }else - { + xVec3SMul(&scaledUpper, &this->origLocalBound.box.box.upper, this->model->Scale.x); + xVec3SMul(&scaledLower, &this->origLocalBound.box.box.lower, this->model->Scale.x); + xVec3SMul(&scaledCenter, &this->origLocalBound.box.center, this->model->Scale.x); + + xVec3Add(&this->bound.box.box.upper, (xVec3*)&this->model->Mat->pos, &scaledUpper); + xVec3Add(&this->bound.box.box.lower, (xVec3*)&this->model->Mat->pos, &scaledLower); + xVec3Add(&this->bound.box.center, (xVec3*)&this->model->Mat->pos, &scaledCenter); - xVec3Add(&this->bound.box.center, (xVec3*)&this->model->Mat->pos, &this->origLocalBound.box.center); - xVec3Add(&this->bound.box.box.lower, (xVec3*)&this->model->Mat->pos, &this->origLocalBound.box.box.lower); - xVec3Add(&this->bound.box.box.upper, (xVec3*)&this->model->Mat->pos, &this->origLocalBound.box.box.upper); - // clang-format on + scaledUpper.y += 0.00005f; + scaledCenter.y += 0.0001f; + } + else + { + xVec3Add(&this->bound.box.box.upper, (xVec3*)&this->model->Mat->pos, + &this->origLocalBound.box.box.upper); + xVec3Add(&this->bound.box.box.lower, (xVec3*)&this->model->Mat->pos, + &this->origLocalBound.box.box.lower); + xVec3Add(&this->bound.box.center, (xVec3*)&this->model->Mat->pos, + &this->origLocalBound.box.center); } - xVec3Sub(&this->deltaPos, (xVec3*)&this->model->Mat->pos, &afStack_4c); + xVec3Sub(&this->deltaPos, (xVec3*)&this->model->Mat->pos, &pos_save); if (this->numChildren != 0) { @@ -956,7 +924,7 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) { if (this->children[i]) { - this->ParentUpdated(this->children[i]); + this->children[i]->ParentUpdated(this); } } } @@ -969,18 +937,12 @@ void zNPCTiki::Process(xScene* xscn, F32 dt) } } -// WIP S32 zNPCTiki::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget, S32* handled) { - *handled = FALSE; - + // TODO: Figure out event enum switch (toEvent) { - case 0x54: - this->chkby = 0; - *handled = TRUE; - break; case 0x32: if ((this->tikiFlag & 0x300) != 0x200 && this->explosion && this->explosion->initCB) { @@ -988,23 +950,17 @@ S32 zNPCTiki::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, } this->RemoveFromFamily(); - + this->Reset(); if (this->SelfType() != NPC_TYPE_TIKI_LOVEY) { - this->tikiFlag = (this->tikiFlag | 5) & ~8; + this->tikiFlag |= 5; + this->tikiFlag &= ~8; this->vel = 0.0f; this->landHt = FLOAT_MIN; } *handled = TRUE; break; - case 0x53: - if ((this->tikiFlag & 0x300) != 0x200) - { - //this->RestoreColFlags(); - } - //*handled = TRUE; - break; case 3: case 0x1F7: @@ -1023,6 +979,7 @@ S32 zNPCTiki::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, } *handled = TRUE; break; + case 4: case 0x1F8: if (xEntIsVisible(this) && toParam) @@ -1033,29 +990,38 @@ S32 zNPCTiki::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, zFXPopOff(*this, toParam[1], toParam[2]); } } - //xEntHide(this); - this->RestoreColFlags(); + xEntHide(this); *handled = TRUE; break; - case 0x55: + case 0x53: if ((this->tikiFlag & 0x300) != 0x200) { this->RestoreColFlags(); } - - xEntShow(this); - - if (toParam) + *handled = TRUE; + break; + case 0x54: + this->chkby = 0; + *handled = TRUE; + break; + case 0x55: + if ((this->tikiFlag & 0x300) != 0x200) { - S32 code = (S32)(0.5f + toParam[0]); - if (code == 'M') + this->RestoreColFlags(); + xEntShow(this); + + if (toParam) { - zFXPopOn(*this, toParam[1], toParam[2]); + S32 code = (S32)(0.5f + toParam[0]); + if (code == 'M') + { + zFXPopOn(*this, toParam[1], toParam[2]); + } } } - *handled = TRUE; break; + case 0x56: this->chkby = 0; @@ -1088,55 +1054,55 @@ S32 zNPCTiki::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, void zNPCTiki::AddChild(zNPCTiki* child) { - U32 i = 0; + U8 i = 0; - while (this->children[i & 0xff] != NULL) + while (this->children[i] != NULL) { i++; } - this->children[i & 0xff] = child; + this->children[i] = child; this->numChildren++; } void zNPCTiki::RemoveChild(zNPCTiki* child) { - U32 i = 0; + U8 i = 0; if (this->numChildren == 0) return; - while (this->children[i & 0xff] != child && (i & 0xff) < sizeof(this->children[0])) + while (this->children[i] != child && i < sizeof(this->children[0])) { i++; } - if (this->children[i & 0xff] != child) + if (this->children[i] != child) return; - this->children[i & 0xff] = NULL; + this->children[i] = NULL; this->numChildren--; } void zNPCTiki::RemoveParent(zNPCTiki* parent) { - U32 i = 0; + U8 i = 0; if (this->numParents == 0) return; - while (this->parents[i & 0xff] != parent && (i & 0xff) < sizeof(this->parents[0])) + while (this->parents[i] != parent && i < sizeof(this->parents[0])) { i++; } - if (this->parents[i & 0xff] == parent) + if (this->parents[i] == parent) { - this->parents[i & 0xff] = NULL; + this->parents[i] = NULL; this->numParents--; } - if ((U8)i == this->contactParent) + if (i == this->contactParent) { this->contactParent = -1; this->tikiFlag |= 1; @@ -1145,71 +1111,60 @@ void zNPCTiki::RemoveParent(zNPCTiki* parent) this->tikiFlag |= 4; } -// WIP void zNPCTiki::FindParents(zScene* zsc) { - xCollis c = { - 0b100000000, // flags - 0, // oid - NULL, // optr - NULL, // mptr - 0.0f, // dist - { 0.0f, 0.0f, 0.0f }, // norm - { 0.0f, 0.0f, 0.0f }, // tohit - { 0.0f, 0.0f, 0.0f }, // depen - { 0.0f, 0.0f, 0.0f }, // hdng - { 0.0f, 0.0f, 0.0f } // union tuv/tri - }; + xCollis c = { 0b100000000, + 0, + NULL, + NULL, + 0.0f, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f } }; xRay3 ray; + xVec3Copy(&ray.origin, (xVec3*)&this->model->Mat->pos); + ray.origin.y = this->bound.box.box.upper.y; - zSurfaceProps* prop; - - S32 i; - xNPCBasic* npc; - zNPCTiki* tiki; - U8 couldBe; - - xVec3Copy(&ray.origin, (xVec3*)&((this->model)->Mat->pos)); ray.dir.x = 0.0f; ray.dir.y = -1.0f; ray.dir.z = 0.0f; - ray.min_t = 0.0f; ray.max_t = 300.0f; + ray.min_t = 0.0f; ray.flags = 0xc00; this->tikiFlag &= ~0x2; - xRayHitsTikiLandableScene(globals.sceneCur, &ray, &c); - if ((c.flags & 1) == 0) - { - this->landHt = FLOAT_MIN; - } - else + if ((c.flags & 1) != 0) { if (c.optr != NULL) { this->nonTikiParent = (xEnt*)c.optr; - - xVec3Sub(&ray.origin, &ray.origin, (xVec3*)&((xEnt*)c.optr)->model->Mat->pos); - F32 dist = ray.max_t - c.dist; + xVec3 temp; + xVec3Sub(&temp, &ray.origin, (xVec3*)&((xEnt*)c.optr)->model->Mat->pos); + temp.y -= c.dist; if (zGooIs(this->nonTikiParent)) this->tikiFlag |= 2; xSurface* surf = zSurfaceGetSurface(&c); - if (surf != NULL && surf->state == '\0' && surf->moprops != NULL) + if (surf != NULL && surf->state == 0 && surf->moprops != NULL) { - if (((U32*)surf->moprops)[0] != 0 && ((U32*)surf->moprops)[2] != 0) + zSurfaceProps* prop = ((zSurfaceProps**)surf->moprops)[0]; + if (prop != NULL && *(U8*)&prop->texanim[0].mode != 0) + { this->tikiFlag |= 2; + } } this->nonTikiParentDisp.x = - xVec3Dot(&ray.origin, (xVec3*)&this->nonTikiParent->model->Mat->right); + xVec3Dot(&temp, (xVec3*)&this->nonTikiParent->model->Mat->right); this->nonTikiParentDisp.y = - xVec3Dot(&ray.origin, (xVec3*)&this->nonTikiParent->model->Mat->up); + xVec3Dot(&temp, (xVec3*)&this->nonTikiParent->model->Mat->up); this->nonTikiParentDisp.z = - xVec3Dot(&ray.origin, (xVec3*)&this->nonTikiParent->model->Mat->at); + xVec3Dot(&temp, (xVec3*)&this->nonTikiParent->model->Mat->at); F32 mag2 = xVec3Length2((xVec3*)&this->nonTikiParent->model->Mat->right); if (mag2 > 0.00001f) @@ -1223,77 +1178,123 @@ void zNPCTiki::FindParents(zScene* zsc) xVec3Init(&this->nonTikiParentDisp, 0.0f, 0.0f, 0.0f); } - this->landHt = ray.origin.y - c.dist; + this->landHt = ray.origin.y; + this->landHt -= c.dist; + } + else + { + this->landHt = FLOAT_MIN; } - F32 oldLower; - F32 oldUpper; + F32 oldLower, oldUpper; if ((this->tikiFlag & 0x20) != 0) { - oldUpper = this->bound.box.box.lower.y; - oldLower = this->bound.box.box.upper.y; - this->bound.box.box.lower.y *= 0.5f; - F32 temp = this->bound.box.box.lower.y + (this->bound.box.box.upper.y * 0.5f); - this->bound.box.box.lower.y = temp; - this->bound.box.box.upper.y = (temp + oldLower) - oldUpper; + oldLower = this->bound.box.box.lower.y; + oldUpper = this->bound.box.box.upper.y; + + this->bound.box.box.lower.y = oldLower / 2; + this->bound.box.box.lower.y += 0.5f * this->bound.box.box.upper.y; + this->bound.box.box.upper.y = (this->bound.box.box.lower.y + oldUpper) - oldLower; } - if (zsc->num_npcs != 0) + for (S32 i = 0; i < zsc->num_npcs; i++) { - for (S32 i = 0; i < zsc->num_npcs; i++) + xNPCBasic* npc = (xNPCBasic*)zsc->npcs[i]; + if (npc == this) + continue; + if ((npc->SelfType() & ~0xFF) != 'NTT\0') + continue; + + zNPCTiki* tiki = (zNPCTiki*)npc; + if ((tiki->tikiFlag & 0x300) != 0) + continue; + if ((tiki->tikiFlag & 0x10) != 0) + continue; + if (tiki->bound.box.box.upper.y < this->landHt) + continue; + + if (!(this->bound.box.box.upper.x > tiki->bound.box.box.lower.x + 0.1f)) + continue; + if (!(tiki->bound.box.box.upper.x > this->bound.box.box.lower.x + 0.1f)) + continue; + if (!(this->bound.box.box.upper.z > tiki->bound.box.box.lower.z + 0.1f)) + continue; + if (!(tiki->bound.box.box.upper.z > this->bound.box.box.lower.z + 0.1f)) + continue; + + if (!(0.75f * tiki->bound.box.box.upper.y + 0.25f * tiki->bound.box.box.lower.y < + this->bound.box.box.lower.y + 0.00001f)) + continue; + if (!(tiki->bound.box.box.upper.y < + 0.75f * this->bound.box.box.lower.y + 0.25f * this->bound.box.box.upper.y + 0.00001f)) + continue; + + bool couldBe = true; + + for (U8 i = 0; i < 4; ++i) { - tiki = (zNPCTiki*)zsc->npcs[i]; - - bool validParent = true; - if (tiki == this || (tiki->SelfType() & ~0xFF) != 'NTT\0' || - (tiki->tikiFlag & 0x300) != 0 || (tiki->tikiFlag & 0x10) != 0 || - (this->landHt + 0.1f > tiki->bound.box.box.upper.y) || - (this->bound.box.box.lower.x + 0.1f > tiki->bound.box.box.upper.x) || - (this->bound.box.box.lower.z + 0.1f > tiki->bound.box.box.upper.z)) + zNPCTiki* p = this->parents[i]; + if (tiki == p) { - validParent = false; + couldBe = false; + break; } - - zNPCTiki* cur = this; - for (S32 couldBe = 0; couldBe < 4; ++couldBe) + if (p != NULL) { - zNPCTiki* p = cur->parents[couldBe]; - if (p == tiki) - { - validParent = false; - break; - } - - if (p && this->landHt < p->bound.box.box.upper.y) + if (!(p->bound.box.box.upper.x > tiki->bound.box.box.lower.x + 0.1f)) + continue; + if (!(tiki->bound.box.box.upper.x > p->bound.box.box.lower.x + 0.1f)) + continue; + if (!(p->bound.box.box.upper.z > tiki->bound.box.box.lower.z + 0.1f)) + continue; + if (!(tiki->bound.box.box.upper.z > p->bound.box.box.lower.z + 0.1f)) + continue; + + if (p->bound.box.box.upper.y * 0.75f + p->bound.box.box.lower.y * 0.25f < + tiki->bound.box.box.lower.y + 0.00001f && + p->bound.box.box.upper.y < 0.75f * tiki->bound.box.box.lower.y + + 0.25f * tiki->bound.box.box.upper.y + 0.00001f) { p->RemoveChild(this); - cur->parents[0] = NULL; + this->parents[i] = NULL; this->numParents--; - if (couldBe == this->contactParent) + if (i == this->contactParent) { this->contactParent = -1; this->tikiFlag |= 1; } } - - cur = (zNPCTiki*)cur->nextprod; + else + { + // else condition – swapped 0.75/0.25 coefficients + if (tiki->bound.box.box.upper.y * 0.75f + tiki->bound.box.box.lower.y * 0.25f < + p->bound.box.box.lower.y + 0.00001f && + tiki->bound.box.box.upper.y < 0.75f * p->bound.box.box.lower.y + + 0.25f * p->bound.box.box.upper.y + + 0.00001f) + { + couldBe = false; + } + } } + } - if (validParent && tiki->numChildren < 4 && this->numParents < 4) - { - for (U8 i = 0; this->parents[i & 0xff] != NULL; i++) - ; - this->parents[i & 0xff] = tiki; - tiki->AddChild(this); - this->numParents++; - } + if (couldBe && tiki->numChildren < 4 && this->numParents < 4) + { + U8 i = 0; + while (this->parents[i] != NULL) + i++; + + this->parents[i] = tiki; + tiki->AddChild(this); + this->numParents++; } } if ((this->tikiFlag & 0x20) != 0) { - this->bound.box.box.upper.y = oldUpper; this->bound.box.box.lower.y = oldLower; + this->bound.box.box.upper.y = oldUpper; this->tikiFlag &= ~0x20; } @@ -1310,7 +1311,7 @@ void zNPCTiki::FindParents(zScene* zsc) void zNPCTiki::ParentUpdated(zNPCTiki* parent) { - for (int i = 0; i < 4; i++) + for (S32 i = 0; i < 4; i++) { if (parent == this->parents[i]) { @@ -1414,18 +1415,16 @@ static S32 loveyPatrolCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, v { zNPCTiki* tiki; S32 nextgoal; - F32 dVar2; - xVec3 afStack_38; + xVec3 delta; // not in dwarf tiki = (zNPCTiki*)rawgoal->GetOwner(); - zNPCGoalTikiPatrol* cur_goal = (zNPCGoalTikiPatrol*)rawgoal; + zNPCGoalTikiPatrol* goal = (zNPCGoalTikiPatrol*)rawgoal; nextgoal = 0; - xVec3AddScaled(&(tiki->v1), &cur_goal->vel, dt); - xVec3Sub(&afStack_38, &cur_goal->dest_pos, &(tiki->v1)); - dVar2 = xVec3Dot(&afStack_38, &cur_goal->vel); - if (dVar2 < 0.0f) + xVec3AddScaled(&(tiki->v1), &goal->vel, dt); + xVec3Sub(&delta, &goal->dest_pos, &(tiki->v1)); + if (xVec3Dot(&delta, &goal->vel) < 0.0f) { - xVec3Copy(&(tiki->v1), &cur_goal->dest_pos); + xVec3Copy(&(tiki->v1), &goal->dest_pos); *trantype = GOAL_TRAN_SET; nextgoal = NPC_GOAL_TIKIIDLE; } @@ -1493,8 +1492,7 @@ static S32 quietHideCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, voi } else { - F32 s = 0.0f; - if (tiki->model->Scale.x == s) + if (!tiki->model->Scale.x) { tiki->model->Scale.x = tiki->model->Scale.y = tiki->model->Scale.z = 1.0f; } @@ -1518,7 +1516,7 @@ static S32 thunderIdleCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, v zNPCTiki* tiki = (zNPCTiki*)rawgoal->GetOwner(); zNPCGoalTikiIdle* goal = (zNPCGoalTikiIdle*)rawgoal; S32 nextgoal = 0; - F32 f; + F32 factor; tiki->t1 = -(0.75f * dt - tiki->t1); if (tiki->t1 < 0.0f) @@ -1526,11 +1524,11 @@ static S32 thunderIdleCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, v tiki->t1 += 1.0f; } - f = tiki->t1; - f = (f * f + 1.0f) - f; - tiki->model->RedMultiplier = f; - tiki->model->BlueMultiplier = f; - tiki->model->GreenMultiplier = f; + factor = tiki->t1; + factor = (factor * factor + 1.0f) - factor; + tiki->model->RedMultiplier = factor; + tiki->model->BlueMultiplier = factor; + tiki->model->GreenMultiplier = factor; goal->tmr_wait -= dt; if (goal->tmr_wait < 0.0f) @@ -1564,24 +1562,28 @@ static S32 thunderIdleCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, v // WIP static S32 thunderCountCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) { - zNPCTiki* tiki = (zNPCTiki*)rawgoal->GetOwner(); - zNPCGoalTikiCount* goal = (zNPCGoalTikiCount*)rawgoal; + zNPCGoalTikiCount* goal; + zNPCTiki* tiki; + S32 nextgoal; + F32 gfactor; + F32 factor; + xVec3 sPos; + xVec3 ePos; + F32 hght; - F32 gfactor = -1.0f; + tiki = (zNPCTiki*)rawgoal->GetOwner(); + goal = (zNPCGoalTikiCount*)rawgoal; - F32 factor = goal->tmr_count - dt; - S32 nextgoal = 0; + nextgoal = 0; - if (!(factor < -1.0f)) - { - gfactor = factor; - } - else + factor = goal->tmr_count - dt; + if (factor < -1.0f) { - goal->tmr_count = gfactor; + factor = -1.0f; } + goal->tmr_count = factor; - if (gfactor < 0.0f) + if (goal->tmr_count < 0.0f) { *trantype = GOAL_TRAN_SET; nextgoal = NPC_GOAL_TIKIDYING; @@ -1590,57 +1592,34 @@ static S32 thunderCountCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, if (!goal->beingCarried && globals.player.carry.grabbed == tiki) { goal->beingCarried = TRUE; - goal->tmr_count = goal->tmr_count + 3.0f; + goal->tmr_count += 3.0f; } - { - const F32 a_base = 8.0f; - const F32 add_base = 0.0f; - - F32 denom = goal->tmr_count + 1.0f; - - F32 tmp = (-1.0f / denom) + 1.0f; + gfactor = goal->tmr_count + 1.0f; + factor = (-1.0f / gfactor) + 1.0f; + hght = 8.0f * factor; - F32 a = add_base + tmp; + gfactor = factor - (F32)(S32)factor; + factor = hght - (F32)(S32)hght; - F32 prod = a_base * a; - - S32 ia = (S32)a; - F32 da = (F32)ia; - F32 a_frac = a - da; - - S32 ip = (S32)prod; - F32 dp = (F32)ip; - F32 p_frac = prod - dp; - - factor = a_frac; - - F32 sub = p_frac - (a_frac * 8.0f); - gfactor = sub * 0.75f + 0.25f; - } - - tiki->model->RedMultiplier = gfactor; - tiki->model->BlueMultiplier = 1.0f - gfactor; - tiki->model->GreenMultiplier = (factor - factor) * 0.75f + 0.25f; + tiki->model->RedMultiplier = factor * 0.75f + 0.25f; + tiki->model->BlueMultiplier = 1.0f - tiki->model->RedMultiplier; + tiki->model->GreenMultiplier = gfactor * 0.75f + 0.25f; tiki->tikiFlag &= ~0xC0; - F32 hght = tiki->t1 - dt; - tiki->t1 = hght; + tiki->t1 -= dt; - if (hght < 0.0f) + if (tiki->t1 < 0.0f) { - F32 r0 = xurand(); - tiki->t1 = r0 * 0.5f + 0.9f; + factor = xurand(); + tiki->t1 = factor * 0.5f + 0.9f; if ((xrand() & 7) == 0) { tiki->t1 = 0.2f; } - xVec3 sPos; - xVec3 ePos; - xVec3Copy(&sPos, (xVec3*)&tiki->model->Mat->pos); sPos.y += 2.6f; sPos.x += tiki->t2; @@ -1648,14 +1627,14 @@ static S32 thunderCountCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, xVec3Copy(&ePos, (xVec3*)&tiki->model->Mat->pos); - F32 rr = xurand(); - ePos.y += rr; + gfactor = xurand(); + ePos.y += gfactor; - F32 r1 = xurand(); - ePos.x += (r1 - 0.5f) * (1.0f - rr); + factor = xurand(); + ePos.x += (factor - 0.5f) * (1.0f - gfactor); - F32 r2 = xurand(); - ePos.z += (1.0f - rr) * (r2 - 0.5f); + hght = xurand(); + ePos.z += (1.0f - gfactor) * (hght - 0.5f); sThunderLightningInfo.start = &sPos; sThunderLightningInfo.end = &ePos; @@ -1665,20 +1644,18 @@ static S32 thunderCountCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, } xVec3Copy(&thunderEmitterInfo.pos, (xVec3*)&tiki->model->Mat->pos); - thunderEmitterInfo.pos.y += 3.0f; thunderEmitterInfo.pos.x += tiki->t2; + thunderEmitterInfo.pos.y += 3.0f; thunderEmitterInfo.pos.z += tiki->t3; xParEmitterEmitCustom(cloudEmitter, 1.0f / 60.0f, &thunderEmitterInfo); - gfactor = tiki->t2 + 0.25f; - tiki->t2 = gfactor; - if (gfactor > 0.5001f) + tiki->t2 += 0.25f; + if (tiki->t2 > 0.5001f) { tiki->t2 = -0.5f; - gfactor = tiki->t3 + 0.25f; - tiki->t3 = gfactor; - if (gfactor > 0.5001f) + tiki->t3 += 0.25f; + if (tiki->t3 > 0.5001f) { tiki->t3 = -0.5f; } @@ -1749,58 +1726,50 @@ static void genericTikiRender(xEnt* ent) xModelRender(ent->model); } -// WIP static void loveyTikiRender(xEnt* ent) { xModelInstance* model = ent->model; F32 factor; - xShadowCache cache; - xVec3 center; - xVec3 shadVec; - if (model == NULL) + if (model == NULL || !xEntIsVisible(ent) || model->Flags & 0x400) return; - if (!xEntIsVisible(ent)) - return; + xVec3 shadVec; + xVec3Sub(&shadVec, (xVec3*)&globals.player.ent.model->Mat->pos, (xVec3*)&model->Mat->pos); + shadVec.y = 0.0f; + factor = 1.0f - xVec3Length2(&shadVec) / 25.0f; - if ((model->Flags & 0x400) == 0) - { - xVec3Sub(&shadVec, (xVec3*)&globals.player.ent.model->Mat->pos, (xVec3*)&model->Mat->pos); - shadVec.y = 0.0f; - factor = 1.0f - xVec3Length2(&shadVec) / 25.0f; - if (gCurrentPlayer != eCurrentPlayerSpongeBob) - { - factor = -1.0f; - } + if (gCurrentPlayer != eCurrentPlayerSpongeBob) + factor = -1.0f; - cache.polyCount = 0; - } + xShadowCache cache; + cache.polyCount = 0; if (factor > 0.0f) { if (factor > 1.0f) factor = 1.0f; - xVec3Copy(¢er, (xVec3*)&model->Mat->pos); + xVec3 center; + xVec3Copy(¢er, (xVec3*)&ent->model->Mat->pos); center.y += sLoveyIconOffset; - NPCC_RenderProjTextureFaceCamera(sHelmetRast, factor, ¢er, 0.7f, sLoveyIconDist + sLoveyIconOffset, &cache, 1, ent); } + S32 shadowResult = 0; S32 alphaTooLow = 0; - S32 skipModelRender = 0; - + xVec3 center; center.x = model->Mat->pos.x; center.y = model->Mat->pos.y - 10.0f; center.z = model->Mat->pos.z; - if (iModelCullPlusShadow(model->Data, model->Mat, ¢er, &alphaTooLow) == 0) + if (iModelCullPlusShadow(model->Data, model->Mat, ¢er, &shadowResult) == 0) { F32 dot = 2.0f; if ((globals.player.ControlOff & 0x23f3) == 0) { + xVec3 shadVec; xVec3Sub(&shadVec, &ent->bound.cyl.center, &globals.camera.mat.pos); dot = xVec3Dot(&shadVec, &globals.camera.mat.at); } @@ -1811,33 +1780,26 @@ static void loveyTikiRender(xEnt* ent) if (model->Alpha < 0.0f) { model->Alpha = 0.0f; - skipModelRender = 1; + alphaTooLow = 1; } } else { model->Alpha += 3.0f * globals.update_dt; if (model->Alpha > 1.0f) - { model->Alpha = 1.0f; - } } - for (xModelInstance* curr = model->Next; curr != NULL; curr = curr->Next) - { + xModelInstance* curr; + for (curr = model->Next; curr != NULL; curr = curr->Next) curr->Alpha = model->Alpha; - } - if (skipModelRender) - { + if (alphaTooLow) return; - } xModelRender(model); } - if ((factor < 0.5f || cache.polyCount == 0) && alphaTooLow == 0) - { + if ((factor < 0.5f || cache.polyCount == 0) && shadowResult == 0) xShadowSimple_Add(ent->simpShadow, ent, 0.667f, 1.0f); - } }