#include "StdAfx.h" #include "T2Archive.h" #include "T2ElevatorModule.h" #include "T2FloorInfo.h" #include "T2Mover.h" #include "T2MoverDef.h" #include "T2MoverModuleList.h" #include "T2People.h" #include "T2PeopleLinkIterator.h" #include "T2Request.h" #include "T2StopInfoArray.h" #include "T2Tenant.h" #include "../T2TowerDoc.h" #include "../T2TowerMainView.h" #include "UT2Coordinate.h" T2ElevatorModule::T2ElevatorModule(int index) { mIndex = index; mStatus = kElevatorStatus0; mHomePosition = 0; mOffsetPos = 0; mNextStop = 0; mRequestCount = 0; mTopTurn = 0; mBottomTurn = 0; mStopInfoArray = new T2StopInfoArray; #line 18 _ASSERT(mStopInfoArray); } /*virtual*/ T2ElevatorModule::~T2ElevatorModule() { if (mStopInfoArray) delete mStopInfoArray; } void T2ElevatorModule::Init(int count, int position) { SetUsed(true); mPosition = position; mDirection = kElevatorDirection0; mWaitCounter = 0; mPatIndex = 0; mNumPeople = 0; _4C = 0; mLink1 = NULL; mLink2 = NULL; mStatus = kElevatorStatus0; mHomePosition = position; mOffsetPos = 0; mNextStop = position; mRequestCount = 0; mTopTurn = position; mBottomTurn = position; mStopInfoArray->Init(count); } /*virtual*/ void T2ElevatorModule::SetUsed(BOOL used) { T2MoverModule::SetUsed(used); if (!used && mStopInfoArray) mStopInfoArray->AllClear(); } BOOL T2ElevatorModule::IsPtInArea(POINT pt, const RECT& area) const { BOOL result = false; if (mUsed) { RECT myArea = area; OffsetRect(&myArea, 0, -(UT2Coordinate::UnitVSize(0) * mPosition + mOffsetPos)); if (PtInRect(&myArea, pt)) result = true; } return result; } /*virtual*/ void T2ElevatorModule::StopAdded(T2TowerDoc*, T2Mover* mover, int position) { if (!mover->IsStopPosition(mHomePosition)) { mHomePosition = position; StartToHomePos(); } } /*virtual*/ void T2ElevatorModule::StopRemoved(T2TowerDoc* towerDoc, T2Mover* mover, int position) { #line 103 ASSERT(mStopInfoArray != NULL); if (IsOffStopPos(position, ERequestUpDown_0) || IsOffStopPos(position, ERequestUpDown_1)) { RemoveContents(towerDoc, mover, position); mStopInfoArray->ClearOffStop(position, ERequestUpDown_0); mStopInfoArray->ClearOffStop(position, ERequestUpDown_1); } if (IsOnStopPos(position, ERequestUpDown_0)) { mRequestCount--; mStopInfoArray->ClearOnStop(position, ERequestUpDown_0); } if (IsOnStopPos(position, ERequestUpDown_1)) { mRequestCount--; mStopInfoArray->ClearOnStop(position, ERequestUpDown_1); } #line 124 ASSERT(mRequestCount >= 0); if (mRequestCount < 0) mRequestCount = 0; BOOL flag = false; if (position == mHomePosition) { flag = !HomePosRemoved(mover, position); if (!flag && !towerDoc->GetElevTransparent() && mover->IsShaftVisible()) { RECT area; CalcUintArea(mover, mHomePosition, area); T2TowerMainView *theView = towerDoc->GetMainView(); #line 142 ASSERT(theView != NULL); theView->InvalUnitRect(area); } } if (!flag) { if (position == mTopTurn) TopTurnPosRemoved(position); if (position == mBottomTurn) BottomTurnPosRemoved(position); if (position == mNextStop) NextStopRemoved(); } } void T2ElevatorModule::Remove(T2TowerDoc* towerDoc, T2Mover* mover) { T2FloorInfo *theFloorInfo = towerDoc->GetFloorInfo(); T2People *theRemovePeople = NULL; BOOL isDown = true; T2Request *theRequest; switch (mStatus) { case kElevatorStatus1: isDown = false; case kElevatorStatus2: theRequest = mover->GetRequest(theFloorInfo, mPosition, isDown); #line 183 ASSERT(theRequest != NULL); theRemovePeople = theRequest->RemoveOffPeople(); break; case kElevatorStatus3: theRequest = GetAppointRequest(theFloorInfo, mover); #line 189 ASSERT(theRequest != NULL); theRemovePeople = theRequest->RemoveOnPeople(); break; } if (theRemovePeople) { POINT curPos = theRemovePeople->GetCurPosition(); T2Tenant *theFloor = theFloorInfo->GetFloor(curPos.y, curPos.x); #line 199 ASSERT(theFloor != NULL); theFloor->Enter(theRemovePeople); } T2MoverModule::RemoveContents(towerDoc); SetUsed(false); } void T2ElevatorModule::RemoveContents(T2TowerDoc* towerDoc, T2Mover* mover, int position) { BOOL flag = false; if (mLink1) { POINT theStopPos = mover->PositionToStopPt(position, ERequestUpDown_0); T2FloorInfo *theFloorInfo = towerDoc->GetFloorInfo(); #line 221 ASSERT(theFloorInfo != NULL); T2Tenant *theDstFloor = theFloorInfo->GetFloor(theStopPos.y, theStopPos.x); #line 224 ASSERT(theDstFloor != NULL); T2PeopleLinkIterator iterator((T2People *) mLink1); T2People *thePeople = NULL; T2People *theNextPeople = NULL; iterator.Next(&thePeople); while (thePeople) { iterator.Next(&theNextPeople); if (thePeople->GetCurrDestPos().y == theStopPos.y) { Leave(thePeople); theDstFloor->Enter(thePeople); thePeople->IncEstimate(-100); flag = true; } thePeople = theNextPeople; theNextPeople = NULL; } if (flag && IsPatChanged(mover)) { RECT theRect; CalcUintArea(mover, theRect); T2TowerMainView *theView = towerDoc->GetMainView(); #line 251 ASSERT(theView != NULL); theView->InvalUnitRect(theRect); } } } BOOL T2ElevatorModule::HomePosRemoved(T2Mover* mover, int position) { BOOL done = false; int theLength = mover->GetLength(); for (unsigned int i = position + 1; !done && i < theLength; i++) { if (mover->IsStopPosition(i)) { mHomePosition = i; done = true; } } if (!done) { for (int i = position - 1; !done && i >= 0; i--) { if (mover->IsStopPosition(i)) { mHomePosition = i; done = true; } } } return done; } void T2ElevatorModule::TopTurnPosRemoved(int position) { if (mDirection != kElevatorDirection0 && mTopTurn != mBottomTurn) { BOOL done = false; for (int p = position; !done && p > mBottomTurn; p--) { if (IsStopPos(p, ERequestUpDown_0) || IsStopPos(p, ERequestUpDown_1)) { mTopTurn = p; done = true; } } if (!done) mTopTurn = mBottomTurn; } else { StartToHomePos(); } } void T2ElevatorModule::BottomTurnPosRemoved(int position) { BOOL done = false; for (int p = position; !done && p < mTopTurn; p++) { if (IsStopPos(p, ERequestUpDown_0) || IsStopPos(p, ERequestUpDown_1)) { mBottomTurn = p; done = true; } } if (!done) mBottomTurn = mTopTurn; } void T2ElevatorModule::NextStopRemoved() { switch (mStatus) { case kElevatorStatus1: case kElevatorStatus2: case kElevatorStatus3: case kElevatorStatus4: mStatus = kElevatorStatus0; } SetNextStop(); if (mNextStop != mPosition || mOffsetPos != 0) { switch (mDirection) { case kElevatorDirection1: if (mNextStop <= mPosition) { mDirection = kElevatorDirection2; mStatus = kElevatorStatus5; } break; case kElevatorDirection2: if (mNextStop > mPosition) { mDirection = kElevatorDirection1; mStatus = kElevatorStatus5; } break; } } else { mStatus = kElevatorStatus0; } } void T2ElevatorModule::MoverExpanded(T2Mover* mover, EEquipPos pos, int count) { #line 383 ASSERT(mStopInfoArray != NULL); mStopInfoArray->Expand(pos, count); int length = mover->GetLength(); BOOL isResetPosition = false; BOOL isResetHomePosition = false; switch (pos) { case EEquipPos_2: if (count < 0) { if (mPosition > (length - 1)) { mOffsetPos = 0; mPosition = length - 1; isResetPosition = true; } else if (mPosition == (length - 1) && mOffsetPos > 0) { mOffsetPos = 0; isResetPosition = true; } if (mHomePosition > (length - 1)) { mHomePosition = length - 1; isResetHomePosition = true; } } break; case EEquipPos_3: mPosition += count; mHomePosition += count; mNextStop += count; mTopTurn += count; mBottomTurn += count; if (count < 0) { if (mPosition < 0) { mOffsetPos = 0; mPosition = 0; isResetPosition = true; } if (mHomePosition < 0) { mHomePosition = 0; isResetHomePosition = true; } } break; } if (isResetPosition) { if (mPosition != mNextStop || mNumPeople == 0) { mStatus = kElevatorStatus0; } else { mWaitCounter = 6; mStatus = kElevatorStatus1; } } if (isResetHomePosition) { mTopTurn = mBottomTurn = mNextStop = mHomePosition; StartToHomePos(); } } BOOL T2ElevatorModule::IsStopPos(int position, ERequestUpDown upDown) const { BOOL result = false; if (mStopInfoArray) result = mStopInfoArray->IsStopPos(position, upDown); return result; } BOOL T2ElevatorModule::IsOnStopPos(int position, ERequestUpDown upDown) const { BOOL result = false; if (mStopInfoArray) result = mStopInfoArray->IsOnStopPos(position, upDown); return result; } BOOL T2ElevatorModule::IsOffStopPos(int position, ERequestUpDown upDown) const { BOOL result = false; if (mStopInfoArray) result = mStopInfoArray->IsOffStopPos(position, upDown); return result; } void T2ElevatorModule::SetOnStop(int position, ERequestUpDown upDown) { if (mStopInfoArray) { mStopInfoArray->SetOnStop(position, upDown); mRequestCount++; if (mTopTurn < position) mTopTurn = position; if (mBottomTurn > position) mBottomTurn = position; if (mDirection == kElevatorDirection0) { if (upDown == ERequestUpDown_0) mDirection = kElevatorDirection1; else mDirection = kElevatorDirection2; } } } void T2ElevatorModule::SetOffStop(int position, ERequestUpDown upDown) { if (mStopInfoArray) { mStopInfoArray->SetOffStop(position, upDown); if (mBottomTurn > position) mBottomTurn = position; if (mTopTurn < position) mTopTurn = position; } } void T2ElevatorModule::ClearOnStop(T2Request* request) { if (mStopInfoArray) { mStopInfoArray->ClearOnStop(mPosition, request->GetUpDown()); mRequestCount--; request->mModuleIndex = -1; } } void T2ElevatorModule::ClearOffStop(T2Request* request) { if (mStopInfoArray) mStopInfoArray->ClearOffStop(mPosition, request->GetUpDown()); } void T2ElevatorModule::SetNextStop() { if (mStopInfoArray) { switch (mDirection) { case kElevatorDirection1: { BOOL isStop = false; for (int p = mPosition + 1; p < mTopTurn && !isStop; p++) { if (IsStopPos(p, ERequestUpDown_0)) { mNextStop = p; isStop = true; } } if (!isStop) mNextStop = mTopTurn; break; } case kElevatorDirection2: { BOOL isStop = false; for (int p = mPosition - 1; p > mBottomTurn && !isStop; p--) { if (IsStopPos(p, ERequestUpDown_1)) { mNextStop = p; isStop = true; } } if (!isStop) mNextStop = mBottomTurn; break; } } } } void T2ElevatorModule::ChangeTurnPos() { if (mStopInfoArray) { switch (mDirection) { case kElevatorDirection1: if (mBottomTurn == mPosition) { BOOL isStop = false; for (int p = mPosition; p < mNextStop && !isStop; p++) { if (IsStopPos(p, ERequestUpDown_0) || IsStopPos(p, ERequestUpDown_1)) { mBottomTurn = p; isStop = true; } } if (!isStop) mBottomTurn = mNextStop; } break; case kElevatorDirection2: if (mTopTurn == mPosition) { BOOL isStop = false; for (int p = mPosition; p > mNextStop && !isStop; p--) { if (IsStopPos(p, ERequestUpDown_0) || IsStopPos(p, ERequestUpDown_1)) { mTopTurn = p; isStop = true; } } if (!isStop) mTopTurn = mNextStop; } break; } } } void T2ElevatorModule::StartToHomePos() { if (mPosition == mHomePosition) { mDirection = kElevatorDirection0; mStatus = kElevatorStatus0; } else { if (mPosition < mHomePosition) mDirection = kElevatorDirection1; else mDirection = kElevatorDirection2; mNextStop = mHomePosition; mTopTurn = mHomePosition; mBottomTurn = mHomePosition; mStatus = kElevatorStatus5; } } T2Request* T2ElevatorModule::GetAppointRequest(T2FloorInfo* floorInfo, T2Mover* mover) { T2Request *request = NULL; if (mDirection == kElevatorDirection1) request = mover->GetRequest(floorInfo, mPosition, 0); else request = mover->GetRequest(floorInfo, mPosition, 1); if (request && request->mModuleIndex != mIndex) request = NULL; return request; } T2Request* T2ElevatorModule::GetAnyRequest(T2FloorInfo* floorInfo, T2Mover* mover) { T2Request *request = NULL; if (mDirection == kElevatorDirection1) request = mover->GetRequest(floorInfo, mPosition, 0); else request = mover->GetRequest(floorInfo, mPosition, 1); return request; } void T2ElevatorModule::CalcUintArea(const T2Mover* mover, RECT& outRect) const { CalcUintArea(mover, mPosition, outRect); if (mOffsetPos > 0) outRect.top--; } void T2ElevatorModule::CalcUintArea(const T2Mover* mover, int position, RECT& outRect) const { T2MoverModuleList *theList = mover->GetModuleList(); #line 787 ASSERT(theList != NULL); theList->GetBaseRect(outRect); OffsetRect(&outRect, 0, -position); } BOOL T2ElevatorModule::IsPatChanged(T2Mover* mover) { BOOL isChanged = false; T2MoverDef *moverDef = (T2MoverDef *) mover->GetEquipDef(); if (moverDef) { int newIndex = moverDef->CalcModulePatIndex(mNumPeople); if (mPatIndex != newIndex) { mPatIndex = newIndex; isChanged = true; } } if (isChanged) { T2MoverModuleMessageData data; data.moverModule = this; data.value = GetPosition(); BroadcastMessage(1001, &data); } return isChanged; } T2People* T2ElevatorModule::LeaveToDstFloor(int y) { T2People *result = NULL; if (mLink1) { T2PeopleLinkIterator iterator((T2People *) mLink1); T2People *people; while (iterator.Next(&people)) { if (people->mCurrDestPos.y == y) { Leave(people); result = people; break; } } } return result; } /*virtual*/ void T2ElevatorModule::Enter(T2Mover* mover, T2People* people) { people->FlipDirection(); T2MoverModule::Enter(mover, people); } /*virtual*/ void T2ElevatorModule::LoadSelf(T2Archive& archive, T2TowerDoc* towerDoc) { T2MoverModule::LoadSelf(archive, towerDoc); if (IsUsed()) { short v; archive >> v; mIndex = v; archive >> v; mHomePosition = v; archive >> v; mOffsetPos = v; archive >> v; mNextStop = v; archive >> v; mRequestCount = v; archive >> v; mTopTurn = v; archive >> v; mBottomTurn = v; mStopInfoArray = T2StopInfoArray::ReadStopInfoArray(archive); } } /*virtual*/ void T2ElevatorModule::SaveSelf(T2Archive& archive) { T2MoverModule::SaveSelf(archive); if (IsUsed()) { archive << (short) mIndex; archive << (short) mHomePosition; archive << (short) mOffsetPos; archive << (short) mNextStop; archive << (short) mRequestCount; archive << (short) mTopTurn; archive << (short) mBottomTurn; T2StopInfoArray::WriteStopInfoArray(mStopInfoArray, archive); } }