]> git.localhorst.tv Git - l2e.git/blob - src/map/MapState.cpp
added entity follower list
[l2e.git] / src / map / MapState.cpp
1 /*
2  * MapState.cpp
3  *
4  *  Created on: Sep 29, 2012
5  *      Author: holy
6  */
7
8 #include "MapState.h"
9
10 #include "Map.h"
11 #include "Tile.h"
12 #include "../app/Application.h"
13 #include "../app/Input.h"
14
15 #include <algorithm>
16
17 using app::Application;
18 using app::Input;
19 using geometry::Vector;
20
21 namespace map {
22
23 MapState::MapState(Map *map)
24 : map(map)
25 , controlled(0)
26 , tempTarget(20, 20)
27 , camera(100, 100, &tempTarget)
28 , walkingSpeed(64)
29 , nextDirection(-1)
30 , afterLock(false) {
31
32 }
33
34
35 void MapState::EnterState(Application &ctrl, SDL_Surface *screen) {
36         camera.Resize(screen->w, screen->h);
37 }
38
39 void MapState::ExitState(Application &ctrl, SDL_Surface *screen) {
40
41 }
42
43 void MapState::ResumeState(Application &ctrl, SDL_Surface *screen) {
44         camera.Resize(screen->w, screen->h);
45 }
46
47 void MapState::PauseState(Application &ctrl, SDL_Surface *screen) {
48
49 }
50
51 void MapState::Resize(int width, int height) {
52         camera.Resize(width, height);
53 }
54
55
56 void MapState::HandleEvents(const Input &input) {
57         if (!controlled) return;
58
59         if (input.IsDown(Input::PAD_UP)) {
60                 nextDirection = Entity::ORIENTATION_NORTH;
61         } else if (input.IsDown(Input::PAD_RIGHT)) {
62                 nextDirection = Entity::ORIENTATION_EAST;
63         } else if (input.IsDown(Input::PAD_DOWN)) {
64                 nextDirection = Entity::ORIENTATION_SOUTH;
65         } else if (input.IsDown(Input::PAD_LEFT)) {
66                 nextDirection = Entity::ORIENTATION_WEST;
67         } else {
68                 nextDirection = -1;
69         }
70 }
71
72 void MapState::UpdateWorld(float deltaT) {
73         if (controlled && controlled->TileLock(map->Tileset()->Width(), map->Tileset()->Height())) {
74                 Vector<int> nowLock(controlled->Position());
75                 if (nowLock != lastLock) {
76                         OnGridLock();
77                 }
78                 if (nextDirection >= 0) {
79                         if (afterLock) {
80                                 // FIXME: this check is unreliable, see #21
81                                 OnMove();
82                                 afterLock = false;
83                         }
84                         controlled->SetOrientation(Entity::Orientation(nextDirection));
85                         const Tile &tile(map->TileAt(controlled->Position()));
86                         bool blocked(false);
87                         switch (controlled->GetOrientation()) {
88                                 case Entity::ORIENTATION_NORTH:
89                                         blocked = tile.BlocksNorth();
90                                         break;
91                                 case Entity::ORIENTATION_EAST:
92                                         blocked = tile.BlocksEast();
93                                         break;
94                                 case Entity::ORIENTATION_SOUTH:
95                                         blocked = tile.BlocksSouth();
96                                         break;
97                                 case Entity::ORIENTATION_WEST:
98                                         blocked = tile.BlocksWest();
99                                         break;
100                         }
101                         if (!blocked) {
102                                 controlled->SetSpeed(walkingSpeed);
103                         } else {
104                                 controlled->SetSpeed(0.0f);
105                         }
106                         if (!controlled->AnimationRunning()) {
107                                 controlled->StartAnimation(*this);
108                         }
109                 } else {
110                         controlled->SetSpeed(0.0f);
111                         controlled->StopAnimation();
112                 }
113                 if (nowLock != lastLock) {
114                         lastLock = nowLock;
115                         afterLock = true;
116                 }
117         }
118         for (std::vector<Entity *>::iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
119                 (*i)->Update(deltaT);
120         }
121 }
122
123 void MapState::OnGridLock() {
124         Trigger *trigger(map->TriggerAt(Vector<int>(controlled->Position())));
125         if (trigger) {
126                 // TODO: run trigger
127         }
128         // TODO: check for adjacent monsters
129         // TODO: force all entities into their grid positions?
130 }
131
132 void MapState::OnMove() {
133         // TODO: evaluate monster movements
134         UpdateFollower(controlled);
135 }
136
137 void MapState::UpdateFollower(Entity *e) {
138         if (!e->Follower()) return;
139         UpdateFollower(e->Follower());
140
141         e->Follower()->SetOrientation(e->GetOrientation());
142         // TODO: set follower speed
143 }
144
145
146 void MapState::Render(SDL_Surface *screen) {
147         SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
148
149         Vector<int> offset(camera.CalculateOffset());
150         map->Render(screen, offset);
151
152         std::sort(entities.begin(), entities.end(), ZCompare);
153         for (std::vector<Entity *>::iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
154                 (*i)->Render(screen, offset);
155         }
156 }
157
158
159 bool MapState::ZCompare(const Entity *lhs, const Entity *rhs) {
160         return lhs->Position().Y() < rhs->Position().Y();
161 }
162
163 }