Changed Yeti behaviour. You must stun him (jump on him) when is under a falling stala...
[supertux.git] / src / badguy / yeti.cpp
index 6e57c7b..5dc3cc0 100644 (file)
@@ -7,9 +7,10 @@
 
 static const float JUMP_VEL1 = 250;
 static const float JUMP_VEL2 = 700;
-static const float RUN_SPEED = 350;
+static const float RUN_SPEED = 300;
 static const float JUMP_TIME = 1.6;
 static const float ANGRY_JUMP_WAIT = .5;
+static const float STUN_TIME = 2;
 
 Yeti::Yeti(const lisp::Lisp& reader)
 {
@@ -21,6 +22,7 @@ Yeti::Yeti(const lisp::Lisp& reader)
   side = LEFT;
   sound_gna = SoundManager::get()->load_sound(
       get_resource_filename("sounds/yeti_gna.wav"));
+  jump_time_left = 0.0f;
 }
 
 Yeti::~Yeti()
@@ -36,21 +38,27 @@ Yeti::active_action(float elapsed_time)
       break;
     case GO_RIGHT:
       physic.set_velocity_x(RUN_SPEED);
-      if(timer.check())
+      if(jump_timer.check())
         physic.set_velocity_y(JUMP_VEL2);
       break;
     case GO_LEFT:
       physic.set_velocity_x(-RUN_SPEED);
-      if(timer.check())
+      if(jump_timer.check())
         physic.set_velocity_y(JUMP_VEL2);
       break;
     case ANGRY_JUMPING:
-      if(timer.check()) {
+      if(jump_timer.check()) {
         // jump
         SoundManager::get()->play_sound(sound_gna);
         physic.set_velocity_y(JUMP_VEL1);
       }
       break;
+
+    case STUNNED:
+        if (stun_timer.check()) {
+            go_right();
+        }
+      
     default:
       break;
   }
@@ -65,7 +73,7 @@ Yeti::go_right()
   physic.set_velocity_y(JUMP_VEL1);
   physic.set_velocity_x(RUN_SPEED);
   state = GO_RIGHT;
-  timer.start(JUMP_TIME);
+  jump_timer.start(JUMP_TIME);
 }
 
 void
@@ -74,22 +82,79 @@ Yeti::go_left()
   physic.set_velocity_y(JUMP_VEL1);
   physic.set_velocity_x(-RUN_SPEED);
   state = GO_LEFT;
-  timer.start(JUMP_TIME);
+  jump_timer.start(JUMP_TIME);
 }
 
 void
 Yeti::angry_jumping()
 {
   jumpcount = 0;
-  timer.start(ANGRY_JUMP_WAIT);
+  jump_timer.start(ANGRY_JUMP_WAIT);
   state = ANGRY_JUMPING;
   physic.set_velocity_x(0);
 }
 
+void
+Yeti::stun()
+{
+  physic.set_acceleration(0.0f, 0.0f);
+  physic.set_velocity(0.0f, 0.0f);
+  jump_time_left = jump_timer.get_timeleft();
+  jump_timer.stop();
+  stun_timer.start(STUN_TIME);
+  state = STUNNED;
+}
+
+HitResponse
+Yeti::collision_player(Player& player, const CollisionHit& hit)
+{     
+  if(player.is_invincible()) {
+    kill_fall();
+    return ABORT_MOVE;
+  } 
+  if(hit.normal.y > .9) {
+    //TODO: fix inaccuracy (tux sometimes dies even if badguy was hit)
+    //      give badguys some invincible time (prevent them from being hit multiple times)
+    //      use hitpoints also when hit by fireball or invincible tux
+    hitpoints--;
+    if(collision_squished(player))
+      return ABORT_MOVE;
+    else if (hitpoints <= 0) {
+      player.kill(Player::SHRINK);
+      return FORCE_MOVE;
+    }
+  }
+
+  if (state == STUNNED)
+    return ABORT_MOVE;
+
+  player.kill(Player::SHRINK);
+  return FORCE_MOVE;
+}
+
+HitResponse
+Yeti::collision_badguy(BadGuy& badguy, const CollisionHit&)
+{
+  YetiStalactite* yeti_stal = dynamic_cast<YetiStalactite*>(&badguy);
+
+  if (state == STUNNED && yeti_stal && yeti_stal->is_harmful())
+  {
+    kill_fall();
+  }
+
+  return FORCE_MOVE;
+} 
+  
+
 bool
 Yeti::collision_squished(Player& player)
 {
-  kill_squished(player);
+  // we don't use the player object, even though it was given to us
+  (void)player;
+
+  // stun yeti
+  stun();
+
   return true;
 }
 
@@ -129,14 +194,14 @@ Yeti::collision_solid(GameObject& , const CollisionHit& hit)
     physic.set_velocity_y(0);
     if(state == INIT) {
       go_right();
-    } else if(state == GO_LEFT && !timer.started()) {
+    } else if(state == GO_LEFT && !jump_timer.started()) {
       side = LEFT;
       angry_jumping();
-    } else if(state == GO_RIGHT && !timer.started()) {
+    } else if(state == GO_RIGHT && !jump_timer.started()) {
       side = RIGHT;
       angry_jumping();
     } else if(state == ANGRY_JUMPING) {
-      if(!timer.started()) {
+      if(!jump_timer.started()) {
         // we just landed
         jumpcount++;
         // make a stalactite falling down and shake camera a bit
@@ -151,7 +216,7 @@ Yeti::collision_solid(GameObject& , const CollisionHit& hit)
             go_left();
         } else {
           // jump again
-          timer.start(ANGRY_JUMP_WAIT);
+          jump_timer.start(ANGRY_JUMP_WAIT);
         }
       }
     }