diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
commit | c0c336500955a23e344651e5412c9d9d441ef4ee (patch) | |
tree | 790769c748db307cf3314f6e896e2f61c68561a2 /src/T2DLL/T2FireBurning.cpp | |
parent | 37e364b2c6cc7487a1c888d256a73e5337bb7189 (diff) | |
download | t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.tar.gz t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.zip |
first pass of T2DLL
Diffstat (limited to '')
-rw-r--r-- | src/T2DLL/T2FireBurning.cpp | 784 |
1 files changed, 761 insertions, 23 deletions
diff --git a/src/T2DLL/T2FireBurning.cpp b/src/T2DLL/T2FireBurning.cpp index b07e3c9..b8cc60d 100644 --- a/src/T2DLL/T2FireBurning.cpp +++ b/src/T2DLL/T2FireBurning.cpp @@ -1,82 +1,820 @@ +#include "CResFile.h" +#include "GlobalFunc.h" +#include "T2BitImage.h" +#include "T2CtrlPalette.h" +#include "T2DateTime.h" +#include "T2Dialog.h" +#include "T2DlgItem.h" +#include "T2EquipPtrList.h" #include "T2FireBurning.h" +#include "T2FloorInfo.h" +#include "T2ImageObj.h" +#include "T2MainWindow.h" +#include "T2People.h" +#include "T2PeoplePtrList.h" +#include "T2RegistedTenantDB.h" +#include "T2Settlement.h" +#include "T2SoundPlayer.h" +#include "T2Sprite.h" +#include "T2Tenant.h" +#include "T2ToolWindow.h" +#include "T2TowerDoc.h" +#include "T2TowerEvent.h" +#include "T2TowerMainView.h" +#include "T2TowerMessage.h" +#include "T2WorldDef.h" +#include "UT2Coordinate.h" +#include "UT2Utils.h" -T2FireBurning::T2FireBurning(T2TowerEvent*, CResFile*, int) { +T2FireBurning::T2FireBurning(T2TowerEvent* inTowerEvent, CResFile* inResFile, int inSubID) + : T2EventItem(inTowerEvent, inResFile, inSubID) +{ + mFightAction = kFireFightNull; + mFireArray = NULL; + mHelicopter = NULL; + mAttach = NULL; + mImage = NULL; + mImageObj = NULL; + + *inResFile >> mHelicopterPrice; + *inResFile >> m40; + if (inResFile->IsBinaryMode()) { + int tmp; + for (int i = 0; i < m40; i++) + *inResFile >> tmp; + } + + mPeopleList = new T2PeoplePtrList; } /*virtual*/ T2FireBurning::~T2FireBurning() { + if (mStatus == kFireBurningStatus1) + StopEvent(mTowerEvent->mDocument); + delete mPeopleList; } -/*virtual*/ int T2FireBurning::Start(T2TowerDoc*) { +/*virtual*/ BOOL T2FireBurning::Start(T2TowerDoc* inDoc) { + BOOL started = false; + + CPoint pt; + T2Tenant *theTenant; + if (IsBreakoutFire(inDoc, pt, theTenant)) { + mStatus = kFireBurningStatus1; + StartEvent(inDoc, pt, theTenant); + inDoc->towerDoc_vf2B0(true); + + switch (mFightAction) { + case kFireFightHelicopter: + { + CString text = LoadStringTable(GetWorldModuleHandle(), 8100, 1); + DoAlert(inDoc, text, 0); + inDoc->towerDoc_vf270(mHelicopterPrice, kFundGroup2); + inDoc->towerDoc_vf2A8(25); + Sounds->Play("FIREBURNING:HELI", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_3, 100); + break; + } + case kFireFightFireman: + inDoc->towerDoc_vf2A8(25); + break; + } + + mTimePassed = 0; + started = true; + } + + return started; } -/*virtual*/ int T2FireBurning::Exec(T2TowerDoc*) { +/*virtual*/ int T2FireBurning::Exec(T2TowerDoc* inDoc) { + CString str; + + switch (mStatus) { + case kFireBurningStatus1: + if (mFightAction != kFireFightNull) { + if (mHelicopter) + mHelicopter->Move(inDoc); + mTimePassed++; + IdleEvent(inDoc); + + T2DateTime *theNow = inDoc->towerDoc_vf120(); + if (!mFireArray || mFireArray->GetCount() == 0 || theNow->GetRawMinutes() == mEndTime) + mStatus = kFireBurningStatus2; + } + + return IsExclusive() ? 1 : 0; + + case kFireBurningStatus2: + StopEvent(inDoc); + str = LoadStringTable(GetWorldModuleHandle(), 8100, 2); + DoAlert(inDoc, str, 0); + return 3; + } + + return 0; } -/*virtual*/ void T2FireBurning::StartEvent(T2TowerDoc*, POINT, const T2Tenant*) { +/*virtual*/ void T2FireBurning::StartEvent(T2TowerDoc* inDoc, POINT inPt, const T2Tenant* inTenant) { + T2FloorInfo *theFloorInfo = inDoc->towerDoc_vf12C(); + mFightAction = kFireFightNull; + mFireArray = new LArray; + + inDoc->towerDoc_vf144(ViewMode_0); + inDoc->towerDoc_vf2A8(25); + inDoc->SetFireBurning(true); + inDoc->towerDoc_vf1A0(true); + inDoc->towerDoc_vf2A0()->EnableIcon(false); + inDoc->GetTowerMainView()->tmv_vf154(); + inDoc->towerDoc_vf1B4(); + + Sounds->FadeOut(); + Sounds->AddSound("FIREBURNING:", SoundPriority_1, 8100, GetWorldModuleHandle()); + Sounds->AddSound("FIREBURNING:HELI", SoundPriority_1, 8101, GetWorldModuleHandle()); + Sounds->AddSound("FIREBURNING:FIRE", SoundPriority_1, 8102, GetWorldModuleHandle()); + Sounds->Play("FIREBURNING:", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_0, 100); + + CString dialogText; + dialogText.Format("%d", inDoc->towerDoc_vf12C()->UnitToFloor(inPt.y)); + dialogText += LoadStringTable(GetWorldModuleHandle(), 8100, 3); + DoDialog(inDoc, 8100, 5100, 3, dialogText); + + if (!mImage) + mImage = new T2BitImage(inDoc->mWorldDef->mModuleHandle, 5000, true); + + if (!mImageObj) { + mImageObj = new T2ImageObj; + mImageObj->AddObject(inDoc->mWorldDef->mModuleHandle, 5000, mImage); + + SIZE size; + mImageObj->GetObjectSize(mImageObj->FindObject("FIRE", 0), &size); + mFireWidth = size.cx / 8; + } + + MakeFire(inPt, inDoc); + + T2TowerMainView *theTowerMainView = inDoc->GetTowerMainView(); + + CRect area; + inTenant->GetEquipArea(area); + theTowerMainView->tmv_vf15C(area); + + ((T2MainWindow *) AfxGetMainWnd())->mCtrlPalette->vf108(0); + + Sounds->Play("FIREBURNING:FIRE", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_3, 100); + + dialogText = LoadStringTable(GetWorldModuleHandle(), 8100, 4); + switch (DoDialog(inDoc, 8110, 5101, 1, dialogText)) { + case 8114: + mHelicopter = new T2Helicopter(inDoc, inTenant); + mFightAction = kFireFightHelicopter; + break; + case 8115: + CallFireman(inDoc, inTenant); + mFightAction = kFireFightFireman; + break; + case 8116: + mFightAction = kFireFightDoNothing; + break; + } + + mAttach = new T2FireAttach(this, 0, true); + theTowerMainView->AddAttachment(mAttach, NULL, true); + + if (mFightAction == kFireFightHelicopter) + theTowerMainView->SetTimer(100, 55, NULL); } -/*virtual*/ void T2FireBurning::SetupDialog(T2Dialog*) { +/*virtual*/ void T2FireBurning::SetupDialog(T2Dialog* inDialog) { + if (inDialog->mTemplate.resID == 8100) + return; + + ((T2DlgItem *) inDialog->GetDlgItem(8114))->AddListener(inDialog); + ((T2DlgItem *) inDialog->GetDlgItem(8115))->AddListener(inDialog); + ((T2DlgItem *) inDialog->GetDlgItem(8116))->AddListener(inDialog); } -/*virtual*/ unsigned int T2FireBurning::DialogHook(T2EventDialog*, unsigned int, T2TowerDoc*) { +/*virtual*/ unsigned int T2FireBurning::DialogHook(T2EventDialog* inDialog, unsigned int inResult, T2TowerDoc* inDoc) { + CString theString; + T2TowerMessage *theTowerMsg = inDoc->mTowerMessage; + T2FloorInfo *theFloorInfo; + T2Tenant *theTenant; + + switch (inResult) { + case 8114: + if (inDoc->towerDoc_vf26C() < mHelicopterPrice) { + theString = LoadStringTable(GetWorldModuleHandle(), 8100, 5); + DoAlert(inDoc, theString, 9000); + inResult = 0; + } + break; + + case 8115: + theFloorInfo = inDoc->towerDoc_vf12C(); + theTenant = theFloorInfo ? theFloorInfo->GetTenantByPID('KEBI') : NULL; + if (!theTenant) { + theString = LoadStringTable(GetWorldModuleHandle(), 8100, 6); + DoAlert(inDoc, theString, 9000); + inResult = 0; + } + break; + } + + return inResult; } -/*virtual*/ void T2FireBurning::IdleEvent(T2TowerDoc*) { +/*virtual*/ void T2FireBurning::IdleEvent(T2TowerDoc* inDoc) { + if (mFireArray) { + if (mFightAction == kFireFightFireman) { + T2Fire *fire = NULL; + if (mFireArray->GetCount() > 0) + mFireArray->FetchItemAt(mFireArray->GetCount(), &fire); + + LArrayIterator iterator(*mPeopleList); + T2People *people; + + while (iterator.Next(&people)) { + if (people->GetStatus() == kStatus15) { + if (fire) { + people->SetDestination(fire->GetArsonTenant()->GetEquipID()); + people->ChangeStyle(kPeopleStyle2); + people->ChangeStatus(kStatus3); + } else { + people->ChangeStyle(kPeopleStyle1); + } + } + } + } + + T2Fire *theFire; + int index = 1; + while (mFireArray->FetchItemAt(index, &theFire)) { + BOOL flag = false; + if ((mTimePassed % 1) == 0) + flag = theFire->Move(); + + if (!flag && mFightAction == kFireFightFireman && theFire->ExtinguishByFireman(inDoc, mPeopleList)) { + flag = true; + Extinguish(theFire); + } + + if (!flag) + index++; + } + } } -/*virtual*/ void T2FireBurning::StopEvent(T2TowerDoc*) { +/*virtual*/ void T2FireBurning::StopEvent(T2TowerDoc* inDoc) { + T2TowerMainView *theView = inDoc->GetTowerMainView(); + theView->KillTimer(100); + + if (mFireArray) { + LArrayIterator iterator(*mFireArray); + T2Fire *theFire; + + while (iterator.Next(&theFire)) + delete theFire; + + delete mFireArray; + mFireArray = NULL; + + delete mImageObj; + mImageObj = NULL; + + delete mImage; + mImage = NULL; + } + + if (mHelicopter) { + delete mHelicopter; + mHelicopter = NULL; + } + + if (theView && mAttach) { + theView->RemoveAttachment(mAttach); + delete mAttach; + mAttach = NULL; + + theView->tmv_vf124(true); + theView->tmv_vf120(); + } + + mStatus = kFireBurningStatus0; + mFightAction = kFireFightNull; + + LArrayIterator iterator(*mPeopleList); + T2People *theFireman; + + while (iterator.Next(&theFireman)) { + theFireman->ChangeStyle(kPeopleStyle1); + theFireman->SetReturnToDestination(); + theFireman->SetStatus(kStatus3); + theFireman->ClearSpecialFlag(kSpecialFlag20 | kSpecialFlag40); + theFireman->ClearColor(); + } + + mPeopleList->RemoveItemsAt(mPeopleList->GetCount(), 1); + + inDoc->towerDoc_vf2B0(false); + + Sounds->Stop("FIREBURNING:"); + Sounds->Stop("FIREBURNING:HELI"); + Sounds->Stop("FIREBURNING:FIRE"); + Sounds->DeleteSound("FIREBURNING:"); + Sounds->DeleteSound("FIREBURNING:HELI"); + Sounds->DeleteSound("FIREBURNING:FIRE"); + Sounds->FadeIn(); + + inDoc->towerDoc_vf1A0(false); + inDoc->SetFireBurning(false); + + if (inDoc->GetTowerMainView()) + inDoc->GetTowerMainView()->tmv_vf150(); + if (inDoc->towerDoc_vf2A0()) + inDoc->towerDoc_vf2A0()->EnableIcon(true); } -int T2FireBurning::MakeFire(POINT, T2TowerDoc*) { +BOOL T2FireBurning::MakeFire(POINT inPt, T2TowerDoc* inDoc) { + BOOL createdFire = false; + + T2FloorInfo *theFloorInfo = inDoc->towerDoc_vf12C(); + T2Tenant *theTenant = theFloorInfo->GetTenant(inPt.y, inPt.x); + + if (theTenant && !theTenant->IsFire() && !theTenant->IsFireproof()) { + CRect rect; + if (AdjustFirePos(theFloorInfo, inPt, rect)) { + for (unsigned int i = 0; i < 2; i++) { + T2Fire *theFire = new T2Fire(rect.TopLeft(), inDoc, i ? -1 : 1, mImageObj); + mFireArray->Add(&theFire); + } + + for (int h = rect.left; h < rect.right; h++) { + T2Tenant *tenant = theFloorInfo->GetTenant(rect.top, h); + if (tenant && !tenant->IsFireproof() && !tenant->IsFire()) + tenant->BurntDown(inDoc); + } + + createdFire = true; + } + } + + return createdFire; } -int T2FireBurning::AdjustFirePos(T2FloorInfo*, POINT&, RECT&) const { +BOOL T2FireBurning::AdjustFirePos(T2FloorInfo* inFloorInfo, POINT& inPt, RECT& outRect) const { + BOOL success = false; + + int distance = mFireWidth / 2; + SetRect(&outRect, inPt.x - distance, inPt.y, inPt.x + distance, inPt.y + 1); + + int dir = 0; + for (unsigned int i = 0; i <= distance; i++) { + if (inFloorInfo->GetTenant(outRect.top, outRect.left)) { + if (inFloorInfo->GetTenant(outRect.top, outRect.right - 1)) { + if (inFloorInfo->IsAllTenant(outRect)) { + success = true; + break; + } + break; + } + + if (dir <= 0) { + dir = -1; + OffsetRect(&outRect, dir, 0); + } else { + break; + } + } else if (inFloorInfo->GetTenant(outRect.top, outRect.right - 1)) { + if (dir >= 0) { + dir = 1; + OffsetRect(&outRect, dir, 0); + } else { + break; + } + } + } + + return success; } -void T2FireBurning::Extinguish(T2Fire*) { +void T2FireBurning::Extinguish(T2Fire* inFire) { + mFireArray->Remove(&inFire); + + T2People *theFireman = inFire->GetFireman(); + if (theFireman) { + theFireman->ChangeStyle(kPeopleStyle1); + theFireman->ChangeStatus(kStatus15); + mPeopleList->InsertItemsAt(1, 1, &theFireman); + } + + delete inFire; } -int T2FireBurning::DoExtinguish(CPoint&) { +BOOL T2FireBurning::DoExtinguish(CPoint& inPt) { + LArrayIterator iterator(*mFireArray); + CRect rect; + T2Fire *theFire; + + while (iterator.Next(&theFire)) { + if (theFire->HitTest(inPt, rect)) { + Extinguish(theFire); + return true; + } + } + + return false; } -void T2FireBurning::CallFireman(T2TowerDoc*, const T2Tenant*) { +void T2FireBurning::CallFireman(T2TowerDoc* inDoc, const T2Tenant* inTenant) { + T2RegistedTenantDB *theDB = inDoc->towerDoc_vf174(); + T2EquipPtrList *theList = theDB->GetList(kTenantRegistID5); + + if (theList) { + LArrayIterator iterator(*theList); + unsigned int numFiremen = 0; + unsigned int nowMinutes = inDoc->towerDoc_vf120()->GetRawMinutes(); + T2Tenant *theFireStation; + + while (numFiremen < 6 && iterator.Next(&theFireStation)) { + while (numFiremen < 6 && theFireStation->GetFirstPeople()) { + T2People *thePeople = theFireStation->GetFirstPeople(); + thePeople->ChangeStyle(kPeopleStyle2); + thePeople->SetSpecialFlag(kSpecialFlag20 | kSpecialFlag40); + thePeople->SetReturn(theFireStation->GetEquipID()); + thePeople->SetDestination(inTenant->GetEquipID()); + thePeople->mColor = 11; + theFireStation->PushOutPeople(inDoc, thePeople); + mPeopleList->InsertItemsAt(1, 1, &thePeople); + numFiremen++; + } + } + } } -int T2FireBurning::IsBreakoutFire(const T2TowerDoc*, POINT&, T2Tenant*&) const { +BOOL T2FireBurning::IsBreakoutFire(const T2TowerDoc* inDoc, POINT& outPt, T2Tenant*& outTenant) const { + BOOL done = false; + T2FloorInfo *theFloorInfo = inDoc->towerDoc_vf12C(); + + unsigned int curAttempt = 0; + unsigned int numAttempt = _4 ? 100000 : 100; + + while (!done && curAttempt < numAttempt) { + curAttempt++; + + POINT pt; + pt.x = UT2Utils::Randomize(theFloorInfo->GetHRange()); + pt.y = UT2Utils::Randomize(theFloorInfo->GetGroundLine() - 2); + T2Tenant *theTn = theFloorInfo->GetTenant(pt.y, pt.x); + + if (theTn && !theTn->IsFire() && !theTn->IsFireproof()) { + RECT rect; + rect.left = pt.x - (mFireWidth / 2 + 1); + rect.top = pt.y; + rect.right = pt.x + (mFireWidth / 2 + 1); + rect.bottom = pt.y + 1; + + if (theFloorInfo->IsAllTenant(rect)) { + outPt = pt; + outTenant = theTn; + done = true; + } + } + } + + return done; } -T2Fire::T2Fire(POINT&, T2TowerDoc*, int, T2ImageObj*) { + + +T2Fire::T2Fire(POINT& inPt, T2TowerDoc* inDoc, int inVar, T2ImageObj* inImageObj) { + CRect junkRect; + CRect theRect; + + inImageObj->GetObjectImage(inImageObj->FindObject("FIRE", 0), theRect); + theRect.OffsetRect(-theRect.left, -theRect.top); + + x0 = 0; + x4 = 0; + mDocument = inDoc; + xC = inVar; + x18 = (theRect.right - theRect.left) / 2; + x1C = (theRect.right - theRect.left) / 8; + + mSprite = &mDocument->mSprite; + mArsonTenant = NULL; + mFireman = NULL; + + for (unsigned int h = 0; h < x1C; h++) { + T2Tenant *theTenant = inDoc->towerDoc_vf12C()->GetTenant(inPt.y, inPt.x + h); + if (theTenant && !theTenant->IsFireproof() && !theTenant->IsFire()) { + if (xC > 0) { + if (mArsonTenant != theTenant) + mArsonTenant = theTenant; + } else { + if (mArsonTenant == NULL) + mArsonTenant = theTenant; + } + } + } + + if (mSprite) { + mFireSpriteID = mSprite->NewSprite(*inImageObj, "FIRE", T2Sprite::ELayer_4); + + POINT spritePt = inPt; + UT2Coordinate::UnitToQD(spritePt, 0, true); + mSprite->MoveSprite(mFireSpriteID, spritePt); + mSprite->ShowSprite(mFireSpriteID, true); + } } T2Fire::~T2Fire() { + if (mSprite) { + mSprite->ShowSprite(mFireSpriteID, false); + mSprite->DeleteSprite(mFireSpriteID); + } } -void T2Fire::SetFireman(T2People*) { +void T2Fire::SetFireman(T2People* inPeople) { + mFireman = inPeople; + mFireman->SetDestination(mArsonTenant->GetEquipID()); + mFireman->ChangeStyle(kPeopleStyle2); + mFireman->ChangeStatus(kStatus3); } -int T2Fire::Move() { +BOOL T2Fire::Move() { + BOOL done = false; + + mSprite->ChangePattern(mFireSpriteID, x0 % 4); + + CRect rect; + mSprite->GetSpriteRect(mFireSpriteID, rect); + + CPoint p = rect.TopLeft(); + + if (x4 == 0) { + p.x = (xC > 0) ? (rect.right + 1) : (rect.left - 1); + UT2Coordinate::QDToUnit(p, 0); + + T2Tenant *theTenant = mDocument->towerDoc_vf12C()->GetTenant(p.y, p.x); + if (theTenant && !theTenant->IsFireproof() && (!theTenant->IsFire() || mArsonTenant == theTenant)) { + p.y = rect.top; + p.x = rect.left + xC; + mSprite->MoveSprite(mFireSpriteID, p); + theTenant->SetStatus(kTenantStatus10000); + mArsonTenant = theTenant; + } else { + x4 = 1; + } + } else { + x4++; + T2TowerMainView *theView = mDocument->GetTowerMainView(); + if (theView) { + CRect unitRect = rect; + UT2Coordinate::QDToUnit(unitRect.TopLeft(), 0); + UT2Coordinate::QDToUnit(unitRect.BottomRight(), 0); + unitRect.right++; + theView->tmv_vf128(unitRect, true); + } + } + + if (x18 != 0) { + x0++; + if ((x0 % x18) == 0) { + T2FireBurning *theFireBurning = mDocument->mWorldDef->GetFireBurning(); + + p.y = rect.top; + p.x = rect.left + x18; + p.x = (xC > 0) ? rect.left : rect.right; + UT2Coordinate::QDToUnit(p, 0); + p.y--; + + for (unsigned int i = 0; i < x1C; i++) { + if (theFireBurning->MakeFire(p, mDocument)) + break; + if (x4 == 0) + break; + + p.x += xC; + } + + if (x4 > x18) { + theFireBurning->Extinguish(this); + done = true; + } + } + } + + return done; } -int T2Fire::HitTest(CPoint&, CRect&) { +BOOL T2Fire::HitTest(CPoint& inPt, CRect& outRect) { + CRect rect; + mSprite->GetSpriteRect(mFireSpriteID, rect); + + BOOL success = rect.PtInRect(inPt); + if (success) + outRect = rect; + + return success; } -int T2Fire::ExtinguishByFireman(T2TowerDoc*, T2PeoplePtrList*) { +BOOL T2Fire::ExtinguishByFireman(T2TowerDoc* inDoc, T2PeoplePtrList* inPeopleList) { + BOOL result = false; + + if (!mFireman) { + T2People *fireman; + if (inPeopleList->FetchItemAt(1, &fireman)) { + inPeopleList->Remove(&fireman); + SetFireman(fireman); + } + } else { + if (mFireman->GetWalkStyle() != 2) { + switch (mFireman->GetStatus()) { + case kStatus14: + case kStatus15: + { + CRect rect; + mSprite->GetSpriteRect(mFireSpriteID, rect); + + CPoint theFirePos = rect.TopLeft(); + theFirePos.x += rect.Width() / 2; + UT2Coordinate::QDToUnit(theFirePos, 0); + + CPoint theFiremanPos = mFireman->GetCurPosition(); + if (theFiremanPos.x != theFirePos.x) { + if (mFireman->GetCurrDestPos().x != theFirePos.x) { + mFireman->SetCurrDestPos(theFirePos); + switch (mFireman->GetDirection()) { + case 0: + if (theFiremanPos.x > theFirePos.x) + mFireman->FlipDirection(); + break; + case 1: + if (theFiremanPos.x < theFirePos.x) + mFireman->FlipDirection(); + break; + } + mFireman->SetStatus(kStatus14); + } + } else { + if (x4 < (x18 - 4) || x4 == 0) { + x4 = x18 - 4; + if (x4 <= 0) + x4 = 1; + } + + mFireman->SetStatus(kStatus15); + mFireman->ChangeWalkStyle(2); + } + } + } + } else { + if (x4 > x18) + result = true; + } + } + + return result; } -T2Helicopter::T2Helicopter(T2TowerDoc*, const T2Tenant*) { + + +T2Helicopter::T2Helicopter(T2TowerDoc* inDoc, const T2Tenant* inTenant) { + mDocument = inDoc; + mSprite = &mDocument->mSprite; + + mHeliSpriteID = 0; + mWaterSpriteID = 0; + + mTimePassed = 0; + mSpeed = 1; + mWaterVisible = false; + + mImage = new T2BitImage(mDocument->mWorldDef->mModuleHandle, 5001, true); + mImageObj = new T2ImageObj; + mImageObj->AddObject(inDoc->mWorldDef->mModuleHandle, 5001, mImage); + + mHeliSpriteID = mSprite->NewSprite(*mImageObj, "HELI", T2Sprite::ELayer_4); + mWaterSpriteID = mSprite->NewSprite(*mImageObj, "WATER", T2Sprite::ELayer_4); + + if (inTenant) { + CRect unitRect, qdRect; + inTenant->GetEquipArea(unitRect); + unitRect.top -= 5; + unitRect.left += 10; + UT2Coordinate::UnitToQD(unitRect, qdRect, 0, true); + + mSprite->MoveSprite(mHeliSpriteID, qdRect.TopLeft()); + mSprite->ShowSprite(mHeliSpriteID, true); + } } T2Helicopter::~T2Helicopter() { + mDocument->mSprite.DeleteSprite(mHeliSpriteID); + mDocument->mSprite.DeleteSprite(mWaterSpriteID); + delete mImage; + delete mImageObj; } -void T2Helicopter::Move(T2TowerDoc*) { +void T2Helicopter::Move(T2TowerDoc* inDoc) { + T2TowerMainView *theMainView = inDoc->GetTowerMainView(); + CRect rect; + CPoint cursorPt, p; + + GetCursorPos(&cursorPt); + theMainView->ScreenToClient(&cursorPt); + + cursorPt += theMainView->m64; + + UT2Coordinate::QDToUnit(cursorPt, mDocument->towerDoc_vf108()); + cursorPt.y -= 1; + cursorPt.x += 1; + UT2Coordinate::UnitToQD(cursorPt, 0, true); + cursorPt.y -= 4; + + mSprite->GetSpriteRect(mHeliSpriteID, rect); + p = rect.TopLeft(); + + float h = cursorPt.x - p.x; + float v = cursorPt.y - p.y; + float dst = sqrt(h * h + v * v); + + if (dst < 36.0f) + mSpeed -= (mSpeed > 1); + else + mSpeed += (mSpeed < 8); + + float ratio = dst / mSpeed; + if (ratio > 1.0f) { + p.x += (int) (h / ratio); + p.y += (int) (v / ratio); + } else { + p.y--; + p.x++; + } + + mTimePassed++; + mSprite->ChangePattern(mHeliSpriteID, mTimePassed & 1); + mSprite->MoveSprite(mHeliSpriteID, p); + + if (GetAsyncKeyState(GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON) < 0) { + p.y += rect.Height(); + mSprite->GetSpriteRect(mWaterSpriteID, rect); + p.x -= rect.Width(); + + mSprite->ChangePattern(mWaterSpriteID, mTimePassed & 1); + mSprite->MoveSprite(mWaterSpriteID, p); + if (!mWaterVisible) { + mSprite->ShowSprite(mWaterSpriteID, true); + mWaterVisible = true; + } + + p.y += rect.Height(); + + T2FireBurning *theFireBurning = mDocument->mWorldDef->GetFireBurning(); + theFireBurning->DoExtinguish(p); + } else if (mWaterVisible) { + p.x = p.y = 0; + mSprite->MoveSprite(mWaterSpriteID, p); + mSprite->ShowSprite(mWaterSpriteID, false); + mWaterVisible = false; + } } -T2FireAttach::T2FireAttach(T2EventItem*, unsigned int, int) { + + +T2FireAttach::T2FireAttach(T2EventItem* inOwner, unsigned int inMessage, BOOL inExecuteHost) + : LAttachment(inMessage, inExecuteHost) +{ + mOwner = inOwner; } /*virtual*/ T2FireAttach::~T2FireAttach() { } -/*virtual*/ void T2FireAttach::ExecuteSelf(unsigned int, void*) { +/*virtual*/ void T2FireAttach::ExecuteSelf(unsigned int inMessage, void* ioData) { + MSG *pMsg; + BOOL newExecuteHost = true; + + if (mOwner->mStatus != 0) { + switch (inMessage) { + case WM_SETCURSOR: + pMsg = (MSG *) ioData; + if (LOWORD(pMsg->lParam) == HTCLIENT) { + SetCursor(LoadCursor(NULL, IDC_ARROW)); + newExecuteHost = false; + } + break; + + case WM_LBUTTONDOWN: + newExecuteHost = false; + break; + + case WM_TIMER: + pMsg = (MSG *) ioData; + if (pMsg->wParam == 100) + newExecuteHost = false; + break; + } + } + + SetExecuteHost(newExecuteHost); } |