more fixes
[supertux.git] / src / badguy.cpp
index b8f8f3b..5e496ec 100644 (file)
@@ -159,13 +159,12 @@ BadGuy::~BadGuy()
 void
 BadGuy::init()
 {
-  base.x = 0;
-  base.y = 0;
-  base.width  = 0;
-  base.height = 0;
+  base.x = start_position.x;
+  base.y = start_position.y;
+  base.width  = 32;
+  base.height = 32;
   
   mode     = NORMAL;
-  dying    = DYING_NOT;
   old_base = base;
   dir      = LEFT;
   seen     = false;
@@ -177,8 +176,6 @@ BadGuy::init()
 
   specs = badguyspecs_manager->load(badguykind_to_string(kind));
 
-  set_action("hide", "hide");
-
   // if we're in a solid tile at start correct that now
   if(Sector::current()) {
   if(kind != BAD_FLAME && kind != BAD_FISH && kind != BAD_FLAMEFISH && collision_object_map(base)) 
@@ -188,20 +185,6 @@ BadGuy::init()
       while(collision_object_map(base))
         --base.y;
     }
-
-  if(Sector::current()->camera) {
-    Vector scroll = Sector::current()->camera->get_translation();
-
-    if(start_position.x > scroll.x - X_OFFSCREEN_DISTANCE &&
-        start_position.x < scroll.x + screen->w + X_OFFSCREEN_DISTANCE &&
-        start_position.y > scroll.y - Y_OFFSCREEN_DISTANCE &&
-        start_position.y < scroll.y + screen->h + Y_OFFSCREEN_DISTANCE) {
-      activate(LEFT);
-    }
-  } } else {
-    if(start_position.x >= 0 && start_position.x < screen->w
-        && start_position.y >= 0 && start_position.y < screen->h)
-      activate(LEFT);
   }
 }
 
@@ -227,9 +210,12 @@ BadGuy::activate(Direction activation_dir)
   frozen_timer.init(true);
   timer.init(true);
 
+  dying = DYING_NOT;
+  seen = true;
+
   dir = activation_dir;
   float dirsign = activation_dir == LEFT ? -1 : 1;
-  
+
   set_action("left", "right");
   if(kind == BAD_MRBOMB) {
     physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0);
@@ -274,11 +260,6 @@ BadGuy::activate(Direction activation_dir)
     base.width = 66;
     base.height = 66;
   }
-
-  base.x = start_position.x;
-  base.y = start_position.y;  
-  old_base = base;
-  seen = true;
 }
 
 Surface*
@@ -772,14 +753,6 @@ BadGuy::action_spiky(double elapsed_time)
     check_horizontal_bump();
 
   fall();
-#if 0
-  // jump when we're about to fall
-  if (physic.get_velocity_y() == 0 && 
-          !issolid(base.x+base.width/2, base.y + base.height)) {
-    physic.enable_gravity(true);
-    physic.set_velocity_y(2);
-  }
-#endif
 
   physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity);
   if (dying != DYING_FALLING)
@@ -794,6 +767,13 @@ BadGuy::action_snowball(double elapsed_time)
 
   fall();
 
+  // jump when we're about to fall
+  if (physic.get_velocity_y() == 0 && 
+          !issolid(base.x+base.width/2, base.y + base.height)) {
+    physic.enable_gravity(true);
+    physic.set_velocity_y(2);
+  }
+
   physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity);
   if (dying != DYING_FALLING)
     collision_swept_object_map(&old_base,&base);
@@ -876,34 +856,53 @@ BadGuy::action(float elapsed_time)
          kill_me(0);
       }
 
-  if(!seen) {
-    /* activate badguys if they're just inside the offscreen_distance around the
-     * screen. Don't activate them inside the screen, since that might have the
-     * effect of badguys suddenly popping up from nowhere
+  if(!seen)
+    {
+    /* Activate badguys if they're just around the screen to avoid
+     * the effect of having badguys suddenly popping up from nowhere.
      */
     if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
-        start_position.x < scroll_x - base.width)
+        start_position.x < scroll_x - base.width &&
+        start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
+        start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE)
       activate(RIGHT);
-    else if(start_position.x > scroll_y - Y_OFFSCREEN_DISTANCE &&
-        start_position.y < scroll_y - base.height)
-      activate(LEFT);
-    else if(start_position.x > scroll_x + screen->w &&
-        start_position.x < scroll_x + screen->w + X_OFFSCREEN_DISTANCE)
-      activate(LEFT);
-    else if(start_position.y > scroll_y + screen->h &&
+    else if (start_position.x > scroll_x + screen->w &&
+        start_position.x < scroll_x + screen->w + X_OFFSCREEN_DISTANCE &&
+        start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
         start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE)
       activate(LEFT);
-  } else {
+    else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
+        start_position.x < scroll_x + screen->w + X_OFFSCREEN_DISTANCE &&
+        ((start_position.y > scroll_y + screen->h &&
+        start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE) ||
+        (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
+        start_position.y < scroll_y)))
+        {
+        if(start_position.x < scroll_x - screen->w/2)
+          activate(RIGHT);
+        else
+          activate(LEFT);
+        }
+    /* Special case for badguys on start of the level.
+     * If in the future, it's possible to set Tux start pos, this case
+     * should contemplate that. */
+    else if (start_position.x > 0 && start_position.x < screen->w &&
+             start_position.y > 0 && start_position.y < screen->h)
+      activate(LEFT);
+    }
+  else
+    {
     if(base.x + base.width < scroll_x - X_OFFSCREEN_DISTANCE*4
       || base.x > scroll_x + screen->w + X_OFFSCREEN_DISTANCE*4
       || base.y + base.height < scroll_y - Y_OFFSCREEN_DISTANCE*4
-      || base.y > scroll_y + screen->h + Y_OFFSCREEN_DISTANCE*4) {
+      || base.y > scroll_y + screen->h + Y_OFFSCREEN_DISTANCE*4)
+      {
       seen = false;
       if(dying != DYING_NOT)
         remove_me();
+      }
     }
-  }
-  
+
   if(!seen)
     return;
   
@@ -970,6 +969,9 @@ BadGuy::action(float elapsed_time)
 void
 BadGuy::draw(DrawingContext& context)
 {
+  if(!seen)
+    return;
+
   if((dir == LEFT && action_left == "hide") ||
      (dir == RIGHT && action_right == "hide"))
     return;
@@ -1007,7 +1009,7 @@ BadGuy::set_action(std::string left, std::string right)
   else
     {
       // FIXME: Using the image size for the physics and collision is
-      // a bad idea, since images should always overlap there physical
+      // a bad idea, since images should always overlap their physical
       // representation
       if(left != 0) {
         if(base.width == 0 && base.height == 0) {
@@ -1205,7 +1207,7 @@ BadGuy::kill_me(int score)
 void
 BadGuy::explode(bool right_way)
 {
-  BadGuy *badguy = Sector::current()->add_bad_guy(base.x, base.y, BAD_BOMB);
+  BadGuy *badguy = Sector::current()->add_bad_guy(base.x, base.y, BAD_BOMB, true);
   if(right_way)
     {
     badguy->timer.start(0);