#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* 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* 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); } BOOL T2TowerEvent::IsBlackOut() { return mBlackOut ? mBlackOut->IsBlackOut() : false; } 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* inEventItem) { mStandby.Add(&inEventItem); } void T2TowerEvent::InsertExecute(T2EventItem* inEventItem) { if (inEventItem->IsExclusive()) mRunning.InsertItemsAt(1, 1, &inEventItem); else mRunning.Add(&inEventItem); } 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(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(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(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(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* 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* 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& 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& 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* 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* inDoc, VIEWMODE inViewMode) { LArrayIterator iterator(mRunning); T2EventItem *theEvent; while (iterator.Next(&theEvent)) theEvent->ViewModeChanged(inDoc, inViewMode); }