Generalized code for changing frozen badguy sprite to iced, and added a default behavior for freezable badguys without iced graphics. Frozen badguys no longer unfreeze on touch. Added ice vulnerability to forest badguys.
Note: there are some mild bugs as a result of this change, which should be fixed in subsequent improvements to make Iceflower a more viable powerup.
(mirror-action "left-middle"))
(action
- (name "left-iced")
+ (name "iced-left")
(hitbox 7 8 31.8 31.8)
(images "iced-left-up.png"))
(action
- (name "right-iced")
+ (name "iced-right")
(hitbox 7 8 31.8 31.8)
- (mirror-action "left-iced"))
+ (mirror-action "iced-left"))
)
(mirror-action "left-middle"))
(action
- (name "left-iced")
+ (name "iced-left")
(hitbox 7 8 31.8 31.8)
(images "iced-left-up.png"))
(action
- (name "right-iced")
+ (name "iced-right")
(hitbox 7 8 31.8 31.8)
- (mirror-action "left-iced"))
+ (mirror-action "iced-left"))
)
BadGuy::active_update(float elapsed_time)
{
movement = physic.get_movement(elapsed_time);
+ if(frozen)
+ sprite->stop_animation();
}
void
return ABORT_MOVE;
}
+ //TODO: unfreeze timer
if(frozen)
- unfreeze();
+ //unfreeze();
+ return FORCE_MOVE;
+
player.kill(false);
return FORCE_MOVE;
}
{
set_group(COLGROUP_MOVING_STATIC);
frozen = true;
+
+ if(sprite->has_action("iced-left"))
+ sprite->set_action(dir == LEFT ? "iced-left" : "iced-right", 1);
+ // when no iced action exists, default to shading badguy blue
+ else
+ {
+ sprite->set_color(Color(0.60, 0.72, 0.88f));
+ sprite->stop_animation();
+ }
}
void
{
set_group(colgroup_active);
frozen = false;
+
+ // restore original color if needed
+ if(!sprite->has_action("iced-left"))
+ {
+ sprite->set_color(Color(1.00, 1.00, 1.00f));
+ sprite->set_animation_loops();
+ }
}
bool
{
BadGuy::freeze();
sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
+ sprite->set_color(Color(1.0f, 1.0f, 1.0f));
waiting.stop();
}
{
if(tstate == STATE_NORMAL){
WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
}
}
run_dead_script();
}
-void
-Haywire::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
bool
Haywire::is_freezable() const
{
void active_update(float elapsed_time);
- void freeze();
bool is_freezable() const;
protected:
HitResponse
Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
{
- // default reaction if hit on front side
- if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) {
+ // default reaction if hit on front side or for freeze and unfreeze
+ if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right) ||
+ (bullet.get_type() == ICE_BONUS) || ((bullet.get_type() == FIRE_BONUS) && (frozen))) {
return BadGuy::collision_bullet(bullet, hit);
}
}
bool
+Igel::is_freezable() const
+{
+ return true;
+}
+
+bool
Igel::collision_squished(GameObject& )
{
// this will hurt
void active_update(float elapsed_time);
+ bool is_freezable() const;
+
protected:
bool collision_squished(GameObject& object);
void be_normal(); /**< switch to state STATE_NORMAL */
{
BadGuy::freeze();
physic.set_velocity_y(std::max(0.0f, physic.get_velocity_y()));
- sprite->set_action(dir == LEFT ? "left-iced" : "right-iced");
}
bool
bool
Mole::collision_squished(GameObject& )
{
+ if (frozen)
+ return true;
+
set_state(DEAD);
sound_manager->play("sounds/squish.wav", get_pos());
run_dead_script();
{
BadGuy::active_update(elapsed_time);
+ if (frozen)
+ return;
+
switch (state) {
case PRE_THROWING:
if (timer.check()) {
}
+bool
+Mole::is_freezable() const
+{
+ return true;
+}
+
void
Mole::set_state(MoleState new_state)
{
+ if (frozen)
+ return;
+
switch (new_state) {
case PRE_THROWING:
sprite->set_action("idle");
void activate();
void active_update(float);
+ bool is_freezable() const;
+
private:
enum MoleState {
PRE_THROWING,
grabbed = false;
}
-void
-MrBomb::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
bool
MrBomb::is_freezable() const
{
void ungrab(MovingObject& object, Direction dir);
bool is_portable() const;
- void freeze();
bool is_freezable() const;
protected:
}
bool
+MrTree::is_freezable() const
+{
+ return true;
+}
+
+bool
MrTree::collision_squished(GameObject& object)
{
// replace with Stumpy
public:
MrTree(const Reader& reader);
+ bool is_freezable() const;
+
protected:
bool collision_squished(GameObject& object);
{
BadGuy::active_update (elapsed_time);
+ if(frozen)
+ return;
+
if (carried_object != NULL) {
if (!is_above_player ()) {
Vector obj_pos = get_anchor_pos (bbox, ANCHOR_BOTTOM);
}
void
+Owl::freeze()
+{
+ if (carried_object != NULL) {
+ carried_object->ungrab (*this, dir);
+ carried_object = NULL;
+ }
+ physic.enable_gravity(true);
+ BadGuy::freeze();
+}
+
+void
+Owl::unfreeze()
+{
+ BadGuy::unfreeze();
+ physic.set_velocity_x(dir == LEFT ? -FLYING_SPEED : FLYING_SPEED);
+ physic.enable_gravity(false);
+ sprite->set_action(dir == LEFT ? "left" : "right");
+}
+
+bool
+Owl::is_freezable() const
+{
+ return true;
+}
+
+void
Owl::collision_solid(const CollisionHit& hit)
{
+ if(frozen)
+ {
+ BadGuy::collision_solid(hit);
+ return;
+ }
if(hit.top || hit.bottom) {
physic.set_velocity_y(0);
} else if(hit.left || hit.right) {
void collision_solid(const CollisionHit& hit);
void kill_fall();
+ void freeze();
+ void unfreeze();
+ bool is_freezable() const;
+
protected:
bool is_above_player (void);
void active_update (float elapsed_time);
}
bool
+PoisonIvy::is_freezable() const
+{
+ return true;
+}
+
+bool
PoisonIvy::collision_squished(GameObject& object)
{
sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
PoisonIvy(const Reader& reader);
PoisonIvy(const Vector& pos, Direction d);
+ bool is_freezable() const;
+
protected:
bool collision_squished(GameObject& object);
bool
SkullyHop::collision_squished(GameObject& object)
{
+ if (frozen)
+ return BadGuy::collision_squished(object);
+
sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
kill_squished(object);
return true;
void
SkullyHop::collision_solid(const CollisionHit& hit)
{
+ if (frozen)
+ {
+ BadGuy::collision_solid(hit);
+ return;
+ }
+
// just default behaviour (i.e. stop at floor/walls) when squished
if (BadGuy::get_state() == STATE_SQUISHED) {
BadGuy::collision_solid(hit);
{
BadGuy::active_update(elapsed_time);
+ // no change if frozen
+ if (frozen)
+ return;
+
// charge when fully recovered
if ((state == STANDING) && (recover_timer.check())) {
set_state(CHARGING);
}
}
+void
+SkullyHop::unfreeze()
+{
+ BadGuy::unfreeze();
+ initialize();
+}
+
+bool
+SkullyHop::is_freezable() const
+{
+ return true;
+}
+
/* EOF */
bool collision_squished(GameObject& object);
void active_update(float elapsed_time);
+ void unfreeze();
+ bool is_freezable() const;
+
private:
enum SkullyHopState {
STANDING,
void
Snail::active_update(float elapsed_time)
{
+ if(frozen)
+ {
+ BadGuy::active_update(elapsed_time);
+ return;
+ }
+
switch (state) {
case STATE_NORMAL:
BadGuy::active_update(elapsed_time);
}
+bool
+Snail::is_freezable() const
+{
+ return true;
+}
+
void
Snail::collision_solid(const CollisionHit& hit)
{
+ if(frozen)
+ {
+ WalkingBadguy::collision_solid(hit);
+ return;
+ }
+
switch (state) {
case STATE_NORMAL:
WalkingBadguy::collision_solid(hit);
HitResponse
Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
{
+ if(frozen)
+ return WalkingBadguy::collision_badguy(badguy, hit);
+
switch(state) {
case STATE_NORMAL:
return WalkingBadguy::collision_badguy(badguy, hit);
HitResponse
Snail::collision_player(Player& player, const CollisionHit& hit)
{
+ if(frozen)
+ return WalkingBadguy::collision_player(player, hit);
+
// handle kicks from left or right side
if(state == STATE_FLAT && (hit.left || hit.right)) {
if(hit.left) {
bool
Snail::collision_squished(GameObject& object)
{
+ if(frozen)
+ return WalkingBadguy::collision_squished(object);
+
Player* player = dynamic_cast<Player*>(&object);
if(player && (player->does_buttjump || player->is_invincible())) {
kill_fall();
void active_update(float elapsed_time);
+ bool is_freezable() const;
+
protected:
bool collision_squished(GameObject& object);
void be_normal(); /**< switch to state STATE_NORMAL */
void
SpiderMite::active_update(float elapsed_time)
{
+ if(frozen)
+ {
+ BadGuy::active_update(elapsed_time);
+ return;
+ }
if(timer.check()) {
if(mode == FLY_UP) {
mode = FLY_DOWN;
}
}
+void
+SpiderMite::freeze()
+{
+ physic.enable_gravity(true);
+ BadGuy::freeze();
+}
+
+void
+SpiderMite::unfreeze()
+{
+ BadGuy::unfreeze();
+ physic.enable_gravity(false);
+ initialize();
+}
+
+bool
+SpiderMite::is_freezable() const
+{
+ return true;
+}
+
/* EOF */
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
+ void freeze();
+ void unfreeze();
+ bool is_freezable() const;
+
protected:
enum SpiderMiteMode {
FLY_UP,
max_drop_height = 600;
}
-void
-Spiky::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
bool
Spiky::is_freezable() const
{
public:
Spiky(const Reader& reader);
- void freeze();
bool is_freezable() const;
private:
SSpiky::freeze()
{
WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
state = SSPIKY_WALKING; // if we get hit while sleeping, wake up :)
}
return CONTINUE;
}
+bool
+Stumpy::is_freezable() const
+{
+ return true;
+}
+
/* EOF */
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
+ bool is_freezable() const;
+
protected:
enum MyState {
STATE_INVINCIBLE, STATE_NORMAL
void
Toad::set_state(ToadState newState)
{
+
if (newState == IDLE) {
physic.set_velocity_x(0);
physic.set_velocity_y(0);
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
+ if (!frozen)
+ sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
recover_timer.start(TOAD_RECOVER_TIME);
} else
void
Toad::collision_solid(const CollisionHit& hit)
{
+ // default behavior when frozen
+ if (frozen)
+ {
+ BadGuy::collision_solid(hit);
+ return;
+ }
+
// just default behaviour (i.e. stop at floor/walls) when squished
if (BadGuy::get_state() == STATE_SQUISHED) {
BadGuy::collision_solid(hit);
{
BadGuy::active_update(elapsed_time);
- // change sprite when we are falling
- if ((state == JUMPING) && (physic.get_velocity_y() > 0)) {
+
+ // change sprite when we are falling and not frozen
+ if ((state == JUMPING) && (physic.get_velocity_y() > 0) && !frozen) {
set_state(FALLING);
return;
}
- // jump when fully recovered
- if ((state == IDLE) && (recover_timer.check())) {
+ // jump when fully recovered and if not frozen
+ if ((state == IDLE) && (recover_timer.check() && !frozen)) {
set_state(JUMPING);
return;
}
}
+void
+Toad::unfreeze()
+{
+ BadGuy::unfreeze();
+ initialize();
+}
+
+bool
+Toad::is_freezable() const
+{
+ return true;
+}
+
/* EOF */
bool collision_squished(GameObject& object);
void active_update(float elapsed_time);
+ void unfreeze();
+ bool is_freezable() const;
+
protected:
enum ToadState {
IDLE,
return true;
}
+bool
+WalkingLeaf::is_freezable() const
+{
+ return true;
+}
/* EOF */
WalkingLeaf(const Reader& reader);
WalkingLeaf(const Vector& pos, Direction d);
+ bool is_freezable() const;
+
protected:
bool collision_squished(GameObject& object);
void
Zeekling::onBumpHorizontal() {
+ if (frozen)
+ {
+ physic.set_velocity_x(0);
+ return;
+ }
if (state == FLYING) {
dir = (dir == LEFT ? RIGHT : LEFT);
sprite->set_action(dir == LEFT ? "left" : "right");
void
Zeekling::onBumpVertical() {
+ if (frozen)
+ {
+ physic.set_velocity_y(0);
+ physic.set_velocity_x(0);
+ return;
+ }
if (state == FLYING) {
physic.set_velocity_y(0);
} else
*/
bool
Zeekling::should_we_dive() {
+ if (frozen)
+ return false;
const MovingObject* player = this->get_nearest_player();
if (player && last_player && (player == last_player)) {
}
}
+void
+Zeekling::freeze()
+{
+ BadGuy::freeze();
+ physic.enable_gravity(true);
+}
+
+void
+Zeekling::unfreeze()
+{
+ BadGuy::unfreeze();
+ physic.enable_gravity(false);
+ state = FLYING;
+ initialize();
+}
+
+bool
+Zeekling::is_freezable() const
+{
+ return true;
+}
+
/* EOF */
void collision_solid(const CollisionHit& hit);
void active_update(float elapsed_time);
+ void freeze();
+ void unfreeze();
+ bool is_freezable() const;
+
private:
bool collision_squished(GameObject& object);
bool should_we_dive();