badguys now have normal hitpoints and bullet hitpoints, so you can make them need...
[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 #define INITIAL_BULLET_HP 10
12
13 static const float WALKSPEED = 90;
14
15 //TODO: Create sprite, limit max number of snowballs
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("nolok_01");
36
37   writer.write_float("x", start_position.x);
38   writer.write_float("y", start_position.y);
39
40   writer.end_list("nolok_01");
41 }
42
43 void
44 Nolok_01::activate()
45 {
46   hitpoints = INITIAL_HITPOINTS;
47   bullet_hitpoints = INITIAL_BULLET_HP;
48   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
49   sprite->set_action(dir == LEFT ? "left" : "right");
50   action = WALKING;
51   action_timer.start(WALK_TIME);
52 }
53
54 void
55 Nolok_01::active_action(float elapsed_time)
56 {
57    if (action_timer.check()) {
58      switch (action) {       
59        case WALKING:
60         {
61          sprite->set_action("jump");
62          physic.set_velocity_y(700);
63          action = JUMPING;
64          action_timer.start(JUMP_TIME);
65          break;
66         }
67        case JUMPING:
68        {
69         sprite->set_action("throw");
70         action = SHOOTING;
71         action_timer.start(SHOOT_TIME);
72         break;
73        }
74        case SHOOTING:
75        {
76         Sector::current()->add_object(new BouncingSnowball(get_pos().x - 64, get_pos().y, LEFT));
77         Sector::current()->add_object(new BouncingSnowball(get_pos().x + 64, get_pos().y, RIGHT));
78         physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
79         sprite->set_action(dir == LEFT ? "left" : "right");
80         action = WALKING;
81         action_timer.start(WALK_TIME);
82         break;
83        }
84      }
85    }
86    movement = physic.get_movement(elapsed_time);
87 }
88
89 bool
90 Nolok_01::collision_squished(Player& player)
91 {
92   bool result = false;
93   player.bounce(*this);
94   if (hitpoints <= 0) {
95     bullet_hitpoints = 0;
96     sprite->set_action("dead"); 
97     kill_squished(player);
98     Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
99     result = true;
100   }
101   return result;
102 }
103
104 HitResponse
105 Nolok_01::collision_solid(GameObject& , const CollisionHit& hit)
106 {
107   if(fabsf(hit.normal.y) > .5){ // hit floor or roof?
108     if (action != JUMPING) physic.set_velocity_y(0);
109   } else { // hit right or left
110     dir = dir == LEFT ? RIGHT : LEFT;
111     sprite->set_action(dir == LEFT ? "left" : "right");
112     physic.set_velocity_x(-physic.get_velocity_x());
113   }
114
115   return CONTINUE;
116 }
117
118 //TODO: Hitpoint count incorrect when combining squishing and shooting
119 void
120 Nolok_01::kill_fall()
121 {
122   bullet_hitpoints--;
123   if (bullet_hitpoints <= 0) {
124    SoundManager::get()->play_sound(IDToSound(SND_FALL), this,
125          Sector::current()->player->get_pos());
126    physic.set_velocity_y(0);
127    physic.enable_gravity(true);
128    set_state(STATE_FALLING);
129    Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
130   }
131 }
132
133 IMPLEMENT_FACTORY(Nolok_01, "nolok_01")