#include "StdAfx.h" #include "CResFile.h" #include "GlobalFunc.h" #include "LArray.h" #include "../T2.h" #include "../T2CtrlPalette.h" #include "T2DateTime.h" #include "T2Dialog.h" #include "T2DlgItem.h" #include "T2DLL.h" #include "T2EquipPtrList.h" #include "T2FInfoAreaIterator.h" #include "T2FInfoPtIterator.h" #include "T2FireBurning.h" #include "T2FloorInfo.h" #include "T2FloorPtrList.h" #include "../T2MainWindow.h" #include "T2People.h" #include "T2RegistedTenantDB.h" #include "T2RouteNavigator.h" #include "T2Settlement.h" #include "T2SoundPlayer.h" #include "T2Tenant.h" #include "T2Terrorist.h" #include "T2ToolWindow.h" #include "../T2TowerDoc.h" #include "../T2TowerMainView.h" #include "T2WorldDef.h" #include "URect.h" #include "UT2Coordinate.h" #include "UT2Utils.h" T2Terrorist::T2Terrorist(T2TowerEvent* inTowerEvent, CResFile* inResFile, int inSubID) : T2EventItem(inTowerEvent, inResFile, inSubID) { *inResFile >> mRansomFee; *inResFile >> mDeadline; *inResFile >> mHigherRansomFee; mBombHideRoomID = 0; mLastMinute = 0; mAttach = NULL; mSearcherL = new LArray; mSearcherR = new LArray; } /*virtual*/ T2Terrorist::~T2Terrorist() { StopEvent(GetTowerDoc()); delete mSearcherL; mSearcherL = NULL; delete mSearcherR; mSearcherR = NULL; } /*virtual*/ BOOL T2Terrorist::Start(T2TowerDoc* inDoc) { mStatus = kTerroristStatus0; BOOL found = false; T2FloorInfo *theFloorInfo = inDoc->GetFloorInfo(); RECT theIteratorArea; int theGroundLine = theFloorInfo->GetGroundLine(); theFloorInfo->GetFloorArea(theIteratorArea); if (theIteratorArea.bottom > (theGroundLine - 3)) theIteratorArea.bottom = theGroundLine - 3; T2FInfoAreaIterator iterator(*theFloorInfo, theIteratorArea); T2Tenant *theTenant; while (iterator.NextTenant(theTenant)) { found = theTenant && !theTenant->IsFireproof() && !theTenant->IsFire(); if (found) break; } if (!found) return false; SetupSound(); inDoc->SetViewMode(kInView); inDoc->towerDoc_vf1A0(true); CString text, tempStr; text = LoadStringTable(GetWorldModuleHandle(), 8300, 1); tempStr.Format("%d", mRansomFee); text += tempStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 2); tempStr.Format("%d", mDeadline / 60); text += tempStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 3); Sounds->Play("Terrorist:", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_0, 100); if (DoDialog(inDoc, 8300, 8300, 2, text) == 8303) { inDoc->DoPay(mRansomFee, kFundGroup2); Sounds->Play("Terrorist:ThankYou", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_0, 100); DWORD time = timeGetTime(); while ((timeGetTime() - time) < 900) gT2App->app_vfB4(); inDoc->towerDoc_vf1A0(false); } else { inDoc->SetDrawSpeed(25); inDoc->SetFireBurning(true); inDoc->towerDoc_vf2A0()->EnableIcon(false); inDoc->GetMainView()->HideToolSprite(); inDoc->towerDoc_vf2B0(true); T2_MAIN_WINDOW->mCtrlPalette->vf108(0); do { mBombHidePos.x = UT2Utils::Randomize(URect::Width(theIteratorArea)) + theIteratorArea.left; mBombHidePos.y = UT2Utils::Randomize(URect::Height(theIteratorArea)) + theIteratorArea.top; theTenant = theFloorInfo->GetTenant(mBombHidePos.y, mBombHidePos.x); } while (!theTenant || theTenant->IsFire() || theTenant->IsFireproof()); mBombHideRoomID = theTenant->GetEquipID(); inDoc->BreakoutEmergency(); inDoc->GetMainView()->tmv_vf120(); T2TowerMainView *theView = inDoc->GetMainView(); text = LoadStringTable(GetWorldModuleHandle(), 8300, 4); DoAlert(inDoc, text, 0); mStatus = kTerroristStatus1; mAttach = new T2FireAttach(this, 0, true); theView->AddAttachment(mAttach, NULL, true); inDoc->SetDrawSpeed(25); T2EquipPtrList *theList = inDoc->GetRegistedTenantDB()->GetList(kTenantRegistID5); if (theList) { T2FloorPtrList *theFloorList = inDoc->GetRouteNavi()->GetFloorPtrList(); LArrayIterator floorIterator(*theFloorList); T2Tenant *theFloor; while (floorIterator.Next(&theFloor)) theFloor->ClearWorkCount(); T2Tenant *iteratorTenant; LArrayIterator tenantIterator(*theList); while (tenantIterator.Next(&iteratorTenant)) { T2Tenant *theCurrFloor = inDoc->GetFloorInfo()->GetTenant(iteratorTenant->GetExitFloorID()); if (theCurrFloor) { CRect area; theCurrFloor->GetEquipArea(area); CPoint ptL(area.left, area.bottom - 1); CPoint ptR(area.right - 2, area.bottom - 1); unsigned int capacity = iteratorTenant->GetBelongCapacity(); BOOL flag = false; for (unsigned int i = 1; i <= capacity; i++) { T2People *people = iteratorTenant->GetBelongPeopleIn(i); if (people) { people->SetSpecialFlag(kSpecialFlag20); if ((i % 2) == 0) { mSearcherL->Add(&people); iteratorTenant->PushOutPeople(inDoc, people); people->ChangeStyle(kPeopleStyle2); people->SetCurrDestPos(ptL); people->SetStatus(kStatus14); if (people->GetDirection() != 1) people->FlipDirection(); } else { mSearcherR->Add(&people); iteratorTenant->PushOutPeople(inDoc, people); people->ChangeStyle(kPeopleStyle2); people->SetCurrDestPos(ptR); people->SetStatus(kStatus14); if (people->GetDirection() != 0) people->FlipDirection(); } flag |= true; } } if (flag) theCurrFloor->IncWorkCount(); } } } Sounds->Play("Terrorist:Tick", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_3, 100); } if (mStatus == kTerroristStatus0) DisposeSound(); return (mStatus != kTerroristStatus0); } void T2Terrorist::SetupSound() { Sounds->FadeOut(); Sounds->AddSound("Terrorist:", SoundPriority_1, 8300, GetWorldModuleHandle()); Sounds->AddSound("Terrorist:Tick", SoundPriority_1, 8301, GetWorldModuleHandle()); Sounds->AddSound("Terrorist:Exp", SoundPriority_1, 8302, GetWorldModuleHandle()); Sounds->AddSound("Terrorist:ThankYou", SoundPriority_1, 8303, GetWorldModuleHandle()); } void T2Terrorist::DisposeSound() { if (Sounds) { Sounds->Stop("Terrorist:"); Sounds->Stop("Terrorist:Tick"); Sounds->Stop("Terrorist:Exp"); Sounds->Stop("Terrorist:ThankYou"); Sounds->DeleteSound("Terrorist:"); Sounds->DeleteSound("Terrorist:Tick"); Sounds->DeleteSound("Terrorist:Exp"); Sounds->DeleteSound("Terrorist:ThankYou"); Sounds->FadeIn(); } } static void MoveNextFloor(T2TowerDoc *inDoc, T2People *inPeople, BOOL inFlag); /*virtual*/ int T2Terrorist::Exec(T2TowerDoc* inDoc) { int result = IsExclusive() ? 1 : 0; T2DateTime *theNow = inDoc->GetNow(); unsigned int nowMinutes = theNow->GetRawMinutes(); if (mStatus == kTerroristStatus1) { T2FloorInfo *theFloorInfo = inDoc->GetFloorInfo(); T2People *theSearcher; LArrayIterator theIteratorL(*mSearcherL); while (mStatus != kTerroristStatus2 && theIteratorL.Next(&theSearcher)) { CPoint pt = theSearcher->GetCurPosition(); T2Tenant *theTenant = theFloorInfo->GetTenant(pt.y, pt.x); if (theTenant && IsBombHideRoom(theTenant->GetEquipID())) mStatus = kTerroristStatus2; if (mStatus != kTerroristStatus2 && theSearcher->GetStatus() == kStatus15) MoveNextFloor(inDoc, theSearcher, false); } LArrayIterator theIteratorR(*mSearcherR); while (mStatus != kTerroristStatus2 && theIteratorR.Next(&theSearcher)) { CPoint pt = theSearcher->GetCurPosition(); T2Tenant *theTenant = theFloorInfo->GetTenant(pt.y, pt.x); if (theTenant && IsBombHideRoom(theTenant->GetEquipID())) mStatus = kTerroristStatus2; if (mStatus != kTerroristStatus2 && theSearcher->GetStatus() == kStatus15) MoveNextFloor(inDoc, theSearcher, true); } } if (mLastMinute != nowMinutes) { CString text; CString tmpStr; switch (mStatus) { case kTerroristStatus1: if (nowMinutes == mDeadline) { text = LoadStringTable(GetWorldModuleHandle(), 8300, 5); tmpStr.Format("%d", mHigherRansomFee); text += tmpStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 6); int hour = mEndTime / 60; tmpStr.Format("%d", (hour > 12) ? (hour - 12) : hour); text += tmpStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 7); tmpStr.Format("%d", (hour > 12) ? (hour - 12) : hour); text += tmpStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 8); tmpStr.Format("%d", mHigherRansomFee); text += tmpStr; text += LoadStringTable(GetWorldModuleHandle(), 8300, 9); if (DoDialog(inDoc, 8300, 8300, 2, text) == 1) { inDoc->DoPay(mHigherRansomFee, kFundGroup2); result = 3; } else { inDoc->SetDrawSpeed(25); } } else if (nowMinutes == mEndTime) { Sounds->Stop("Terrorist:Tick"); Sounds->Play("Terrorist:Exp", SoundMask_10, SoundFlags_10 | SoundFlags_10000, NULL, PlayMode_0, 100); mStatus = kTerroristStatus3; } break; case kTerroristStatus3: { int hL, hR, vF, vA; T2Tenant *theTenant; hL = mBombHidePos.x; hR = mBombHidePos.x; for (int numOfAttempts = 0; numOfAttempts <= 40; numOfAttempts++) { for (int hDir = 0; hDir < 2; hDir++) { vA = vF = mBombHidePos.y; for (int i = 0; i <= 2; i++) { int h = (hDir == 0) ? hL : hR; if (h > 0 && h < GetWorldDef()->GetWidth()) { for (int vDir = 0; vDir < 2; vDir++) { int v = (vDir == 0) ? vA : vF; if (v > 0 && v < GetWorldDef()->mGroundLine) { theTenant = inDoc->GetFloorInfo()->GetTenant(v, h); if (theTenant && !theTenant->IsFire() && !theTenant->IsFireproof()) theTenant->BurntDown(inDoc); if (vDir == 0) vA = theTenant ? (vA - 1) : 0; else vF = theTenant ? (vF + 1) : 0; } } if (vA == 0 && vF == 0) break; } else { break; } } if (hDir == 0) hL = (vA == 0 && vF == 0) ? 0 : (hL - 1); else hR = (vA == 0 && vF == 0) ? 0 : (hR + 1); } if (hL == 0 && hR == 0) break; } T2TowerMainView *theMainView = inDoc->GetMainView(); CRect theBombArea; UT2Coordinate::MakeRect(theBombArea, mBombHidePos, 1, 1); theMainView->CenterOnRect(theBombArea); if (inDoc->GetViewMode() != kOutView) inDoc->towerDoc_vf284(); else T2_MAIN_WINDOW->mCtrlPalette->vf108(false); text = LoadStringTable(GetWorldModuleHandle(), 8300, 10); DoAlert(inDoc, text, 0); result = 3; break; } case kTerroristStatus2: text = LoadStringTable(GetWorldModuleHandle(), 8300, 11); DoAlert(inDoc, text, 0); result = 3; break; } mLastMinute = nowMinutes; } if (result == 3) StopEvent(inDoc); return result; } static void MoveNextFloor(T2TowerDoc *inDoc, T2People *inPeople, BOOL inFlag) { int theNextDirection; if (inPeople->GetDirection() == 0) theNextDirection = 1; else theNextDirection = 0; T2Tenant *theNextFloor = NULL; BOOL search = true; CRect theEquipRect; CPoint theNextPt; T2FloorInfo *theFloorInfo = inDoc->GetFloorInfo(); T2Tenant *theCurrFloor = theFloorInfo->GetTenant(inPeople->GetCurrEquipID()); CRect theSearchRect; theCurrFloor->GetEquipArea(theSearchRect); CPoint searchPtRight, searchPtLeft; int entranceH; while (!theNextFloor && search) { searchPtRight.x = theSearchRect.left; searchPtLeft.x = theSearchRect.right - 1; if (inFlag) { searchPtRight.y = theSearchRect.bottom; searchPtLeft.y = theSearchRect.bottom; } else { searchPtRight.y = theSearchRect.top - 1; searchPtLeft.y = theSearchRect.top - 1; } SetRect(&theSearchRect, searchPtRight.x, searchPtRight.y, searchPtRight.x, searchPtRight.y); search = false; if (theNextDirection) { T2FInfoPtIterator iterator(*theFloorInfo, searchPtLeft); T2Tenant *iterTenant; while (!theNextFloor && iterator.LeftTenant(iterTenant)) { search |= true; T2Tenant *theFloor = theFloorInfo->GetTenant(iterTenant->GetFloorID(-1)); theFloor->GetEquipArea(theEquipRect); if (theEquipRect.right < searchPtRight.x) break; UnionRect(&theSearchRect, &theEquipRect, &theSearchRect); if (theFloor->GetWorkCount() == 0) { theNextFloor = theFloor; theNextPt.y = theEquipRect.bottom - 1; entranceH = theEquipRect.right - 2; theNextPt.x = theEquipRect.left; } } } else { T2FInfoPtIterator iterator(*theFloorInfo, searchPtRight); T2Tenant *iterTenant; while (!theNextFloor && iterator.RightTenant(iterTenant)) { T2Tenant *theFloor = theFloorInfo->GetTenant(iterTenant->GetFloorID(-1)); theFloor->GetEquipArea(theEquipRect); if (theEquipRect.left > searchPtLeft.x) break; search |= true; UnionRect(&theSearchRect, &theEquipRect, &theSearchRect); if (theFloor->GetWorkCount() == 0) { theNextFloor = theFloor; theNextPt.y = theEquipRect.bottom - 1; entranceH = theEquipRect.left; theNextPt.x = theEquipRect.right - 2; } } } } CRect theSilhouetteArea; inPeople->CalcWalkingSilhouetteArea(theSilhouetteArea); theFloorInfo->SetTenantDrawModeByRect(theSilhouetteArea, DrawMode1); inDoc->GetMainView()->InvalUnitRect(theSilhouetteArea); if (theNextFloor) { theCurrFloor->Leave(inPeople); inPeople->MoveVTo(theNextPt.y); inPeople->MoveHTo(entranceH); theNextFloor->Enter(inPeople); inPeople->SetCurrDestPos(theNextPt); inPeople->SetStatus(kStatus14); inPeople->FlipDirection(); theNextFloor->IncWorkCount(); } else { inPeople->ChangeStyle(kPeopleStyle1); inPeople->ChangeWalkStyle(0); unsigned int theWorkID = inPeople->GetWorkTenant(); inPeople->SetDestination(theWorkID); inPeople->SetStatus(kStatus3); } } /*virtual*/ void T2Terrorist::StopEvent(T2TowerDoc* inDoc) { T2TowerMainView *theMainView = inDoc->GetMainView(); if (theMainView && mAttach) { theMainView->RemoveAttachment(mAttach); delete mAttach; mAttach = NULL; } CRect theSilhouetteArea; T2FloorInfo *theFloorInfo = inDoc->GetFloorInfo(); T2People *theSecurityMan; LArrayIterator theIteratorL(*mSearcherL); while (theIteratorL.Next(&theSecurityMan)) { #line 536 _ASSERT(theSecurityMan != NULL); if (theSecurityMan) { theSecurityMan->ClearSpecialFlag(kSpecialFlag20); if (theSecurityMan->GetStatus() == kStatus14 || theSecurityMan->GetStatus() == kStatus15) { theSecurityMan->ChangeStyle(kPeopleStyle1); unsigned int theWorkID = theSecurityMan->GetWorkTenant(); #line 562 _ASSERT(theWorkID != 0); theSecurityMan->SetDestination(theWorkID); theSecurityMan->SetStatus(kStatus3); } theSecurityMan->CalcWalkingSilhouetteArea(theSilhouetteArea); theFloorInfo->SetTenantDrawModeByRect(theSilhouetteArea, DrawMode1); theMainView->InvalUnitRect(theSilhouetteArea); } } mSearcherL->RemoveItemsAt(mSearcherL->GetCount(), 1); LArrayIterator theIteratorR(*mSearcherR); while (theIteratorR.Next(&theSecurityMan)) { #line 577 _ASSERT(theSecurityMan != NULL); if (theSecurityMan) { theSecurityMan->ClearSpecialFlag(kSpecialFlag20); if (theSecurityMan->GetStatus() == kStatus14 || theSecurityMan->GetStatus() == kStatus15) { theSecurityMan->ChangeStyle(kPeopleStyle1); unsigned int theWorkID = theSecurityMan->GetWorkTenant(); #line 603 _ASSERT(theWorkID != 0); theSecurityMan->SetDestination(theWorkID); theSecurityMan->SetStatus(kStatus3); } theSecurityMan->CalcWalkingSilhouetteArea(theSilhouetteArea); theFloorInfo->SetTenantDrawModeByRect(theSilhouetteArea, DrawMode1); theMainView->InvalUnitRect(theSilhouetteArea); } } mSearcherR->RemoveItemsAt(mSearcherR->GetCount(), 1); DisposeSound(); inDoc->towerDoc_vf2B0(false); inDoc->towerDoc_vf1A0(false); inDoc->SetFireBurning(false); if (inDoc->GetMainView()) inDoc->GetMainView()->UnhideToolSprite(); if (inDoc->towerDoc_vf2A0()) inDoc->towerDoc_vf2A0()->EnableIcon(true); mStatus = kTerroristStatus0; } /*virtual*/ unsigned int T2Terrorist::DialogHook(T2EventDialog* inDialog, unsigned int inResult, T2TowerDoc* inDoc) { T2FloorInfo *theFloorInfo = inDoc->GetFloorInfo(); T2Tenant *theTenant = theFloorInfo->GetTenantByPID('KEBI'); BOOL isMissing = (theTenant == NULL); switch (inResult) { case 8303: if (isMissing) break; if (mStatus == kTerroristStatus1) { inResult = (inDoc->GetCurrentFunds() >= mHigherRansomFee) ? inResult : 0; } else { inResult = (inDoc->GetCurrentFunds() >= mRansomFee) ? inResult : 0; } if (inResult == 0) { CString text = LoadStringTable(GetWorldModuleHandle(), 8300, 12); DoAlert(inDoc, text, 9000); } break; case 8304: if (isMissing) { CString text = LoadStringTable(GetWorldModuleHandle(), 8300, 13); DoAlert(inDoc, text, 9000); inResult = 0; } break; } return inResult; } /*virtual*/ void T2Terrorist::SetupDialog(T2Dialog* inDialog) { ((T2DlgItem *) inDialog->GetDlgItem(8303))->AddListener(inDialog); ((T2DlgItem *) inDialog->GetDlgItem(8304))->AddListener(inDialog); }