#include "StdAfx.h" #include "CResFile.h" #include "GlobalFunc.h" #include "T2Archive.h" #include "T2DateTime.h" #include "T2DLL.h" #include "T2EquipPtrList.h" #include "T2FloorInfo.h" #include "T2Maru_Reggae.h" #include "T2Name.h" #include "T2NameList.h" #include "T2People.h" #include "T2PeopleArrayList.h" #include "T2PeopleDef.h" #include "T2PeopleLinkIterator.h" #include "T2Pool.h" #include "T2RegistedTenantDB.h" #include "T2RouteNavigator.h" #include "T2SoundPlayer.h" #include "T2TemplatePluginList.h" #include "T2Tenant.h" #include "../T2TowerDoc.h" #include "T2TowerEvent.h" #include "../T2TowerMainView.h" #include "T2TowerMessage.h" #include "T2WorldDef.h" #include "URect.h" #include "UT2Coordinate.h" #include "UT2Utils.h" T2Maru_Reggae::T2Maru_Reggae(T2TowerEvent* inTowerEvent, CResFile* inResFile, int inSubID) : T2EventItem(inTowerEvent, inResFile, inSubID) { int subResID; *inResFile >> mAnimResID; *inResFile >> subResID; *inResFile >> mTargetTenantCategory; *inResFile >> m3C; *inResFile >> mReggaeName; mIsReggae = (mReggaeName.GetLength() > 0); CResFile subResFile; if (subResFile.OpenResource(GetWorldDef()->mModuleHandle, subResID, 'VIPL')) subResFile >> mSilhouetteType; else mSilhouetteType = 0; mStatus = kMaruReggaeStatus0; mReggaeManID = 0; mVisitTenantID = 0; mLastMinutes = 0; mDidSetSilhouetteDef = false; mDidChangeDirection = false; mCounter = 0; mGuardman = NULL; Sounds->AddSound("MR:Maru", SoundPriority_1, 9003, GetWorldModuleHandle()); Sounds->AddSound("MR:Rege", SoundPriority_1, 9004, GetWorldModuleHandle()); } /*virtual*/ T2Maru_Reggae::~T2Maru_Reggae() { if (Sounds) { Sounds->DeleteSound("MR:Maru"); Sounds->DeleteSound("MR:Rege"); } if (mGuardman) delete mGuardman; } /*virtual*/ BOOL T2Maru_Reggae::Start(T2TowerDoc* inDoc) { mStatus = kMaruReggaeStatus0; mReggaeManID = 0; mVisitTenantID = 0; mDidChangeDirection = false; mLastMinutes = 0; T2Tenant *theTenant = FindTargetTenant(inDoc); if (theTenant) { T2Pool *thePool = inDoc->GetPool(); #line 85 _ASSERT(thePool != NULL); T2People *thePeople = thePool->BornVIP(mSilhouetteType, 0); if (thePeople) { CString nameStr; thePeople->GetName(nameStr); T2Name *theName = inDoc->mNameDB->Search(thePeople); if (theName) { theName->SetName(nameStr); } else { T2Name *theNewName = new T2Name(nameStr, thePeople, false); inDoc->mNameDB->Add(theNewName); } T2MatterDef *theMatterDef = thePeople->GetMatterDef(); T2TemplatePluginList *thePluginList = inDoc->GetSilhouetteTemplates(); T2SilhouetteDef *theSilhouetteDef = thePluginList ? thePluginList->FindSilhouette(theMatterDef->mSilhouetteID + 1) : NULL; if (theSilhouetteDef) { thePeople->SetSilhouetteDef(kPeopleStyle1, theSilhouetteDef); mDidSetSilhouetteDef = true; } else { mDidSetSilhouetteDef = false; } thePeople->mColor = 11; thePeople->SetDestination(theTenant->mEquipID); thePeople->SetSpecialFlag(kSpecialFlag20 | kSpecialFlag40); mReggaeManID = thePeople->GetPeopleID(); mVisitTenantID = theTenant->GetEquipID(); mLastMinutes = GetEndTime(); mLastStatus = thePeople->GetStatus(); mStatus = kMaruReggaeStatus1; } } return (mStatus != kMaruReggaeStatus0); } /*virtual*/ int T2Maru_Reggae::Exec(T2TowerDoc* inDoc) { int result = 0; switch (mStatus) { case kMaruReggaeStatus0: case kMaruReggaeStatus9: mStatus = kMaruReggaeStatus0; result = 3; break; } if (DoReception(inDoc)) result = 3; else result = IsExclusive() ? 1 : 0; return result; } BOOL T2Maru_Reggae::DoReception(T2TowerDoc* inDoc) { if (mGuardman && !mGuardman->DoReception(inDoc)) { delete mGuardman; mGuardman = NULL; mLastMinutes = 0; } T2People *thePeople = GetReggaeMan(); T2Tenant *theTenant; int pplStatus; if (thePeople) { T2DateTime *theNow = inDoc->mNow; pplStatus = thePeople->GetStatus(); if (pplStatus != mLastStatus || theNow->GetRawMinutes() > mLastMinutes) { mLastMinutes = theNow->GetRawMinutes(); switch (pplStatus) { case kStatus12: if (mStatus != kMaruReggaeStatus11 && mLastMinutes < GetEndTime()) { theTenant = FindTargetTenant(inDoc); if (theTenant) { thePeople->SetDestination(theTenant->GetEquipID()); thePeople->ChangeStatus(kStatus3); mStatus = kMaruReggaeStatus1; mLastMinutes = GetEndTime(); } else { mStatus = kMaruReggaeStatus11; } } break; case kStatus1: if (mStatus != kMaruReggaeStatus8) { T2Name *theName = inDoc->mNameDB->Search(thePeople); if (theName) { inDoc->mNameDB->RemoveName(theName); delete theName; } mStatus = kMaruReggaeStatus8; } else if (mGuardman == NULL) { T2Pool *thePool = inDoc->GetPool(); #line 208 _ASSERT(thePool != NULL); thePool->DeadVIP(thePeople); return true; } break; case kStatus9: thePeople->UpdateEstimation(); mLastMinutes = GetEndTime(); break; case kStatus15: { unsigned int theNextTenant; switch (mStatus) { case kMaruReggaeStatus1: theTenant = inDoc->GetFloorInfo()->GetTenant(mVisitTenantID); if (theTenant) { T2EquipDef *theDef = theTenant->GetEquipDef(); if (theTenant->IsTherePeople() && !theTenant->IsFireproof()) { if (mTargetTenantCategory == 0 || (theDef && theDef->GetCategory() == mTargetTenantCategory)) { if (mIsReggae) ReggaeReception(inDoc, thePeople); else MaruReception(inDoc, thePeople); break; } } } theNextTenant = FindNextTenant(inDoc); if (theNextTenant) { mVisitTenantID = theNextTenant; thePeople->SetDestination(mVisitTenantID); thePeople->ChangeStatus(kStatus3); mLastMinutes = GetEndTime(); break; } case kMaruReggaeStatus5: theTenant = FindTargetTenant(inDoc); if (mLastMinutes >= GetEndTime() || theTenant == NULL) { mVisitTenantID = 1; mStatus = kMaruReggaeStatus11; } else { mVisitTenantID = theTenant->GetEquipID(); mStatus = kMaruReggaeStatus1; } thePeople->ChangeStatus(kStatus3); thePeople->ChangeStyle(kPeopleStyle0); thePeople->SetDestination(mVisitTenantID); mDidChangeDirection = false; mLastMinutes = GetEndTime(); break; case kMaruReggaeStatus2: case kMaruReggaeStatus3: case kMaruReggaeStatus4: MaruReception(inDoc, thePeople); break; case kMaruReggaeStatus6: case kMaruReggaeStatus7: ReggaeReception(inDoc, thePeople); break; } break; } default: mLastMinutes = GetEndTime(); } mLastStatus = thePeople->GetStatus(); } } return false; } void T2Maru_Reggae::MaruReception(T2TowerDoc* inDoc, T2People* inPeople) { switch (mStatus) { case kMaruReggaeStatus1: inPeople->SetDestination(0); inPeople->UpdateEstimation(); if (mDidSetSilhouetteDef) inPeople->ChangeStyle(kPeopleStyle1); inPeople->ChangeWalkStyle(0); inPeople->ChangeStatus(kStatus14); mLastMinutes = GetEndTime(); mStatus = kMaruReggaeStatus2; break; case kMaruReggaeStatus2: mLastMinutes += 30; if (mLastMinutes > GetEndTime()) mLastMinutes = GetEndTime(); mStatus = kMaruReggaeStatus3; break; case kMaruReggaeStatus3: case kMaruReggaeStatus4: { POINT curPos = inPeople->GetCurPosition(); CRect theRect; T2TowerMainView *theView = inDoc->GetMainView(); theView->GetClientRect(theRect); theRect.OffsetRect(theView->mScrollOffset); UT2Coordinate::QDToUnit(theRect, inDoc->GetZoomLevel()); if (theRect.PtInRect(curPos) && inDoc->GetViewMode() != kOutView) { UT2Coordinate::MakeRect(theRect, curPos, 2, 1); theView->InvalUnitRect(theRect, true); } else { mStatus = kMaruReggaeStatus4; } mStatus++; if (mStatus < kMaruReggaeStatus5) { Sounds->Play("MR:Maru", SoundMask_10, SoundFlags_10, &curPos, PlayMode_0, 100); inPeople->ChangeWalkStyle(2); mLastMinutes += 8; } else { inPeople->ChangeWalkStyle(0); mLastMinutes += 30; if (mLastMinutes > GetEndTime()) mLastMinutes = GetEndTime(); } break; } } } void T2Maru_Reggae::ReggaeReception(T2TowerDoc* inDoc, T2People* inPeople) { POINT curPos; T2Tenant *theTenant; switch (mStatus) { case kMaruReggaeStatus1: inPeople->SetDestination(0); inPeople->UpdateEstimation(); theTenant = inDoc->GetFloorInfo()->GetTenant(mVisitTenantID); if (theTenant) { CRect rect; theTenant->GetEquipArea(rect); rect.left += URect::Width(rect) / 2; POINT curPos = inPeople->GetCurPosition(); if ( (curPos.x > rect.left && inPeople->GetDirection() == 0) || (curPos.x < rect.left && inPeople->GetDirection() == 1) ) inPeople->FlipDirection(); inPeople->SetCurrDestPos(rect.TopLeft()); inPeople->ChangeStatus(kStatus14); mLastMinutes = GetEndTime(); mCounter = 0; mStatus = kMaruReggaeStatus6; } else { mStatus = kMaruReggaeStatus5; } break; case kMaruReggaeStatus6: curPos = inPeople->GetCurPosition(); theTenant = inDoc->GetFloorInfo()->GetTenant(curPos.y, curPos.x); if (theTenant && !theTenant->IsFloor() && mLastMinutes < GetEndTime()) { CRect theRect; T2TowerMainView *theView = inDoc->GetMainView(); theView->GetClientRect(&theRect); theRect.OffsetRect(theView->mScrollOffset); UT2Coordinate::QDToUnit(theRect, inDoc->GetZoomLevel()); if (theRect.PtInRect(curPos) && inDoc->GetViewMode() != kOutView) { UT2Coordinate::MakeRect(theRect, curPos, 2, 1); theView->InvalUnitRect(theRect, true); if (inPeople->GetWalkStyle() == 0) inPeople->ChangeWalkStyle(1); else inPeople->ChangeWalkStyle(0); Sounds->Play("MR:Rege", SoundMask_10, SoundFlags_10, &curPos, PlayMode_0, 100); } mCounter++; if ((mCounter % 60) == 0) { CString message; MakeClaimMessage(inDoc, theTenant, message); inDoc->GetTowerMessage()->InfoBarMessage(message, 180, NULL); if (!mGuardman) mGuardman = new T2Guardman(this, inDoc, theTenant); } if ((mCounter % 10) == 0 && theTenant->GetFirstPeople()) { T2PeopleLinkIterator iterator(theTenant->GetFirstPeople()); T2People *people; while (iterator.Next(&people)) { if (people) people->IncStress(10); } } mLastMinutes += 3; } else { mStatus = kMaruReggaeStatus5; } break; case kMaruReggaeStatus7: int anims[3] = {2, 0, 0}; anims[1] = mAnimResID; anims[2] = mAnimResID + 1; CString message; curPos = inPeople->GetCurPosition(); theTenant = inDoc->GetFloorInfo()->GetTenant(curPos.y, curPos.x); MakeClaimMessage(inDoc, theTenant, message); inDoc->GetTowerMessage()->CancelInfoBarMessage(message); // "レゲエのおじさんは警備員につかまりました。" // Uncle Reggae was caught by a security guard. message = "\x83\x8C\x83\x51\x83\x47\x82\xCC\x82\xA8\x82\xB6\x82\xB3\x82\xF1\x82\xCD\x8C\x78\x94\xF5\x88\xF5\x82\xC9\x82\xC2\x82\xA9\x82\xDC\x82\xE8\x82\xDC\x82\xB5\x82\xBD\x81\x42"; DoDialog(inDoc, 9200, mAnimResID, 2, message); mVisitTenantID = 1; mStatus = kMaruReggaeStatus11; inPeople->ChangeStatus(kStatus3); inPeople->SetDestination(mVisitTenantID); mDidChangeDirection = false; mLastMinutes = GetEndTime(); if (mGuardman) mGuardman->GoHome(); break; } } void T2Maru_Reggae::MakeClaimMessage(T2TowerDoc* inDoc, T2Tenant* inTenant, CString& outStr) { CString floorStr, roomStr, nameStr; int floorNum = inTenant->GetFloorNumber(inDoc->GetFloorInfo()); if (floorNum < 0) floorStr.Format("B%d", -floorNum); else floorStr.Format("%d", floorNum); int roomNum = inTenant->GetRoomNumber(inDoc->GetFloorInfo()); if (roomNum < 0) roomStr.Format("B%d", -roomNum); else roomStr.Format("%d", roomNum); T2EquipDef *theTenantDef = inTenant->GetEquipDef(); if (theTenantDef) theTenantDef->GetName(nameStr, 0); // "%sと%s階%s号室%sから苦情です" // Complaints from %s and %s Floor %s Room %s outStr.Format( "%s\x82\xC6%s\x8A\x4B%s\x8D\x86\x8E\xBA%s\x82\xA9\x82\xE7\x8B\xEA\x8F\xEE\x82\xC5\x82\xB7", mReggaeName, floorStr, roomStr, nameStr); } T2Tenant* T2Maru_Reggae::FindTargetTenant(T2TowerDoc* inDoc) { T2RouteNavigator *theNavi = inDoc->GetRouteNavi(); #line 521 _ASSERT(theNavi != NULL); POINT theTargetPos; int theHRange = GetWorldDef()->GetWidth(); int theVRange = GetWorldDef()->mGroundLine - 2; int theTotal = theHRange * theVRange; T2Tenant *theTenant; T2EquipDef *theEquipDef; do { theTotal--; if (theTotal <= 0) return NULL; theTargetPos.y = UT2Utils::Randomize(theHRange); theTargetPos.x = UT2Utils::Randomize(theVRange); theTenant = inDoc->mFloorInfo->GetTenant(theTargetPos.x, theTargetPos.y); theEquipDef = theTenant ? theTenant->GetEquipDef() : NULL; } while ( !theTenant || !theNavi->IsConnectRouteFromLobby(theTenant->GetEntrancePt()) || theTenant->IsFireproof() || theTenant->GetEquipID() == mVisitTenantID || !theEquipDef || (mTargetTenantCategory != 0 && theEquipDef->GetCategory() != mTargetTenantCategory) ); return theTenant; } unsigned int T2Maru_Reggae::FindNextTenant(T2TowerDoc* inDoc) { unsigned int theNextTenantID = 0; T2FloorInfo *fInfo = inDoc->GetFloorInfo(); #line 550 _ASSERT(fInfo != NULL); T2People *thePeople = GetReggaeMan(); #line 552 _ASSERT(thePeople != NULL); T2Tenant *theTenant = fInfo->GetTenant(mVisitTenantID); if (theTenant) { RECT rect; theTenant->GetEquipArea(rect); do { rect.left += thePeople->GetDirection() ? -1 : 1; theNextTenantID = fInfo->GetTenantID(rect.bottom - 1, rect.left); } while (theNextTenantID == mVisitTenantID); if (theNextTenantID == 0 && !mDidChangeDirection) { mDidChangeDirection = true; thePeople->FlipDirection(); theNextTenantID = mVisitTenantID; } } return theNextTenantID; } T2People* T2Maru_Reggae::GetReggaeMan() { return GetTowerDoc()->mPeopleArrayList->FindPeople(mReggaeManID); } T2Tenant* T2Maru_Reggae::GetVisitTenant() { return (mStatus == kMaruReggaeStatus6) ? GetTowerDoc()->GetFloorInfo()->GetTenant(mVisitTenantID) : NULL; } /*virtual*/ void T2Maru_Reggae::Write(T2Archive& inArchive) { unsigned int len = 14; inArchive << len; inArchive << (short) mStatus; inArchive << mReggaeManID; inArchive << (unsigned short) mVisitTenantID; unsigned char flag = (mDidChangeDirection != 0); inArchive << flag; flag = (mDidSetSilhouetteDef != 0); inArchive << flag; inArchive << mCounter; } /*virtual*/ void T2Maru_Reggae::Read(T2Archive& inArchive) { unsigned int len; unsigned short theUInt16; short theSInt16; unsigned char theChar; inArchive >> len; inArchive >> theSInt16; mStatus = theSInt16; inArchive >> mReggaeManID; inArchive >> theUInt16; mVisitTenantID = theUInt16; inArchive >> theChar; mDidChangeDirection = (theChar != 0); inArchive >> theChar; mDidSetSilhouetteDef = (theChar != 0); inArchive >> mCounter; } T2Guardman::T2Guardman(T2Maru_Reggae *inOwner, T2TowerDoc *inDoc, T2Tenant *inTenant) { mOwner = inOwner; mPeople = NULL; T2RegistedTenantDB *theDB = inDoc->GetRegistedTenantDB(); #line 647 _ASSERT(theDB != NULL); T2EquipPtrList *theList = theDB->GetList(kTenantRegistID5); if (theList) { T2Tenant *theTenant; theList->FetchItemAt(1, &theTenant); if (theTenant) { T2RouteNavigator *theNavi = inDoc->GetRouteNavi(); #line 656 _ASSERT(theNavi != NULL); POINT theNextPt = inTenant->GetEntrancePt(); T2Tenant *selectedTenant = NULL; LArrayIterator iterator(*theList); for (int score = theTenant->GetEmployeeSearchScore(); score > 0; score--) { int found = 0; iterator.ResetTo(0); while (iterator.Next(&theTenant)) { POINT exitPt = theTenant->GetExitPt(); if (theNavi->CheckRoute(exitPt, theNextPt, score)) { selectedTenant = theTenant; found++; if (found > 1) break; } } if (found <= 1) break; } if (selectedTenant && selectedTenant->GetFirstPeople()) { mPeople = selectedTenant->GetFirstPeople(); mPeople->SetDestination(inTenant->GetEquipID()); mPeople->SetSpecialFlag(kSpecialFlag20 | kSpecialFlag40); mPeople->SetReturn(selectedTenant->GetEquipID()); mPeople->mColor = 11; selectedTenant->PushOutPeople(inDoc, mPeople); } } } } T2Guardman::~T2Guardman() { if (mPeople) { mPeople->UpdateEstimation(); mPeople->ClearSpecialFlag(kSpecialFlag20 | kSpecialFlag40); mPeople->ClearColor(); } } BOOL T2Guardman::DoReception(T2TowerDoc *inDoc) { BOOL result = true; if (mPeople) { switch (mPeople->GetStatus()) { case kStatus15: { CPoint curPos = mPeople->GetCurPosition(); T2Tenant *theTenant = inDoc->GetFloorInfo()->GetTenant(curPos.y, curPos.x); T2People *theReggaeMan = mOwner->GetReggaeMan(); if (theTenant && theReggaeMan && mOwner->mStatus == kMaruReggaeStatus6) { CPoint reggaeManPos = theReggaeMan->GetCurPosition(); if (theTenant == inDoc->GetFloorInfo()->GetTenant(reggaeManPos.y, reggaeManPos.x)) { if (reggaeManPos == curPos) { mOwner->mStatus = kMaruReggaeStatus7; } else { if ( (curPos.x > reggaeManPos.x && mPeople->GetDirection() == 0) || (curPos.x < reggaeManPos.x && mPeople->GetDirection() == 1) ) mPeople->FlipDirection(); mPeople->SetCurrDestPos(reggaeManPos); mPeople->ChangeStatus(kStatus14); } } } break; } case kStatus11: result = false; break; } } else { result = false; } return result; } void T2Guardman::GoHome() { mPeople->SetReturnToDestination(); mPeople->SetStatus(kStatus3); mPeople->ClearSpecialFlag(kSpecialFlag40); }