Skip to content

Commit d5b171e

Browse files
Merge pull request #518 from lethal-guitar/fix-item-boxes
Make item container release sequence match the original
2 parents 8af75ea + 82743cd commit d5b171e

4 files changed

Lines changed: 75 additions & 24 deletions

File tree

src/game_logic/entity_configuration.ipp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,6 @@ const int FLY_ANIMATION_SEQUENCE[] = { 0, 1, 2, 1 };
6767
const int BOSS4_PROJECTILE_SPAWN_ANIM_SEQ[] = { 0, 1, 1, 2, 2, 3, 3, 4 };
6868

6969

70-
const base::Point<float> CONTAINER_BOUNCE_SEQUENCE[] = {
71-
{0.0f, -3.0f},
72-
{0.0f, -2.0f},
73-
{0.0f, -1.0f},
74-
{0.0f, 0.0f},
75-
{0.0f, 1.0f},
76-
{0.0f, 2.0f},
77-
{0.0f, 3.0f},
78-
{0.0f, -1.0f},
79-
{0.0f, 1.0f}
80-
};
81-
82-
8370
#include "destruction_effect_specs.ipp"
8471

8572

@@ -759,11 +746,9 @@ void EntityFactory::configureItemBox(
759746
addToContainer(
760747
container,
761748
Active{},
762-
MovementSequence{
763-
CONTAINER_BOUNCE_SEQUENCE, ResetAfterSequence{true}, EnableX{false}});
764-
addDefaultMovingBody(
765-
container,
766-
engine::inferBoundingBox(*entity.component<Sprite>(), entity));
749+
MovingBody{Velocity{0.0f, 0.0f}, GravityAffected{false}},
750+
engine::inferBoundingBox(*entity.component<Sprite>(), entity),
751+
ActivationSettings{ActivationSettings::Policy::Always});
767752

768753
auto containerSprite = createSpriteForId(actorIdForBoxColor(color));
769754
turnIntoContainer(entity, containerSprite, givenScore, std::move(container));
@@ -1072,7 +1057,7 @@ void EntityFactory::configureEntity(
10721057
std::move(livingTurkeyContainer));
10731058
entity.assign<DestructionEffects>(CONTAINER_BOX_KILL_EFFECT_SPEC);
10741059
entity.component<ItemContainer>()->mStyle =
1075-
ItemContainer::ReleaseStyle::ItemBox;
1060+
ItemContainer::ReleaseStyle::ItemBoxNoBounce;
10761061
entity.assign<AppearsOnRadar>();
10771062
}
10781063
break;
@@ -1993,6 +1978,7 @@ void EntityFactory::configureEntity(
19931978
PlayerDamaging{Damage{1}},
19941979
AnimationLoop{1},
19951980
AutoDestroy::afterTimeout(numAnimationFrames),
1981+
ActivationSettings{ActivationSettings::Policy::Always},
19961982
Active{});
19971983
container.mStyle = ItemContainer::ReleaseStyle::NuclearWasteBarrel;
19981984

src/game_logic/ingame_systems.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ IngameSystems::IngameSystems(
115115
pEntityFactory,
116116
&mParticles,
117117
eventManager)
118-
, mItemContainerSystem(&entities, eventManager)
118+
, mItemContainerSystem(&entities, &mCollisionChecker, eventManager)
119119
, mBlueGuardSystem(
120120
&mPlayer,
121121
&mCollisionChecker,
@@ -230,6 +230,7 @@ void IngameSystems::update(
230230
// Physics and other updates
231231
// ----------------------------------------------------------------------
232232
mPhysicsSystem.updatePhase1(es);
233+
mItemContainerSystem.updateItemBounce(es);
233234

234235
// Collect items after physics, so that any collectible
235236
// items are in their final positions for this frame.

src/game_logic/interactive/item_container.cpp

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,38 @@
3232

3333
namespace rigel::game_logic {
3434

35+
namespace {
36+
3537
using engine::components::Active;
3638
using engine::components::BoundingBox;
39+
using engine::components::MovingBody;
3740
using engine::components::Sprite;
3841
using engine::components::WorldPosition;
3942
using game_logic::components::ItemContainer;
4043

44+
constexpr int ITEM_BOUNCE_SEQUENCE[] = {-3, -2, -1, 0, 1, 2, 3, -1, 1};
45+
46+
47+
struct ItemBounceEffect {
48+
explicit ItemBounceEffect(const float fallVelocity)
49+
: mFallVelocity(fallVelocity)
50+
{
51+
}
52+
53+
int mFramesElapsed = 1;
54+
float mFallVelocity = 0.0f;
55+
};
56+
57+
}
58+
4159

4260
ItemContainerSystem::ItemContainerSystem(
4361
entityx::EntityManager* pEntityManager,
62+
const engine::CollisionChecker* pCollisionChecker,
4463
entityx::EventManager& events
4564
)
4665
: mpEntityManager(pEntityManager)
66+
, mpCollisionChecker(pCollisionChecker)
4767
{
4868
events.subscribe<events::ShootableKilled>(*this);
4969
}
@@ -62,8 +82,7 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
6282
}
6383

6484
contents.assign<WorldPosition>(*entity.component<WorldPosition>());
65-
66-
entity.destroy();
85+
return contents;
6786
};
6887

6988
for (auto& entity : mShotContainersQueue) {
@@ -72,15 +91,26 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
7291
switch (container.mStyle) {
7392
case RS::Default:
7493
releaseItem(entity, container.mContainedComponents);
94+
entity.destroy();
7595
break;
7696

7797
case RS::ItemBox:
98+
case RS::ItemBoxNoBounce:
7899
++container.mFramesElapsed;
79100

80101
if (container.mFramesElapsed == 1) {
81102
entity.component<Sprite>()->flashWhite();
82103
} else if (container.mFramesElapsed == 2) {
83-
releaseItem(entity, container.mContainedComponents);
104+
auto item = releaseItem(entity, container.mContainedComponents);
105+
106+
if (container.mStyle != RS::ItemBoxNoBounce) {
107+
const auto fallVelocity =
108+
entity.component<MovingBody>()->mVelocity.y;
109+
item.assign<ItemBounceEffect>(fallVelocity);
110+
item.component<WorldPosition>()->y += ITEM_BOUNCE_SEQUENCE[0];
111+
}
112+
113+
entity.destroy();
84114
}
85115
break;
86116

@@ -97,6 +127,7 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
97127
entity.component<Sprite>()->mShow = false;
98128
} else if (container.mFramesElapsed == 4) {
99129
releaseItem(entity, container.mContainedComponents);
130+
entity.destroy();
100131
}
101132
break;
102133
}
@@ -111,6 +142,35 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
111142
}
112143

113144

145+
void ItemContainerSystem::updateItemBounce(entityx::EntityManager& es) {
146+
es.each<WorldPosition, BoundingBox, MovingBody, ItemBounceEffect>(
147+
[this](
148+
entityx::Entity entity,
149+
WorldPosition& position,
150+
const BoundingBox& bbox,
151+
MovingBody& body,
152+
ItemBounceEffect& state
153+
) {
154+
position.y += ITEM_BOUNCE_SEQUENCE[state.mFramesElapsed];
155+
156+
const auto hasLanded =
157+
mpCollisionChecker->isOnSolidGround(position, bbox);
158+
if (
159+
(state.mFramesElapsed == 7 && !hasLanded) ||
160+
state.mFramesElapsed == 9
161+
) {
162+
body.mGravityAffected = true;
163+
body.mVelocity.y = state.mFallVelocity;
164+
}
165+
166+
++state.mFramesElapsed;
167+
if (state.mFramesElapsed == 9) {
168+
entity.remove<ItemBounceEffect>();
169+
}
170+
});
171+
}
172+
173+
114174
void ItemContainerSystem::receive(const events::ShootableKilled& event) {
115175
auto entity = event.mEntity;
116176
if (entity.has_component<ItemContainer>()) {
@@ -194,7 +254,7 @@ void NapalmBomb::explode(GlobalDependencies& d, entityx::Entity entity) {
194254
mState = NapalmBomb::State::SpawningFires;
195255
mFramesElapsed = 0;
196256
entity.component<Sprite>()->mShow = false;
197-
entity.remove<engine::components::MovingBody>();
257+
entity.remove<MovingBody>();
198258
entity.remove<game_logic::components::AppearsOnRadar>();
199259

200260
// Once the bomb explodes, it counts towards bonus 6. This means we need to

src/game_logic/interactive/item_container.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct ItemContainer {
8383
enum class ReleaseStyle : std::uint8_t {
8484
Default,
8585
ItemBox,
86+
ItemBoxNoBounce,
8687
NuclearWasteBarrel
8788
};
8889

@@ -103,13 +104,16 @@ class ItemContainerSystem : public entityx::Receiver<ItemContainerSystem> {
103104
public:
104105
ItemContainerSystem(
105106
entityx::EntityManager* pEntityManager,
107+
const engine::CollisionChecker* pCollisionChecker,
106108
entityx::EventManager& events);
107109

108110
void update(entityx::EntityManager& es);
111+
void updateItemBounce(entityx::EntityManager& es);
109112
void receive(const events::ShootableKilled& event);
110113

111114
private:
112115
entityx::EntityManager* mpEntityManager;
116+
const engine::CollisionChecker* mpCollisionChecker;
113117
std::vector<entityx::Entity> mShotContainersQueue;
114118
};
115119

0 commit comments

Comments
 (0)