The BIG COMMIT(tm)
[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(32, 32);
15   sprite = sprite_manager->create("mriceblock");
16 }
17
18 void
19 MrIceBlock::write(LispWriter& writer)
20 {
21   writer.start_list("mriceblock");
22
23   writer.write_float("x", get_pos().x);
24   writer.write_float("y", get_pos().y);
25
26   writer.end_list("mriceblock");
27 }
28
29 void
30 MrIceBlock::activate()
31 {
32   physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
33   sprite->set_action(dir == LEFT ? "left" : "right");
34 }
35
36 void
37 MrIceBlock::active_action(float elapsed_time)
38 {
39   if(ice_state == ICESTATE_FLAT && flat_timer.check()) {
40     printf("unflat.\n");
41     ice_state = ICESTATE_NORMAL;
42     physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
43     sprite->set_action(dir == LEFT ? "left" : "right");
44   }
45   BadGuy::active_action(elapsed_time);
46 }
47
48 HitResponse
49 MrIceBlock::collision_solid(GameObject& other, const CollisionHit& hit)
50 {
51   if(fabsf(hit.normal.y) > .5) { // floor or roof
52     physic.set_velocity_y(0);
53     return CONTINUE;
54   }
55   // hit left or right
56   switch(ice_state) {
57     case ICESTATE_NORMAL:
58       dir = dir == LEFT ? RIGHT : LEFT;
59       sprite->set_action(dir == LEFT ? "left" : "right");
60       physic.set_velocity_x(-physic.get_velocity_x());       
61       break;
62     case ICESTATE_KICKED:
63       dir = dir == LEFT ? RIGHT : LEFT;
64       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
65       physic.set_velocity_x(-physic.get_velocity_x());
66       SoundManager::get()->play_sound(IDToSound(SND_RICOCHET), get_pos(),
67           Sector::current()->player->get_pos());
68       break;
69     case ICESTATE_FLAT:
70       physic.set_velocity_x(0);
71       break;
72   }
73
74   return CONTINUE;
75 }
76
77 bool
78 MrIceBlock::collision_squished(Player& player)
79 {
80   switch(ice_state) {
81     case ICESTATE_KICKED:
82     case ICESTATE_NORMAL:
83       squishcount++;
84       if(squishcount >= MAXSQUISHES) {
85         kill_fall();
86         return true;
87       }
88
89       // flatten
90       SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(),
91           player.get_pos());
92       physic.set_velocity_x(0);
93       physic.set_velocity_y(0); 
94       
95       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
96       flat_timer.start(4);
97       ice_state = ICESTATE_FLAT;
98       printf("flat.\n");
99       break;
100     case ICESTATE_FLAT:
101       // kick
102       SoundManager::get()->play_sound(IDToSound(SND_KICK), this,
103           player.get_pos());
104
105       if(player.get_pos().x < get_pos().x) {
106         dir = RIGHT;
107       } else {
108         dir = LEFT;
109       }
110       physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
111       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
112       ice_state = ICESTATE_KICKED;
113       printf("kicked.\n");
114       break;
115   }
116
117   player.bounce(*this);
118   return true;
119 }
120