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