diff options
-rw-r--r-- | res/maps/hallucination.tsx | 30 | ||||
-rw-r--r-- | res/sprites/boney_anim.txt | 4 | ||||
-rw-r--r-- | res/sprites/duster_anim.txt | 4 | ||||
-rw-r--r-- | res/sprites/kuma_anim.txt | 4 | ||||
-rw-r--r-- | res/sprites/lucas_anim.txt | 4 | ||||
-rw-r--r-- | src/animation_system.cpp | 20 | ||||
-rw-r--r-- | src/animation_system.h | 3 | ||||
-rw-r--r-- | src/character_system.cpp | 122 | ||||
-rw-r--r-- | src/character_system.h | 3 | ||||
-rw-r--r-- | src/map.cpp | 22 | ||||
-rw-r--r-- | src/map.h | 4 | ||||
-rw-r--r-- | src/sprite.h | 10 | ||||
-rw-r--r-- | src/transform_system.cpp | 31 | ||||
-rw-r--r-- | src/transform_system.h | 2 |
14 files changed, 224 insertions, 39 deletions
diff --git a/res/maps/hallucination.tsx b/res/maps/hallucination.tsx index 82edada..e06dab1 100644 --- a/res/maps/hallucination.tsx +++ b/res/maps/hallucination.tsx | |||
@@ -1096,6 +1096,16 @@ | |||
1096 | <property name="runSound" value="grass"/> | 1096 | <property name="runSound" value="grass"/> |
1097 | </properties> | 1097 | </properties> |
1098 | </tile> | 1098 | </tile> |
1099 | <tile id="320"> | ||
1100 | <properties> | ||
1101 | <property name="medium" value="ladder"/> | ||
1102 | </properties> | ||
1103 | </tile> | ||
1104 | <tile id="321"> | ||
1105 | <properties> | ||
1106 | <property name="medium" value="ladder"/> | ||
1107 | </properties> | ||
1108 | </tile> | ||
1099 | <tile id="322"> | 1109 | <tile id="322"> |
1100 | <properties> | 1110 | <properties> |
1101 | <property name="solid" type="bool" value="true"/> | 1111 | <property name="solid" type="bool" value="true"/> |
@@ -1151,6 +1161,11 @@ | |||
1151 | <property name="solid" type="bool" value="true"/> | 1161 | <property name="solid" type="bool" value="true"/> |
1152 | </properties> | 1162 | </properties> |
1153 | </tile> | 1163 | </tile> |
1164 | <tile id="333"> | ||
1165 | <properties> | ||
1166 | <property name="medium" value="ladder"/> | ||
1167 | </properties> | ||
1168 | </tile> | ||
1154 | <tile id="334"> | 1169 | <tile id="334"> |
1155 | <properties> | 1170 | <properties> |
1156 | <property name="solid" type="bool" value="true"/> | 1171 | <property name="solid" type="bool" value="true"/> |
@@ -1281,6 +1296,16 @@ | |||
1281 | <property name="runSound" value="grass"/> | 1296 | <property name="runSound" value="grass"/> |
1282 | </properties> | 1297 | </properties> |
1283 | </tile> | 1298 | </tile> |
1299 | <tile id="360"> | ||
1300 | <properties> | ||
1301 | <property name="medium" value="ladder"/> | ||
1302 | </properties> | ||
1303 | </tile> | ||
1304 | <tile id="361"> | ||
1305 | <properties> | ||
1306 | <property name="medium" value="ladder"/> | ||
1307 | </properties> | ||
1308 | </tile> | ||
1284 | <tile id="362"> | 1309 | <tile id="362"> |
1285 | <properties> | 1310 | <properties> |
1286 | <property name="solid" type="bool" value="true"/> | 1311 | <property name="solid" type="bool" value="true"/> |
@@ -1311,6 +1336,11 @@ | |||
1311 | <property name="solid" type="bool" value="true"/> | 1336 | <property name="solid" type="bool" value="true"/> |
1312 | </properties> | 1337 | </properties> |
1313 | </tile> | 1338 | </tile> |
1339 | <tile id="368"> | ||
1340 | <properties> | ||
1341 | <property name="medium" value="ladder"/> | ||
1342 | </properties> | ||
1343 | </tile> | ||
1314 | <tile id="369"> | 1344 | <tile id="369"> |
1315 | <properties> | 1345 | <properties> |
1316 | <property name="runSound" value="land"/> | 1346 | <property name="runSound" value="land"/> |
diff --git a/res/sprites/boney_anim.txt b/res/sprites/boney_anim.txt index a8b036c..5dfb65f 100644 --- a/res/sprites/boney_anim.txt +++ b/res/sprites/boney_anim.txt | |||
@@ -47,4 +47,6 @@ barking[up_left]: 3,35,43,35,43,35,43 | |||
47 | barking[up]: 4,36,44,36,44,36,44 | 47 | barking[up]: 4,36,44,36,44,36,44 |
48 | barking[up_right]: 5,37,45,37,45,37,45 | 48 | barking[up_right]: 5,37,45,37,45,37,45 |
49 | barking[right]: 6,38,46,38,46,38,46 | 49 | barking[right]: 6,38,46,38,46,38,46 |
50 | barking[down_right]: 7,39,47,39,47,39,47 \ No newline at end of file | 50 | barking[down_right]: 7,39,47,39,47,39,47 |
51 | climb.[up]: 240,241,242,243,244,245,246,247,248,249,250,251,252 | ||
52 | climb.[down]: 253,254,255,256,257,258,259,260,261,262,263,264,265 \ No newline at end of file | ||
diff --git a/res/sprites/duster_anim.txt b/res/sprites/duster_anim.txt index 57c470c..538ddd1 100644 --- a/res/sprites/duster_anim.txt +++ b/res/sprites/duster_anim.txt | |||
@@ -39,4 +39,6 @@ run[up_left]: 75,83,91,99,107 | |||
39 | run[up]: 76,84,92,100,108 | 39 | run[up]: 76,84,92,100,108 |
40 | run[up_right]: 77,85,93,101,109 | 40 | run[up_right]: 77,85,93,101,109 |
41 | run[right]: 78,86,94,102,110 | 41 | run[right]: 78,86,94,102,110 |
42 | run[down_right]: 79,87,95,103,111 \ No newline at end of file | 42 | run[down_right]: 79,87,95,103,111 |
43 | climb.[up]: 200,201,202,206,207,208,203,204,205,206,207,208 | ||
44 | climb.[down]: 200,201,202,206,207,208,203,204,205,206,207,208 \ No newline at end of file | ||
diff --git a/res/sprites/kuma_anim.txt b/res/sprites/kuma_anim.txt index 01ca970..a691b7d 100644 --- a/res/sprites/kuma_anim.txt +++ b/res/sprites/kuma_anim.txt | |||
@@ -47,4 +47,6 @@ talk[up_left]: 35,43 | |||
47 | talk[up]: 36,44 | 47 | talk[up]: 36,44 |
48 | talk[up_right]: 37,45 | 48 | talk[up_right]: 37,45 |
49 | talk[right]: 38,46 | 49 | talk[right]: 38,46 |
50 | talk[down_right]: 39,47 \ No newline at end of file | 50 | talk[down_right]: 39,47 |
51 | climb.[up]: 257,258,259,263,264,265,260,261,262,263,264,265 | ||
52 | climb.[down]: 257,258,259,263,264,265,260,261,262,263,264,265 \ No newline at end of file | ||
diff --git a/res/sprites/lucas_anim.txt b/res/sprites/lucas_anim.txt index 1a8b62b..cd5ee9f 100644 --- a/res/sprites/lucas_anim.txt +++ b/res/sprites/lucas_anim.txt | |||
@@ -41,4 +41,6 @@ run[up_right]: 72,80,88,96 | |||
41 | run[right]: 73,81,89,97 | 41 | run[right]: 73,81,89,97 |
42 | run[down_right]: 74,82,90,98 | 42 | run[down_right]: 74,82,90,98 |
43 | lightning_electrocute![down]: 116,117,118,116,117,118 | 43 | lightning_electrocute![down]: 116,117,118,116,117,118 |
44 | lightning_collapse![down]: 119,120,121,122 \ No newline at end of file | 44 | lightning_collapse![down]: 119,120,121,122 |
45 | climb.[up]: 123,124,125,128,127,127,129,130,131,128,127,126 | ||
46 | climb.[down]: 123,124,125,128,127,127,129,130,131,128,127,126 \ No newline at end of file | ||
diff --git a/src/animation_system.cpp b/src/animation_system.cpp index d23eae2..a280aee 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp | |||
@@ -65,7 +65,7 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { | |||
65 | std::string animLine; | 65 | std::string animLine; |
66 | std::getline(datafile, animLine); // blank | 66 | std::getline(datafile, animLine); // blank |
67 | while (std::getline(datafile, animLine)) { | 67 | while (std::getline(datafile, animLine)) { |
68 | std::regex re(R"(([a-z!_]+)\[([a-z_]+)\]: ([0-9,]+))"); | 68 | std::regex re(R"(([a-z!._]+)\[([a-z_]+)\]: ([0-9,]+))"); |
69 | std::smatch m; | 69 | std::smatch m; |
70 | std::regex_match(animLine, m, re); | 70 | std::regex_match(animLine, m, re); |
71 | 71 | ||
@@ -78,6 +78,8 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { | |||
78 | 78 | ||
79 | if (animName.back() == '!') { | 79 | if (animName.back() == '!') { |
80 | anim.looping = false; | 80 | anim.looping = false; |
81 | } else if (animName.back() == '.') { | ||
82 | anim.manual = true; | ||
81 | } | 83 | } |
82 | 84 | ||
83 | int animId = sprite.animations.size(); | 85 | int animId = sprite.animations.size(); |
@@ -96,7 +98,7 @@ void AnimationSystem::tick(double dt) { | |||
96 | animTimer_.accumulate(dt); | 98 | animTimer_.accumulate(dt); |
97 | while (animTimer_.step()) { | 99 | while (animTimer_.step()) { |
98 | for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { | 100 | for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { |
99 | if (sprite.isAnimated && !sprite.animFinished) { | 101 | if (sprite.isAnimated && !sprite.animFinished && !sprite.animPaused) { |
100 | sprite.animationFrame++; | 102 | sprite.animationFrame++; |
101 | 103 | ||
102 | if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size()) { | 104 | if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size()) { |
@@ -112,6 +114,19 @@ void AnimationSystem::tick(double dt) { | |||
112 | } | 114 | } |
113 | } | 115 | } |
114 | 116 | ||
117 | void AnimationSystem::advanceAnimation(int spriteId) { | ||
118 | Sprite& sprite = game_.getSprite(spriteId); | ||
119 | Animation& animation = sprite.animations[sprite.animationId]; | ||
120 | |||
121 | if (animation.manual) { | ||
122 | sprite.animationFrame++; | ||
123 | |||
124 | if (sprite.animationFrame >= animation.frameIndices.size()) { | ||
125 | sprite.animationFrame = 0; | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
115 | void AnimationSystem::setSpriteDirection(int spriteId, Direction dir) { | 130 | void AnimationSystem::setSpriteDirection(int spriteId, Direction dir) { |
116 | Sprite& sprite = game_.getSprite(spriteId); | 131 | Sprite& sprite = game_.getSprite(spriteId); |
117 | if (sprite.dir != dir) { | 132 | if (sprite.dir != dir) { |
@@ -133,4 +148,5 @@ void AnimationSystem::updateAnimation(int spriteId) { | |||
133 | sprite.animationId = sprite.nameDirToAnim[sprite.animationName][sprite.dir]; | 148 | sprite.animationId = sprite.nameDirToAnim[sprite.animationName][sprite.dir]; |
134 | sprite.animationFrame = 0; | 149 | sprite.animationFrame = 0; |
135 | sprite.animFinished = false; | 150 | sprite.animFinished = false; |
151 | sprite.animPaused = false; | ||
136 | } | 152 | } |
diff --git a/src/animation_system.h b/src/animation_system.h index a116673..8352c19 100644 --- a/src/animation_system.h +++ b/src/animation_system.h | |||
@@ -17,6 +17,9 @@ public: | |||
17 | 17 | ||
18 | void tick(double dt) override; | 18 | void tick(double dt) override; |
19 | 19 | ||
20 | // Advances animation by a frame. Only to be used on manual animations. | ||
21 | void advanceAnimation(int spriteId); | ||
22 | |||
20 | void initSprite(int spriteId, std::string_view filename); | 23 | void initSprite(int spriteId, std::string_view filename); |
21 | 24 | ||
22 | void setSpriteDirection(int spriteId, Direction dir); | 25 | void setSpriteDirection(int spriteId, Direction dir); |
diff --git a/src/character_system.cpp b/src/character_system.cpp index 99b6929..27c2280 100644 --- a/src/character_system.cpp +++ b/src/character_system.cpp | |||
@@ -34,7 +34,7 @@ void CharacterSystem::addSpriteToParty(int leaderId, int followerId) { | |||
34 | 34 | ||
35 | for (int i=0; i<truePartyDelay; i++) { | 35 | for (int i=0; i<truePartyDelay; i++) { |
36 | vec2i tween = ((follower.loc - targetPos) * i) / static_cast<double>(truePartyDelay) + targetPos; | 36 | vec2i tween = ((follower.loc - targetPos) * i) / static_cast<double>(truePartyDelay) + targetPos; |
37 | follower.trail.push_front({.pos = tween, .dir = toFace}); | 37 | follower.trail.push_front({.pos = tween, .dir = toFace, .medium = CharacterMedium::Normal}); |
38 | } | 38 | } |
39 | 39 | ||
40 | leader.followers.push_back(followerId); | 40 | leader.followers.push_back(followerId); |
@@ -70,14 +70,31 @@ void CharacterSystem::transplantParty(int leaderId, vec2i pos, Direction dir) { | |||
70 | 70 | ||
71 | void CharacterSystem::moveInDirection(int spriteId, Direction dir) { | 71 | void CharacterSystem::moveInDirection(int spriteId, Direction dir) { |
72 | Sprite& sprite = game_.getSprite(spriteId); | 72 | Sprite& sprite = game_.getSprite(spriteId); |
73 | sprite.movementDir = dir; | ||
73 | 74 | ||
74 | game_.getSystem<AnimationSystem>().setSpriteDirection(spriteId, dir); | 75 | switch (sprite.characterMedium) { |
76 | case CharacterMedium::Normal: { | ||
77 | game_.getSystem<AnimationSystem>().setSpriteDirection(spriteId, dir); | ||
78 | break; | ||
79 | } | ||
80 | case CharacterMedium::Ladder: { | ||
81 | if (dirHasDir(dir, Direction::up)) { | ||
82 | game_.getSystem<AnimationSystem>().setSpriteDirection(spriteId, Direction::up); | ||
83 | } else if (dirHasDir(dir, Direction::down)) { | ||
84 | game_.getSystem<AnimationSystem>().setSpriteDirection(spriteId, Direction::down); | ||
85 | } | ||
86 | break; | ||
87 | } | ||
88 | } | ||
75 | 89 | ||
76 | if (sprite.characterState == CharacterState::Still) { | 90 | if (sprite.characterState == CharacterState::Still) { |
77 | setPartyState(spriteId, CharacterState::Walking); | 91 | setPartyState(spriteId, CharacterState::Walking); |
78 | } else if (sprite.characterState == CharacterState::Crouching) { | 92 | } else if (sprite.characterState == CharacterState::Crouching) { |
79 | for (int followerId : sprite.followers) { | 93 | for (int followerId : sprite.followers) { |
80 | game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, dir); | 94 | Sprite& follower = game_.getSprite(followerId); |
95 | if (follower.characterMedium == CharacterMedium::Normal) { | ||
96 | game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, dir); | ||
97 | } | ||
81 | } | 98 | } |
82 | } | 99 | } |
83 | } | 100 | } |
@@ -107,14 +124,18 @@ void CharacterSystem::tick(double dt) { | |||
107 | } | 124 | } |
108 | 125 | ||
109 | int speed = sprite.movementSpeed; | 126 | int speed = sprite.movementSpeed; |
110 | if (sprite.characterState == CharacterState::Running) { | 127 | if (sprite.characterState == CharacterState::Running && sprite.characterMedium == CharacterMedium::Normal) { |
111 | speed *= 2; | 128 | speed *= 2; |
112 | } | 129 | } |
113 | 130 | ||
114 | pLoc += (unitVecInDirection(sprite.dir) * speed); | 131 | if (sprite.characterMedium == CharacterMedium::Ladder) { |
132 | //game_.getSystem<AnimationSystem>().advanceAnimation(spriteId); | ||
133 | } | ||
134 | |||
135 | pLoc += (unitVecInDirection(sprite.movementDir) * speed); | ||
115 | 136 | ||
116 | // Check collision. | 137 | // Check collision. |
117 | CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, pLoc, sprite.dir); | 138 | CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, pLoc, sprite.movementDir); |
118 | bool blocked = collision.horiz.blocked || collision.vert.blocked; | 139 | bool blocked = collision.horiz.blocked || collision.vert.blocked; |
119 | 140 | ||
120 | if (collision.horiz.blocked && !sprite.clipping) { | 141 | if (collision.horiz.blocked && !sprite.clipping) { |
@@ -146,6 +167,12 @@ void CharacterSystem::tick(double dt) { | |||
146 | if (pLoc != sprite.loc) { | 167 | if (pLoc != sprite.loc) { |
147 | game_.getSystem<TransformSystem>().moveSprite(spriteId, pLoc); | 168 | game_.getSystem<TransformSystem>().moveSprite(spriteId, pLoc); |
148 | 169 | ||
170 | CharacterMedium newMedium = game_.getSystem<TransformSystem>().getMediumAtPosition(spriteId, pLoc); | ||
171 | if (newMedium != sprite.characterMedium) { | ||
172 | sprite.characterMedium = newMedium; | ||
173 | setAnimationFor(spriteId, sprite.characterState); | ||
174 | } | ||
175 | |||
149 | if (sprite.characterState == CharacterState::Running) { | 176 | if (sprite.characterState == CharacterState::Running) { |
150 | const Map& map = game_.getMap(); | 177 | const Map& map = game_.getMap(); |
151 | 178 | ||
@@ -164,12 +191,20 @@ void CharacterSystem::tick(double dt) { | |||
164 | 191 | ||
165 | for (int followerId : sprite.followers) { | 192 | for (int followerId : sprite.followers) { |
166 | Sprite& pNext = game_.getSprite(followerId); | 193 | Sprite& pNext = game_.getSprite(followerId); |
194 | if (pNext.characterMedium == CharacterMedium::Ladder) { | ||
195 | //game_.getSystem<AnimationSystem>().advanceAnimation(followerId); | ||
196 | } | ||
197 | |||
167 | const Movement& posdir = pNext.trail.front(); | 198 | const Movement& posdir = pNext.trail.front(); |
168 | game_.getSystem<TransformSystem>().moveSprite(followerId, posdir.pos); | 199 | game_.getSystem<TransformSystem>().moveSprite(followerId, posdir.pos); |
169 | game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, posdir.dir); | 200 | game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, posdir.dir); |
201 | if (posdir.medium != pNext.characterMedium) { | ||
202 | pNext.characterMedium = posdir.medium; | ||
203 | setAnimationFor(followerId, sprite.characterState); | ||
204 | } | ||
170 | 205 | ||
171 | pNext.trail.pop_front(); | 206 | pNext.trail.pop_front(); |
172 | pNext.trail.push_back({.pos = pLoc, .dir = sprite.dir}); | 207 | pNext.trail.push_back({.pos = pLoc, .dir = sprite.dir, .medium = sprite.characterMedium}); |
173 | } | 208 | } |
174 | } | 209 | } |
175 | } | 210 | } |
@@ -180,6 +215,10 @@ void CharacterSystem::tick(double dt) { | |||
180 | void CharacterSystem::beginCrouch(int spriteId) { | 215 | void CharacterSystem::beginCrouch(int spriteId) { |
181 | Sprite& sprite = game_.getSprite(spriteId); | 216 | Sprite& sprite = game_.getSprite(spriteId); |
182 | 217 | ||
218 | if (sprite.characterMedium == CharacterMedium::Ladder) { | ||
219 | return; | ||
220 | } | ||
221 | |||
183 | if (sprite.characterState == CharacterState::Running) { | 222 | if (sprite.characterState == CharacterState::Running) { |
184 | stopRunning(spriteId); | 223 | stopRunning(spriteId); |
185 | } else { | 224 | } else { |
@@ -242,32 +281,12 @@ void CharacterSystem::stopRunning(int spriteId) { | |||
242 | } | 281 | } |
243 | 282 | ||
244 | void CharacterSystem::setPartyState(int spriteId, CharacterState state) { | 283 | void CharacterSystem::setPartyState(int spriteId, CharacterState state) { |
245 | std::string animName; | ||
246 | switch (state) { | ||
247 | case CharacterState::Still: { | ||
248 | animName = "still"; | ||
249 | break; | ||
250 | } | ||
251 | case CharacterState::Walking: { | ||
252 | animName = "walk"; | ||
253 | break; | ||
254 | } | ||
255 | case CharacterState::Crouching: { | ||
256 | animName = "crouch"; | ||
257 | break; | ||
258 | } | ||
259 | case CharacterState::Running: { | ||
260 | animName = "run"; | ||
261 | break; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | Sprite& sprite = game_.getSprite(spriteId); | 284 | Sprite& sprite = game_.getSprite(spriteId); |
266 | sprite.characterState = state; | 285 | sprite.characterState = state; |
267 | 286 | ||
268 | game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, animName); | 287 | setAnimationFor(spriteId, state); |
269 | for (int followerId : sprite.followers) { | 288 | for (int followerId : sprite.followers) { |
270 | game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, animName); | 289 | setAnimationFor(followerId, state); |
271 | } | 290 | } |
272 | } | 291 | } |
273 | 292 | ||
@@ -297,3 +316,48 @@ void CharacterSystem::destroySprite(int spriteId) { | |||
297 | stopRunningSound(sprite); | 316 | stopRunningSound(sprite); |
298 | } | 317 | } |
299 | } | 318 | } |
319 | |||
320 | void CharacterSystem::setAnimationFor(int spriteId, CharacterState state) { | ||
321 | Sprite& sprite = game_.getSprite(spriteId); | ||
322 | std::string animName; | ||
323 | |||
324 | switch (sprite.characterMedium) { | ||
325 | case CharacterMedium::Normal: { | ||
326 | std::string animName; | ||
327 | |||
328 | switch (state) { | ||
329 | case CharacterState::Still: { | ||
330 | animName = "still"; | ||
331 | break; | ||
332 | } | ||
333 | case CharacterState::Walking: { | ||
334 | animName = "walk"; | ||
335 | break; | ||
336 | } | ||
337 | case CharacterState::Crouching: { | ||
338 | animName = "crouch"; | ||
339 | break; | ||
340 | } | ||
341 | case CharacterState::Running: { | ||
342 | animName = "run"; | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, animName); | ||
348 | |||
349 | break; | ||
350 | } | ||
351 | case CharacterMedium::Ladder: { | ||
352 | game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "climb."); | ||
353 | |||
354 | if (state == CharacterState::Still || state == CharacterState::Crouching) { | ||
355 | sprite.animPaused = true; | ||
356 | } else { | ||
357 | sprite.animPaused = false; | ||
358 | } | ||
359 | |||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | } | ||
diff --git a/src/character_system.h b/src/character_system.h index 79c1710..ef49d0e 100644 --- a/src/character_system.h +++ b/src/character_system.h | |||
@@ -47,6 +47,9 @@ private: | |||
47 | 47 | ||
48 | void stopRunningSound(Sprite& sprite); | 48 | void stopRunningSound(Sprite& sprite); |
49 | 49 | ||
50 | // state should be the party leader's state | ||
51 | void setAnimationFor(int spriteId, CharacterState state); | ||
52 | |||
50 | Game& game_; | 53 | Game& game_; |
51 | Timer inputTimer_ {33}; | 54 | Timer inputTimer_ {33}; |
52 | }; | 55 | }; |
diff --git a/src/map.cpp b/src/map.cpp index 4781231..0425962 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
@@ -44,6 +44,10 @@ Map::Map(std::string_view name) : name_(name) { | |||
44 | tile.blocked = true; | 44 | tile.blocked = true; |
45 | } else if (property.getName() == "runSound") { | 45 | } else if (property.getName() == "runSound") { |
46 | tile.step = stepTypeFromString(property.getStringValue()); | 46 | tile.step = stepTypeFromString(property.getStringValue()); |
47 | } else if (property.getName() == "medium") { | ||
48 | if (property.getStringValue() == "ladder") { | ||
49 | tile.medium = CharacterMedium::Ladder; | ||
50 | } | ||
47 | } | 51 | } |
48 | } | 52 | } |
49 | 53 | ||
@@ -178,3 +182,21 @@ StepType Map::getStepType(int x, int y) const { | |||
178 | 182 | ||
179 | return StepType::none; | 183 | return StepType::none; |
180 | } | 184 | } |
185 | |||
186 | CharacterMedium Map::getMedium(int x, int y) const { | ||
187 | CharacterMedium ret = CharacterMedium::Normal; | ||
188 | |||
189 | if (x < 0 || y < 0 || x >= mapSize_.w() || y >= mapSize_.h()) { | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | int i = x + y * mapSize_.w(); | ||
194 | |||
195 | for (const std::vector<Tile>& layer : lowerLayers_) { | ||
196 | if (layer.at(i).medium > ret) { | ||
197 | ret = layer.at(i).medium; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | return ret; | ||
202 | } | ||
diff --git a/src/map.h b/src/map.h index 9467d75..1a88cc8 100644 --- a/src/map.h +++ b/src/map.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <vector> | 7 | #include <vector> |
8 | #include "vector.h" | 8 | #include "vector.h" |
9 | #include "step_type.h" | 9 | #include "step_type.h" |
10 | #include "sprite.h" | ||
10 | 11 | ||
11 | struct Tile { | 12 | struct Tile { |
12 | unsigned int id = 0; | 13 | unsigned int id = 0; |
@@ -14,6 +15,7 @@ struct Tile { | |||
14 | bool flipVertical = false; | 15 | bool flipVertical = false; |
15 | bool blocked = false; | 16 | bool blocked = false; |
16 | StepType step = StepType::none; | 17 | StepType step = StepType::none; |
18 | CharacterMedium medium = CharacterMedium::Normal; | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | struct Prototype { | 21 | struct Prototype { |
@@ -64,6 +66,8 @@ public: | |||
64 | 66 | ||
65 | StepType getStepType(int x, int y) const; | 67 | StepType getStepType(int x, int y) const; |
66 | 68 | ||
69 | CharacterMedium getMedium(int x, int y) const; | ||
70 | |||
67 | const std::vector<Prototype>& getPrototypes() const { return prototypes_; } | 71 | const std::vector<Prototype>& getPrototypes() const { return prototypes_; } |
68 | 72 | ||
69 | const vec2i& getWarpPoint(const std::string& name) const { return warpPoints_.at(name); } | 73 | const vec2i& getWarpPoint(const std::string& name) const { return warpPoints_.at(name); } |
diff --git a/src/sprite.h b/src/sprite.h index 3d2e9df..59d2caf 100644 --- a/src/sprite.h +++ b/src/sprite.h | |||
@@ -23,6 +23,7 @@ struct SpriteFrame { | |||
23 | 23 | ||
24 | struct Animation { | 24 | struct Animation { |
25 | bool looping = true; | 25 | bool looping = true; |
26 | bool manual = false; | ||
26 | std::vector<int> frameIndices; | 27 | std::vector<int> frameIndices; |
27 | }; | 28 | }; |
28 | 29 | ||
@@ -33,9 +34,15 @@ enum class CharacterState { | |||
33 | Running | 34 | Running |
34 | }; | 35 | }; |
35 | 36 | ||
37 | enum class CharacterMedium { | ||
38 | Normal, | ||
39 | Ladder | ||
40 | }; | ||
41 | |||
36 | struct Movement { | 42 | struct Movement { |
37 | vec2i pos; | 43 | vec2i pos; |
38 | Direction dir; | 44 | Direction dir; |
45 | CharacterMedium medium; | ||
39 | }; | 46 | }; |
40 | 47 | ||
41 | class Sprite { | 48 | class Sprite { |
@@ -68,6 +75,7 @@ public: | |||
68 | std::map<std::string, std::map<Direction, int>> nameDirToAnim; | 75 | std::map<std::string, std::map<Direction, int>> nameDirToAnim; |
69 | bool animFinished = false; | 76 | bool animFinished = false; |
70 | bool hasShadow = false; | 77 | bool hasShadow = false; |
78 | bool animPaused = false; | ||
71 | 79 | ||
72 | // Character | 80 | // Character |
73 | bool orientable = false; | 81 | bool orientable = false; |
@@ -75,6 +83,8 @@ public: | |||
75 | std::vector<int> followers; | 83 | std::vector<int> followers; |
76 | std::deque<Movement> trail; | 84 | std::deque<Movement> trail; |
77 | CharacterState characterState = CharacterState::Still; | 85 | CharacterState characterState = CharacterState::Still; |
86 | CharacterMedium characterMedium = CharacterMedium::Normal; | ||
87 | Direction movementDir = Direction::down; | ||
78 | StepType stepType = StepType::none; | 88 | StepType stepType = StepType::none; |
79 | int runningSfxChannel = -1; | 89 | int runningSfxChannel = -1; |
80 | bool clipping = false; | 90 | bool clipping = false; |
diff --git a/src/transform_system.cpp b/src/transform_system.cpp index ee392f1..4056f46 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp | |||
@@ -72,7 +72,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
72 | enclosureZone = &map.getZone(sprite.enclosureZone); | 72 | enclosureZone = &map.getZone(sprite.enclosureZone); |
73 | } | 73 | } |
74 | 74 | ||
75 | if (dirHasDir(sprite.dir, Direction::right)) { | 75 | if (dirHasDir(dir, Direction::right)) { |
76 | if (newTileDR.x() > oldTileDR.x() && | 76 | if (newTileDR.x() > oldTileDR.x() && |
77 | newColDR.x() < mapBounds.w()) { | 77 | newColDR.x() < mapBounds.w()) { |
78 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { | 78 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { |
@@ -113,7 +113,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | if (dirHasDir(sprite.dir, Direction::left)) { | 116 | if (dirHasDir(dir, Direction::left)) { |
117 | if (newTileUL.x() < oldTileUL.x() && | 117 | if (newTileUL.x() < oldTileUL.x() && |
118 | newColUL.x() >= 0) { | 118 | newColUL.x() >= 0) { |
119 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { | 119 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { |
@@ -154,7 +154,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
154 | } | 154 | } |
155 | } | 155 | } |
156 | 156 | ||
157 | if (dirHasDir(sprite.dir, Direction::down)) { | 157 | if (dirHasDir(dir, Direction::down)) { |
158 | if (newTileDR.y() > oldTileDR.y() && | 158 | if (newTileDR.y() > oldTileDR.y() && |
159 | newColDR.y() < mapBounds.h()) { | 159 | newColDR.y() < mapBounds.h()) { |
160 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { | 160 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { |
@@ -195,7 +195,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
195 | } | 195 | } |
196 | } | 196 | } |
197 | 197 | ||
198 | if (dirHasDir(sprite.dir, Direction::up)) { | 198 | if (dirHasDir(dir, Direction::up)) { |
199 | if (newTileUL.y() < oldTileUL.y() && | 199 | if (newTileUL.y() < oldTileUL.y() && |
200 | newColUL.y() >= 0) { | 200 | newColUL.y() >= 0) { |
201 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { | 201 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { |
@@ -239,6 +239,29 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
239 | return result; | 239 | return result; |
240 | } | 240 | } |
241 | 241 | ||
242 | CharacterMedium TransformSystem::getMediumAtPosition(int spriteId, vec2i newLoc) { | ||
243 | Sprite& sprite = game_.getSprite(spriteId); | ||
244 | |||
245 | const Map& map = game_.getMap(); | ||
246 | |||
247 | vec2i newColUL = newLoc + sprite.collisionOffset; | ||
248 | vec2i newColDR = newColUL + sprite.collisionSize; | ||
249 | vec2i newTileUL = newColUL / map.getTileSize(); | ||
250 | vec2i newTileDR = newColDR / map.getTileSize(); | ||
251 | |||
252 | CharacterMedium result = CharacterMedium::Normal; | ||
253 | for (int y=newTileUL.y(); y<=newTileDR.y(); y++) { | ||
254 | for (int x=newTileUL.x(); x<=newTileDR.x(); x++) { | ||
255 | CharacterMedium tileMedium = map.getMedium(x, y); | ||
256 | if (tileMedium > result) { | ||
257 | result = tileMedium; | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | return result; | ||
263 | } | ||
264 | |||
242 | void TransformSystem::addCollidable(int spriteId) { | 265 | void TransformSystem::addCollidable(int spriteId) { |
243 | Sprite& sprite = game_.getSprite(spriteId); | 266 | Sprite& sprite = game_.getSprite(spriteId); |
244 | 267 | ||
diff --git a/src/transform_system.h b/src/transform_system.h index d894b30..a07447c 100644 --- a/src/transform_system.h +++ b/src/transform_system.h | |||
@@ -47,6 +47,8 @@ public: | |||
47 | 47 | ||
48 | CollisionResult checkCollision(int spriteId, vec2i newLoc, Direction dir); | 48 | CollisionResult checkCollision(int spriteId, vec2i newLoc, Direction dir); |
49 | 49 | ||
50 | CharacterMedium getMediumAtPosition(int spriteId, vec2i newLoc); | ||
51 | |||
50 | void destroySprite(int spriteId) override; | 52 | void destroySprite(int spriteId) override; |
51 | 53 | ||
52 | private: | 54 | private: |