summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2RoutingTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/T2DLL/T2RoutingTable.cpp360
1 files changed, 340 insertions, 20 deletions
diff --git a/src/T2DLL/T2RoutingTable.cpp b/src/T2DLL/T2RoutingTable.cpp
index 8380825..c6ae7fa 100644
--- a/src/T2DLL/T2RoutingTable.cpp
+++ b/src/T2DLL/T2RoutingTable.cpp
@@ -1,82 +1,402 @@
+#include "T2FInfoAreaIterator.h"
+#include "T2FloorInfo.h"
+#include "T2FloorPtrList.h"
+#include "T2Mover.h"
+#include "T2MoverRoutingTable.h"
#include "T2RoutingTable.h"
+#include "T2Tenant.h"
-T2RoutingTable::T2RoutingTable(T2FloorInfo*, T2FloorPtrList*, int) {
+T2RoutingTable::T2RoutingTable(T2FloorInfo* inFloorInfo, T2FloorPtrList* inFloorPtrList, int inWhichTable)
+ : LArray(sizeof(T2MoverRoutingTable *))
+{
+ mAttributeMask = kMoverAttrRoutingTable0 << inWhichTable;
+ mFloorPtrList = inFloorPtrList;
+ mFloorInfo = inFloorInfo;
}
/*virtual*/ T2RoutingTable::~T2RoutingTable() {
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *theTable;
+
+ while (iterator.Next(&theTable))
+ delete theTable;
}
void T2RoutingTable::FloorAdded() {
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *theTable;
+
+ while (iterator.Next(&theTable))
+ theTable->AddItems(1);
}
-void T2RoutingTable::FloorRemoved(int) {
+void T2RoutingTable::FloorRemoved(int inFloorID) {
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *theTable;
+
+ while (iterator.Next(&theTable))
+ theTable->RemoveItem(inFloorID);
}
-int T2RoutingTable::IsRelatedMover(T2Mover*) const {
+BOOL T2RoutingTable::IsRelatedMover(T2Mover* inMover) const {
+ return inMover->IsSetAttribute(mAttributeMask);
}
-void T2RoutingTable::MoverAdded(T2Mover*, int) {
+void T2RoutingTable::MoverAdded(T2Mover* inMover, BOOL inFlag) {
+ if (IsRelatedMover(inMover)) {
+ AddItem(inMover);
+
+ if (inFlag) {
+ T2MoverRoutingTable *theTable = GetItem(inMover);
+ if (theTable) {
+ theTable->SetStopFloor();
+ Update();
+ }
+ }
+ }
}
-void T2RoutingTable::MoverRemoved(T2Mover*, int) {
+void T2RoutingTable::MoverRemoved(T2Mover* inMover, BOOL inFlag) {
+ if (IsRelatedMover(inMover)) {
+ RemoveItem(inMover);
+
+ if (inFlag)
+ FullUpdate();
+ }
}
-void T2RoutingTable::MoverModified(T2Mover*, int) {
+void T2RoutingTable::MoverModified(T2Mover* inMover, BOOL inFlag) {
+ if (IsRelatedMover(inMover)) {
+ if (inFlag) {
+ FullUpdate();
+ } else {
+ T2MoverRoutingTable *theTable = GetItem(inMover);
+ if (theTable) {
+ theTable->SetStopFloor();
+ Update();
+ }
+ }
+ }
}
-void T2RoutingTable::AddItem(T2Mover*) {
+void T2RoutingTable::AddItem(T2Mover* inMover) {
+ T2MoverRoutingTable *theMoverRoutingTable = new T2MoverRoutingTable(mFloorInfo, mFloorPtrList, inMover);
+#line 162
+ _ASSERT(theMoverRoutingTable != NULL);
+
+ InsertItemsAt(1, mItemCount + 1, &theMoverRoutingTable);
}
-void T2RoutingTable::RemoveItem(T2Mover*) {
+void T2RoutingTable::RemoveItem(T2Mover* inMover) {
+ RemoveItemsAt(1, GetIndex(inMover));
}
-T2MoverRoutingTable* T2RoutingTable::GetItem(T2Mover*) const {
+T2MoverRoutingTable* T2RoutingTable::GetItem(T2Mover* inMover) const {
+ T2MoverRoutingTable *theMoverRoutingTable = NULL;
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *item;
+
+ while (!theMoverRoutingTable && iterator.Next(&item)) {
+ if (item->GetMover() == inMover)
+ theMoverRoutingTable = item;
+ }
+
+ return theMoverRoutingTable;
}
-int T2RoutingTable::GetElem(T2Mover*, int, T2RoutingTableElem&) const {
+BOOL T2RoutingTable::GetElem(T2Mover* inMover, int inFloor, T2RoutingTableElem& outElem) const {
+ BOOL ok = false;
+
+ T2MoverRoutingTable *theMoverRoutingTable = GetItem(inMover);
+ if (theMoverRoutingTable && theMoverRoutingTable->GetItem(inFloor, outElem))
+ ok = true;
+
+ return ok;
}
-int T2RoutingTable::GetIndex(T2Mover*) const {
+int T2RoutingTable::GetIndex(T2Mover* inMover) const {
+ int result = 0;
+ int unused = 0;
+ LArrayIterator iterator(*this);
+ int i = 1;
+ T2MoverRoutingTable *theMoverRoutingTable;
+
+ while (result == 0 && iterator.Next(&theMoverRoutingTable)) {
+ if (theMoverRoutingTable->GetMover() == inMover)
+ result = i;
+ else
+ i++;
+ }
+
+ return result;
}
void T2RoutingTable::Update() {
+ BOOL working = true;
+
+ while (working) {
+ working = false;
+
+ LArrayIterator iterator1(*this);
+ T2MoverRoutingTable *table1;
+ while (iterator1.Next(&table1)) {
+ LArrayIterator iterator2(*this);
+ T2MoverRoutingTable *table2;
+
+ while (iterator2.Next(&table2)) {
+ if (table1 != table2)
+ working |= table1->Update(table2);
+ }
+ }
+ }
}
void T2RoutingTable::FullUpdate() {
+ ClearData();
+
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *theMoverRoutingTable;
+
+ while (iterator.Next(&theMoverRoutingTable))
+ theMoverRoutingTable->SetStopFloor();
+
+ Update();
}
void T2RoutingTable::ClearData() {
+ LArrayIterator iterator(*this);
+ T2MoverRoutingTable *theMoverRoutingTable;
+
+ while (iterator.Next(&theMoverRoutingTable))
+ theMoverRoutingTable->ClearData();
}
-int T2RoutingTable::CheckRoute(POINT, POINT, unsigned int) const {
+BOOL T2RoutingTable::CheckRoute(POINT inFromPt, POINT inToPt, unsigned int inSearchScore) const {
+ BOOL result = false;
+
+ T2Tenant *nextFloor = mFloorInfo->GetFloor(inToPt.y, inToPt.x);
+ int nextFloorIdx = mFloorPtrList->GetIndex(nextFloor);
+
+ if (nextFloorIdx) {
+ T2Tenant *prevFloor = mFloorInfo->GetFloor(inFromPt.y, inFromPt.x);
+ if (prevFloor) {
+ if (prevFloor == nextFloor) {
+ if (abs(inFromPt.x - inToPt.x) <= inSearchScore)
+ result = true;
+ } else {
+ unsigned int prevFloorID = prevFloor->GetEquipID();
+ LArrayIterator iterator(*prevFloor->GetCEArray());
+ unsigned int moverID;
+
+ while (!result && iterator.Next(&moverID)) {
+ T2Mover *theMover = mFloorInfo->GetMover(moverID);
+ if (theMover && IsRelatedMover(theMover)) {
+ T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover);
+ if (theMoverRoutingTable) {
+ unsigned int distance;
+ if (theMoverRoutingTable->GetNextRoute(inFromPt, prevFloorID, inToPt, nextFloorIdx, distance)) {
+ if (distance <= inSearchScore)
+ result = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
}
-int T2RoutingTable::IsConnectRouteFromLobby(POINT) const {
+BOOL T2RoutingTable::IsConnectRouteFromLobby(POINT inPt) const {
+ BOOL result = false;
+
+ T2Tenant *floor = mFloorInfo->GetFloor(inPt.y, inPt.x);
+ int floorIndex = mFloorPtrList->GetIndex(floor);
+
+ if (floorIndex) {
+ T2Tenant *lobby = mFloorInfo->GetTenant(1000);
+ if (lobby) {
+ LArrayIterator iterator(*lobby->GetCEArray());
+ unsigned int moverID;
+
+ while (!result && iterator.Next(&moverID)) {
+ T2Mover *theMover = mFloorInfo->GetMover(moverID);
+ if (theMover && IsRelatedMover(theMover)) {
+ T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover);
+ if (theMoverRoutingTable)
+ result = theMoverRoutingTable->IsConnectRoute(floorIndex);
+ }
+ }
+ }
+ }
+
+ return result;
}
-int T2RoutingTable::GetNextRoute(POINT, POINT&) const {
+BOOL T2RoutingTable::GetNextRoute(POINT inFromPt, POINT& ioToPt) const {
+ BOOL result = false;
+
+ POINT toPt = ioToPt;
+ T2Tenant *destFloor = mFloorInfo->GetFloor(toPt.y, toPt.x);
+ int destFloorIdx = mFloorPtrList->GetIndex(destFloor);
+
+ if (destFloorIdx) {
+ T2Tenant *srcFloor = mFloorInfo->GetFloor(inFromPt.y, inFromPt.x);
+ if (srcFloor) {
+ unsigned int optimalScore = 100000;
+ T2Mover *optimalMover = NULL;
+ int srcFloorIdx = srcFloor->GetEquipID();
+
+ LArrayIterator iterator(*srcFloor->GetCEArray());
+ unsigned int theMoverID;
+
+ while (iterator.Next(&theMoverID)) {
+ T2Mover *theMover = mFloorInfo->GetMover(theMoverID);
+ if (theMover && IsRelatedMover(theMover)) {
+ T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover);
+ if (theMoverRoutingTable) {
+ POINT thisPt = toPt;
+ unsigned int thisScore;
+ if (theMoverRoutingTable->GetNextRoute(inFromPt, srcFloorIdx, thisPt, destFloorIdx, thisScore)) {
+ if (thisScore < optimalScore) {
+ optimalScore = thisScore;
+ optimalMover = theMover;
+ ioToPt = thisPt;
+ result |= true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
}
-T2Tenant* T2RoutingTable::SelectNearTenant(POINT, unsigned int) const {
+T2Tenant* T2RoutingTable::SelectNearTenant(POINT inPt, unsigned int inSearchScore) const {
+ T2Tenant *selectedTenant = NULL;
+
+ T2Tenant *theFloor = mFloorInfo->GetFloor(inPt.y, inPt.x);
+ if (theFloor) {
+ T2CrossEquipArray *theCEArray = theFloor->GetCEArray();
+ if (theCEArray) {
+ unsigned int first;
+ unsigned int numOfCE = theCEArray->GetCount();
+
+ if (numOfCE != 0)
+ first = (rand() % numOfCE) + 1;
+ else
+ first = 1;
+
+ T2Mover *theMover = NULL;
+ for (unsigned int i = 0; !theMover && i < numOfCE; i++) {
+ int index = first + i;
+ if (index > numOfCE)
+ index -= numOfCE;
+
+ unsigned int theMoverID;
+ theCEArray->FetchItemAt(index, &theMoverID);
+
+ theMover = mFloorInfo->GetMover(theMoverID);
+ if (theMover && !IsRelatedMover(theMover))
+ theMover = NULL;
+ }
+
+ T2Tenant *flr = NULL;
+ unsigned int maxHDistance = inSearchScore;
+ int hPos = inPt.x;
+
+ if (theMover) {
+ T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover);
+ if (theMoverRoutingTable)
+ flr = theMoverRoutingTable->SelectNearFloor(inPt, hPos, maxHDistance);
+ }
+
+ if (!flr)
+ flr = theFloor;
+
+ selectedTenant = SelectNearTenant(flr, hPos, maxHDistance);
+ }
+ }
+
+ return selectedTenant;
}
-T2Tenant* T2RoutingTable::SelectNearTenant(T2Tenant*, int, unsigned int) const {
+T2Tenant* T2RoutingTable::SelectNearTenant(T2Tenant* inTenant, int inH, unsigned int inSearchScore) const {
+ T2Tenant *selectedTenant = NULL;
+
+ RECT searchRect;
+ inTenant->GetEquipArea(searchRect);
+ searchRect.top = searchRect.bottom - 1;
+ searchRect.left = inH - inSearchScore;
+ searchRect.right = inH + inSearchScore;
+
+ T2FInfoAreaIterator iterator(*mFloorInfo, searchRect);
+ T2Tenant *theTenant;
+ int count = 0;
+
+ while (iterator.NextTenant(theTenant)) {
+ if (!theTenant->IsFloor() && !theTenant->IsBind() && theTenant->IsTherePeople())
+ count++;
+ }
+
+ if (count > 0) {
+ int randomIndex = rand() % count;
+ int i = 0;
+ iterator.Reset();
+
+ while (!selectedTenant && iterator.NextTenant(theTenant)) {
+ if (!theTenant->IsFloor() && !theTenant->IsBind() && theTenant->IsTherePeople()) {
+ if (i == randomIndex)
+ selectedTenant = theTenant;
+ else
+ i++;
+ }
+ }
+ }
+
+ return selectedTenant;
}
+
+
T2RoutingTableElem::T2RoutingTableElem() {
+ mNextFloorID = 0;
+ mScore = 0;
+ mTime = 0;
+ mFinalHPos = 0;
}
T2RoutingTableElem::~T2RoutingTableElem() {
}
-int T2RoutingTableElem::IsStopFloor() const {
+BOOL T2RoutingTableElem::IsStopFloor() const {
+ return ((mNextFloorID != 0) && (mScore == 0));
}
-void T2RoutingTableElem::SetTable(unsigned int, int) {
+void T2RoutingTableElem::SetTable(unsigned int inNextFloorID, int inFinalHPos) {
+ mNextFloorID = inNextFloorID;
+ mScore = 0;
+ mTime = 0;
+ mFinalHPos = inFinalHPos;
}
-int T2RoutingTableElem::IsSetTable(unsigned int, unsigned int, int, int) {
+BOOL T2RoutingTableElem::IsSetTable(unsigned int inNextFloorID, unsigned int inScore, int inTime, int inFinalHPos) {
+ BOOL result = false;
+
+ if (mNextFloorID == 0 || mScore > inScore) {
+ mNextFloorID = inNextFloorID;
+ mScore = inScore;
+ mTime = inTime;
+ mFinalHPos = inFinalHPos;
+ result = true;
+ }
+
+ return result;
}
-int T2RoutingTableElem::HasNextRoute(unsigned int) const {
+BOOL T2RoutingTableElem::HasNextRoute(unsigned int inFloorID) const {
+ return (mNextFloorID != 0) && (mNextFloorID != inFloorID);
}