#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* 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* 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* 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* 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* 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; }