From c0c336500955a23e344651e5412c9d9d441ef4ee Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Wed, 28 Jun 2023 22:22:32 +0100 Subject: first pass of T2DLL --- src/T2DLL/T2OutDecoration.cpp | 223 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 218 insertions(+), 5 deletions(-) (limited to 'src/T2DLL/T2OutDecoration.cpp') diff --git a/src/T2DLL/T2OutDecoration.cpp b/src/T2DLL/T2OutDecoration.cpp index ba8e432..575f0f8 100644 --- a/src/T2DLL/T2OutDecoration.cpp +++ b/src/T2DLL/T2OutDecoration.cpp @@ -1,22 +1,235 @@ +#include "CResFile.h" +#include "GlobalFunc.h" +#include "T2BitImage.h" +#include "T2FloorInfo.h" +#include "T2ImageObj.h" #include "T2OutDecoration.h" +#include "T2PaletteAnime.h" +#include "T2Sprite.h" +#include "T2Tenant.h" +#include "T2TowerDoc.h" +#include "T2WorldDef.h" +#include "URect.h" +#include "UT2Coordinate.h" -T2OutDecoration::T2OutDecoration(T2TowerEvent*, CResFile*, int) { +T2OutDecoration::T2OutDecoration(T2TowerEvent* inTowerEvent, CResFile* inResFile, int inSubID) + : T2EventItem(inTowerEvent, inResFile, inSubID) +{ + int resID; + int numOfOutDeco; + T2OutDeco *theOutDeco; + + *inResFile >> numOfOutDeco; + for (int index = 0; index < numOfOutDeco; index++) { + unsigned int frameCount; + + *inResFile >> resID; + *inResFile >> frameCount; + + theOutDeco = new T2OutDeco(this, resID, frameCount); + mArray.Add(&theOutDeco); + } + + mCurrentViewMode = -1; + mCurrentFrame = 0; } /*virtual*/ T2OutDecoration::~T2OutDecoration() { + LArrayIterator iterator(mArray); + T2OutDeco *theOutDeco; + + while (iterator.Next(&theOutDeco)) + delete theOutDeco; } -/*virtual*/ int T2OutDecoration::Exec(T2TowerDoc*) { +/*virtual*/ int T2OutDecoration::Exec(T2TowerDoc* inDoc) { + T2PaletteAnime *thePalette = inDoc->towerDoc_vf160(); + int frame = thePalette->IsSnow() ? 1 : 0; + + if (inDoc->towerDoc_vf140() != mCurrentViewMode || frame != mCurrentFrame) + DoDecoration(inDoc, (VIEWMODE) inDoc->towerDoc_vf140(), frame); + + return 0; } -void T2OutDecoration::DoDecoration(T2TowerDoc*, VIEWMODE, int) { +void T2OutDecoration::DoDecoration(T2TowerDoc* inDoc, VIEWMODE inViewMode, int inFrame) { + T2OutDeco *theOutDeco; + + if (inViewMode == ViewMode_1) { + LArray *theRoofList = MakeLoofList(); + if (theRoofList) { + T2Sprite *theSprite = &inDoc->mSprite; + BOOL isGap = false; + + LArrayIterator roofIterator(*theRoofList); + T2RoofInfo *theRoofInfo; + + while (roofIterator.Next(&theRoofInfo)) { + if (theRoofInfo->flag || isGap) { + LArrayIterator outDecoIterator(mArray); + + while (outDecoIterator.Next(&theOutDeco)) { + if (!theOutDeco->mVisible) { + CRect rect = theRoofInfo->rect; + UT2Coordinate::UnitToQD(rect, 0); + + if (URect::Width(rect) > (URect::Width(theOutDeco->mRect) + 64)) { + theOutDeco->Load(inFrame); + if (theOutDeco->mSpriteID != -1) { + OffsetRect(&rect, 42, 28 - URect::Height(theOutDeco->mRect)); + theSprite->MoveSprite(theOutDeco->mSpriteID, rect.TopLeft()); + theSprite->ShowSprite(theOutDeco->mSpriteID, true); + } + theOutDeco->mVisible = true; + break; + } + } + } + } + + isGap = !theRoofInfo->flag; + theRoofList->RemoveItemsAt(1, roofIterator.GetCurrentIndex()); + roofIterator.Reset(); + delete theRoofInfo; + } + + delete theRoofList; + } + } + + LArrayIterator outDecoIterator(mArray); + while (outDecoIterator.Next(&theOutDeco)) { + if (!theOutDeco->mVisible) + theOutDeco->Unload(); + theOutDeco->mVisible = false; + } + + mCurrentViewMode = inViewMode; + mCurrentFrame = inFrame; } -/*virtual*/ void T2OutDecoration::ViewModeChanged(T2TowerDoc*, VIEWMODE) { +/*virtual*/ void T2OutDecoration::ViewModeChanged(T2TowerDoc* inDoc, VIEWMODE inViewMode) { + if (inViewMode != mCurrentViewMode && (inViewMode == ViewMode_1 || mCurrentViewMode == ViewMode_1)) { + T2PaletteAnime *thePalette = inDoc->towerDoc_vf160(); + int frame = thePalette->IsSnow() ? 1 : 0; + + DoDecoration(inDoc, inViewMode, frame); + } } -void T2OutDecoration::CheckRoofTop(T2Equip*) { +void T2OutDecoration::CheckRoofTop(T2Equip* inEquip) { + mCurrentViewMode = -1; } LArray* T2OutDecoration::MakeLoofList() { + LArray *theArray = new LArray; + + if (theArray) { + T2FloorInfo *theFloorInfo = GetTowerDoc()->towerDoc_vf12C(); + int curV; + int groundV = GetWorldDef()->mGroundLine - 1; + int nextH; + int v, h; + + CRect theBuildArea; + GetWorldDef()->GetBuildArea(theBuildArea); + + for (h = theBuildArea.left; h < theBuildArea.right; h++) { + if (theFloorInfo->GetTenant(groundV, h)) + break; + } + int lobbyLeftH = h; + + for (h = theBuildArea.right - 1; h > theBuildArea.left; h--) { + if (theFloorInfo->GetTenant(groundV, h)) + break; + } + int lobbyRightH = h; + + if (lobbyLeftH < lobbyRightH) { + for (h = lobbyLeftH; h <= lobbyRightH; h = nextH) { + for (v = groundV; ; v--) { + if (!theFloorInfo->GetTenant(v, h)) + break; + } + + for (nextH = h; nextH <= lobbyRightH; nextH++) { + curV = v; + if (theFloorInfo->GetTenant(curV, nextH)) + break; + + curV = v + 1; + T2Tenant *theTenant = theFloorInfo->GetTenant(curV, nextH); + if (!theTenant) + break; + if (theTenant->IsSetAttribute(kTenantAttr40000)) + break; + } + + T2RoofInfo *theRoofInfo = new T2RoofInfo(h, v, nextH, v + 1, curV == v); + theArray->Add(&theRoofInfo); + } + } + } + + return theArray; +} + + + +T2OutDeco::T2OutDeco(T2OutDecoration *inOwner, int inResID, unsigned int inFrameCount) { + mOwner = inOwner; + mSpriteID = -1; + mLoaded = false; + mResID = inResID; + mFrameCount = (inFrameCount > 0) ? inFrameCount : 1; + mCurrent = 0; + mVisible = false; + mImage = NULL; + mImageObj = NULL; + + try { + T2BitImage image(GetWorldModuleHandle(), mResID, true); + SetRect(&mRect, 0, 0, image.mBitmap.header.biWidth, image.mBitmap.header.biHeight); + mRect.bottom = mRect.top + (mRect.Height() / mFrameCount); + } catch (int err) { + SetRect(&mRect, 0, 0, 0, 0); + } +} + +T2OutDeco::~T2OutDeco() { +} + +void T2OutDeco::Load(int inID) { + if (!SetRectEmpty(&mRect) && (mSpriteID == -1 || mCurrent != inID)) { + Unload(); + + mImage = new T2BitImage(GetWorldModuleHandle(), mResID, true); + mCurrent = (inID >= 0 && inID < mFrameCount) ? inID : 0; + + T2Sprite *theSprite = &mOwner->GetTowerDoc()->mSprite; + mImageObj = new T2ImageObj; + mImageObj->AddObject("OUTDECO", 0, *mImage, NULL, false, false); + mSpriteID = theSprite->NewSprite(*mImageObj, "OUTDECO", T2Sprite::ELayer_1); + mLoaded = true; + } +} + +void T2OutDeco::Unload() { + if (mSpriteID != -1) { + T2Sprite *theSprite = &mOwner->GetTowerDoc()->mSprite; + theSprite->DeleteSprite(mSpriteID); + mSpriteID = -1; + + delete mImageObj; + delete mImage; + } + mLoaded = false; +} + + + +T2RoofInfo::T2RoofInfo(int inLeft, int inTop, int inRight, int inBottom, BOOL inFlag) { + SetRect(&rect, inLeft, inTop, inRight, inBottom); + flag = inFlag; } -- cgit v1.2.3