Skip to content

Commit

Permalink
Merge pull request #518 from lethal-guitar/fix-item-boxes
Browse files Browse the repository at this point in the history
Make item container release sequence match the original
  • Loading branch information
lethal-guitar authored May 10, 2020
2 parents 8af75ea + 82743cd commit d5b171e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 24 deletions.
24 changes: 5 additions & 19 deletions src/game_logic/entity_configuration.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,6 @@ const int FLY_ANIMATION_SEQUENCE[] = { 0, 1, 2, 1 };
const int BOSS4_PROJECTILE_SPAWN_ANIM_SEQ[] = { 0, 1, 1, 2, 2, 3, 3, 4 };


const base::Point<float> CONTAINER_BOUNCE_SEQUENCE[] = {
{0.0f, -3.0f},
{0.0f, -2.0f},
{0.0f, -1.0f},
{0.0f, 0.0f},
{0.0f, 1.0f},
{0.0f, 2.0f},
{0.0f, 3.0f},
{0.0f, -1.0f},
{0.0f, 1.0f}
};


#include "destruction_effect_specs.ipp"


Expand Down Expand Up @@ -759,11 +746,9 @@ void EntityFactory::configureItemBox(
addToContainer(
container,
Active{},
MovementSequence{
CONTAINER_BOUNCE_SEQUENCE, ResetAfterSequence{true}, EnableX{false}});
addDefaultMovingBody(
container,
engine::inferBoundingBox(*entity.component<Sprite>(), entity));
MovingBody{Velocity{0.0f, 0.0f}, GravityAffected{false}},
engine::inferBoundingBox(*entity.component<Sprite>(), entity),
ActivationSettings{ActivationSettings::Policy::Always});

auto containerSprite = createSpriteForId(actorIdForBoxColor(color));
turnIntoContainer(entity, containerSprite, givenScore, std::move(container));
Expand Down Expand Up @@ -1072,7 +1057,7 @@ void EntityFactory::configureEntity(
std::move(livingTurkeyContainer));
entity.assign<DestructionEffects>(CONTAINER_BOX_KILL_EFFECT_SPEC);
entity.component<ItemContainer>()->mStyle =
ItemContainer::ReleaseStyle::ItemBox;
ItemContainer::ReleaseStyle::ItemBoxNoBounce;
entity.assign<AppearsOnRadar>();
}
break;
Expand Down Expand Up @@ -1993,6 +1978,7 @@ void EntityFactory::configureEntity(
PlayerDamaging{Damage{1}},
AnimationLoop{1},
AutoDestroy::afterTimeout(numAnimationFrames),
ActivationSettings{ActivationSettings::Policy::Always},
Active{});
container.mStyle = ItemContainer::ReleaseStyle::NuclearWasteBarrel;

Expand Down
3 changes: 2 additions & 1 deletion src/game_logic/ingame_systems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ IngameSystems::IngameSystems(
pEntityFactory,
&mParticles,
eventManager)
, mItemContainerSystem(&entities, eventManager)
, mItemContainerSystem(&entities, &mCollisionChecker, eventManager)
, mBlueGuardSystem(
&mPlayer,
&mCollisionChecker,
Expand Down Expand Up @@ -230,6 +230,7 @@ void IngameSystems::update(
// Physics and other updates
// ----------------------------------------------------------------------
mPhysicsSystem.updatePhase1(es);
mItemContainerSystem.updateItemBounce(es);

// Collect items after physics, so that any collectible
// items are in their final positions for this frame.
Expand Down
68 changes: 64 additions & 4 deletions src/game_logic/interactive/item_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,38 @@

namespace rigel::game_logic {

namespace {

using engine::components::Active;
using engine::components::BoundingBox;
using engine::components::MovingBody;
using engine::components::Sprite;
using engine::components::WorldPosition;
using game_logic::components::ItemContainer;

constexpr int ITEM_BOUNCE_SEQUENCE[] = {-3, -2, -1, 0, 1, 2, 3, -1, 1};


struct ItemBounceEffect {
explicit ItemBounceEffect(const float fallVelocity)
: mFallVelocity(fallVelocity)
{
}

int mFramesElapsed = 1;
float mFallVelocity = 0.0f;
};

}


ItemContainerSystem::ItemContainerSystem(
entityx::EntityManager* pEntityManager,
const engine::CollisionChecker* pCollisionChecker,
entityx::EventManager& events
)
: mpEntityManager(pEntityManager)
, mpCollisionChecker(pCollisionChecker)
{
events.subscribe<events::ShootableKilled>(*this);
}
Expand All @@ -62,8 +82,7 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
}

contents.assign<WorldPosition>(*entity.component<WorldPosition>());

entity.destroy();
return contents;
};

for (auto& entity : mShotContainersQueue) {
Expand All @@ -72,15 +91,26 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
switch (container.mStyle) {
case RS::Default:
releaseItem(entity, container.mContainedComponents);
entity.destroy();
break;

case RS::ItemBox:
case RS::ItemBoxNoBounce:
++container.mFramesElapsed;

if (container.mFramesElapsed == 1) {
entity.component<Sprite>()->flashWhite();
} else if (container.mFramesElapsed == 2) {
releaseItem(entity, container.mContainedComponents);
auto item = releaseItem(entity, container.mContainedComponents);

if (container.mStyle != RS::ItemBoxNoBounce) {
const auto fallVelocity =
entity.component<MovingBody>()->mVelocity.y;
item.assign<ItemBounceEffect>(fallVelocity);
item.component<WorldPosition>()->y += ITEM_BOUNCE_SEQUENCE[0];
}

entity.destroy();
}
break;

Expand All @@ -97,6 +127,7 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
entity.component<Sprite>()->mShow = false;
} else if (container.mFramesElapsed == 4) {
releaseItem(entity, container.mContainedComponents);
entity.destroy();
}
break;
}
Expand All @@ -111,6 +142,35 @@ void ItemContainerSystem::update(entityx::EntityManager& es) {
}


void ItemContainerSystem::updateItemBounce(entityx::EntityManager& es) {
es.each<WorldPosition, BoundingBox, MovingBody, ItemBounceEffect>(
[this](
entityx::Entity entity,
WorldPosition& position,
const BoundingBox& bbox,
MovingBody& body,
ItemBounceEffect& state
) {
position.y += ITEM_BOUNCE_SEQUENCE[state.mFramesElapsed];

const auto hasLanded =
mpCollisionChecker->isOnSolidGround(position, bbox);
if (
(state.mFramesElapsed == 7 && !hasLanded) ||
state.mFramesElapsed == 9
) {
body.mGravityAffected = true;
body.mVelocity.y = state.mFallVelocity;
}

++state.mFramesElapsed;
if (state.mFramesElapsed == 9) {
entity.remove<ItemBounceEffect>();
}
});
}


void ItemContainerSystem::receive(const events::ShootableKilled& event) {
auto entity = event.mEntity;
if (entity.has_component<ItemContainer>()) {
Expand Down Expand Up @@ -194,7 +254,7 @@ void NapalmBomb::explode(GlobalDependencies& d, entityx::Entity entity) {
mState = NapalmBomb::State::SpawningFires;
mFramesElapsed = 0;
entity.component<Sprite>()->mShow = false;
entity.remove<engine::components::MovingBody>();
entity.remove<MovingBody>();
entity.remove<game_logic::components::AppearsOnRadar>();

// Once the bomb explodes, it counts towards bonus 6. This means we need to
Expand Down
4 changes: 4 additions & 0 deletions src/game_logic/interactive/item_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct ItemContainer {
enum class ReleaseStyle : std::uint8_t {
Default,
ItemBox,
ItemBoxNoBounce,
NuclearWasteBarrel
};

Expand All @@ -103,13 +104,16 @@ class ItemContainerSystem : public entityx::Receiver<ItemContainerSystem> {
public:
ItemContainerSystem(
entityx::EntityManager* pEntityManager,
const engine::CollisionChecker* pCollisionChecker,
entityx::EventManager& events);

void update(entityx::EntityManager& es);
void updateItemBounce(entityx::EntityManager& es);
void receive(const events::ShootableKilled& event);

private:
entityx::EntityManager* mpEntityManager;
const engine::CollisionChecker* mpCollisionChecker;
std::vector<entityx::Entity> mShotContainersQueue;
};

Expand Down

0 comments on commit d5b171e

Please sign in to comment.