]> git.localhorst.tv Git - l2e.git/blob - src/map/Entity.cpp
renamed namespace geometry -> math
[l2e.git] / src / map / Entity.cpp
1 #include "Entity.h"
2
3 #include "../battle/Monster.h"
4 #include "../battle/PartyLayout.h"
5 #include "../graphics/Animation.h"
6 #include "../graphics/Sprite.h"
7 #include "../loader/Interpreter.h"
8 #include "../loader/TypeDescription.h"
9
10 using battle::Monster;
11 using battle::PartyLayout;
12 using graphics::Animation;
13 using graphics::Sprite;
14 using math::Vector;
15 using loader::FieldDescription;
16 using loader::Interpreter;
17 using loader::TypeDescription;
18
19 namespace map {
20
21 Entity::Entity()
22 : follower(0)
23 , animation(0)
24 , sprite(0)
25 , partyLayout(0)
26 , monsters(0)
27 , numMonsters(0)
28 , orientation(ORIENTATION_NORTH)
29 , speed(0)
30 , flags(0) {
31         runner.SetFrameShift(1);
32 }
33
34
35 void Entity::SetOrientation(Orientation o) {
36         orientation = o;
37         UpdateVelocity();
38         if (CanTurn()) {
39                 runner.SetColOffset(orientation);
40         }
41 }
42
43 void Entity::SetSpeed(float s) {
44         speed = s;
45         UpdateVelocity();
46 }
47
48
49 void Entity::StartAnimation(app::Application &ctrl) {
50         runner.Start(ctrl);
51 }
52
53 void Entity::StartAnimation(app::State &ctrl) {
54         runner.Start(ctrl);
55 }
56
57 void Entity::StopAnimation() {
58         runner.Stop();
59 }
60
61
62 void Entity::SetHandsFree() {
63         runner.SetRowOffset(0);
64 }
65
66 void Entity::SetCarrying() {
67         runner.SetRowOffset(2);
68 }
69
70 void Entity::SetPushing() {
71         runner.SetRowOffset(4);
72 }
73
74
75 void Entity::AddFollower(Entity *f) {
76         if (follower) {
77                 follower->AddFollower(f);
78         } else {
79                 follower = f;
80         }
81 }
82
83 void Entity::RemoveFollower(Entity *f) {
84         if (follower == f) {
85                 follower = follower->follower;
86         } else if (follower) {
87                 follower->RemoveFollower(f);
88         }
89 }
90
91 void Entity::SetAnimation(const graphics::Animation *a) {
92         animation = a;
93         runner.ChangeAnimation(animation);
94         if (!sprite) {
95                 sprite = animation->GetSprite();
96         }
97 }
98
99
100 void Entity::UpdateVelocity() {
101         if (speed == 0.0f) {
102                 velocity = Vector<float>();
103                 return;
104         }
105         switch (orientation) {
106                 case ORIENTATION_NORTH:
107                         velocity = Vector<float>(0.0f, -speed);
108                         break;
109                 case ORIENTATION_EAST:
110                         velocity = Vector<float>(speed, 0.0f);
111                         break;
112                 case ORIENTATION_SOUTH:
113                         velocity = Vector<float>(0.0f, speed);
114                         break;
115                 case ORIENTATION_WEST:
116                         velocity = Vector<float>(-speed, 0.0f);
117                         break;
118         }
119 }
120
121
122 bool Entity::TileLock(const math::Vector<int> &tileSize) const {
123         // TODO: change position to point to the top-left corner of a tile
124         Vector<int> tilePosition(position);
125         return (tilePosition.X() % tileSize.X() == 0) && (tilePosition.Y() % tileSize.Y() == 0);
126 }
127
128
129 void Entity::Update(float deltaT) {
130         position += velocity * deltaT;
131 }
132
133
134 void Entity::Render(SDL_Surface *dest, const Vector<int> &offset) const {
135         // TODO: configurable sprite offsets
136         if (runner.Running()) {
137                 runner.Draw(dest, offset + position + spriteOffset);
138         } else {
139                 sprite->Draw(dest, offset + position + spriteOffset, CanTurn() ? orientation : 0);
140         }
141 }
142
143
144 void Entity::CreateTypeDescription() {
145         Entity e;
146
147         TypeDescription &td(TypeDescription::Create(TYPE_ID, "Entity"));
148         td.SetConstructor(&Construct);
149         td.SetLoader(&Load);
150         td.SetSize(sizeof(Entity));
151
152         td.AddField("animation", FieldDescription(((char *)&e.animation) - ((char *)&e), Animation::TYPE_ID).SetReferenced());
153         td.AddField("sprite", FieldDescription(((char *)&e.sprite) - ((char *)&e), Sprite::TYPE_ID).SetReferenced());
154         td.AddField("partyLayout", FieldDescription(((char *)&e.partyLayout) - ((char *)&e), PartyLayout::TYPE_ID).SetReferenced());
155         td.AddField("monsters", FieldDescription(((char *)&e.monsters) - ((char *)&e), Monster::TYPE_ID).SetReferenced().SetAggregate());
156         td.AddField("spriteOffset", FieldDescription(((char *)&e.spriteOffset) - ((char *)&e), Interpreter::VECTOR_ID));
157         td.AddField("position", FieldDescription(((char *)&e.tilePosition) - ((char *)&e), Interpreter::VECTOR_ID));
158         td.AddField("flags", FieldDescription(((char *)&e.flags) - ((char *)&e), Interpreter::NUMBER_ID));
159 }
160
161 void Entity::Construct(void *data) {
162         new (data) Entity;
163 }
164
165 void Entity::Load(void *data) {
166         Entity *entity(reinterpret_cast<Entity *>(data));
167         if (entity->animation) {
168                 entity->runner.ChangeAnimation(entity->animation);
169                 if (!entity->sprite) {
170                         entity->sprite = entity->animation->GetSprite();
171                 }
172         }
173 }
174
175 }