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