diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-04-28 09:22:44 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-04-28 09:22:44 -0400 |
commit | 8016a7146fec3f6f43ca05723441750e5aae3d4d (patch) | |
tree | 0d527c1af80cf9ac34a027f9ee6f1acbb95db9f4 /src/systems | |
parent | f782b81ba10c9b7a1e221b16de0aaa7b6c521729 (diff) | |
download | therapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.tar.gz therapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.tar.bz2 therapy-8016a7146fec3f6f43ca05723441750e5aae3d4d.zip |
Restructured the way the world is loaded
The World class was removed and replaced by the RealizingSystem and RealizableComponent. The realizable entity is intended to be a singleton and to represent the world. The Map class was also removed and integrated into the MappableComponent. These changes are to facilitate implementation of map objects without needing special intermediary objects (including the Map class). Now, map entities are created as soon as the world is created, and map object entities will be as well. They will simply be deactivated while the map is not active. Multiple players are now slightly better supported, which will be important in the future. This will likely become inefficient as the world becomes bigger, and some sort of sector-loading process will have to be designed. This also reduces the usefulness of EntityManager's entity-searching capabilities (which are not the most efficiently implemented currently anyway), and will likely in the future require some added functionality to better search subsets of entities. A lot of the components were also rewritten to use bare member variables instead of accessor methods, as they never had special functionality and just took up space. These components were also documented.
Diffstat (limited to 'src/systems')
-rw-r--r-- | src/systems/animating.cpp | 93 | ||||
-rw-r--r-- | src/systems/animating.h | 2 | ||||
-rw-r--r-- | src/systems/mapping.cpp | 127 | ||||
-rw-r--r-- | src/systems/mapping.h | 2 | ||||
-rw-r--r-- | src/systems/orienting.cpp | 22 | ||||
-rw-r--r-- | src/systems/playing.cpp | 220 | ||||
-rw-r--r-- | src/systems/playing.h | 9 | ||||
-rw-r--r-- | src/systems/pondering.cpp | 354 | ||||
-rw-r--r-- | src/systems/pondering.h | 2 | ||||
-rw-r--r-- | src/systems/realizing.cpp | 321 | ||||
-rw-r--r-- | src/systems/realizing.h | 43 |
11 files changed, 800 insertions, 395 deletions
diff --git a/src/systems/animating.cpp b/src/systems/animating.cpp index 634af67..8543ba2 100644 --- a/src/systems/animating.cpp +++ b/src/systems/animating.cpp | |||
@@ -13,26 +13,29 @@ void AnimatingSystem::tick(double) | |||
13 | auto& sprite = game_.getEntityManager(). | 13 | auto& sprite = game_.getEntityManager(). |
14 | getComponent<AnimatableComponent>(entity); | 14 | getComponent<AnimatableComponent>(entity); |
15 | 15 | ||
16 | if (!sprite.isFrozen()) | 16 | if (sprite.active) |
17 | { | 17 | { |
18 | sprite.setCountdown(sprite.getCountdown() + 1); | 18 | if (!sprite.frozen) |
19 | } | 19 | { |
20 | 20 | sprite.countdown++; | |
21 | const Animation& anim = sprite.getAnimation(); | 21 | } |
22 | if (sprite.getCountdown() >= anim.getDelay()) | ||
23 | { | ||
24 | sprite.setFrame(sprite.getFrame() + 1); | ||
25 | sprite.setCountdown(0); | ||
26 | 22 | ||
27 | if (sprite.getFrame() >= anim.getFirstFrame() + anim.getNumFrames()) | 23 | const Animation& anim = sprite.getAnimation(); |
24 | if (sprite.countdown >= anim.getDelay()) | ||
28 | { | 25 | { |
29 | sprite.setFrame(anim.getFirstFrame()); | 26 | sprite.frame++; |
27 | sprite.countdown = 0; | ||
28 | |||
29 | if (sprite.frame >= anim.getFirstFrame() + anim.getNumFrames()) | ||
30 | { | ||
31 | sprite.frame = anim.getFirstFrame(); | ||
32 | } | ||
30 | } | 33 | } |
31 | } | ||
32 | 34 | ||
33 | if (sprite.isFlickering()) | 35 | if (sprite.flickering) |
34 | { | 36 | { |
35 | sprite.setFlickerTimer((sprite.getFlickerTimer() + 1) % 6); | 37 | sprite.flickerTimer = (sprite.flickerTimer + 1) % 6; |
38 | } | ||
36 | } | 39 | } |
37 | } | 40 | } |
38 | } | 41 | } |
@@ -49,36 +52,52 @@ void AnimatingSystem::render(Texture& texture) | |||
49 | auto& sprite = game_.getEntityManager(). | 52 | auto& sprite = game_.getEntityManager(). |
50 | getComponent<AnimatableComponent>(entity); | 53 | getComponent<AnimatableComponent>(entity); |
51 | 54 | ||
52 | auto& transform = game_.getEntityManager(). | 55 | if (sprite.active) |
53 | getComponent<TransformableComponent>(entity); | ||
54 | |||
55 | double alpha = 1.0; | ||
56 | if (sprite.isFlickering() && (sprite.getFlickerTimer() < 3)) | ||
57 | { | 56 | { |
58 | alpha = 0.0; | 57 | auto& transform = game_.getEntityManager(). |
59 | } | 58 | getComponent<TransformableComponent>(entity); |
60 | 59 | ||
61 | Rectangle dstrect { | 60 | double alpha = 1.0; |
62 | static_cast<int>(transform.getX()), | 61 | if (sprite.flickering && (sprite.flickerTimer < 3)) |
63 | static_cast<int>(transform.getY()), | 62 | { |
64 | transform.getW(), | 63 | alpha = 0.0; |
65 | transform.getH()}; | 64 | } |
66 | 65 | ||
67 | const AnimationSet& aset = sprite.getAnimationSet(); | 66 | Rectangle dstrect { |
68 | game_.getRenderer().blit( | 67 | static_cast<int>(transform.x), |
69 | aset.getTexture(), | 68 | static_cast<int>(transform.y), |
70 | texture, | 69 | transform.w, |
71 | aset.getFrameRect(sprite.getFrame()), | 70 | transform.h}; |
72 | dstrect, | 71 | |
73 | alpha); | 72 | const AnimationSet& aset = sprite.animationSet; |
73 | game_.getRenderer().blit( | ||
74 | aset.getTexture(), | ||
75 | texture, | ||
76 | aset.getFrameRect(sprite.frame), | ||
77 | dstrect, | ||
78 | alpha); | ||
79 | } | ||
74 | } | 80 | } |
75 | } | 81 | } |
76 | 82 | ||
83 | void AnimatingSystem::initPrototype(id_type entity) | ||
84 | { | ||
85 | auto& sprite = game_.getEntityManager(). | ||
86 | getComponent<AnimatableComponent>(entity); | ||
87 | |||
88 | startAnimation(entity, sprite.origAnimation); | ||
89 | |||
90 | sprite.countdown = 0; | ||
91 | sprite.flickering = false; | ||
92 | sprite.flickerTimer = 0; | ||
93 | sprite.frozen = false; | ||
94 | } | ||
95 | |||
77 | void AnimatingSystem::startAnimation(id_type entity, std::string animation) | 96 | void AnimatingSystem::startAnimation(id_type entity, std::string animation) |
78 | { | 97 | { |
79 | auto& sprite = game_.getEntityManager(). | 98 | auto& sprite = game_.getEntityManager(). |
80 | getComponent<AnimatableComponent>(entity); | 99 | getComponent<AnimatableComponent>(entity); |
81 | 100 | ||
82 | sprite.setAnimation(animation); | 101 | sprite.animation = std::move(animation); |
83 | sprite.setFrame(sprite.getAnimation().getFirstFrame()); | 102 | sprite.frame = sprite.getAnimation().getFirstFrame(); |
84 | } | 103 | } |
diff --git a/src/systems/animating.h b/src/systems/animating.h index 548bff1..acc6191 100644 --- a/src/systems/animating.h +++ b/src/systems/animating.h | |||
@@ -16,6 +16,8 @@ public: | |||
16 | 16 | ||
17 | void render(Texture& texture); | 17 | void render(Texture& texture); |
18 | 18 | ||
19 | void initPrototype(id_type entity); | ||
20 | |||
19 | void startAnimation(id_type entity, std::string animation); | 21 | void startAnimation(id_type entity, std::string animation); |
20 | 22 | ||
21 | }; | 23 | }; |
diff --git a/src/systems/mapping.cpp b/src/systems/mapping.cpp index a3a17ec..af67aed 100644 --- a/src/systems/mapping.cpp +++ b/src/systems/mapping.cpp | |||
@@ -1,5 +1,7 @@ | |||
1 | #include "mapping.h" | 1 | #include "mapping.h" |
2 | #include "components/mappable.h" | 2 | #include "components/mappable.h" |
3 | #include "components/realizable.h" | ||
4 | #include "systems/realizing.h" | ||
3 | #include "game.h" | 5 | #include "game.h" |
4 | #include "consts.h" | 6 | #include "consts.h" |
5 | 7 | ||
@@ -18,104 +20,95 @@ inline void addBoundary( | |||
18 | 20 | ||
19 | void MappingSystem::render(Texture& texture) | 21 | void MappingSystem::render(Texture& texture) |
20 | { | 22 | { |
21 | auto entities = game_.getEntityManager().getEntitiesWithComponents< | 23 | auto& realizable = game_.getEntityManager(). |
22 | MappableComponent>(); | 24 | getComponent<RealizableComponent>( |
25 | game_.getSystemManager().getSystem<RealizingSystem>().getSingleton()); | ||
23 | 26 | ||
24 | for (id_type entity : entities) | 27 | id_type map = realizable.activeMap; |
25 | { | ||
26 | auto& mappable = game_.getEntityManager(). | ||
27 | getComponent<MappableComponent>(entity); | ||
28 | 28 | ||
29 | const Map& map = game_.getWorld().getMap(mappable.getMapId()); | 29 | auto& mappable = game_.getEntityManager(). |
30 | getComponent<MappableComponent>(map); | ||
30 | 31 | ||
31 | for (int i = 0; i < MAP_WIDTH * MAP_HEIGHT; i++) | 32 | for (int i = 0; i < MAP_WIDTH * MAP_HEIGHT; i++) |
32 | { | 33 | { |
33 | int x = i % MAP_WIDTH; | 34 | int x = i % MAP_WIDTH; |
34 | int y = i / MAP_WIDTH; | 35 | int y = i / MAP_WIDTH; |
35 | int tile = map.getTiles()[i]; | 36 | int tile = mappable.tiles[i]; |
36 | |||
37 | if (tile > 0) | ||
38 | { | ||
39 | Rectangle dst { | ||
40 | x * TILE_WIDTH, | ||
41 | y * TILE_HEIGHT, | ||
42 | TILE_WIDTH, | ||
43 | TILE_HEIGHT}; | ||
44 | |||
45 | Rectangle src { | ||
46 | (tile % TILESET_COLS) * TILE_WIDTH, | ||
47 | (tile / TILESET_COLS) * TILE_HEIGHT, | ||
48 | TILE_WIDTH, | ||
49 | TILE_HEIGHT}; | ||
50 | |||
51 | game_.getRenderer().blit( | ||
52 | mappable.getTileset(), | ||
53 | texture, | ||
54 | std::move(src), | ||
55 | std::move(dst)); | ||
56 | } | ||
57 | } | ||
58 | 37 | ||
59 | int startX = ((GAME_WIDTH / TILE_WIDTH) / 2) - (map.getTitle().size() / 2); | 38 | if (tile > 0) |
60 | for (size_t i = 0; i < map.getTitle().size(); i++) | ||
61 | { | 39 | { |
62 | Rectangle src { | 40 | Rectangle dst { |
63 | (map.getTitle()[i] % FONT_COLS) * TILE_WIDTH, | 41 | x * TILE_WIDTH, |
64 | (map.getTitle()[i] / FONT_COLS) * TILE_HEIGHT, | 42 | y * TILE_HEIGHT, |
65 | TILE_WIDTH, | 43 | TILE_WIDTH, |
66 | TILE_HEIGHT}; | 44 | TILE_HEIGHT}; |
67 | 45 | ||
68 | Rectangle dst { | 46 | Rectangle src { |
69 | (startX + static_cast<int>(i)) * TILE_WIDTH, | 47 | (tile % TILESET_COLS) * TILE_WIDTH, |
70 | 24 * TILE_HEIGHT, | 48 | (tile / TILESET_COLS) * TILE_HEIGHT, |
71 | TILE_WIDTH, | 49 | TILE_WIDTH, |
72 | TILE_HEIGHT}; | 50 | TILE_HEIGHT}; |
73 | 51 | ||
74 | game_.getRenderer().blit( | 52 | game_.getRenderer().blit( |
75 | mappable.getFont(), | 53 | mappable.tileset, |
76 | texture, | 54 | texture, |
77 | std::move(src), | 55 | std::move(src), |
78 | std::move(dst)); | 56 | std::move(dst)); |
79 | } | 57 | } |
80 | } | 58 | } |
59 | |||
60 | int startX = ((GAME_WIDTH / TILE_WIDTH) / 2) - (mappable.title.size() / 2); | ||
61 | |||
62 | for (size_t i = 0; i < mappable.title.size(); i++) | ||
63 | { | ||
64 | Rectangle src { | ||
65 | (mappable.title[i] % FONT_COLS) * TILE_WIDTH, | ||
66 | (mappable.title[i] / FONT_COLS) * TILE_HEIGHT, | ||
67 | TILE_WIDTH, | ||
68 | TILE_HEIGHT}; | ||
69 | |||
70 | Rectangle dst { | ||
71 | (startX + static_cast<int>(i)) * TILE_WIDTH, | ||
72 | 24 * TILE_HEIGHT, | ||
73 | TILE_WIDTH, | ||
74 | TILE_HEIGHT}; | ||
75 | |||
76 | game_.getRenderer().blit( | ||
77 | mappable.font, | ||
78 | texture, | ||
79 | std::move(src), | ||
80 | std::move(dst)); | ||
81 | } | ||
81 | } | 82 | } |
82 | 83 | ||
83 | void MappingSystem::loadMap(size_t mapId) | 84 | void MappingSystem::generateBoundaries(id_type mapEntity) |
84 | { | 85 | { |
85 | id_type mapEntity = game_.getEntityManager().emplaceEntity(); | ||
86 | |||
87 | auto& mappable = game_.getEntityManager(). | 86 | auto& mappable = game_.getEntityManager(). |
88 | emplaceComponent<MappableComponent>(mapEntity, | 87 | getComponent<MappableComponent>(mapEntity); |
89 | Texture("res/tiles.png"), | ||
90 | Texture("res/font.bmp")); | ||
91 | |||
92 | mappable.setMapId(mapId); | ||
93 | |||
94 | const Map& map = game_.getWorld().getMap(mappable.getMapId()); | ||
95 | 88 | ||
96 | addBoundary( | 89 | addBoundary( |
97 | mappable.getLeftBoundaries(), | 90 | mappable.leftBoundaries, |
98 | -WALL_GAP, | 91 | -WALL_GAP, |
99 | 0, | 92 | 0, |
100 | MAP_HEIGHT * TILE_HEIGHT, | 93 | MAP_HEIGHT * TILE_HEIGHT, |
101 | MappableComponent::Boundary::Type::adjacency); | 94 | MappableComponent::Boundary::Type::adjacency); |
102 | 95 | ||
103 | addBoundary( | 96 | addBoundary( |
104 | mappable.getRightBoundaries(), | 97 | mappable.rightBoundaries, |
105 | GAME_WIDTH + WALL_GAP, | 98 | GAME_WIDTH + WALL_GAP, |
106 | 0, | 99 | 0, |
107 | MAP_HEIGHT * TILE_HEIGHT, | 100 | MAP_HEIGHT * TILE_HEIGHT, |
108 | MappableComponent::Boundary::Type::adjacency); | 101 | MappableComponent::Boundary::Type::adjacency); |
109 | 102 | ||
110 | addBoundary( | 103 | addBoundary( |
111 | mappable.getUpBoundaries(), | 104 | mappable.upBoundaries, |
112 | -WALL_GAP, | 105 | -WALL_GAP, |
113 | 0, | 106 | 0, |
114 | GAME_WIDTH, | 107 | GAME_WIDTH, |
115 | MappableComponent::Boundary::Type::adjacency); | 108 | MappableComponent::Boundary::Type::adjacency); |
116 | 109 | ||
117 | addBoundary( | 110 | addBoundary( |
118 | mappable.getDownBoundaries(), | 111 | mappable.downBoundaries, |
119 | MAP_HEIGHT * TILE_HEIGHT + WALL_GAP, | 112 | MAP_HEIGHT * TILE_HEIGHT + WALL_GAP, |
120 | 0, | 113 | 0, |
121 | GAME_WIDTH, | 114 | GAME_WIDTH, |
@@ -125,12 +118,12 @@ void MappingSystem::loadMap(size_t mapId) | |||
125 | { | 118 | { |
126 | size_t x = i % MAP_WIDTH; | 119 | size_t x = i % MAP_WIDTH; |
127 | size_t y = i / MAP_WIDTH; | 120 | size_t y = i / MAP_WIDTH; |
128 | int tile = map.getTiles()[i]; | 121 | int tile = mappable.tiles[i]; |
129 | 122 | ||
130 | if ((tile >= 5) && (tile <= 7)) | 123 | if ((tile >= 5) && (tile <= 7)) |
131 | { | 124 | { |
132 | addBoundary( | 125 | addBoundary( |
133 | mappable.getDownBoundaries(), | 126 | mappable.downBoundaries, |
134 | y * TILE_HEIGHT, | 127 | y * TILE_HEIGHT, |
135 | x * TILE_WIDTH, | 128 | x * TILE_WIDTH, |
136 | (x + 1) * TILE_WIDTH, | 129 | (x + 1) * TILE_WIDTH, |
@@ -138,28 +131,28 @@ void MappingSystem::loadMap(size_t mapId) | |||
138 | } else if ((tile > 0) && (tile < 28)) | 131 | } else if ((tile > 0) && (tile < 28)) |
139 | { | 132 | { |
140 | addBoundary( | 133 | addBoundary( |
141 | mappable.getRightBoundaries(), | 134 | mappable.rightBoundaries, |
142 | x * TILE_WIDTH, | 135 | x * TILE_WIDTH, |
143 | y * TILE_HEIGHT, | 136 | y * TILE_HEIGHT, |
144 | (y+1) * TILE_HEIGHT, | 137 | (y+1) * TILE_HEIGHT, |
145 | MappableComponent::Boundary::Type::wall); | 138 | MappableComponent::Boundary::Type::wall); |
146 | 139 | ||
147 | addBoundary( | 140 | addBoundary( |
148 | mappable.getLeftBoundaries(), | 141 | mappable.leftBoundaries, |
149 | (x+1) * TILE_WIDTH, | 142 | (x+1) * TILE_WIDTH, |
150 | y * TILE_HEIGHT, | 143 | y * TILE_HEIGHT, |
151 | (y+1) * TILE_HEIGHT, | 144 | (y+1) * TILE_HEIGHT, |
152 | MappableComponent::Boundary::Type::wall); | 145 | MappableComponent::Boundary::Type::wall); |
153 | 146 | ||
154 | addBoundary( | 147 | addBoundary( |
155 | mappable.getDownBoundaries(), | 148 | mappable.downBoundaries, |
156 | y * TILE_HEIGHT, | 149 | y * TILE_HEIGHT, |
157 | x * TILE_WIDTH, | 150 | x * TILE_WIDTH, |
158 | (x+1) * TILE_WIDTH, | 151 | (x+1) * TILE_WIDTH, |
159 | MappableComponent::Boundary::Type::wall); | 152 | MappableComponent::Boundary::Type::wall); |
160 | 153 | ||
161 | addBoundary( | 154 | addBoundary( |
162 | mappable.getUpBoundaries(), | 155 | mappable.upBoundaries, |
163 | (y+1) * TILE_HEIGHT, | 156 | (y+1) * TILE_HEIGHT, |
164 | x * TILE_WIDTH, | 157 | x * TILE_WIDTH, |
165 | (x+1) * TILE_WIDTH, | 158 | (x+1) * TILE_WIDTH, |
@@ -167,28 +160,28 @@ void MappingSystem::loadMap(size_t mapId) | |||
167 | } else if (tile == 42) | 160 | } else if (tile == 42) |
168 | { | 161 | { |
169 | addBoundary( | 162 | addBoundary( |
170 | mappable.getRightBoundaries(), | 163 | mappable.rightBoundaries, |
171 | x * TILE_WIDTH, | 164 | x * TILE_WIDTH, |
172 | y * TILE_HEIGHT, | 165 | y * TILE_HEIGHT, |
173 | (y+1) * TILE_HEIGHT, | 166 | (y+1) * TILE_HEIGHT, |
174 | MappableComponent::Boundary::Type::danger); | 167 | MappableComponent::Boundary::Type::danger); |
175 | 168 | ||
176 | addBoundary( | 169 | addBoundary( |
177 | mappable.getLeftBoundaries(), | 170 | mappable.leftBoundaries, |
178 | (x+1) * TILE_WIDTH, | 171 | (x+1) * TILE_WIDTH, |
179 | y * TILE_HEIGHT, | 172 | y * TILE_HEIGHT, |
180 | (y+1) * TILE_HEIGHT, | 173 | (y+1) * TILE_HEIGHT, |
181 | MappableComponent::Boundary::Type::danger); | 174 | MappableComponent::Boundary::Type::danger); |
182 | 175 | ||
183 | addBoundary( | 176 | addBoundary( |
184 | mappable.getDownBoundaries(), | 177 | mappable.downBoundaries, |
185 | y * TILE_HEIGHT, | 178 | y * TILE_HEIGHT, |
186 | x * TILE_WIDTH, | 179 | x * TILE_WIDTH, |
187 | (x+1) * TILE_WIDTH, | 180 | (x+1) * TILE_WIDTH, |
188 | MappableComponent::Boundary::Type::danger); | 181 | MappableComponent::Boundary::Type::danger); |
189 | 182 | ||
190 | addBoundary( | 183 | addBoundary( |
191 | mappable.getUpBoundaries(), | 184 | mappable.upBoundaries, |
192 | (y+1) * TILE_HEIGHT, | 185 | (y+1) * TILE_HEIGHT, |
193 | x * TILE_WIDTH, | 186 | x * TILE_WIDTH, |
194 | (x+1) * TILE_WIDTH, | 187 | (x+1) * TILE_WIDTH, |
diff --git a/src/systems/mapping.h b/src/systems/mapping.h index 53d054b..3c47419 100644 --- a/src/systems/mapping.h +++ b/src/systems/mapping.h | |||
@@ -12,7 +12,7 @@ public: | |||
12 | 12 | ||
13 | void render(Texture& texture); | 13 | void render(Texture& texture); |
14 | 14 | ||
15 | void loadMap(size_t mapId); | 15 | void generateBoundaries(id_type mapEntity); |
16 | 16 | ||
17 | }; | 17 | }; |
18 | 18 | ||
diff --git a/src/systems/orienting.cpp b/src/systems/orienting.cpp index 2df8f87..206ebf6 100644 --- a/src/systems/orienting.cpp +++ b/src/systems/orienting.cpp | |||
@@ -24,27 +24,27 @@ void OrientingSystem::tick(double) | |||
24 | { | 24 | { |
25 | case OrientableComponent::WalkState::still: | 25 | case OrientableComponent::WalkState::still: |
26 | { | 26 | { |
27 | ponderable.setVelocityX(0); | 27 | ponderable.velX = 0.0; |
28 | 28 | ||
29 | break; | 29 | break; |
30 | } | 30 | } |
31 | 31 | ||
32 | case OrientableComponent::WalkState::left: | 32 | case OrientableComponent::WalkState::left: |
33 | { | 33 | { |
34 | ponderable.setVelocityX(-WALK_SPEED); | 34 | ponderable.velX = -WALK_SPEED; |
35 | 35 | ||
36 | break; | 36 | break; |
37 | } | 37 | } |
38 | 38 | ||
39 | case OrientableComponent::WalkState::right: | 39 | case OrientableComponent::WalkState::right: |
40 | { | 40 | { |
41 | ponderable.setVelocityX(WALK_SPEED); | 41 | ponderable.velX = WALK_SPEED; |
42 | 42 | ||
43 | break; | 43 | break; |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | if (orientable.isJumping() && (ponderable.getVelocityY() > 0)) | 47 | if (orientable.isJumping() && (ponderable.velY > 0)) |
48 | { | 48 | { |
49 | orientable.setJumping(false); | 49 | orientable.setJumping(false); |
50 | } | 50 | } |
@@ -63,7 +63,7 @@ void OrientingSystem::moveLeft(id_type entity) | |||
63 | orientable.setWalkState(OrientableComponent::WalkState::left); | 63 | orientable.setWalkState(OrientableComponent::WalkState::left); |
64 | 64 | ||
65 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); | 65 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); |
66 | if (ponderable.isGrounded()) | 66 | if (ponderable.grounded) |
67 | { | 67 | { |
68 | animating.startAnimation(entity, "walkingLeft"); | 68 | animating.startAnimation(entity, "walkingLeft"); |
69 | } else { | 69 | } else { |
@@ -83,7 +83,7 @@ void OrientingSystem::moveRight(id_type entity) | |||
83 | orientable.setWalkState(OrientableComponent::WalkState::right); | 83 | orientable.setWalkState(OrientableComponent::WalkState::right); |
84 | 84 | ||
85 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); | 85 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); |
86 | if (ponderable.isGrounded()) | 86 | if (ponderable.grounded) |
87 | { | 87 | { |
88 | animating.startAnimation(entity, "walkingRight"); | 88 | animating.startAnimation(entity, "walkingRight"); |
89 | } else { | 89 | } else { |
@@ -113,7 +113,7 @@ void OrientingSystem::jump(id_type entity) | |||
113 | auto& ponderable = game_.getEntityManager(). | 113 | auto& ponderable = game_.getEntityManager(). |
114 | getComponent<PonderableComponent>(entity); | 114 | getComponent<PonderableComponent>(entity); |
115 | 115 | ||
116 | if (ponderable.isGrounded()) | 116 | if (ponderable.grounded) |
117 | { | 117 | { |
118 | auto& orientable = game_.getEntityManager(). | 118 | auto& orientable = game_.getEntityManager(). |
119 | getComponent<OrientableComponent>(entity); | 119 | getComponent<OrientableComponent>(entity); |
@@ -122,8 +122,8 @@ void OrientingSystem::jump(id_type entity) | |||
122 | 122 | ||
123 | playSound("res/Randomize87.wav", 0.25); | 123 | playSound("res/Randomize87.wav", 0.25); |
124 | 124 | ||
125 | ponderable.setVelocityY(JUMP_VELOCITY); | 125 | ponderable.velY = JUMP_VELOCITY; |
126 | ponderable.setAccelY(JUMP_GRAVITY); | 126 | ponderable.accelY = JUMP_GRAVITY; |
127 | 127 | ||
128 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); | 128 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); |
129 | if (orientable.isFacingRight()) | 129 | if (orientable.isFacingRight()) |
@@ -147,7 +147,7 @@ void OrientingSystem::stopJumping(id_type entity) | |||
147 | auto& ponderable = game_.getEntityManager(). | 147 | auto& ponderable = game_.getEntityManager(). |
148 | getComponent<PonderableComponent>(entity); | 148 | getComponent<PonderableComponent>(entity); |
149 | 149 | ||
150 | ponderable.setAccelY(NORMAL_GRAVITY); | 150 | ponderable.accelY = NORMAL_GRAVITY; |
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
@@ -211,7 +211,7 @@ void OrientingSystem::drop(id_type entity) | |||
211 | auto& ponderable = game_.getEntityManager(). | 211 | auto& ponderable = game_.getEntityManager(). |
212 | getComponent<PonderableComponent>(entity); | 212 | getComponent<PonderableComponent>(entity); |
213 | 213 | ||
214 | if (ponderable.isGrounded() | 214 | if (ponderable.grounded |
215 | && (orientable.getDropState() == OrientableComponent::DropState::none)) | 215 | && (orientable.getDropState() == OrientableComponent::DropState::none)) |
216 | { | 216 | { |
217 | orientable.setDropState(OrientableComponent::DropState::ready); | 217 | orientable.setDropState(OrientableComponent::DropState::ready); |
diff --git a/src/systems/playing.cpp b/src/systems/playing.cpp index 40d9706..b04f0cb 100644 --- a/src/systems/playing.cpp +++ b/src/systems/playing.cpp | |||
@@ -5,61 +5,17 @@ | |||
5 | #include "components/playable.h" | 5 | #include "components/playable.h" |
6 | #include "components/controllable.h" | 6 | #include "components/controllable.h" |
7 | #include "components/orientable.h" | 7 | #include "components/orientable.h" |
8 | #include "components/realizable.h" | ||
8 | #include "systems/mapping.h" | 9 | #include "systems/mapping.h" |
9 | #include "systems/pondering.h" | 10 | #include "systems/pondering.h" |
10 | #include "systems/orienting.h" | 11 | #include "systems/orienting.h" |
11 | #include "systems/scheduling.h" | 12 | #include "systems/scheduling.h" |
12 | #include "systems/controlling.h" | 13 | #include "systems/controlling.h" |
14 | #include "systems/animating.h" | ||
15 | #include "systems/realizing.h" | ||
13 | #include "animation.h" | 16 | #include "animation.h" |
14 | #include "muxer.h" | 17 | #include "muxer.h" |
15 | 18 | ||
16 | void PlayingSystem::tick(double) | ||
17 | { | ||
18 | // Check if we need to change the map | ||
19 | auto players = game_.getEntityManager().getEntitiesWithComponents< | ||
20 | PlayableComponent, | ||
21 | TransformableComponent>(); | ||
22 | |||
23 | for (id_type player : players) | ||
24 | { | ||
25 | auto& playable = game_.getEntityManager(). | ||
26 | getComponent<PlayableComponent>(player); | ||
27 | |||
28 | if (playable.changingMap) | ||
29 | { | ||
30 | // Change the map! | ||
31 | auto entities = game_.getEntityManager().getEntities(); | ||
32 | |||
33 | for (id_type entity : entities) | ||
34 | { | ||
35 | if (entity != player) | ||
36 | { | ||
37 | game_.getEntityManager().deleteEntity(entity); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | game_.getSystemManager().getSystem<MappingSystem>(). | ||
42 | loadMap(playable.newMapId); | ||
43 | |||
44 | auto& transformable = game_.getEntityManager(). | ||
45 | getComponent<TransformableComponent>(player); | ||
46 | |||
47 | transformable.setX(playable.newMapX); | ||
48 | transformable.setY(playable.newMapY); | ||
49 | |||
50 | playable.changingMap = false; | ||
51 | |||
52 | if (playable.newMapCallback) | ||
53 | { | ||
54 | playable.newMapCallback(); | ||
55 | playable.newMapCallback = nullptr; | ||
56 | } | ||
57 | |||
58 | break; | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | void PlayingSystem::initPlayer() | 19 | void PlayingSystem::initPlayer() |
64 | { | 20 | { |
65 | id_type player = game_.getEntityManager().emplaceEntity(); | 21 | id_type player = game_.getEntityManager().emplaceEntity(); |
@@ -72,15 +28,24 @@ void PlayingSystem::initPlayer() | |||
72 | 28 | ||
73 | game_.getEntityManager().emplaceComponent<AnimatableComponent>( | 29 | game_.getEntityManager().emplaceComponent<AnimatableComponent>( |
74 | player, | 30 | player, |
75 | std::move(playerGraphics), | 31 | std::move(playerGraphics)); |
76 | "stillLeft"); | ||
77 | 32 | ||
78 | game_.getEntityManager().emplaceComponent<TransformableComponent>( | 33 | game_.getSystemManager().getSystem<AnimatingSystem>().startAnimation( |
79 | player, | 34 | player, |
80 | game_.getWorld().getStartingX(), | 35 | "stillLeft"); |
81 | game_.getWorld().getStartingY(), | 36 | |
82 | 10, | 37 | auto& realizing = game_.getSystemManager().getSystem<RealizingSystem>(); |
83 | 12); | 38 | |
39 | auto& realizable = game_.getEntityManager(). | ||
40 | getComponent<RealizableComponent>(realizing.getSingleton()); | ||
41 | |||
42 | auto& transformable = game_.getEntityManager(). | ||
43 | emplaceComponent<TransformableComponent>(player); | ||
44 | |||
45 | transformable.x = realizable.startingX; | ||
46 | transformable.y = realizable.startingY; | ||
47 | transformable.w = 10; | ||
48 | transformable.h = 12; | ||
84 | 49 | ||
85 | game_.getSystemManager().getSystem<PonderingSystem>().initializeBody( | 50 | game_.getSystemManager().getSystem<PonderingSystem>().initializeBody( |
86 | player, | 51 | player, |
@@ -92,84 +57,103 @@ void PlayingSystem::initPlayer() | |||
92 | auto& playable = game_.getEntityManager(). | 57 | auto& playable = game_.getEntityManager(). |
93 | emplaceComponent<PlayableComponent>(player); | 58 | emplaceComponent<PlayableComponent>(player); |
94 | 59 | ||
95 | playable.checkpointMapId = game_.getWorld().getStartingMapId(); | 60 | playable.mapId = realizable.activeMap; |
96 | playable.checkpointX = game_.getWorld().getStartingX(); | 61 | playable.checkpointMapId = realizable.startingMapId; |
97 | playable.checkpointY = game_.getWorld().getStartingY(); | 62 | playable.checkpointX = realizable.startingX; |
63 | playable.checkpointY = realizable.startingY; | ||
64 | |||
65 | realizing.enterActiveMap(player); | ||
66 | |||
67 | realizable.activePlayer = player; | ||
98 | } | 68 | } |
99 | 69 | ||
100 | void PlayingSystem::changeMap( | 70 | void PlayingSystem::changeMap( |
71 | id_type player, | ||
101 | size_t mapId, | 72 | size_t mapId, |
102 | double x, | 73 | double x, |
103 | double y, | 74 | double y) |
104 | PlayableComponent::MapChangeCallback callback) | ||
105 | { | 75 | { |
106 | auto players = game_.getEntityManager().getEntitiesWithComponents< | 76 | auto& playable = game_.getEntityManager(). |
107 | PlayableComponent>(); | 77 | getComponent<PlayableComponent>(player); |
108 | 78 | ||
109 | for (id_type player : players) | 79 | auto& transformable = game_.getEntityManager(). |
80 | getComponent<TransformableComponent>(player); | ||
81 | |||
82 | auto& animatable = game_.getEntityManager(). | ||
83 | getComponent<AnimatableComponent>(player); | ||
84 | |||
85 | auto& ponderable = game_.getEntityManager(). | ||
86 | getComponent<PonderableComponent>(player); | ||
87 | |||
88 | auto& realizing = game_.getSystemManager().getSystem<RealizingSystem>(); | ||
89 | |||
90 | auto& realizable = game_.getEntityManager(). | ||
91 | getComponent<RealizableComponent>(realizing.getSingleton()); | ||
92 | |||
93 | id_type newMapEntity = realizable.entityByMapId[mapId]; | ||
94 | |||
95 | if (playable.mapId != newMapEntity) | ||
110 | { | 96 | { |
111 | auto& playable = game_.getEntityManager(). | 97 | if (playable.mapId == realizable.activeMap) |
112 | getComponent<PlayableComponent>(player); | 98 | { |
99 | realizing.leaveActiveMap(player); | ||
100 | } else if (newMapEntity == realizable.activeMap) | ||
101 | { | ||
102 | realizing.enterActiveMap(player); | ||
103 | } | ||
113 | 104 | ||
114 | playable.changingMap = true; | 105 | playable.mapId = newMapEntity; |
115 | playable.newMapId = mapId; | 106 | } |
116 | playable.newMapX = x; | 107 | |
117 | playable.newMapY = y; | 108 | transformable.x = x; |
118 | playable.newMapCallback = std::move(callback); | 109 | transformable.y = y; |
110 | |||
111 | if (realizable.activePlayer == player) | ||
112 | { | ||
113 | realizing.loadMap(newMapEntity); | ||
119 | } | 114 | } |
120 | } | 115 | } |
121 | 116 | ||
122 | void PlayingSystem::die() | 117 | void PlayingSystem::die(id_type player) |
123 | { | 118 | { |
124 | playSound("res/Hit_Hurt5.wav", 0.25); | 119 | playSound("res/Hit_Hurt5.wav", 0.25); |
125 | 120 | ||
126 | auto players = game_.getEntityManager().getEntitiesWithComponents< | 121 | auto& animatable = game_.getEntityManager(). |
127 | OrientableComponent, | 122 | getComponent<AnimatableComponent>(player); |
128 | ControllableComponent, | ||
129 | AnimatableComponent, | ||
130 | PonderableComponent, | ||
131 | PlayableComponent>(); | ||
132 | 123 | ||
133 | for (id_type player : players) | 124 | auto& ponderable = game_.getEntityManager(). |
134 | { | 125 | getComponent<PonderableComponent>(player); |
135 | auto& animatable = game_.getEntityManager(). | 126 | |
136 | getComponent<AnimatableComponent>(player); | 127 | auto& controlling = game_.getSystemManager().getSystem<ControllingSystem>(); |
137 | 128 | controlling.freeze(player); | |
138 | auto& ponderable = game_.getEntityManager(). | 129 | |
139 | getComponent<PonderableComponent>(player); | 130 | animatable.frozen = true; |
140 | 131 | animatable.flickering = true; | |
141 | auto& controlling = game_.getSystemManager().getSystem<ControllingSystem>(); | 132 | ponderable.frozen = true; |
142 | controlling.freeze(player); | 133 | ponderable.collidable = false; |
143 | 134 | ||
144 | animatable.setFrozen(true); | 135 | auto& scheduling = game_.getSystemManager().getSystem<SchedulingSystem>(); |
145 | animatable.setFlickering(true); | 136 | |
146 | ponderable.setFrozen(true); | 137 | scheduling.schedule(player, 0.75, [&] (id_type player) { |
147 | ponderable.setCollidable(false); | 138 | auto& playable = game_.getEntityManager(). |
148 | 139 | getComponent<PlayableComponent>(player); | |
149 | auto& scheduling = game_.getSystemManager().getSystem<SchedulingSystem>(); | 140 | |
150 | 141 | changeMap( | |
151 | scheduling.schedule(player, 0.75, [&] (id_type player) { | 142 | player, |
152 | auto& playable = game_.getEntityManager(). | 143 | playable.checkpointMapId, |
153 | getComponent<PlayableComponent>(player); | 144 | playable.checkpointX, |
154 | 145 | playable.checkpointY); | |
155 | changeMap( | 146 | |
156 | playable.checkpointMapId, | 147 | animatable.frozen = false; |
157 | playable.checkpointX, | 148 | animatable.flickering = false; |
158 | playable.checkpointY, | 149 | ponderable.frozen = false; |
159 | [&, player] () { | 150 | ponderable.collidable = true; |
160 | animatable.setFrozen(false); | 151 | |
161 | animatable.setFlickering(false); | 152 | // Reset the walk state, and then potentially let the |
162 | ponderable.setFrozen(false); | 153 | // ControllingSystem set it again. |
163 | ponderable.setCollidable(true); | 154 | auto& orienting = game_.getSystemManager().getSystem<OrientingSystem>(); |
164 | 155 | orienting.stopWalking(player); | |
165 | // Reset the walk state, and then potentially let the | 156 | |
166 | // ControllingSystem set it again. | 157 | controlling.unfreeze(player); |
167 | auto& orienting = game_.getSystemManager(). | 158 | }); |
168 | getSystem<OrientingSystem>(); | ||
169 | orienting.stopWalking(player); | ||
170 | |||
171 | controlling.unfreeze(player); | ||
172 | }); | ||
173 | }); | ||
174 | } | ||
175 | } | 159 | } |
diff --git a/src/systems/playing.h b/src/systems/playing.h index ff16808..9ba403b 100644 --- a/src/systems/playing.h +++ b/src/systems/playing.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define PLAYING_H_70A54F7D | 2 | #define PLAYING_H_70A54F7D |
3 | 3 | ||
4 | #include "system.h" | 4 | #include "system.h" |
5 | #include "components/playable.h" | ||
6 | 5 | ||
7 | class PlayingSystem : public System { | 6 | class PlayingSystem : public System { |
8 | public: | 7 | public: |
@@ -11,17 +10,15 @@ public: | |||
11 | { | 10 | { |
12 | } | 11 | } |
13 | 12 | ||
14 | void tick(double dt); | ||
15 | |||
16 | void initPlayer(); | 13 | void initPlayer(); |
17 | 14 | ||
18 | void changeMap( | 15 | void changeMap( |
16 | id_type player, | ||
19 | size_t mapId, | 17 | size_t mapId, |
20 | double x, | 18 | double x, |
21 | double y, | 19 | double y); |
22 | PlayableComponent::MapChangeCallback callback = nullptr); | ||
23 | 20 | ||
24 | void die(); | 21 | void die(id_type player); |
25 | 22 | ||
26 | }; | 23 | }; |
27 | 24 | ||
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index 02d5cfc..4ae6176 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp | |||
@@ -5,149 +5,153 @@ | |||
5 | #include "components/transformable.h" | 5 | #include "components/transformable.h" |
6 | #include "components/orientable.h" | 6 | #include "components/orientable.h" |
7 | #include "components/mappable.h" | 7 | #include "components/mappable.h" |
8 | #include "components/realizable.h" | ||
9 | #include "components/playable.h" | ||
8 | #include "systems/orienting.h" | 10 | #include "systems/orienting.h" |
9 | #include "systems/playing.h" | 11 | #include "systems/playing.h" |
12 | #include "systems/realizing.h" | ||
10 | #include "consts.h" | 13 | #include "consts.h" |
11 | #include "collision.h" | 14 | #include "collision.h" |
12 | 15 | ||
13 | void PonderingSystem::tick(double dt) | 16 | void PonderingSystem::tick(double dt) |
14 | { | 17 | { |
18 | auto& realizable = game_.getEntityManager(). | ||
19 | getComponent<RealizableComponent>( | ||
20 | game_.getSystemManager().getSystem<RealizingSystem>().getSingleton()); | ||
21 | |||
22 | id_type mapEntity = realizable.activeMap; | ||
23 | |||
24 | auto& mappable = game_.getEntityManager(). | ||
25 | getComponent<MappableComponent>(mapEntity); | ||
26 | |||
15 | auto entities = game_.getEntityManager().getEntitiesWithComponents< | 27 | auto entities = game_.getEntityManager().getEntitiesWithComponents< |
16 | PonderableComponent, | 28 | PonderableComponent, |
17 | TransformableComponent>(); | 29 | TransformableComponent>(); |
18 | 30 | ||
19 | auto maps = game_.getEntityManager().getEntitiesWithComponents< | ||
20 | MappableComponent>(); | ||
21 | |||
22 | for (id_type entity : entities) | 31 | for (id_type entity : entities) |
23 | { | 32 | { |
24 | auto& transformable = game_.getEntityManager(). | ||
25 | getComponent<TransformableComponent>(entity); | ||
26 | |||
27 | auto& ponderable = game_.getEntityManager(). | 33 | auto& ponderable = game_.getEntityManager(). |
28 | getComponent<PonderableComponent>(entity); | 34 | getComponent<PonderableComponent>(entity); |
29 | 35 | ||
30 | if (ponderable.isFrozen()) | 36 | if (!ponderable.active || ponderable.frozen) |
31 | { | 37 | { |
32 | continue; | 38 | continue; |
33 | } | 39 | } |
34 | 40 | ||
35 | // Accelerate | 41 | auto& transformable = game_.getEntityManager(). |
36 | ponderable.setVelocityX( | 42 | getComponent<TransformableComponent>(entity); |
37 | ponderable.getVelocityX() + ponderable.getAccelX() * dt); | ||
38 | 43 | ||
39 | ponderable.setVelocityY( | 44 | // Accelerate |
40 | ponderable.getVelocityY() + ponderable.getAccelY() * dt); | 45 | ponderable.velX += ponderable.accelX * dt; |
46 | ponderable.velY += ponderable.accelY * dt; | ||
41 | 47 | ||
42 | if ((ponderable.getType() == PonderableComponent::Type::freefalling) | 48 | if ((ponderable.type == PonderableComponent::Type::freefalling) |
43 | && (ponderable.getVelocityY() > TERMINAL_VELOCITY)) | 49 | && (ponderable.velY > TERMINAL_VELOCITY)) |
44 | { | 50 | { |
45 | ponderable.setVelocityY(TERMINAL_VELOCITY); | 51 | ponderable.velY = TERMINAL_VELOCITY; |
46 | } | 52 | } |
47 | 53 | ||
48 | const double oldX = transformable.getX(); | 54 | const double oldX = transformable.x; |
49 | const double oldY = transformable.getY(); | 55 | const double oldY = transformable.y; |
50 | const double oldRight = oldX + transformable.getW(); | 56 | const double oldRight = oldX + transformable.w; |
51 | const double oldBottom = oldY + transformable.getH(); | 57 | const double oldBottom = oldY + transformable.h; |
52 | 58 | ||
53 | double newX = oldX + ponderable.getVelocityX() * dt; | 59 | double newX = oldX + ponderable.velX * dt; |
54 | double newY = oldY + ponderable.getVelocityY() * dt; | 60 | double newY = oldY + ponderable.velY * dt; |
55 | 61 | ||
56 | bool oldGrounded = ponderable.isGrounded(); | 62 | bool oldGrounded = ponderable.grounded; |
57 | ponderable.setGrounded(false); | 63 | ponderable.grounded = false; |
58 | 64 | ||
59 | std::priority_queue<Collision> collisions; | 65 | std::priority_queue<Collision> collisions; |
60 | 66 | ||
61 | // Find collisions | 67 | // Find collisions |
62 | for (id_type mapEntity : maps) | 68 | if (newX < oldX) |
63 | { | 69 | { |
64 | auto& mappable = game_.getEntityManager(). | 70 | for (auto it = mappable.leftBoundaries.lower_bound(oldX); |
65 | getComponent<MappableComponent>(mapEntity); | 71 | (it != std::end(mappable.leftBoundaries)) && (it->first >= newX); |
66 | 72 | it++) | |
67 | if (newX < oldX) | ||
68 | { | 73 | { |
69 | for (auto it = mappable.getLeftBoundaries().lower_bound(oldX); | 74 | if ((oldBottom > it->second.lower) |
70 | (it != std::end(mappable.getLeftBoundaries())) && (it->first >= newX); | 75 | && (oldY < it->second.upper)) |
71 | it++) | ||
72 | { | 76 | { |
73 | if ((oldBottom > it->second.getLower()) | 77 | // We have a collision! |
74 | && (oldY < it->second.getUpper())) | 78 | collisions.emplace( |
75 | { | 79 | mapEntity, |
76 | // We have a collision! | 80 | Direction::left, |
77 | collisions.emplace( | 81 | it->second.type, |
78 | mapEntity, | 82 | it->first, |
79 | Direction::left, | 83 | it->second.lower, |
80 | it->second.getType(), | 84 | it->second.upper); |
81 | it->first, | ||
82 | it->second.getLower(), | ||
83 | it->second.getUpper()); | ||
84 | } | ||
85 | } | 85 | } |
86 | } else if (newX > oldX) | 86 | } |
87 | } else if (newX > oldX) | ||
88 | { | ||
89 | for (auto it = mappable.rightBoundaries.lower_bound(oldRight); | ||
90 | (it != std::end(mappable.rightBoundaries)) | ||
91 | && (it->first <= (newX + transformable.w)); | ||
92 | it++) | ||
87 | { | 93 | { |
88 | for (auto it = mappable.getRightBoundaries().lower_bound(oldRight); | 94 | if ((oldBottom > it->second.lower) |
89 | (it != std::end(mappable.getRightBoundaries())) | 95 | && (oldY < it->second.upper)) |
90 | && (it->first <= (newX + transformable.getW())); | ||
91 | it++) | ||
92 | { | 96 | { |
93 | if ((oldBottom > it->second.getLower()) | 97 | // We have a collision! |
94 | && (oldY < it->second.getUpper())) | 98 | collisions.emplace( |
95 | { | 99 | mapEntity, |
96 | // We have a collision! | 100 | Direction::right, |
97 | collisions.emplace( | 101 | it->second.type, |
98 | mapEntity, | 102 | it->first, |
99 | Direction::right, | 103 | it->second.lower, |
100 | it->second.getType(), | 104 | it->second.upper); |
101 | it->first, | ||
102 | it->second.getLower(), | ||
103 | it->second.getUpper()); | ||
104 | } | ||
105 | } | 105 | } |
106 | } | 106 | } |
107 | } | ||
107 | 108 | ||
108 | if (newY < oldY) | 109 | if (newY < oldY) |
110 | { | ||
111 | for (auto it = mappable.upBoundaries.lower_bound(oldY); | ||
112 | (it != std::end(mappable.upBoundaries)) && (it->first >= newY); | ||
113 | it++) | ||
109 | { | 114 | { |
110 | for (auto it = mappable.getUpBoundaries().lower_bound(oldY); | 115 | if ((oldRight > it->second.lower) |
111 | (it != std::end(mappable.getUpBoundaries())) && (it->first >= newY); | 116 | && (oldX < it->second.upper)) |
112 | it++) | ||
113 | { | 117 | { |
114 | if ((oldRight > it->second.getLower()) | 118 | // We have a collision! |
115 | && (oldX < it->second.getUpper())) | 119 | collisions.emplace( |
116 | { | 120 | mapEntity, |
117 | // We have a collision! | 121 | Direction::up, |
118 | collisions.emplace( | 122 | it->second.type, |
119 | mapEntity, | 123 | it->first, |
120 | Direction::up, | 124 | it->second.lower, |
121 | it->second.getType(), | 125 | it->second.upper); |
122 | it->first, | ||
123 | it->second.getLower(), | ||
124 | it->second.getUpper()); | ||
125 | } | ||
126 | } | 126 | } |
127 | } else if (newY > oldY) | 127 | } |
128 | } else if (newY > oldY) | ||
129 | { | ||
130 | for (auto it = mappable.downBoundaries.lower_bound(oldBottom); | ||
131 | (it != std::end(mappable.downBoundaries)) | ||
132 | && (it->first <= (newY + transformable.h)); | ||
133 | it++) | ||
128 | { | 134 | { |
129 | for (auto it = mappable.getDownBoundaries().lower_bound(oldBottom); | 135 | if ((oldRight > it->second.lower) |
130 | (it != std::end(mappable.getDownBoundaries())) | 136 | && (oldX < it->second.upper)) |
131 | && (it->first <= (newY + transformable.getH())); | ||
132 | it++) | ||
133 | { | 137 | { |
134 | if ((oldRight > it->second.getLower()) | 138 | // We have a collision! |
135 | && (oldX < it->second.getUpper())) | 139 | collisions.emplace( |
136 | { | 140 | mapEntity, |
137 | // We have a collision! | 141 | Direction::down, |
138 | collisions.emplace( | 142 | it->second.type, |
139 | mapEntity, | 143 | it->first, |
140 | Direction::down, | 144 | it->second.lower, |
141 | it->second.getType(), | 145 | it->second.upper); |
142 | it->first, | ||
143 | it->second.getLower(), | ||
144 | it->second.getUpper()); | ||
145 | } | ||
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | // Process collisions in order of priority | 150 | // Process collisions in order of priority |
151 | bool adjacentlyWarping = false; | ||
152 | Direction adjWarpDir; | ||
153 | size_t adjWarpMapId; | ||
154 | |||
151 | while (!collisions.empty()) | 155 | while (!collisions.empty()) |
152 | { | 156 | { |
153 | Collision collision = collisions.top(); | 157 | Collision collision = collisions.top(); |
@@ -157,8 +161,8 @@ void PonderingSystem::tick(double dt) | |||
157 | if (!collision.isColliding( | 161 | if (!collision.isColliding( |
158 | newX, | 162 | newX, |
159 | newY, | 163 | newY, |
160 | transformable.getW(), | 164 | transformable.w, |
161 | transformable.getH())) | 165 | transformable.h)) |
162 | { | 166 | { |
163 | continue; | 167 | continue; |
164 | } | 168 | } |
@@ -201,33 +205,33 @@ void PonderingSystem::tick(double dt) | |||
201 | { | 205 | { |
202 | auto& mappable = game_.getEntityManager(). | 206 | auto& mappable = game_.getEntityManager(). |
203 | getComponent<MappableComponent>(collision.getCollider()); | 207 | getComponent<MappableComponent>(collision.getCollider()); |
204 | const Map& map = game_.getWorld().getMap(mappable.getMapId()); | 208 | |
205 | auto& adj = [&] () -> const Map::Adjacent& { | 209 | auto& adj = [&] () -> const MappableComponent::Adjacent& { |
206 | switch (collision.getDirection()) | 210 | switch (collision.getDirection()) |
207 | { | 211 | { |
208 | case Direction::left: return map.getLeftAdjacent(); | 212 | case Direction::left: return mappable.leftAdjacent; |
209 | case Direction::right: return map.getRightAdjacent(); | 213 | case Direction::right: return mappable.rightAdjacent; |
210 | case Direction::up: return map.getUpAdjacent(); | 214 | case Direction::up: return mappable.upAdjacent; |
211 | case Direction::down: return map.getDownAdjacent(); | 215 | case Direction::down: return mappable.downAdjacent; |
212 | } | 216 | } |
213 | }(); | 217 | }(); |
214 | 218 | ||
215 | switch (adj.getType()) | 219 | switch (adj.type) |
216 | { | 220 | { |
217 | case Map::Adjacent::Type::wall: | 221 | case MappableComponent::Adjacent::Type::wall: |
218 | { | 222 | { |
219 | touchedWall = true; | 223 | touchedWall = true; |
220 | 224 | ||
221 | break; | 225 | break; |
222 | } | 226 | } |
223 | 227 | ||
224 | case Map::Adjacent::Type::wrap: | 228 | case MappableComponent::Adjacent::Type::wrap: |
225 | { | 229 | { |
226 | switch (collision.getDirection()) | 230 | switch (collision.getDirection()) |
227 | { | 231 | { |
228 | case Direction::left: | 232 | case Direction::left: |
229 | { | 233 | { |
230 | newX = GAME_WIDTH + WALL_GAP - transformable.getW(); | 234 | newX = GAME_WIDTH + WALL_GAP - transformable.w; |
231 | 235 | ||
232 | break; | 236 | break; |
233 | } | 237 | } |
@@ -241,8 +245,7 @@ void PonderingSystem::tick(double dt) | |||
241 | 245 | ||
242 | case Direction::up: | 246 | case Direction::up: |
243 | { | 247 | { |
244 | newY = MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - | 248 | newY = MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - transformable.h; |
245 | transformable.getH(); | ||
246 | 249 | ||
247 | break; | 250 | break; |
248 | } | 251 | } |
@@ -256,46 +259,22 @@ void PonderingSystem::tick(double dt) | |||
256 | } | 259 | } |
257 | } | 260 | } |
258 | 261 | ||
259 | case Map::Adjacent::Type::warp: | 262 | case MappableComponent::Adjacent::Type::warp: |
260 | { | 263 | { |
261 | double warpX = newX; | 264 | if (game_.getEntityManager(). |
262 | double warpY = newY; | 265 | hasComponent<PlayableComponent>(entity)) |
263 | |||
264 | switch (collision.getDirection()) | ||
265 | { | 266 | { |
266 | case Direction::left: | 267 | adjacentlyWarping = true; |
267 | { | 268 | adjWarpDir = collision.getDirection(); |
268 | warpX = GAME_WIDTH + WALL_GAP - transformable.getW(); | 269 | adjWarpMapId = adj.mapId; |
269 | |||
270 | break; | ||
271 | } | ||
272 | |||
273 | case Direction::right: | ||
274 | { | ||
275 | warpX = -WALL_GAP; | ||
276 | |||
277 | break; | ||
278 | } | ||
279 | |||
280 | case Direction::up: | ||
281 | { | ||
282 | warpY = MAP_HEIGHT * TILE_HEIGHT - transformable.getH(); | ||
283 | |||
284 | break; | ||
285 | } | ||
286 | |||
287 | case Direction::down: | ||
288 | { | ||
289 | warpY = -WALL_GAP; | ||
290 | |||
291 | break; | ||
292 | } | ||
293 | } | 270 | } |
294 | 271 | ||
295 | game_.getSystemManager().getSystem<PlayingSystem>(). | 272 | break; |
296 | changeMap(adj.getMapId(), warpX, warpY); | 273 | } |
297 | 274 | ||
298 | stopProcessing = true; | 275 | case MappableComponent::Adjacent::Type::reverse: |
276 | { | ||
277 | // TODO: not yet implemented. | ||
299 | 278 | ||
300 | break; | 279 | break; |
301 | } | 280 | } |
@@ -306,7 +285,13 @@ void PonderingSystem::tick(double dt) | |||
306 | 285 | ||
307 | case Collision::Type::danger: | 286 | case Collision::Type::danger: |
308 | { | 287 | { |
309 | game_.getSystemManager().getSystem<PlayingSystem>().die(); | 288 | if (game_.getEntityManager(). |
289 | hasComponent<PlayableComponent>(entity)) | ||
290 | { | ||
291 | game_.getSystemManager().getSystem<PlayingSystem>().die(entity); | ||
292 | |||
293 | adjacentlyWarping = false; | ||
294 | } | ||
310 | 295 | ||
311 | stopProcessing = true; | 296 | stopProcessing = true; |
312 | 297 | ||
@@ -333,15 +318,15 @@ void PonderingSystem::tick(double dt) | |||
333 | case Direction::left: | 318 | case Direction::left: |
334 | { | 319 | { |
335 | newX = collision.getAxis(); | 320 | newX = collision.getAxis(); |
336 | ponderable.setVelocityX(0.0); | 321 | ponderable.velX = 0.0; |
337 | 322 | ||
338 | break; | 323 | break; |
339 | } | 324 | } |
340 | 325 | ||
341 | case Direction::right: | 326 | case Direction::right: |
342 | { | 327 | { |
343 | newX = collision.getAxis() - transformable.getW(); | 328 | newX = collision.getAxis() - transformable.w; |
344 | ponderable.setVelocityX(0.0); | 329 | ponderable.velX = 0.0; |
345 | 330 | ||
346 | break; | 331 | break; |
347 | } | 332 | } |
@@ -349,16 +334,16 @@ void PonderingSystem::tick(double dt) | |||
349 | case Direction::up: | 334 | case Direction::up: |
350 | { | 335 | { |
351 | newY = collision.getAxis(); | 336 | newY = collision.getAxis(); |
352 | ponderable.setVelocityY(0.0); | 337 | ponderable.velY = 0.0; |
353 | 338 | ||
354 | break; | 339 | break; |
355 | } | 340 | } |
356 | 341 | ||
357 | case Direction::down: | 342 | case Direction::down: |
358 | { | 343 | { |
359 | newY = collision.getAxis() - transformable.getH(); | 344 | newY = collision.getAxis() - transformable.h; |
360 | ponderable.setVelocityY(0.0); | 345 | ponderable.velY = 0.0; |
361 | ponderable.setGrounded(true); | 346 | ponderable.grounded = true; |
362 | 347 | ||
363 | break; | 348 | break; |
364 | } | 349 | } |
@@ -367,8 +352,8 @@ void PonderingSystem::tick(double dt) | |||
367 | } | 352 | } |
368 | 353 | ||
369 | // Move | 354 | // Move |
370 | transformable.setX(newX); | 355 | transformable.x = newX; |
371 | transformable.setY(newY); | 356 | transformable.y = newY; |
372 | 357 | ||
373 | // Perform cleanup for orientable entites | 358 | // Perform cleanup for orientable entites |
374 | if (game_.getEntityManager().hasComponent<OrientableComponent>(entity)) | 359 | if (game_.getEntityManager().hasComponent<OrientableComponent>(entity)) |
@@ -377,9 +362,9 @@ void PonderingSystem::tick(double dt) | |||
377 | getComponent<OrientableComponent>(entity); | 362 | getComponent<OrientableComponent>(entity); |
378 | 363 | ||
379 | // Handle changes in groundedness | 364 | // Handle changes in groundedness |
380 | if (ponderable.isGrounded() != oldGrounded) | 365 | if (ponderable.grounded != oldGrounded) |
381 | { | 366 | { |
382 | if (ponderable.isGrounded()) | 367 | if (ponderable.grounded) |
383 | { | 368 | { |
384 | game_.getSystemManager().getSystem<OrientingSystem>().land(entity); | 369 | game_.getSystemManager().getSystem<OrientingSystem>().land(entity); |
385 | } else { | 370 | } else { |
@@ -394,6 +379,51 @@ void PonderingSystem::tick(double dt) | |||
394 | orientable.setDropState(OrientableComponent::DropState::none); | 379 | orientable.setDropState(OrientableComponent::DropState::none); |
395 | } | 380 | } |
396 | } | 381 | } |
382 | |||
383 | // Move to an adjacent map, if necessary | ||
384 | if (adjacentlyWarping) | ||
385 | { | ||
386 | double warpX = newX; | ||
387 | double warpY = newY; | ||
388 | |||
389 | switch (adjWarpDir) | ||
390 | { | ||
391 | case Direction::left: | ||
392 | { | ||
393 | warpX = GAME_WIDTH + WALL_GAP - transformable.w; | ||
394 | |||
395 | break; | ||
396 | } | ||
397 | |||
398 | case Direction::right: | ||
399 | { | ||
400 | warpX = -WALL_GAP; | ||
401 | |||
402 | break; | ||
403 | } | ||
404 | |||
405 | case Direction::up: | ||
406 | { | ||
407 | warpY = MAP_HEIGHT * TILE_HEIGHT - transformable.h; | ||
408 | |||
409 | break; | ||
410 | } | ||
411 | |||
412 | case Direction::down: | ||
413 | { | ||
414 | warpY = -WALL_GAP; | ||
415 | |||
416 | break; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | game_.getSystemManager().getSystem<PlayingSystem>(). | ||
421 | changeMap( | ||
422 | entity, | ||
423 | adjWarpMapId, | ||
424 | warpX, | ||
425 | warpY); | ||
426 | } | ||
397 | } | 427 | } |
398 | } | 428 | } |
399 | 429 | ||
@@ -406,6 +436,20 @@ void PonderingSystem::initializeBody( | |||
406 | 436 | ||
407 | if (type == PonderableComponent::Type::freefalling) | 437 | if (type == PonderableComponent::Type::freefalling) |
408 | { | 438 | { |
409 | ponderable.setAccelY(NORMAL_GRAVITY); | 439 | ponderable.accelY = NORMAL_GRAVITY; |
410 | } | 440 | } |
411 | } | 441 | } |
442 | |||
443 | void PonderingSystem::initPrototype(id_type prototype) | ||
444 | { | ||
445 | auto& ponderable = game_.getEntityManager(). | ||
446 | getComponent<PonderableComponent>(prototype); | ||
447 | |||
448 | ponderable.velX = 0.0; | ||
449 | ponderable.velY = 0.0; | ||
450 | ponderable.accelX = 0.0; | ||
451 | ponderable.accelY = 0.0; | ||
452 | ponderable.grounded = false; | ||
453 | ponderable.frozen = false; | ||
454 | ponderable.collidable = true; | ||
455 | } | ||
diff --git a/src/systems/pondering.h b/src/systems/pondering.h index d70525b..58e6496 100644 --- a/src/systems/pondering.h +++ b/src/systems/pondering.h | |||
@@ -16,6 +16,8 @@ public: | |||
16 | 16 | ||
17 | void initializeBody(id_type entity, PonderableComponent::Type type); | 17 | void initializeBody(id_type entity, PonderableComponent::Type type); |
18 | 18 | ||
19 | void initPrototype(id_type prototype); | ||
20 | |||
19 | }; | 21 | }; |
20 | 22 | ||
21 | #endif /* end of include guard: PONDERING_H_F2530E0E */ | 23 | #endif /* end of include guard: PONDERING_H_F2530E0E */ |
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp new file mode 100644 index 0000000..09c38f3 --- /dev/null +++ b/src/systems/realizing.cpp | |||
@@ -0,0 +1,321 @@ | |||
1 | #include "realizing.h" | ||
2 | #include <stdexcept> | ||
3 | #include <libxml/parser.h> | ||
4 | #include <cstring> | ||
5 | #include "game.h" | ||
6 | #include "consts.h" | ||
7 | #include "components/realizable.h" | ||
8 | #include "components/mappable.h" | ||
9 | #include "components/animatable.h" | ||
10 | #include "components/playable.h" | ||
11 | #include "components/ponderable.h" | ||
12 | #include "components/transformable.h" | ||
13 | #include "systems/mapping.h" | ||
14 | #include "systems/animating.h" | ||
15 | #include "systems/pondering.h" | ||
16 | |||
17 | inline xmlChar* getProp(xmlNodePtr node, const char* attr) | ||
18 | { | ||
19 | xmlChar* key = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attr)); | ||
20 | if (key == nullptr) | ||
21 | { | ||
22 | throw std::invalid_argument("Error parsing world file"); | ||
23 | } | ||
24 | |||
25 | return key; | ||
26 | } | ||
27 | |||
28 | // TODO: neither the XML doc nor any of the emplaced entities are properly | ||
29 | // destroyed if this method throws an exception. | ||
30 | EntityManager::id_type RealizingSystem::initSingleton(std::string filename) | ||
31 | { | ||
32 | id_type world = game_.getEntityManager().emplaceEntity(); | ||
33 | |||
34 | auto& realizable = game_.getEntityManager(). | ||
35 | emplaceComponent<RealizableComponent>(world); | ||
36 | |||
37 | auto& mapping = game_.getSystemManager().getSystem<MappingSystem>(); | ||
38 | |||
39 | xmlDocPtr doc = xmlParseFile(filename.c_str()); | ||
40 | if (doc == nullptr) | ||
41 | { | ||
42 | throw std::invalid_argument("Cannot find world file"); | ||
43 | } | ||
44 | |||
45 | xmlNodePtr top = xmlDocGetRootElement(doc); | ||
46 | if (top == nullptr) | ||
47 | { | ||
48 | throw std::invalid_argument("Error parsing world file"); | ||
49 | } | ||
50 | |||
51 | if (xmlStrcmp(top->name, reinterpret_cast<const xmlChar*>("world"))) | ||
52 | { | ||
53 | throw std::invalid_argument("Error parsing world file"); | ||
54 | } | ||
55 | |||
56 | xmlChar* key = nullptr; | ||
57 | |||
58 | key = getProp(top, "startx"); | ||
59 | realizable.startingX = atoi(reinterpret_cast<char*>(key)); | ||
60 | xmlFree(key); | ||
61 | |||
62 | key = getProp(top, "starty"); | ||
63 | realizable.startingY = atoi(reinterpret_cast<char*>(key)); | ||
64 | xmlFree(key); | ||
65 | |||
66 | key = getProp(top, "startmap"); | ||
67 | realizable.startingMapId = atoi(reinterpret_cast<char*>(key)); | ||
68 | xmlFree(key); | ||
69 | |||
70 | for (xmlNodePtr node = top->xmlChildrenNode; | ||
71 | node != nullptr; | ||
72 | node = node->next) | ||
73 | { | ||
74 | if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("map"))) | ||
75 | { | ||
76 | id_type map = game_.getEntityManager().emplaceEntity(); | ||
77 | |||
78 | auto& mappable = game_.getEntityManager(). | ||
79 | emplaceComponent<MappableComponent>(map, | ||
80 | Texture("res/tiles.png"), | ||
81 | Texture("res/font.bmp")); | ||
82 | |||
83 | key = getProp(node, "id"); | ||
84 | mappable.mapId = atoi(reinterpret_cast<char*>(key)); | ||
85 | xmlFree(key); | ||
86 | |||
87 | key = getProp(node, "title"); | ||
88 | mappable.title = reinterpret_cast<char*>(key); | ||
89 | xmlFree(key); | ||
90 | |||
91 | for (xmlNodePtr mapNode = node->xmlChildrenNode; | ||
92 | mapNode != nullptr; | ||
93 | mapNode = mapNode->next) | ||
94 | { | ||
95 | if (!xmlStrcmp( | ||
96 | mapNode->name, | ||
97 | reinterpret_cast<const xmlChar*>("environment"))) | ||
98 | { | ||
99 | key = xmlNodeGetContent(mapNode); | ||
100 | if (key == nullptr) | ||
101 | { | ||
102 | throw std::invalid_argument("Error parsing world file"); | ||
103 | } | ||
104 | |||
105 | mappable.tiles.clear(); | ||
106 | mappable.tiles.push_back(atoi(strtok( | ||
107 | reinterpret_cast<char*>(key), | ||
108 | ",\n"))); | ||
109 | |||
110 | for (size_t i = 1; i < (MAP_WIDTH * MAP_HEIGHT); i++) | ||
111 | { | ||
112 | mappable.tiles.push_back(atoi(strtok(nullptr, ",\n"))); | ||
113 | } | ||
114 | |||
115 | xmlFree(key); | ||
116 | } else if (!xmlStrcmp( | ||
117 | mapNode->name, | ||
118 | reinterpret_cast<const xmlChar*>("adjacent"))) | ||
119 | { | ||
120 | key = getProp(mapNode, "type"); | ||
121 | std::string adjTypeStr(reinterpret_cast<char*>(key)); | ||
122 | xmlFree(key); | ||
123 | |||
124 | MappableComponent::Adjacent::Type adjType; | ||
125 | if (adjTypeStr == "wall") | ||
126 | { | ||
127 | adjType = MappableComponent::Adjacent::Type::wall; | ||
128 | } else if (adjTypeStr == "wrap") | ||
129 | { | ||
130 | adjType = MappableComponent::Adjacent::Type::wrap; | ||
131 | } else if (adjTypeStr == "warp") | ||
132 | { | ||
133 | adjType = MappableComponent::Adjacent::Type::warp; | ||
134 | } else if (adjTypeStr == "reverseWarp") | ||
135 | { | ||
136 | adjType = MappableComponent::Adjacent::Type::reverse; | ||
137 | } else { | ||
138 | throw std::logic_error("Invalid adjacency type"); | ||
139 | } | ||
140 | |||
141 | key = getProp(mapNode, "map"); | ||
142 | size_t adjMapId = atoi(reinterpret_cast<char*>(key)); | ||
143 | xmlFree(key); | ||
144 | |||
145 | key = getProp(mapNode, "dir"); | ||
146 | std::string adjDir(reinterpret_cast<char*>(key)); | ||
147 | xmlFree(key); | ||
148 | |||
149 | if (adjDir == "left") | ||
150 | { | ||
151 | mappable.leftAdjacent = {adjType, adjMapId}; | ||
152 | } else if (adjDir == "right") | ||
153 | { | ||
154 | mappable.rightAdjacent = {adjType, adjMapId}; | ||
155 | } else if (adjDir == "up") | ||
156 | { | ||
157 | mappable.upAdjacent = {adjType, adjMapId}; | ||
158 | } else if (adjDir == "down") | ||
159 | { | ||
160 | mappable.downAdjacent = {adjType, adjMapId}; | ||
161 | } else { | ||
162 | throw std::logic_error("Invalid adjacency direction"); | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | mapping.generateBoundaries(map); | ||
168 | |||
169 | realizable.maps.insert(map); | ||
170 | realizable.entityByMapId[mappable.mapId] = map; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | xmlFreeDoc(doc); | ||
175 | |||
176 | loadMap(realizable.entityByMapId[realizable.startingMapId]); | ||
177 | |||
178 | return world; | ||
179 | } | ||
180 | |||
181 | EntityManager::id_type RealizingSystem::getSingleton() const | ||
182 | { | ||
183 | std::set<id_type> result = | ||
184 | game_.getEntityManager().getEntitiesWithComponents< | ||
185 | RealizableComponent>(); | ||
186 | |||
187 | if (result.empty()) | ||
188 | { | ||
189 | throw std::logic_error("No realizable entity found"); | ||
190 | } else if (result.size() > 1) | ||
191 | { | ||
192 | throw std::logic_error("Multiple realizable entities found"); | ||
193 | } | ||
194 | |||
195 | return *std::begin(result); | ||
196 | } | ||
197 | |||
198 | void RealizingSystem::loadMap(id_type mapEntity) | ||
199 | { | ||
200 | id_type world = getSingleton(); | ||
201 | |||
202 | auto& realizable = game_.getEntityManager(). | ||
203 | getComponent<RealizableComponent>(world); | ||
204 | |||
205 | auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); | ||
206 | auto& pondering = game_.getSystemManager().getSystem<PonderingSystem>(); | ||
207 | |||
208 | std::set<id_type> players = | ||
209 | game_.getEntityManager().getEntitiesWithComponents< | ||
210 | PlayableComponent>(); | ||
211 | |||
212 | if (realizable.hasActiveMap) | ||
213 | { | ||
214 | id_type oldMap = realizable.activeMap; | ||
215 | |||
216 | auto& oldMappable = game_.getEntityManager(). | ||
217 | getComponent<MappableComponent>(oldMap); | ||
218 | |||
219 | // Deactivate any map objects from the old map. | ||
220 | for (id_type prototype : oldMappable.objects) | ||
221 | { | ||
222 | leaveActiveMap(prototype); | ||
223 | } | ||
224 | |||
225 | // Deactivate players that were on the old map. | ||
226 | for (id_type player : players) | ||
227 | { | ||
228 | auto& playable = game_.getEntityManager(). | ||
229 | getComponent<PlayableComponent>(player); | ||
230 | |||
231 | if (playable.mapId == oldMap) | ||
232 | { | ||
233 | leaveActiveMap(player); | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | |||
238 | realizable.hasActiveMap = true; | ||
239 | realizable.activeMap = mapEntity; | ||
240 | |||
241 | auto& mappable = game_.getEntityManager(). | ||
242 | getComponent<MappableComponent>(mapEntity); | ||
243 | |||
244 | // Initialize the new map's objects. | ||
245 | for (id_type prototype : mappable.objects) | ||
246 | { | ||
247 | if (game_.getEntityManager(). | ||
248 | hasComponent<TransformableComponent>(prototype)) | ||
249 | { | ||
250 | auto& transformable = game_.getEntityManager(). | ||
251 | getComponent<TransformableComponent>(prototype); | ||
252 | |||
253 | transformable.x = transformable.origX; | ||
254 | transformable.y = transformable.origY; | ||
255 | transformable.w = transformable.origW; | ||
256 | transformable.h = transformable.origH; | ||
257 | } | ||
258 | |||
259 | if (game_.getEntityManager().hasComponent<AnimatableComponent>(prototype)) | ||
260 | { | ||
261 | animating.initPrototype(prototype); | ||
262 | } | ||
263 | |||
264 | if (game_.getEntityManager().hasComponent<PonderableComponent>(prototype)) | ||
265 | { | ||
266 | pondering.initPrototype(prototype); | ||
267 | } | ||
268 | |||
269 | enterActiveMap(prototype); | ||
270 | } | ||
271 | |||
272 | // Activate any players on the map. | ||
273 | for (id_type player : players) | ||
274 | { | ||
275 | auto& playable = game_.getEntityManager(). | ||
276 | getComponent<PlayableComponent>(player); | ||
277 | |||
278 | if (playable.mapId == mapEntity) | ||
279 | { | ||
280 | enterActiveMap(player); | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | void RealizingSystem::enterActiveMap(id_type entity) | ||
286 | { | ||
287 | if (game_.getEntityManager().hasComponent<AnimatableComponent>(entity)) | ||
288 | { | ||
289 | auto& animatable = game_.getEntityManager(). | ||
290 | getComponent<AnimatableComponent>(entity); | ||
291 | |||
292 | animatable.active = true; | ||
293 | } | ||
294 | |||
295 | if (game_.getEntityManager().hasComponent<PonderableComponent>(entity)) | ||
296 | { | ||
297 | auto& ponderable = game_.getEntityManager(). | ||
298 | getComponent<PonderableComponent>(entity); | ||
299 | |||
300 | ponderable.active = true; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | void RealizingSystem::leaveActiveMap(id_type entity) | ||
305 | { | ||
306 | if (game_.getEntityManager().hasComponent<AnimatableComponent>(entity)) | ||
307 | { | ||
308 | auto& animatable = game_.getEntityManager(). | ||
309 | getComponent<AnimatableComponent>(entity); | ||
310 | |||
311 | animatable.active = false; | ||
312 | } | ||
313 | |||
314 | if (game_.getEntityManager().hasComponent<PonderableComponent>(entity)) | ||
315 | { | ||
316 | auto& ponderable = game_.getEntityManager(). | ||
317 | getComponent<PonderableComponent>(entity); | ||
318 | |||
319 | ponderable.active = false; | ||
320 | } | ||
321 | } | ||
diff --git a/src/systems/realizing.h b/src/systems/realizing.h new file mode 100644 index 0000000..c681892 --- /dev/null +++ b/src/systems/realizing.h | |||
@@ -0,0 +1,43 @@ | |||
1 | #ifndef REALIZING_H_6853748C | ||
2 | #define REALIZING_H_6853748C | ||
3 | |||
4 | #include "system.h" | ||
5 | |||
6 | class RealizingSystem : public System { | ||
7 | public: | ||
8 | |||
9 | RealizingSystem(Game& game) : System(game) | ||
10 | { | ||
11 | } | ||
12 | |||
13 | /** | ||
14 | * Creates the singleton realizable entity and initializes it with the | ||
15 | * provided world definition. | ||
16 | */ | ||
17 | id_type initSingleton(std::string filename); | ||
18 | |||
19 | /** | ||
20 | * Helper method that returns the entity ID of the (assumed) singleton entity | ||
21 | * with a RealizableComponent. Throws an exception if the number of realizable | ||
22 | * entities is not exactly one. | ||
23 | */ | ||
24 | id_type getSingleton() const; | ||
25 | |||
26 | /** | ||
27 | * Loads the given map. | ||
28 | */ | ||
29 | void loadMap(id_type mapEntity); | ||
30 | |||
31 | /** | ||
32 | * Treats the given entity as part of the active map. | ||
33 | */ | ||
34 | void enterActiveMap(id_type entity); | ||
35 | |||
36 | /** | ||
37 | * Stops treating the given entity as part of the active map. | ||
38 | */ | ||
39 | void leaveActiveMap(id_type entity); | ||
40 | |||
41 | }; | ||
42 | |||
43 | #endif /* end of include guard: REALIZING_H_6853748C */ | ||