mapSelan.SetAnimation(&mapSelanAnimation);
mapSelan.Position() = Vector<float>(64, 128);
mapSelan.SpriteOffset() = Vector<float>(0, -32);
+ mapSelan.SetFlags(Entity::FLAG_NONBLOCKING);
mapMaxim.AddFollower(&mapSelan);
SDL_Surface *mapGuyImg(IMG_Load("test-data/guy-map.png"));
mapGuy.SetAnimation(&mapGuyAnimation);
mapGuy.Position() = Vector<float>(64, 128);
mapGuy.SpriteOffset() = Vector<float>(0, -32);
+ mapSelan.SetFlags(Entity::FLAG_NONBLOCKING);
mapSelan.AddFollower(&mapGuy);
SDL_Surface *mapDekarImg(IMG_Load("test-data/dekar-map.png"));
mapDekar.SetAnimation(&mapDekarAnimation);
mapDekar.Position() = Vector<float>(64, 128);
mapDekar.SpriteOffset() = Vector<float>(0, -32);
+ mapDekar.SetFlags(Entity::FLAG_NONBLOCKING);
mapGuy.AddFollower(&mapDekar);
SDL_Surface *mapMonsterImg(IMG_Load("test-data/monster-map.png"));
ORIENTATION_SOUTH = 2,
ORIENTATION_WEST = 3,
};
+ enum Flags {
+ FLAG_NONBLOCKING = 0x01,
+ };
public:
geometry::Vector<float> &Position() { return position; }
Orientation GetOrientation() const { return orientation; }
void SetSpeed(float);
+ void SetFlags(int f) { flags = f; }
+ bool Blocking() const { return !(flags & FLAG_NONBLOCKING); }
+
Entity *Follower() { return follower; }
const Entity *Follower() const { return follower; }
void AddFollower(Entity *);
geometry::Vector<float> velocity;
Orientation orientation;
float speed;
+ int flags;
};
// TODO: halt all activity if lock caused a state/map transition
if (nextDirection >= 0) {
- const Tile &tile(map->TileAt(controlled->Position()));
- bool blocked(false);
- switch (nextDirection) {
- case Entity::ORIENTATION_NORTH:
- blocked = tile.BlocksNorth();
- break;
- case Entity::ORIENTATION_EAST:
- blocked = tile.BlocksEast();
- break;
- case Entity::ORIENTATION_SOUTH:
- blocked = tile.BlocksSouth();
- break;
- case Entity::ORIENTATION_WEST:
- blocked = tile.BlocksWest();
- break;
- }
+ bool blocked(CheckBlocking());
if (afterLock) {
OnMove(!blocked);
afterLock = false;
lastLock = nowLock;
}
+bool MapState::CheckBlocking() const {
+ const Tile &tile(map->TileAt(controlled->Position()));
+ Vector<int> nextPosition;
+ switch (nextDirection) {
+ case Entity::ORIENTATION_NORTH:
+ if (tile.BlocksNorth()) {
+ return true;
+ } else {
+ nextPosition = Vector<int>(
+ controlled->Position().X(),
+ controlled->Position().Y() - map->Tileset()->Height());
+ }
+ break;
+ case Entity::ORIENTATION_EAST:
+ if (tile.BlocksEast()) {
+ return true;
+ } else {
+ nextPosition = Vector<int>(
+ controlled->Position().X() + map->Tileset()->Width(),
+ controlled->Position().Y());
+ }
+ break;
+ case Entity::ORIENTATION_SOUTH:
+ if (tile.BlocksSouth()) {
+ return true;
+ } else {
+ nextPosition = Vector<int>(
+ controlled->Position().X(),
+ controlled->Position().Y() + map->Tileset()->Height());
+ }
+ break;
+ case Entity::ORIENTATION_WEST:
+ if (tile.BlocksWest()) {
+ return true;
+ } else {
+ nextPosition = Vector<int>(
+ controlled->Position().X() - map->Tileset()->Width(),
+ controlled->Position().Y());
+ }
+ break;
+ default:
+ return false;
+ }
+ Vector<int> nextTileCoords(map->TileCoordinates(nextPosition));
+ for (std::vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
+ const Entity &e(**i);
+ if (map->TileCoordinates(e.Position()) == nextTileCoords && e.Blocking()) {
+ return true;
+ }
+ }
+ return false;
+}
+
void MapState::OnGridLock() {
LockEntities();
Trigger *trigger(map->TriggerAt(Vector<int>(controlled->Position())));