updated dispenser -- can summon mriceblock, snowball, bouncing_snowball and mrbomb now
[supertux.git] / src / badguy / mriceblock.cpp
1 #include <config.h>
2
3 #include "mriceblock.h"
4
5 static const float WALKSPEED = 80;
6 static const float KICKSPEED = 500;
7 static const int MAXSQUISHES = 10;
8
9 MrIceBlock::MrIceBlock(LispReader& reader)
10   : ice_state(ICESTATE_NORMAL), squishcount(0)
11 {
12   reader.read_float("x", start_position.x);
13   reader.read_float("y", start_position.y);
14   bbox.set_size(31.8, 31.8);
15   sprite = sprite_manager->create("mriceblock");
16   set_direction = false;
17 }
18
19 MrIceBlock::MrIceBlock(float pos_x, float pos_y, Direction d)
20   : ice_state(ICESTATE_NORMAL), squishcount(0)
21 {
22   start_position.x = pos_x;
23   start_position.y = pos_y;
24   bbox.set_size(31.8, 31.8);
25   sprite = sprite_manager->create("mriceblock");
26   set_direction = true;
27   initial_direction = d;
28 }
29
30 void
31 MrIceBlock::write(LispWriter& writer)
32 {
33   writer.start_list("mriceblock");
34
35   writer.write_float("x", get_pos().x);
36   writer.write_float("y", get_pos().y);
37
38   writer.end_list("mriceblock");
39 }
40
41 void
42 MrIceBlock::activate()
43 {
44   if (set_direction) {dir = initial_direction;}
45   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
46   sprite->set_action(dir == LEFT ? "left" : "right");
47 }
48
49 void
50 MrIceBlock::active_action(float elapsed_time)
51 {
52   if(ice_state == ICESTATE_FLAT && flat_timer.check()) {
53     printf("unflat.\n");
54     ice_state = ICESTATE_NORMAL;
55     physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
56     sprite->set_action(dir == LEFT ? "left" : "right");
57   }
58   BadGuy::active_action(elapsed_time);
59 }
60
61 HitResponse
62 MrIceBlock::collision_solid(GameObject& , const CollisionHit& hit)
63 {
64   if(fabsf(hit.normal.y) > .5) { // floor or roof
65     physic.set_velocity_y(0);
66     return CONTINUE;
67   }
68   // hit left or right
69   switch(ice_state) {
70     case ICESTATE_NORMAL:
71       dir = dir == LEFT ? RIGHT : LEFT;
72       sprite->set_action(dir == LEFT ? "left" : "right");
73       physic.set_velocity_x(-physic.get_velocity_x());       
74       break;
75     case ICESTATE_KICKED:
76       dir = dir == LEFT ? RIGHT : LEFT;
77       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
78       physic.set_velocity_x(-physic.get_velocity_x());
79       SoundManager::get()->play_sound(IDToSound(SND_RICOCHET), get_pos(),
80           Sector::current()->player->get_pos());
81       break;
82     case ICESTATE_FLAT:
83       physic.set_velocity_x(0);
84       break;
85   }
86
87   return CONTINUE;
88 }
89
90 bool
91 MrIceBlock::collision_squished(Player& player)
92 {
93   switch(ice_state) {
94     case ICESTATE_KICKED:
95     case ICESTATE_NORMAL:
96       squishcount++;
97       if(squishcount >= MAXSQUISHES) {
98         kill_fall();
99         return true;
100       }
101
102       // flatten
103       SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(),
104           player.get_pos());
105       physic.set_velocity_x(0);
106       physic.set_velocity_y(0); 
107       
108       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
109       flat_timer.start(4);
110       ice_state = ICESTATE_FLAT;
111       printf("flat.\n");
112       break;
113     case ICESTATE_FLAT:
114       // kick
115       SoundManager::get()->play_sound(IDToSound(SND_KICK), this,
116           player.get_pos());
117
118       if(player.get_pos().x < get_pos().x) {
119         dir = RIGHT;
120       } else {
121         dir = LEFT;
122       }
123       physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
124       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
125       ice_state = ICESTATE_KICKED;
126       printf("kicked.\n");
127       break;
128   }
129
130   player.bounce(*this);
131   return true;
132 }
133