925e4de907851a8aeacef5e2ca63cc61be8b55ba
[supertux.git] / src / badguy / nolok_01.cpp
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2005 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
19 //  02111-1307, USA.
20
21 #include <config.h>
22
23 #include "nolok_01.hpp"
24 #include "badguy/bouncing_snowball.hpp"
25 #include "trigger/door.hpp"
26
27 #define WALK_TIME 2.5
28 #define SHOOT_TIME 0.4
29 #define JUMP_TIME 0.5
30 #define INITIAL_HITPOINTS 3
31 #define INITIAL_BULLET_HP 10
32
33 static const float WALKSPEED = 90;
34
35 //TODO: Create sprite, limit max number of snowballs
36 Nolok_01::Nolok_01(const lisp::Lisp& reader)
37 {
38   reader.get("x", start_position.x);
39   reader.get("y", start_position.y);
40   bbox.set_size(31.8, 63.8);
41   sprite = sprite_manager->create("dummyguy");
42   countMe = false;
43 }
44
45 Nolok_01::Nolok_01(float pos_x, float pos_y)
46 {
47   start_position.x = pos_x;
48   start_position.y = pos_y;
49   bbox.set_size(31.8, 63.8);
50   sprite = sprite_manager->create("dummyguy");
51   countMe = false;
52 }
53
54 void
55 Nolok_01::write(lisp::Writer& writer)
56 {
57   writer.start_list("nolok_01");
58
59   writer.write_float("x", start_position.x);
60   writer.write_float("y", start_position.y);
61
62   writer.end_list("nolok_01");
63 }
64
65 void
66 Nolok_01::activate()
67 {
68   //hitpoints = INITIAL_HITPOINTS;
69   //bullet_hitpoints = INITIAL_BULLET_HP;
70   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
71   sprite->set_action(dir == LEFT ? "left" : "right");
72   action = WALKING;
73   action_timer.start(WALK_TIME);
74 }
75
76 void
77 Nolok_01::active_update(float elapsed_time)
78 {
79    if (action_timer.check()) {
80      switch (action) {       
81        case WALKING:
82         {
83          sprite->set_action("jump");
84          physic.set_velocity_y(700);
85          action = JUMPING;
86          action_timer.start(JUMP_TIME);
87          break;
88         }
89        case JUMPING:
90        {
91         sprite->set_action("throw");
92         action = SHOOTING;
93         action_timer.start(SHOOT_TIME);
94         break;
95        }
96        case SHOOTING:
97        {
98         Sector::current()->add_object(new BouncingSnowball(get_pos().x - 64, get_pos().y, LEFT));
99         Sector::current()->add_object(new BouncingSnowball(get_pos().x + 64, get_pos().y, RIGHT));
100         physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
101         sprite->set_action(dir == LEFT ? "left" : "right");
102         action = WALKING;
103         action_timer.start(WALK_TIME);
104         break;
105        }
106      }
107    }
108    movement = physic.get_movement(elapsed_time);
109 }
110
111 bool
112 Nolok_01::collision_squished(Player& player)
113 {
114   bool result = false;
115   player.bounce(*this);
116 #if 0
117   if (hitpoints <= 0) {
118     bullet_hitpoints = 0;
119     sprite->set_action("dead"); 
120     kill_squished(player);
121     Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
122     result = true;
123   }
124 #endif
125   return result;
126 }
127
128 HitResponse
129 Nolok_01::collision_solid(GameObject& , const CollisionHit& hit)
130 {
131   if(fabsf(hit.normal.y) > .5){ // hit floor or roof?
132     if (action != JUMPING) physic.set_velocity_y(0);
133   } else { // hit right or left
134     dir = dir == LEFT ? RIGHT : LEFT;
135     sprite->set_action(dir == LEFT ? "left" : "right");
136     physic.set_velocity_x(-physic.get_velocity_x());
137   }
138
139   return CONTINUE;
140 }
141
142 //TODO: Hitpoint count incorrect when combining squishing and shooting
143 void
144 Nolok_01::kill_fall()
145 {
146 #if 0
147   bullet_hitpoints--;
148   if (bullet_hitpoints <= 0) {
149    hitpoints = 0;
150    sound_manager->play("sounds/fall.wav", this,
151                              Sector::current()->player->get_pos());
152    physic.set_velocity_y(0);
153    physic.enable_gravity(true);
154    set_state(STATE_FALLING);
155    Sector::current()->add_object(new Door((int)get_pos().x+32, 512, "sector1", "main2"));
156   }
157 #endif
158 }
159
160 IMPLEMENT_FACTORY(Nolok_01, "nolok_01")