static const float Y_OFFSCREEN_DISTANCE = 1200;
BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT)
+ : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false)
{
start_position = bbox.p1;
}
BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), state(STATE_INIT)
+ : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), state(STATE_INIT), on_ground_flag(false)
{
start_position = bbox.p1;
}
BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer)
- : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT)
+ : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false)
{
start_position = bbox.p1;
if (state == STATE_ACTIVE) deactivate();
set_state(STATE_INACTIVE);
}
-
+
switch(state) {
case STATE_ACTIVE:
active_update(elapsed_time);
movement = physic.get_movement(elapsed_time);
break;
}
+
+ on_ground_flag = false;
}
Direction
return AUTO;
if( dir_str == "left" )
return LEFT;
- if( dir_str == "right" )
+ if( dir_str == "right" )
return RIGHT;
//default to "auto"
- log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"\n";
- return dir;
+ log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"" << std::endl;;
+ return AUTO;
}
void
void
BadGuy::save(lisp::Writer& )
{
- log_warning << "tried to write out a generic badguy" << std::endl;
+ log_warning << "tried to write out a generic badguy" << std::endl;
}
void
case STATE_INACTIVE:
return ABORT_MOVE;
case STATE_ACTIVE: {
- if(other.get_flags() & FLAG_SOLID)
- return collision_solid(other, hit);
-
BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING)
return collision_badguy(*badguy, hit);
return FORCE_MOVE;
}
case STATE_SQUISHED:
- if(other.get_flags() & FLAG_SOLID)
- return CONTINUE;
return FORCE_MOVE;
case STATE_FALLING:
return FORCE_MOVE;
return ABORT_MOVE;
}
-HitResponse
-BadGuy::collision_solid(GameObject& , const CollisionHit& )
+void
+BadGuy::collision_solid(const CollisionHit& hit)
{
- return FORCE_MOVE;
+ physic.set_velocity_x(0);
+ physic.set_velocity_y(0);
+ update_on_ground_flag(hit);
}
HitResponse
BadGuy::collision_player(Player& player, const CollisionHit& )
{
- /*
- printf("PlayerHit: GT %3.1f PM: %3.1f %3.1f BM: %3.1f %3.1f Hit: %3.1f %3.1f\n",
- game_time,
- player.get_movement().x, player.get_movement().y,
- get_movement().x, get_movement().y,
- hit.normal.x, hit.normal.y);
- */
-
// hit from above?
if(player.get_bbox().p2.y < (bbox.p1.y + 16)) {
// if it's not possible to squish us, then this will hurt
- if(collision_squished(player))
+ if(collision_squished(player)) {
return ABORT_MOVE;
+ }
}
if(player.is_invincible()) {
}
HitResponse
-BadGuy::collision_bullet(Bullet& , const CollisionHit& )
+BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& )
{
+ bullet.remove_me();
kill_fall();
return ABORT_MOVE;
}
{
float scroll_x = Sector::current()->camera->get_translation().x;
float scroll_y = Sector::current()->camera->get_translation().y;
-
+
if(bbox.p2.x < scroll_x - X_OFFSCREEN_DISTANCE
|| bbox.p1.x > scroll_x + X_OFFSCREEN_DISTANCE
|| bbox.p2.y < scroll_y - Y_OFFSCREEN_DISTANCE
* the effect of having badguys suddenly popping up from nowhere.
*/
//Badguy left of screen
- if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
+ if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
start_position.x < scroll_x - bbox.get_width() &&
start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) ||
(start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
start_position.y < scroll_y - bbox.get_height() ))) {
- if (start_dir != AUTO) dir = start_dir; else dir = start_position.x < scroll_x ? RIGHT : LEFT;
+ if (start_dir != AUTO) dir = start_dir;
+ else{
+ // if nearest player is to our right, start facing right
+ Player* player = get_nearest_player();
+ if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
+ dir = RIGHT;
+ } else {
+ dir = LEFT;
+ }
+ }
set_state(STATE_ACTIVE);
activate();
} else if(state == STATE_INIT
&& start_position.x < scroll_x + X_OFFSCREEN_DISTANCE
&& start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
&& start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- if (start_dir != AUTO) dir = start_dir; else dir = LEFT;
+ if (start_dir != AUTO) {
+ dir = start_dir;
+ } else {
+ // if nearest player is to our right, start facing right
+ Player* player = get_nearest_player();
+ if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
+ dir = RIGHT;
+ } else {
+ dir = LEFT;
+ }
+ }
set_state(STATE_ACTIVE);
activate();
- }
+ }
}
bool
return Sector::current()->is_free_space(Rect(x1, y1, x2, y2));
}
-Player*
+Player*
BadGuy::get_nearest_player()
{
// FIXME: does not really return nearest player
return 0;
}
+
+void
+BadGuy::update_on_ground_flag(const CollisionHit& hit)
+{
+ if (hit.bottom) on_ground_flag = true;
+}
+
+bool
+BadGuy::on_ground()
+{
+ return on_ground_flag;
+}