5 * Created by Alyssa Milburn on Tue May 25 2004.
6 * Copyright (c) 2004 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
27 for (std::vector
<MetaRoom
*>::iterator i
= metarooms
.begin(); i
!= metarooms
.end(); i
++) {
31 // todo: metarooms should be responsible for deleting rooms, so use the following instead of clear:
32 // assert(rooms.empty());
36 void Map::SetMapDimensions(unsigned int w
, unsigned int h
) {
37 // todo: check for outlying metarooms
42 int Map::addMetaRoom(MetaRoom
*m
) {
43 // todo: check if it's outlying
44 while (getMetaRoom(metaroom_base
))
46 m
->id
= metaroom_base
++;
47 metarooms
.push_back(m
);
51 MetaRoom
*Map::getMetaRoom(unsigned int room
) {
52 for (std::vector
<MetaRoom
*>::iterator i
= metarooms
.begin(); i
!= metarooms
.end(); i
++)
58 shared_ptr
<Room
> Map::getRoom(unsigned int r
) {
59 for (std::vector
<shared_ptr
<Room
> >::iterator i
= rooms
.begin(); i
!= rooms
.end(); i
++)
62 return shared_ptr
<Room
>();
65 unsigned int Map::getMetaRoomCount() {
66 return metarooms
.size();
69 unsigned int Map::getRoomCount() {
75 for (std::vector
<MetaRoom
*>::iterator m
= metarooms
.begin(); m
!= metarooms
.end(); m
++)
76 for (std::vector
<shared_ptr
<Room
> >::iterator i
= (*m
)->rooms
.begin(); i
!= (*m
)->rooms
.end(); i
++)
78 for (std::vector
<MetaRoom
*>::iterator m
= metarooms
.begin(); m
!= metarooms
.end(); m
++)
79 for (std::vector
<shared_ptr
<Room
> >::iterator i
= (*m
)->rooms
.begin(); i
!= (*m
)->rooms
.end(); i
++)
81 for (std::vector
<MetaRoom
*>::iterator m
= metarooms
.begin(); m
!= metarooms
.end(); m
++)
82 for (std::vector
<shared_ptr
<Room
> >::iterator i
= (*m
)->rooms
.begin(); i
!= (*m
)->rooms
.end(); i
++)
86 MetaRoom
*Map::metaRoomAt(unsigned int _x
, unsigned int _y
) {
87 for (std::vector
<MetaRoom
*>::iterator i
= metarooms
.begin(); i
!= metarooms
.end(); i
++) {
89 if ((_x
>= r
->x()) && (_y
>= r
->y()))
90 if ((_x
<= (r
->x() + r
->width())) && (_y
<= (r
->y() + r
->height())))
96 shared_ptr
<Room
> Map::roomAt(float _x
, float _y
) {
97 MetaRoom
*m
= metaRoomAt((unsigned int)_x
, (unsigned int)_y
); // TODO: good casts?
98 if (!m
) return shared_ptr
<Room
>();
99 return m
->roomAt(_x
, _y
);
102 std::vector
<shared_ptr
<Room
> > Map::roomsAt(float _x
, float _y
) {
103 MetaRoom
*m
= metaRoomAt((unsigned int)_x
, (unsigned int)_y
); // TODO: good casts?
104 if (!m
) return std::vector
<shared_ptr
<Room
> >();
105 return m
->roomsAt(_x
, _y
);
108 bool Map::collideLineWithRoomSystem(Point src
, Point dest
, shared_ptr
<Room
> &room
, Point
&where
, Line
&wall
, unsigned int &walldir
, int perm
) {
109 shared_ptr
<Room
> newRoom
;
114 if (!collideLineWithRoomBoundaries(where
, dest
, room
, newRoom
, where
, wall
, walldir
, perm
))
115 return false; // failure
117 return true; // collision
119 return false; // got there
121 assert(newRoom
!= room
); // tsk
128 * poss. optimisation: skip checking the rest of the lines if our distance is 0?
130 bool Map::collideLineWithRoomBoundaries(Point src
, Point dest
, shared_ptr
<Room
> room
, shared_ptr
<Room
> &newroom
, Point
&where
, Line
&wall
, unsigned int &walldir
, int perm
) {
132 // TODO: this assert fails. why? 'where' is presumably outside the dest room sometimes.. mmh
133 //assert(room->containsPoint(src.x, src.y));
134 if (src
== dest
) return false;
138 /* if (room->containsPoint(dest.x, dest.y)) {
143 float distance
= 100000000.0f
; // TODO: lots.
144 bool foundsomething
= false;
145 bool previousroom
= (newroom
);
146 Point oldpoint
= where
;
147 Line
movement(src
, dest
);
149 Line x
[4] = { room
->left
, room
->right
, room
->top
, room
->bot
};
150 for (unsigned int i
= 0; i
< 4; i
++) {
152 if (x[i].containsPoint(oldpoint)) continue; */
155 if (x
[i
].intersect(movement
, temppoint
)) {
156 if (!movement
.containsPoint(temppoint
)) {
157 std::cout
<< "physics bug: intersect wasn't on movement line at (" << temppoint
.x
<< ", " << temppoint
.y
<< ")" << std::endl
;
158 std::cout
<< "room line: (" << x
[i
].getStart().x
<< ", " << x
[i
].getStart().y
<< ") to ";
159 std::cout
<< "(" << x
[i
].getEnd().x
<< ", " << x
[i
].getEnd().y
<< ")" << std::endl
;
160 std::cout
<< "movement line: (" << src
.x
<< ", " << src
.y
<< ") to ";
161 std::cout
<< "(" << dest
.x
<< ", " << dest
.y
<< ")" << std::endl
;
162 return false; // go away
164 assert(movement
.containsPoint(temppoint
));
166 //if (temppoint == src) return false; // for debug use: sneakily fail all movement between rooms
168 // see if this is nearer than any previous points we've found
169 double distx
= temppoint
.x
- src
.x
;
170 double disty
= temppoint
.y
- src
.y
;
171 double d
= distx
*distx
+ disty
*disty
;
175 // work out which room is next along our movement vector
176 // TODO: this code utterly sucks, doesn't work properly
178 /*if (temppoint == src) { // TODO: this is not an accurate check!! likely cause of falling through PERM
179 // we might be on a PERM line! check backwards.
180 newx = temppoint.x + (src.x <= dest.x ? (src.x == dest.x ? 0.0 : -0.5) : 0.5);
181 newy = temppoint.y + (src.y <= dest.y ? (src.y == dest.y ? 0.0 : -0.5) : 0.5);
183 newx
= temppoint
.x
+ (src
.x
<= dest
.x
? (src
.x
== dest
.x
? 0.0 : 0.5) : -0.5);
184 newy
= temppoint
.y
+ (src
.y
<= dest
.y
? (src
.y
== dest
.y
? 0.0 : 0.5) : -0.5);
187 if (room
->containsPoint(newx
, newy
)) { // if a little along our movement vector is still in our room, forget it
188 /*std::cout << "physics debug: next room is original room at (" << temppoint.x << ", " << temppoint.y << ")" << std::endl;
189 std::cout << "room line: (" << x[i].getStart().x << ", " << x[i].getStart().y << ") to ";
190 std::cout << "(" << x[i].getEnd().x << ", " << x[i].getEnd().y << ")" << std::endl;
191 std::cout << "movement line: (" << movement.getStart().x << ", " << movement.getStart().y << ") to ";
192 std::cout << "(" << movement.getEnd().x << ", " << movement.getEnd().y << ")" << std::endl;
194 continue; // continue, bad collision
197 shared_ptr
<Room
> nextroom
;
198 bool foundroom
= false;
200 for (std::map
<boost::weak_ptr
<Room
>,RoomDoor
*>::iterator r
= room
->doors
.begin(); r
!= room
->doors
.end(); r
++) {
201 shared_ptr
<Room
> otherroom
= r
->first
.lock();
204 if (otherroom
->containsPoint(newx
, newy
)) {
205 // this is our next room!
207 // if boundary perm is going to let us through..
208 if (perm
<= r
->second
->perm
) // TODO: right?
209 nextroom
= otherroom
;
214 if (!foundroom
&& !nextroom
)
215 nextroom
= roomAt(newx
, newy
);
217 /*if (temppoint == src) { // if we're just doing the backwards PERM check
218 if (!foundroom || nextroom != 0) {
219 // either there's no previous room or PERM let us into the previous room..
220 // ..so forget this collision
225 shared_ptr
<Room
> z
= roomAt(temppoint
.x
, temppoint
.y
); // TODO: evil performance-killing debug check
227 // TODO: commented out this error message for sake of fuzzie's sanity, but it's still an issue
228 /*std::cout << "physics bug: fell out of room system at (" << where.x << ", " << where.y << ")" << std::endl;
229 std::cout << "room line: (" << x[i].getStart().x << ", " << x[i].getStart().y << ") to ";
230 std::cout << "(" << x[i].getEnd().x << ", " << x[i].getEnd().y << ")" << std::endl;
231 std::cout << "movement line: (" << movement.getStart().x << ", " << movement.getStart().y << ") to ";
232 std::cout << "(" << movement.getEnd().x << ", " << movement.getEnd().y << ")" << std::endl;*/
233 return false; // go away
236 // it is nearer and not the same room, so make it our priority
238 foundsomething
= true;
246 if (!foundsomething
) {
247 if (room
->containsPoint(dest
.x
, dest
.y
)) {
250 where
= src
; // TODO: can't we assume this anyway?
251 // TODO: commented out this error message for sake of fuzzie's sanity, but it's still an issue
252 /*std::cout << "physics bug: didn't collide with a line, nor stay in the current room!" << std::endl;
253 std::cout << "movement line: (" << movement.getStart().x << ", " << movement.getStart().y << ") to ";
254 std::cout << "(" << movement.getEnd().x << ", " << movement.getEnd().y << ")" << std::endl;*/