Badguys read hitbox from .sprite file
[supertux.git] / src / badguy / nolok_01.cpp
1 //  $Id$
2 //
3 //  SuperTux
4 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include "nolok_01.hpp"
23 #include "badguy/snail.hpp"
24 #include "trigger/door.hpp"
25
26 #define WALK_TIME 2.5
27 #define SHOOT_TIME 0.4
28 #define JUMP_TIME 0.5
29 #define INITIAL_HITPOINTS 3
30 #define INITIAL_BULLET_HP 10
31
32 static const float WALKSPEED = 90;
33
34 //TODO: Create sprite, limit max number of snowballs
35 Nolok_01::Nolok_01(const lisp::Lisp& reader)
36 {
37   reader.get("x", start_position.x);
38   reader.get("y", start_position.y);
39   sprite = sprite_manager->create("images/creatures/nolok/nolok.sprite");
40   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
41   countMe = false;
42 }
43
44 Nolok_01::Nolok_01(float pos_x, float pos_y)
45 {
46   start_position.x = pos_x;
47   start_position.y = pos_y;
48   sprite = sprite_manager->create("images/creatures/nolok/nolok.sprite");
49   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
50   countMe = false;
51 }
52
53 void
54 Nolok_01::write(lisp::Writer& writer)
55 {
56   writer.start_list("nolok_01");
57
58   writer.write_float("x", start_position.x);
59   writer.write_float("y", start_position.y);
60
61   writer.end_list("nolok_01");
62 }
63
64 void
65 Nolok_01::activate()
66 {
67   //hitpoints = INITIAL_HITPOINTS;
68   //bullet_hitpoints = INITIAL_BULLET_HP;
69   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
70   sprite->set_action(dir == LEFT ? "left" : "right");
71   action = WALKING;
72   action_timer.start(WALK_TIME);
73 }
74
75 void
76 Nolok_01::active_update(float elapsed_time)
77 {
78    if (action_timer.check()) {
79      switch (action) {       
80        case WALKING:
81         {
82          sprite->set_action("jump");
83          physic.set_velocity_y(700);
84          action = JUMPING;
85          action_timer.start(JUMP_TIME);
86          break;
87         }
88        case JUMPING:
89        {
90         sprite->set_action("throw");
91         action = SHOOTING;
92         action_timer.start(SHOOT_TIME);
93         break;
94        }
95        case SHOOTING:
96        {
97         Sector::current()->add_object(new Snail(get_pos().x - 64, get_pos().y, LEFT));
98         Sector::current()->add_object(new Snail(get_pos().x + 64, get_pos().y, RIGHT));
99         physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
100         sprite->set_action(dir == LEFT ? "left" : "right");
101         action = WALKING;
102         action_timer.start(WALK_TIME);
103         break;
104        }
105      }
106    }
107    movement = physic.get_movement(elapsed_time);
108 }
109
110 bool
111 Nolok_01::collision_squished(Player& player)
112 {
113   bool result = false;
114   player.bounce(*this);
115 #if 0
116   if (hitpoints <= 0) {
117     bullet_hitpoints = 0;
118     sprite->set_action("dead"); 
119     kill_squished(player);
120     Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
121     result = true;
122   }
123 #endif
124   return result;
125 }
126
127 HitResponse
128 Nolok_01::collision_solid(GameObject& , const CollisionHit& hit)
129 {
130   if(fabsf(hit.normal.y) > .5){ // hit floor or roof?
131     if (action != JUMPING) physic.set_velocity_y(0);
132   } else { // hit right or left
133     dir = dir == LEFT ? RIGHT : LEFT;
134     sprite->set_action(dir == LEFT ? "left" : "right");
135     physic.set_velocity_x(-physic.get_velocity_x());
136   }
137
138   return CONTINUE;
139 }
140
141 //TODO: Hitpoint count incorrect when combining squishing and shooting
142 void
143 Nolok_01::kill_fall()
144 {
145 #if 0
146   bullet_hitpoints--;
147   if (bullet_hitpoints <= 0) {
148    hitpoints = 0;
149    sound_manager->play("sounds/fall.wav", this,
150                              this->get_pos());
151    physic.set_velocity_y(0);
152    physic.enable_gravity(true);
153    set_state(STATE_FALLING);
154    Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
155   }
156 #endif
157 }
158
159 IMPLEMENT_FACTORY(Nolok_01, "nolok_01")