e3b7c00f47fc47b723712f7cda5577330fb5e385
[supertux.git] / src / badguy / nolok_01.cpp
1 #include <config.h>
2
3 #include "nolok_01.h"
4 #include "badguy/bouncing_snowball.h"
5 #include "trigger/door.h"
6
7 #define WALK_TIME 2.5
8 #define SHOOT_TIME 0.4
9 #define JUMP_TIME 0.5
10 #define INITIAL_HITPOINTS 3
11
12 static const float WALKSPEED = 90;
13
14 //TODO: Create sprite, limit max number of snowballs
15 //      Stop actions when pause button is hit (probably a general problem of timers)
16 Nolok_01::Nolok_01(const lisp::Lisp& reader)
17 {
18   reader.get("x", start_position.x);
19   reader.get("y", start_position.y);
20   bbox.set_size(31.8, 63.8);
21   sprite = sprite_manager->create("dummyguy");
22 }
23
24 Nolok_01::Nolok_01(float pos_x, float pos_y)
25 {
26   start_position.x = pos_x;
27   start_position.y = pos_y;
28   bbox.set_size(31.8, 63.8);
29   sprite = sprite_manager->create("dummyguy");
30 }
31
32 void
33 Nolok_01::write(lisp::Writer& writer)
34 {
35   writer.start_list("nolok01");
36
37   writer.write_float("x", start_position.x);
38   writer.write_float("y", start_position.y);
39
40   writer.end_list("nolok01");
41 }
42
43 void
44 Nolok_01::activate()
45 {
46   hitpoints = INITIAL_HITPOINTS;
47   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
48   sprite->set_action(dir == LEFT ? "left" : "right");
49   action = WALKING;
50   action_timer.start(WALK_TIME);
51 }
52
53 void
54 Nolok_01::active_action(float elapsed_time)
55 {
56    if (action_timer.check()) {
57      switch (action) {       
58        case WALKING:
59         {
60          sprite->set_action("jump");
61          physic.set_velocity_y(700);
62          action = JUMPING;
63          action_timer.start(JUMP_TIME);
64          break;
65         }
66        case JUMPING:
67        {
68         sprite->set_action("throw");
69         action = SHOOTING;
70         action_timer.start(SHOOT_TIME);
71         break;
72        }
73        case SHOOTING:
74        {
75         Sector::current()->add_object(new BouncingSnowball(get_pos().x - 64, get_pos().y, LEFT));
76         Sector::current()->add_object(new BouncingSnowball(get_pos().x + 64, get_pos().y, RIGHT));
77         physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
78         sprite->set_action(dir == LEFT ? "left" : "right");
79         action = WALKING;
80         action_timer.start(WALK_TIME);
81         break;
82        }
83      }
84    }
85    movement = physic.get_movement(elapsed_time);
86 }
87
88 bool
89 Nolok_01::collision_squished(Player& player)
90 {
91   bool result = false;
92   player.bounce(*this);
93   if (hitpoints <= 0) {
94     sprite->set_action("dead"); 
95     kill_squished(player);
96     Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
97     result = true;
98   }
99   return result;
100 }
101
102 HitResponse
103 Nolok_01::collision_solid(GameObject& , const CollisionHit& hit)
104 {
105   if(fabsf(hit.normal.y) > .5){ // hit floor or roof?
106     if (action != JUMPING) physic.set_velocity_y(0);
107   } else { // hit right or left
108     dir = dir == LEFT ? RIGHT : LEFT;
109     sprite->set_action(dir == LEFT ? "left" : "right");
110     physic.set_velocity_x(-physic.get_velocity_x());
111   }
112
113   return CONTINUE;
114 }
115
116 IMPLEMENT_FACTORY(Nolok_01, "nolok_01")