small fixes (timing and animation) on nolok
[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
11 static const float WALKSPEED = 90;
12
13 //TODO: Create sprite, give multiple hitpoints, limit max number of snowballs
14 //      Stop actions when pause button is hit (probably a general problem of timers)
15 Nolok_01::Nolok_01(LispReader& reader)
16 {
17   reader.read_float("x", start_position.x);
18   reader.read_float("y", start_position.y);
19   bbox.set_size(31.8, 63.8);
20   sprite = sprite_manager->create("dummyguy");
21 }
22
23 Nolok_01::Nolok_01(float pos_x, float pos_y)
24 {
25   start_position.x = pos_x;
26   start_position.y = pos_y;
27   bbox.set_size(31.8, 63.8);
28   sprite = sprite_manager->create("dummyguy");
29 }
30
31 void
32 Nolok_01::write(LispWriter& writer)
33 {
34   writer.start_list("nolok01");
35
36   writer.write_float("x", get_pos().x);
37   writer.write_float("y", get_pos().y);
38
39   writer.end_list("nolok01");
40 }
41
42 void
43 Nolok_01::activate()
44 {
45   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
46   sprite->set_action(dir == LEFT ? "left" : "right");
47   action = WALKING;
48   action_timer.start(WALK_TIME);
49 }
50
51 void
52 Nolok_01::active_action(float elapsed_time)
53 {
54    if (action_timer.check()) {
55      switch (action) {       
56        case WALKING:
57         {
58          sprite->set_action("jump");
59          physic.set_velocity_y(700);
60          action = JUMPING;
61          action_timer.start(JUMP_TIME);
62          break;
63         }
64        case JUMPING:
65        {
66         sprite->set_action("throw");
67         action = SHOOTING;
68         action_timer.start(SHOOT_TIME);
69         break;
70        }
71        case SHOOTING:
72        {
73         Sector::current()->add_object(new BouncingSnowball(get_pos().x - 64, get_pos().y, LEFT));
74         Sector::current()->add_object(new BouncingSnowball(get_pos().x + 64, get_pos().y, RIGHT));
75         physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
76         sprite->set_action(dir == LEFT ? "left" : "right");
77         action = WALKING;
78         action_timer.start(WALK_TIME);
79         break;
80        }
81      }
82    }
83    movement = physic.get_movement(elapsed_time);
84 }
85
86 bool
87 Nolok_01::collision_squished(Player& player)
88 {
89   sprite->set_action("dead"); 
90   kill_squished(player);
91   Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
92   return true;
93 }
94
95 HitResponse
96 Nolok_01::collision_solid(GameObject& , const CollisionHit& hit)
97 {
98   if(fabsf(hit.normal.y) > .5){ // hit floor or roof?
99     if (action != JUMPING) physic.set_velocity_y(0);
100   } else { // hit right or left
101     dir = dir == LEFT ? RIGHT : LEFT;
102     sprite->set_action(dir == LEFT ? "left" : "right");
103     physic.set_velocity_x(-physic.get_velocity_x());
104   }
105
106   return CONTINUE;
107 }
108