summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2OutDecoration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/T2DLL/T2OutDecoration.cpp')
-rw-r--r--src/T2DLL/T2OutDecoration.cpp223
1 files changed, 218 insertions, 5 deletions
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;
}