Entity defaults to an NPC
[Tsunagari.git] / src / player.cpp
blob9bbd0dd98a540a5647c480ac6214a53a2053087e
1 /*********************************
2 ** Tsunagari Tile Engine **
3 ** player.cpp **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
7 #include <boost/foreach.hpp>
8 #include <boost/format.hpp>
9 #include <Gosu/Audio.hpp>
10 #include <Gosu/Input.hpp>
11 #include <Gosu/Math.hpp>
13 #include "area.h"
14 #include "config.h"
15 #include "entity.h"
16 #include "log.h"
17 #include "player.h"
18 #include "world.h"
19 #include "window.h"
21 template<class Cont, class ValueType>
22 void removeValue(Cont* c, ValueType v)
24 typename Cont::iterator it;
25 for (it = c->begin(); it != c->end(); ++it) {
26 if (*it == v) {
27 c->erase(it);
28 return;
34 Player::Player()
35 : Entity(), velocity(0, 0)
37 nowalkFlags = TILE_NOWALK | TILE_NOWALK_PLAYER;
40 bool Player::init(const std::string& descriptor)
42 bool b = Entity::init(descriptor);
43 if (b) {
44 // Set an initial phase.
45 setPhase(directionStr(setFacing(ivec2(0, 1))));
47 return b;
50 void Player::startMovement(ivec2 delta)
52 switch (conf.moveMode) {
53 case TURN:
54 moveByTile(delta);
55 break;
56 case TILE:
57 movements.push_back(delta);
58 velocity = delta;
59 moveByTile(velocity);
60 break;
61 case NOTILE:
62 // TODO
63 break;
65 stillMoving = velocity;
68 void Player::stopMovement(ivec2 delta)
70 switch (conf.moveMode) {
71 case TURN:
72 break;
73 case TILE:
74 removeValue(&movements, delta);
75 velocity = movements.size() ?
76 movements.back() :
77 ivec2(0, 0);
78 if (velocity)
79 moveByTile(velocity);
80 break;
81 case NOTILE:
82 // TODO
83 break;
85 stillMoving = velocity;
88 void Player::moveByTile(ivec2 delta)
90 if (frozen)
91 return;
92 if (moving)
93 return;
95 setFacing(delta);
97 // Left CTRL allows changing facing, but disallows movement.
98 const GameWindow& window = GameWindow::instance();
99 if (window.input().down(Gosu::kbLeftControl)) {
100 setPhase(directionStr(facing));
101 redraw = true;
102 return;
105 Entity::moveByTile(delta);
108 void Player::useTile()
110 std::vector<icoord> tiles = frontTiles();
111 BOOST_FOREACH(icoord& c, tiles) {
112 Tile& t = area->getTile(c);
113 t.onUseScripts(this);
117 void Player::setFrozen(bool b)
119 movements.clear();
121 Entity::setFrozen(b);
124 void Player::postMove()
126 Entity::postMove();
128 // Normal exit.
129 if (destTile) {
130 Exit* exit = destTile->exits[EXIT_NORMAL];
131 if (exit)
132 takeExit(exit);
135 // Side exit.
136 ivec2 dxy(deltaCoord.x, deltaCoord.y);
137 Exit* exit = fromTile->exitAt(dxy);
138 if (exit)
139 takeExit(exit);
141 // If we have a velocity, keep moving.
142 if (conf.moveMode == TILE && velocity)
143 moveByTile(velocity);
146 void Player::takeExit(Exit* exit)
148 World* world = World::instance();
149 Area* newArea = world->getArea(exit->area);
150 if (newArea) {
151 world->focusArea(newArea, exit->coords);
153 else {
154 // Roll back movement if exit failed to open.
155 r = fromCoord;
156 Log::err("Exit", exit->area + ": failed to load properly");