-
Notifications
You must be signed in to change notification settings - Fork 68
Closed
Description
The dump does not include area linkages when 2 areas connect without a clickable object (i.e. as in Act 1 is often the case).
Other apis do it like this:
`
void ActMap::FindRoomLinkageExits(ExitArray& exits) const
{
using namespace std;
multimap<int, std::pair<Point, std::pair<Point, int>>> exitMap; // <level, <rooms[i], <middlepoint, size> > >
for(Room2* room = level->pRoom2First; room; room = room->pRoom2Next)
{
Room2** rooms = room->pRoom2Near;
for(DWORD i = 0; i < room->dwRoomsNear; i++)
{
if(rooms[i]->pLevel->dwLevelNo == level->dwLevelNo)
continue;
// does this link already exist?
bool exists = false;
ExitArray::iterator begin = exits.begin(), last = exits.end();
for(ExitArray::iterator it = begin; it != last; it++)
{
if(it->Target == rooms[i]->pLevel->dwLevelNo)
{
exists = true;
break;
}
}
if(exists)
continue;
// A -> origin of local room, B -> opposite corner from origin in local room ... X, Y -> like local but for adjecent room
Point A, B, X, Y, startPoint, edgeDirection, orthogonalDirection;
int overlappingX, overlappingY, edgeSize;
// this could be enum
bool startLeft = false, startRight = false, startTop = false, startBottom = false;
A = Point(room->dwPosX * 5, room->dwPosY * 5);
B = Point(room->dwPosX * 5 + room->dwSizeX * 5, room->dwPosY * 5 + room->dwSizeY * 5);
X = Point(rooms[i]->dwPosX * 5, rooms[i]->dwPosY * 5);
Y = Point(rooms[i]->dwPosX * 5 + rooms[i]->dwSizeX * 5, rooms[i]->dwPosY * 5 + rooms[i]->dwSizeY * 5);
overlappingX = min(B.first, Y.first) - max(A.first, X.first);
overlappingY = min(B.second, Y.second) - max(A.second, X.second);
if (overlappingX > 0) // top or bottom edge
{
if (A.second < X.second) // bottom edge
{
startPoint = Point(max(A.first, X.first), B.second-1);
startBottom = true;
}
else
{
startPoint = Point(max(A.first, X.first), A.second);
startTop = true;
}
}
else if (overlappingY > 0) // left or right edge
{
if (A.first < X.first) // right edge
{
startPoint = Point(B.first-1, max(A.second, X.second));
startRight = true;
}
else
{
startPoint = Point(A.first, max(A.second, X.second));
startLeft = true;
}
}
if (overlappingX < 0 || overlappingY < 0)
{
// Print("�c1d2bs�c3ActMap::GetExits�c0 adjecent room is out of reach - it's not even touching local room in corner!");
continue;
}
if (overlappingX > 0 && overlappingY > 0)
{
// Print("�c1d2bs�c3ActMap::GetExits�c0 WTF local and adjecent rooms are overlapping (they share some points)!!!");
continue;
}
if (overlappingX < 3 && overlappingY < 3)
{
// edge is not large enough to even bother to check for exit (exit should be at least 3 points wide)
continue;
}
if (startLeft || startRight) // -> going down
{
edgeSize = overlappingY; // number of vertical touched points
edgeDirection = Point(0, 1); // down
orthogonalDirection = Point((startLeft ? -1 : 1), 0); // checking adjecent spaces -> left / right
}
else // startTop || startBottom -> going right
{
edgeSize = overlappingX; // number of horizontal touched points
edgeDirection = Point(1, 0); // right
orthogonalDirection = Point(0, (startTop ? -1 : 1)); // checking adjecent spaces -> up / down
}
Point currentPoint, lastWalkablePoint;
bool isPointWalkable = false;
int spaces = 0, j;
for (j = 0; j < edgeSize; j++)
{
// would be nice to convert this line to => currentPoint = startPoint + edgeDirection * j;
currentPoint = Point(startPoint.first + j * edgeDirection.first, startPoint.second + j * edgeDirection.second);
isPointWalkable = EdgeIsWalkable(currentPoint, orthogonalDirection, true);
if (isPointWalkable)
{
lastWalkablePoint = currentPoint;
spaces++;
}
if (false == isPointWalkable || j + 1 == edgeSize)
{
if (spaces > 0)
{
Point centerEdgePoint = GetEdgeCenterPoint(currentPoint, edgeDirection);
currentPoint = Point(lastWalkablePoint.first - edgeDirection.first * spaces / 2, lastWalkablePoint.second - edgeDirection.second * spaces / 2);
exitMap.insert(make_pair(rooms[i]->pLevel->dwLevelNo, make_pair(centerEdgePoint, make_pair(currentPoint, spaces))));
}
spaces = 0;
}
}
}
}
std::pair<Point, std::pair<Point, int>> currentExit;
std::multimap<int, std::pair<Point, std::pair<Point, int>>>::iterator it = exitMap.begin();
int level = 0;
double minDistance = -1, tmpDistance;
do
{
if (level == 0 && it == exitMap.end())
{
break;
}
if (level == 0)
{
level = it->first;
currentExit = it->second;
}
if (it == exitMap.end() || level != it->first)
{
exits.push_back(Exit(currentExit.second.first, level, Linkage, 0));
if (it == exitMap.end())
{
break;
}
level = it->first;
currentExit = it->second;
minDistance = -1;
}
tmpDistance = GetDistance(
it->second.first.first,
it->second.first.second,
it->second.second.first.first,
it->second.second.first.second
);
if (minDistance == -1 || minDistance > tmpDistance)
{
currentExit = it->second;
minDistance = tmpDistance;
}
} while(it++ != exitMap.end());
}
`
prty sure this project is dead but maybe this could be implemented
Metadata
Metadata
Assignees
Labels
No labels