7cb48db06f2cc12e6f6faaf845213d05f40a4996
[supertux.git] / src / badguy / dispenser.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 "dispenser.hpp"
23 #include "badguy/bouncing_snowball.hpp"
24 #include "badguy/snowball.hpp"
25 #include "badguy/mrbomb.hpp"
26 #include "badguy/mriceblock.hpp"
27 #include "badguy/mrrocket.hpp"
28 #include "badguy/poisonivy.hpp"
29 #include "badguy/snail.hpp"
30 #include "badguy/skullyhop.hpp"
31 #include "random_generator.hpp"
32
33 Dispenser::Dispenser(const lisp::Lisp& reader)
34 {
35   reader.get("x", start_position.x);
36   reader.get("y", start_position.y);
37   reader.get("cycle", cycle);
38   reader.get("badguy", badguy);
39   bbox.set_size(32, 32);
40   sprite = sprite_manager->create("images/creatures/dispenser/dispenser.sprite");
41   if (badguy == "mrrocket") {
42      sprite->set_action(dir == LEFT ? "working-left" : "working-right");
43   }
44   else {sprite->set_action("dropper");}
45   countMe = false;
46 }
47
48 void
49 Dispenser::write(lisp::Writer& writer)
50 {
51   writer.start_list("dispenser");
52
53   writer.write_float("x", start_position.x);
54   writer.write_float("y", start_position.y);
55   writer.write_float("cycle", cycle);
56   writer.write_string("badguy", badguy);
57
58   writer.end_list("dispenser");
59 }
60
61 void
62 Dispenser::activate()
63 {  
64    dispense_timer.start(cycle, true);
65    launch_badguy();
66 }
67
68 bool
69 Dispenser::collision_squished(Player& player)
70 {
71   //TODO: Should it act like a normal tile when killed?
72   sprite->set_action(dir == LEFT ? "broken-left" : "broken-right");
73   dispense_timer.start(0);
74   player.bounce(*this);
75   kill_squished(player);
76   return true;
77 }
78
79 void
80 Dispenser::active_update(float )
81 {
82   if (dispense_timer.check()) {
83     launch_badguy();
84   }
85 }
86
87 //TODO: Add launching velocity to certain badguys
88 //      Add themed randomizer
89 //      Fix initial direction (everyone but MrRocket walks the wrong direction)
90 void
91 Dispenser::launch_badguy()
92 {
93   //FIXME: Does is_offscreen() work right here?
94   if (!is_offscreen()) {
95     if (badguy == "snowball")
96       Sector::current()->add_object(new SnowBall(get_pos().x, get_pos().y+32, dir));
97     else if (badguy == "bouncingsnowball")
98       Sector::current()->add_object(new BouncingSnowball(get_pos().x, get_pos().y+32, dir));
99     else if (badguy == "mrbomb")
100       Sector::current()->add_object(new MrBomb(get_pos().x, get_pos().y+32, dir));
101     else if (badguy == "mriceblock")
102       Sector::current()->add_object(new MrIceBlock(get_pos().x, get_pos().y+32, dir));
103     else if (badguy == "snail")
104       Sector::current()->add_object(new Snail(get_pos().x, get_pos().y+32, dir));
105     else if (badguy == "mrrocket") {
106       Sector::current()->add_object(new MrRocket(get_pos().x+(dir == LEFT ? -32 : 32), get_pos().y, dir));}
107     else if (badguy == "poisonivy")
108       Sector::current()->add_object(new PoisonIvy(get_pos().x, get_pos().y+32, dir));
109     else if (badguy == "skullyhop")
110       Sector::current()->add_object(new SkullyHop(get_pos().x, get_pos().y+44, dir));
111     else if (badguy == "random")
112     {
113       switch (systemRandom.rand(7))
114       {
115         case 0: Sector::current()->add_object(new SnowBall(get_pos().x, get_pos().y+32, dir)); break;
116         case 1: Sector::current()->add_object(new BouncingSnowball(get_pos().x, get_pos().y+32, dir)); break;
117         case 2: Sector::current()->add_object(new MrBomb(get_pos().x, get_pos().y+32, dir)); break;
118         case 3: Sector::current()->add_object(new MrIceBlock(get_pos().x, get_pos().y+32, dir)); break;
119         case 4: Sector::current()->add_object(new PoisonIvy(get_pos().x, get_pos().y+32, dir)); break;
120         case 5: Sector::current()->add_object(new Snail(get_pos().x, get_pos().y+32, dir)); break;
121         case 6: Sector::current()->add_object(new SkullyHop(get_pos().x, get_pos().y+44, dir)); break;
122       }
123     }
124   }
125 }
126
127 IMPLEMENT_FACTORY(Dispenser, "dispenser")