diff options
Diffstat (limited to 'src/T2DLL/T2TowerEvent.cpp')
-rw-r--r-- | src/T2DLL/T2TowerEvent.cpp | 462 |
1 files changed, 445 insertions, 17 deletions
diff --git a/src/T2DLL/T2TowerEvent.cpp b/src/T2DLL/T2TowerEvent.cpp index 57882f2..84dc878 100644 --- a/src/T2DLL/T2TowerEvent.cpp +++ b/src/T2DLL/T2TowerEvent.cpp @@ -1,79 +1,507 @@ +#include "CProgramPlugin.h" +#include "CResFile.h" +#include "T2Archive.h" +#include "T2BlackOut.h" +#include "T2DateTime.h" +#include "T2FireBurning.h" +#include "T2ImageObj.h" +#include "T2Maru_Reggae.h" +#include "T2MetroRailway.h" +#include "T2OutDecoration.h" +#include "T2SantaClaus.h" +#include "T2Tenant.h" +#include "T2TenantDef.h" +#include "T2Terrorist.h" +#include "T2TowerDoc.h" #include "T2TowerEvent.h" +#include "T2TowerVision.h" +#include "T2VisitVIP.h" +#include "T2WorldDef.h" +#include "UT2Coordinate.h" -T2TowerEvent::T2TowerEvent(T2WorldDef*) { +T2TowerEvent::T2TowerEvent(T2WorldDef* inWorldDef) { + mWorldDef = inWorldDef; + mDocument = NULL; + _8 = 1441; + mLevel = 0; + + mFireBurning = NULL; + mMetroRailway = NULL; + mBlackOut = NULL; + mSantaClaus = NULL; + mTowerVision = NULL; + mOutDecoration = NULL; + + _88 = 0; + mLatestBuild = NULL; + + CResFile resFile; + T2EventItem *theEvent; + + if (resFile.OpenResource(inWorldDef->mModuleHandle, 1, 'T2Ev')) { + int numEvent; + resFile >> numEvent; + + DWORD theEventID; + int theEventSubID; + + for (int i = 0; i < numEvent; i++) { + resFile >> theEventID; + resFile >> theEventSubID; + + CResFile subResFile; + if (subResFile.OpenResource(inWorldDef->mModuleHandle, theEventSubID, theEventID)) { + switch (theEventID) { + case 'FBEv': + theEvent = new T2FireBurning(this, &subResFile, theEventSubID); + mFireBurning = (T2FireBurning *) theEvent; + break; + case 'TrEv': + theEvent = new T2Terrorist(this, &subResFile, theEventSubID); + break; + case 'ViEv': + theEvent = new T2VisitVIP(this, &subResFile, theEventSubID); + break; + case 'BOEv': + theEvent = new T2BlackOut(this, &subResFile, theEventSubID); + mBlackOut = (T2BlackOut *) theEvent; + break; + case 'SaEv': + theEvent = new T2SantaClaus(this, &subResFile, theEventSubID); + mSantaClaus = (T2SantaClaus *) theEvent; + break; + case 'MREv': + theEvent = new T2MetroRailway(this, &subResFile, theEventSubID); + mMetroRailway = (T2MetroRailway *) theEvent; + break; + case 'OdEv': + theEvent = new T2OutDecoration(this, &subResFile, theEventSubID); + mOutDecoration = (T2OutDecoration *) theEvent; + break; + case 'MaEv': + theEvent = new T2Maru_Reggae(this, &subResFile, theEventSubID); + break; + default: + theEvent = inWorldDef->MakeXEvent(this, &subResFile, theEventID, theEventSubID); + break; + } + + if (theEvent) { + mStandby.Add(&theEvent); + } else { + CString str; + str.Format("EVENT ITEM %c%c%c%c Undefined!\n", + ((char *) &theEventID)[3], + ((char *) &theEventID)[2], + ((char *) &theEventID)[1], + ((char *) &theEventID)[0] + ); + OutputDebugString(str); + } + } + } + } } T2TowerEvent::~T2TowerEvent() { + T2EventItem *theEvent; + + while (mStandby.FetchItemAt(1, &theEvent)) { + mStandby.RemoveItemsAt(1, 1); + delete theEvent; + } + while (mWaiting.FetchItemAt(1, &theEvent)) { + mWaiting.RemoveItemsAt(1, 1); + delete theEvent; + } + while (mRunning.FetchItemAt(1, &theEvent)) { + mRunning.RemoveItemsAt(1, 1); + delete theEvent; + } } -void T2TowerEvent::InitTowerEvent(T2TowerDoc*) { +void T2TowerEvent::InitTowerEvent(T2TowerDoc* inDoc) { + mDocument = inDoc; } T2FireBurning* T2TowerEvent::GetFireBurning() { + return mFireBurning; } T2MetroRailway* T2TowerEvent::GetMetroRailway() { + return mMetroRailway; } T2BlackOut* T2TowerEvent::GetBlackOut() { + return mBlackOut; } T2TowerVision* T2TowerEvent::GetTowerVision() { + return mTowerVision; } T2Transport* T2TowerEvent::GetCruise() { + return mWorldDef->GetCruise(this); } -int T2TowerEvent::IsBlackOut() { +BOOL T2TowerEvent::IsBlackOut() { + return mBlackOut ? mBlackOut->IsBlackOut() : false; } -void T2TowerEvent::SetLatestBuild(T2Equip*, T2ToolDef*, int) { +void T2TowerEvent::SetLatestBuild(T2Equip* inEquip, T2ToolDef* inToolDef, BOOL inFlag) { + CProgramPlugin *thePlugin = inToolDef ? inToolDef->GetPlugin() : NULL; + + if (mBlackOut) { + int consumptionPower = inToolDef ? inToolDef->GetConsumptionPower(0) : 0; + if (thePlugin) { + BOOL isHEND = (thePlugin->GetID() == 'HEND'); + if (inFlag) { + if (isHEND) + mBlackOut->AddSupplyPower(1); + mBlackOut->AddConsumptionPower(consumptionPower); + } else { + if (isHEND) + mBlackOut->SubSupplyPower(); + mBlackOut->SubConsumptionPower(consumptionPower); + } + } + } + + mLatestBuild = (inFlag && inToolDef && inToolDef->IsTenant()) ? inEquip : NULL; + + if (mOutDecoration && inEquip && inToolDef && inToolDef->IsTenant()) { + if (inFlag) + mOutDecoration->CheckRoofTop(inEquip); + else if (((T2TenantDef *) inToolDef)->IsFloor()) + mOutDecoration->CheckRoofTop(NULL); + } } T2Equip* T2TowerEvent::GetLatestBuild() { + return mLatestBuild; } -void T2TowerEvent::AppendStandby(T2EventItem*) { +void T2TowerEvent::AppendStandby(T2EventItem* inEventItem) { + mStandby.Add(&inEventItem); } -void T2TowerEvent::InsertExecute(T2EventItem*) { +void T2TowerEvent::InsertExecute(T2EventItem* inEventItem) { + if (inEventItem->IsExclusive()) + mRunning.InsertItemsAt(1, 1, &inEventItem); + else + mRunning.Add(&inEventItem); } -void T2TowerEvent::MakeTowerVisionEvent(T2OutObj*) { +void T2TowerEvent::MakeTowerVisionEvent(T2OutObj* inOutObj) { + if (!mTowerVision) { + mTowerVision = new T2TowerVision(this, 0, 0xFF, false, 1, 0, 1440, inOutObj); + if (mTowerVision) + mRunning.Add(&mTowerVision); + } } void T2TowerEvent::KillTowerVisionEvent() { + if (mTowerVision) { + mRunning.Remove(&mTowerVision); + delete mTowerVision; + mTowerVision = NULL; + } } -T2EventItem* T2TowerEvent::MakeXEvent(unsigned long) { +T2EventItem* T2TowerEvent::MakeXEvent(DWORD inID) { + T2EventItem *theEvent = NULL; + + CResFile theResFile; + if (theResFile.OpenResource(mWorldDef->mModuleHandle, 128, inID)) { + theEvent = mWorldDef->MakeXEvent(this, &theResFile, inID, 128); + StoreWaitSequence(theEvent); + } + + return theEvent; } -void T2TowerEvent::KillXEvent(unsigned long) { +void T2TowerEvent::KillXEvent(DWORD inID) { + T2EventItem *theEvent; + + LArrayIterator eventIteratorRunning(mRunning); + while (eventIteratorRunning.Next(&theEvent)) { + if (theEvent->GetID() == inID) { + mRunning.RemoveItemsAt(1, eventIteratorRunning.GetCurrentIndex()); + delete theEvent; + eventIteratorRunning.Reset(); + } + } + + LArrayIterator eventIteratorStandby(mStandby); + while (eventIteratorStandby.Next(&theEvent)) { + if (theEvent->GetID() == inID) { + mStandby.RemoveItemsAt(1, eventIteratorStandby.GetCurrentIndex()); + delete theEvent; + eventIteratorStandby.Reset(); + } + } + + LArrayIterator eventIteratorWaiting(mWaiting); + while (eventIteratorWaiting.Next(&theEvent)) { + if (theEvent->GetID() == inID) { + mWaiting.RemoveItemsAt(1, eventIteratorWaiting.GetCurrentIndex()); + delete theEvent; + eventIteratorWaiting.Reset(); + } + } } -T2EventItem* T2TowerEvent::GetEvent(unsigned long) { +T2EventItem* T2TowerEvent::GetEvent(DWORD inID) { + T2EventItem *theEvent; + + LArrayIterator eventIteratorRunning(mRunning); + while (eventIteratorRunning.Next(&theEvent)) { + if (theEvent->GetID() == inID) + return theEvent; + } + + LArrayIterator eventIteratorStandby(mStandby); + while (eventIteratorStandby.Next(&theEvent)) { + if (theEvent->GetID() == inID) + return theEvent; + } + + LArrayIterator eventIteratorWaiting(mWaiting); + while (eventIteratorWaiting.Next(&theEvent)) { + if (theEvent->GetID() == inID) + return theEvent; + } + + return NULL; } -unsigned int T2TowerEvent::GetXEvent(unsigned long) { +unsigned int T2TowerEvent::GetXEvent(DWORD inID) { + T2EventItem *theEvent = GetEvent(inID); + return (unsigned int) theEvent; // ??? } void T2TowerEvent::StopEvent() { + T2EventItem *theEvent; + + LArrayIterator iterator(mRunning); + while (iterator.Next(&theEvent)) + theEvent->StopEvent(mDocument); } -int T2TowerEvent::Idle(T2TowerDoc*) { +int T2TowerEvent::Idle(T2TowerDoc* inDoc) { + T2EventItem *theEvent; + T2DateTime *theNow = inDoc->towerDoc_vf120(); + int nowMinutes = theNow->GetRawMinutes(); + + if ((nowMinutes == 0 && _8 != nowMinutes) || mLevel != inDoc->towerDoc_vf138()) { +#pragma var_order(day, eventIteratorWaiting, eventIteratorStandby, theLevelBit) + mLevel = inDoc->towerDoc_vf138(); + unsigned int theLevelBit = (mLevel > 0) ? (1 << (mLevel - 1)) : 0; + int day = theNow->CalcLapseDays(12) + 1; + + LArrayIterator eventIteratorStandby(mStandby); + while (eventIteratorStandby.Next(&theEvent)) { + if (theEvent->_4 || ((theEvent->GetLevelBit() & theLevelBit) && theEvent->IsBeginDay(day))) { + mStandby.Remove(&theEvent); + eventIteratorStandby.Reset(); + StoreWaitSequence(theEvent); + } + } + + LArrayIterator eventIteratorWaiting(mWaiting); + while (eventIteratorWaiting.Next(&theEvent)) { + if (!theEvent->_4 && !(theEvent->GetLevelBit() & theLevelBit)) { + mWaiting.Remove(&theEvent); + eventIteratorWaiting.Reset(); + mStandby.Add(&theEvent); + } + } + } + + LArrayIterator iterator(mRunning); + while (iterator.Next(&theEvent)) { + switch (theEvent->Exec(inDoc)) { + case 1: + _8 = nowMinutes; + return 1; + + case 3: + mRunning.Remove(&theEvent); + iterator.Reset(); + if (nowMinutes <= theEvent->GetBeginTime()) { + unsigned int theLevelBit = (mLevel > 0) ? (1 << (mLevel - 1)) : 0; + int day = theNow->CalcLapseDays(12) + 1; + + if ((theEvent->GetLevelBit() & theLevelBit) && theEvent->IsBeginDay(day)) + StoreWaitSequence(theEvent); + else + mStandby.Add(&theEvent); + } else { + mStandby.Add(&theEvent); + } + break; + } + } + + if (_8 != nowMinutes) { + LArrayIterator eventIteratorWaiting(mWaiting); + while (eventIteratorWaiting.Next(&theEvent)) { + if (theEvent->GetBeginTime() > nowMinutes) + break; + + mWaiting.Remove(&theEvent); + eventIteratorWaiting.Reset(); + + if (theEvent->IsBeginTime(nowMinutes) && theEvent->Start(inDoc)) { + if (theEvent->IsExclusive()) + mRunning.InsertItemsAt(1, 1, &theEvent); + else + mRunning.Add(&theEvent); + } else { + mStandby.Add(&theEvent); + } + } + + _8 = nowMinutes; + } + + return 0; } -void T2TowerEvent::StoreWaitSequence(T2EventItem*) { +void T2TowerEvent::StoreWaitSequence(T2EventItem* inEventItem) { + LArrayIterator iterator(mWaiting); + T2EventItem *theEvent; + + while (iterator.Next(&theEvent)) { + if (inEventItem->GetBeginTime() < theEvent->GetBeginTime()) + break; + } + + if (iterator.GetCurrentIndex() == 0) + mWaiting.Add(&inEventItem); + else + mWaiting.InsertItemsAt(1, iterator.GetCurrentIndex(), &inEventItem); } -void T2TowerEvent::Write(T2Archive&) { +void T2TowerEvent::Write(T2Archive& inArchive) { +#pragma var_order(theEvent, eventIteratorStandby, eventIteratorWaiting, numOfEvent, eventIteratorRunning, isRunning, theEventSubID, theEventID) + int numOfEvent = mStandby.GetCount() + mWaiting.GetCount() + mRunning.GetCount(); + unsigned char isRunning = 0; + + inArchive << _88; + inArchive << (short) numOfEvent; + + T2EventItem *theEvent; + DWORD theEventID; + short theEventSubID; + + LArrayIterator eventIteratorStandby(mStandby); + while (eventIteratorStandby.Next(&theEvent)) { + theEventID = theEvent->GetID(); + theEventSubID = theEvent->GetSubID(); + + inArchive << theEventID; + inArchive << theEventSubID; + inArchive << isRunning; + theEvent->Write(inArchive); + } + + LArrayIterator eventIteratorWaiting(mWaiting); + while (eventIteratorWaiting.Next(&theEvent)) { + theEventID = theEvent->GetID(); + theEventSubID = theEvent->GetSubID(); + + inArchive << theEventID; + inArchive << theEventSubID; + inArchive << isRunning; + theEvent->Write(inArchive); + } + + isRunning = 1; + + LArrayIterator eventIteratorRunning(mRunning); + while (eventIteratorRunning.Next(&theEvent)) { + theEventID = theEvent->GetID(); + theEventSubID = theEvent->GetSubID(); + + inArchive << theEventID; + inArchive << theEventSubID; + inArchive << isRunning; + theEvent->Write(inArchive); + } } -void T2TowerEvent::Read(T2Archive&) { +void T2TowerEvent::Read(T2Archive& inArchive) { + short numOfEvent; + unsigned char isRunning; + T2EventItem *theEvent; + DWORD theEventID; + short theEventSubID; + + LArrayIterator iteratorStandby(mStandby); + + inArchive >> _88; + inArchive >> numOfEvent; + + for (short num = 0; num < numOfEvent; num++) { + inArchive >> theEventID; + inArchive >> theEventSubID; + inArchive >> isRunning; + BOOL eventOK = false; + iteratorStandby.ResetTo(0); + + while (!eventOK && iteratorStandby.Next(&theEvent)) { + if (theEvent->GetID() == theEventID && theEvent->GetSubID() == theEventSubID) { + theEvent->Read(inArchive); + if (isRunning) { + mStandby.RemoveItemsAt(1, iteratorStandby.GetCurrentIndex()); + if (theEvent->ReStart(mDocument)) + mRunning.InsertItemsAt(1, theEvent->IsExclusive() ? 1 : (mRunning.GetCount() + 1), &theEvent); + else + mStandby.InsertItemsAt(1, mRunning.GetCount() + 1, &theEvent); + } + eventOK = true; + } + } + + LArrayIterator iteratorWaiting(mWaiting); + while (!eventOK && iteratorWaiting.Next(&theEvent)) { + if (theEvent->GetID() == theEventID && theEvent->GetSubID() == theEventSubID) { + theEvent->Read(inArchive); + eventOK = true; + } + } + + if (!eventOK) { + unsigned char tmp; + unsigned int len; + inArchive >> len; + for (unsigned int i = 0; i < len; i++) + inArchive >> tmp; + } + } } -void T2TowerEvent::DrawRubble(T2TowerDoc*, T2Tenant*) { +void T2TowerEvent::DrawRubble(T2TowerDoc* inDoc, T2Tenant* inTenant) { + int objectID = inDoc->mWorldDef->mImageObj->FindObject("Rubble"); + if (objectID >= 0) { + CRect rect1, rect2; + + inTenant->GetEquipArea(rect1); + UT2Coordinate::UnitToQD(rect1, rect2, inDoc->towerDoc_vf108(), true); + rect2.bottom = rect2.top + UT2Coordinate::UnitVSize(inDoc->towerDoc_vf108()); + + for (int i = 0; i < rect1.Height(); i++) { + inDoc->mWorldDef->mImageObj->DrawObject(inDoc->towerDoc_vf10C(), objectID, rect2, inDoc->towerDoc_vf108()); + rect2.OffsetRect(0, UT2Coordinate::UnitVSize(inDoc->towerDoc_vf108())); + } + } } -void T2TowerEvent::ViewModeChanged(T2TowerDoc*, VIEWMODE) { +void T2TowerEvent::ViewModeChanged(T2TowerDoc* inDoc, VIEWMODE inViewMode) { + LArrayIterator iterator(mRunning); + T2EventItem *theEvent; + + while (iterator.Next(&theEvent)) + theEvent->ViewModeChanged(inDoc, inViewMode); } |