fix redraw at top-left of map
[Tsunagari.git] / src / player.cpp
blob31de1a76fd28d079c49297a413d4be43ec7c2ae0
1 /******************************
2 ** Tsunagari Tile Engine **
3 ** player.cpp **
4 ** Copyright 2011 OmegaSDG **
5 ******************************/
7 #include <Gosu/Audio.hpp>
8 #include <Gosu/Input.hpp>
9 #include <Gosu/Math.hpp>
11 #include "area.h"
12 #include "config.h"
13 #include "entity.h"
14 #include "player.h"
15 #include "world.h"
16 #include "window.h"
18 Player::Player(Resourcer* rc, Area* area)
19 : Entity(rc, area), velocity(coord(0, 0, 0))
23 void Player::startMovement(coord_t delta)
25 if (GAME_MODE == JUMP_MOVE) {
26 // TODO Move by velocity would allow true diagonal movement
27 moveByTile(delta);
29 else if (GAME_MODE == SLIDE_MOVE) {
30 velocity.x += delta.x;
31 velocity.y += delta.y;
32 velocity.z += delta.z;
33 normalizeVelocity();
34 moveByTile(velocity);
38 void Player::stopMovement(coord_t delta)
40 if (GAME_MODE == SLIDE_MOVE) {
41 velocity.x -= delta.x;
42 velocity.y -= delta.y;
43 velocity.z -= delta.z;
44 normalizeVelocity();
45 if (velocity.x || velocity.y || velocity.z)
46 moveByTile(velocity);
50 void Player::moveByTile(coord_t delta)
52 // You can't interrupt an in-progress movement.
53 if (moving)
54 return;
56 // Left CTRL allows changing facing, but disallows movement.
57 const GameWindow& window = GameWindow::getWindow();
58 if (window.input().down(Gosu::kbLeftControl)) {
59 calculateFacing(delta);
60 setPhase(facing);
61 return;
64 // Try to actually move.
65 coord_t newCoord = getCoordsByTile();
66 newCoord.x += delta.x;
67 newCoord.y += delta.y;
68 newCoord.z += delta.z;
69 const Area::Tile& dest = area->getTile(newCoord);
70 if ((dest.flags & Area::player_nowalk) != 0 ||
71 (dest.type->flags & Area::player_nowalk) != 0) {
72 // The tile we're trying to move onto is set as player_nowalk.
73 // Turn to face the direction, but don't move.
74 calculateFacing(delta);
75 setPhase(facing);
76 return;
79 Entity::moveByTile(delta);
82 void Player::preMove(coord_t delta)
84 Entity::preMove(delta);
86 SampleRef step = getSound("step");
87 if (step)
88 step->play(1, 1, 0);
92 void Player::postMove()
94 Entity::postMove();
96 const coord_t coord = getCoordsByTile();
97 const Area::Tile& dest = area->getTile(coord);
98 const boost::optional<Area::Door> door = dest.door;
99 if (door)
100 World::getWorld()->loadArea(door->area, door->coord);
101 if (GAME_MODE == SLIDE_MOVE)
102 if (velocity.x || velocity.y || velocity.z)
103 moveByTile(velocity);
106 void Player::normalizeVelocity()
108 velocity.x = Gosu::boundBy(velocity.x, -1L, 1L);
109 velocity.y = Gosu::boundBy(velocity.y, -1L, 1L);
110 velocity.z = Gosu::boundBy(velocity.z, -1L, 1L);