//------------------------------------------------------------------------- /* Copyright (C) 2010-2019 EDuke32 developers and contributors Copyright (C) 2019 sirlemonhead, Nuke.YKT This file is part of PCExhumed. PCExhumed is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- #include "ns.h" #include "aistuff.h" #include "exhumed.h" #include "engine.h" #include "sequence.h" #include "mapinfo.h" #include BEGIN_PS_NS //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void DestroyBubble(DExhumedActor* pActor) { runlist_DoSubRunRec(pActor->spr.lotag - 1); runlist_DoSubRunRec(pActor->spr.intowner); runlist_SubRunRec(pActor->nRun); DeleteActor(pActor); } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- DExhumedActor* BuildBubble(const DVector3& pos, sectortype* pSector) { int nSize = RandomSize(3); if (nSize > 4) { nSize -= 4; } auto pActor = insertActor(pSector, 402); pActor->spr.pos = pos; pActor->spr.cstat = 0; pActor->spr.shade = -32; pActor->spr.pal = 0; pActor->clipdist = 1.25; pActor->spr.SetScale(0.625, 0.625); pActor->spr.xoffset = 0; pActor->spr.yoffset = 0; pActor->spr.picnum = 1; pActor->spr.angle = inita; pActor->vel.X = 0; pActor->vel.Y = 0; pActor->vel.Z = -1200 / 256.; pActor->spr.hitag = -1; pActor->spr.extra = -1; pActor->spr.lotag = runlist_HeadRun() + 1; pActor->backuppos(); // GrabTimeSlot(3); pActor->nFrame = 0; pActor->nIndex = SeqOffsets[kSeqBubble] + nSize; pActor->spr.intowner = runlist_AddRunRec(pActor->spr.lotag - 1, pActor, 0x140000); pActor->nRun = runlist_AddRunRec(NewRun, pActor, 0x140000); return pActor; } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void AIBubble::Tick(RunListEvent* ev) { auto pActor = ev->pObjActor; if (!pActor) return; int nSeq = pActor->nIndex; seq_MoveSequence(pActor, nSeq, pActor->nFrame); pActor->nFrame++; if (pActor->nFrame >= SeqSize[nSeq]) { pActor->nFrame = 0; } pActor->spr.pos.Z = pActor->vel.Z; auto pSector = pActor->sector(); if (pActor->spr.pos.Z <= pSector->ceilingz) { auto pSectAbove = pSector->pAbove; if (pActor->spr.hitag > -1 && pSectAbove != nullptr) { BuildAnim(nullptr, 70, 0, DVector3(pActor->spr.pos.XY(), pSectAbove->floorz), pSectAbove, 64, 0); } DestroyBubble(pActor); } } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void AIBubble::Draw(RunListEvent* ev) { auto pActor = ev->pObjActor; if (!pActor) return; seq_PlotSequence(ev->nParam, pActor->nIndex, pActor->nFrame, 1); ev->pTSprite->ownerActor = nullptr; } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void DoBubbleMachines() { ExhumedStatIterator it(kStatBubbleMachine); while (auto pActor = it.Next()) { pActor->nCount--; if (pActor->nCount <= 0) { pActor->nCount = (RandomWord() % pActor->nFrame) + 30; BuildBubble(pActor->spr.pos, pActor->sector()); } } } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void BuildBubbleMachine(DExhumedActor* pActor) { pActor->nFrame = 75; pActor->nCount = pActor->nFrame; pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE; ChangeActorStat(pActor, kStatBubbleMachine); } //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- void DoBubbles(int nPlayer) { sectortype* pSector; auto pos = WheresMyMouth(nPlayer, &pSector); auto pActor = BuildBubble(pos, pSector); pActor->spr.hitag = nPlayer; } END_PS_NS