Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snail stomping #1337

Merged
merged 7 commits into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion data/images/creatures/snail/snail.sprite
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,12 @@
(action (name "burning-right")
(hitbox 2 35 31.8 31.8)
(fps 15)
(mirror-action "burning-left")))
(mirror-action "burning-left"))

(action (name "shielded-left")
(hitbox 2 3 31.8 31.8)
(images "snowsnail_unflip.png"))

(action (name "shielded-right")
(hitbox 2 3 31.8 31.8)
(mirror-action "shielded-left")))
Binary file added data/images/creatures/snail/snowsnail_unflip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 62 additions & 9 deletions src/badguy/snail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@
#include "audio/sound_manager.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
#include "supertux/sector.hpp"

namespace {
const float SNAIL_KICK_SPEED = 500;
const int MAX_SNAIL_SQUISHES = 10;
const float SNAIL_KICK_SPEED_Y = -500; /**< y-velocity gained when kicked */
const float DANGER_SENSE_DIST = 25;
const float SHIELDED_TIME = 0.5f;
}

Snail::Snail(const ReaderMapping& reader) :
WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"),
state(STATE_NORMAL),
kicked_delay_timer(),
danger_gone_timer(),
squishcount(0)
{
walk_speed = 80;
Expand Down Expand Up @@ -74,23 +78,52 @@ void Snail::be_grabbed()
}

void
Snail::be_kicked()
Snail::be_kicked(bool upwards)
{
state = STATE_KICKED_DELAY;
if(upwards)
state = STATE_KICKED_DELAY;
else
state = STATE_KICKED;
m_sprite->set_action(m_dir == Direction::LEFT ? "flat-left" : "flat-right", 1);

m_physic.set_velocity_x(m_dir == Direction::LEFT ? -SNAIL_KICK_SPEED : SNAIL_KICK_SPEED);
m_physic.set_velocity_y(0);

// start a timer to delay addition of upward movement until we are (hopefully) out from under the player
kicked_delay_timer.start(0.05f);
if (upwards)
kicked_delay_timer.start(0.05f);
}

void
Snail::be_shielded()
{
state = STATE_SHIELDED;

m_physic.set_velocity_x(0);
m_physic.set_velocity_y(0);

m_sprite->set_action(m_dir == Direction::LEFT ? "shielded-left" : "shielded-right");

danger_gone_timer.start(SHIELDED_TIME);
}

bool
Snail::can_break() const {
return state == STATE_KICKED;
}

bool
Snail::is_in_danger()
{
Rectf sense_zone = get_bbox().moved(Vector(0, -DANGER_SENSE_DIST));
auto player = Sector::get().get_nearest_player(get_bbox());
if (player && sense_zone.contains(player->get_bbox()) && player->get_velocity().y > 0)
{
return true;
}
return false;
}

void
Snail::active_update(float dt_sec)
{
Expand All @@ -103,6 +136,11 @@ Snail::active_update(float dt_sec)
return;
}

if(state == STATE_NORMAL && is_in_danger())
{
be_shielded();
}

switch (state) {

case STATE_NORMAL:
Expand Down Expand Up @@ -130,6 +168,13 @@ Snail::active_update(float dt_sec)

case STATE_GRABBED:
break;

case STATE_SHIELDED:
if (danger_gone_timer.check())
{
be_normal();
}
break;
}

BadGuy::active_update(dt_sec);
Expand All @@ -156,6 +201,7 @@ Snail::collision_solid(const CollisionHit& hit)
switch (state)
{
case STATE_NORMAL:
case STATE_SHIELDED:
WalkingBadguy::collision_solid(hit);
return;

Expand Down Expand Up @@ -194,6 +240,7 @@ Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)

switch (state) {
case STATE_NORMAL:
case STATE_SHIELDED:
return WalkingBadguy::collision_badguy(badguy, hit);
case STATE_FLAT:
case STATE_KICKED_DELAY:
Expand Down Expand Up @@ -222,7 +269,7 @@ Snail::collision_player(Player& player, const CollisionHit& hit)
m_dir = Direction::LEFT;
}
player.kick();
be_kicked();
be_kicked(false);
return FORCE_MOVE;
}

Expand All @@ -236,17 +283,23 @@ Snail::collision_squished(GameObject& object)
return WalkingBadguy::collision_squished(object);

Player* player = dynamic_cast<Player*>(&object);
if (player && (player->m_does_buttjump || player->is_invincible())) {
if (player && player->is_invincible()) {
kill_fall();
player->bounce(*this);
return true;
}

switch (state) {

case STATE_KICKED:
case STATE_SHIELDED:
case STATE_NORMAL:

if(player && !player->m_does_buttjump)
{
player->bounce(*this);
break;
}
BOOST_FALLTHROUGH;
case STATE_KICKED:
squishcount++;
if (squishcount >= MAX_SNAIL_SQUISHES) {
kill_fall();
Expand All @@ -266,7 +319,7 @@ Snail::collision_squished(GameObject& object)
m_dir = Direction::LEFT;
}
}
be_kicked();
be_kicked(true);
break;
case STATE_GRABBED:
case STATE_KICKED_DELAY:
Expand Down Expand Up @@ -296,7 +349,7 @@ Snail::ungrab(MovingObject& object, Direction dir_)
be_flat();
} else {
m_dir = dir_;
be_kicked();
be_kicked(true);
}
set_colgroup_active(COLGROUP_MOVING);
Portable::ungrab(object, dir_);
Expand Down
8 changes: 6 additions & 2 deletions src/badguy/snail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,28 @@ class Snail final :

protected:
virtual bool collision_squished(GameObject& object) override;
bool is_in_danger();

void be_normal(); /**< switch to state STATE_NORMAL */
void be_flat(); /**< switch to state STATE_FLAT */
void be_kicked(); /**< switch to state STATE_KICKED_DELAY */
void be_kicked(bool upwards); /**< switch to state STATE_KICKED_DELAY */
void be_grabbed();
void be_shielded();

private:
enum State {
STATE_NORMAL, /**< walking around */
STATE_FLAT, /**< flipped upside-down */
STATE_KICKED_DELAY, /**< short delay before being launched */
STATE_KICKED, /**< launched */
STATE_GRABBED /**< grabbed by tux */
STATE_GRABBED, /**< grabbed by tux */
STATE_SHIELDED /*< hidden into shell for protection */
};

private:
State state;
Timer kicked_delay_timer; /**< wait time until switching from STATE_KICKED_DELAY to STATE_KICKED */
Timer danger_gone_timer; /**< time after which snail turns back from STATE_SHELLED */
int squishcount;

private:
Expand Down