1 /* modPill.cc
2 A "pill" which gives the player mods when taken
3
4 Copyright (C) 2000 Mathias Broxvall
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (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
21 #include "modPill.h"
22
23 #include "debris.h"
24 #include "game.h"
25 #include "mainMode.h"
26 #include "map.h"
27 #include "player.h"
28 #include "sign.h"
29 #include "sound.h"
30
31 int isGoodPill[NUM_MODS] = {1, 1, 1, 0, 0, 0, 1, 1};
32
ModPill(Game & g,Real x,Real y,int kind,int time,int resurrecting)33 ModPill::ModPill(Game &g, Real x, Real y, int kind, int time, int resurrecting)
34 : Ball(g, Role_OtherAnimated), kind(kind), resurrecting(resurrecting), time(time) {
35 no_physics = true;
36 realRadius = 0.2;
37 radius = realRadius;
38 is_on = true;
39
40 /* Change our color to red */
41 primaryColor = Color(1., 0.2, 0.2, 1.0);
42
43 /* set bogus velocity for the rendering of speed mods */
44 if (kind == MOD_SPEED) {
45 velocity[0] = 0.0;
46 velocity[1] = -1.2;
47 } else {
48 velocity = Coord3d();
49 }
50
51 modTimeLeft[kind] = -1.0;
52 clock = 0.0;
53
54 if (kind == MOD_EXTRA_LIFE) {
55 realRadius = 0.3;
56 radius = realRadius;
57 primaryColor = Color(1., 0.9, 0.2, 1.);
58 specularColor = Color(1., 0.9, 0.2, 1.);
59 }
60
61 position[0] = x;
62 position[1] = y;
63 position[2] = game.map->getHeight(position[0], position[1]) + radius;
64
65 timeLeft = 0.;
66 }
67
~ModPill()68 ModPill::~ModPill() {}
69
tick(Real t)70 void ModPill::tick(Real t) {
71 Animated::tick(t);
72
73 Player *player = game.player1;
74 if (!is_on) {
75 timeLeft -= t;
76 if (resurrecting > 0.0 && timeLeft < 0) is_on = true;
77 }
78
79 clock += t;
80 if (kind == MOD_LARGE) {
81 realRadius = 0.2 * (1.0 + std::fmod(clock, 2.0) / 2.0);
82 radius = realRadius;
83 } else if (kind == MOD_SMALL) {
84 realRadius = 0.2 / (1.0 + std::fmod(clock, 2.0) / 2.0);
85 radius = realRadius;
86 }
87
88 if (is_on && kind == MOD_NITRO) Ball::generateNitroDebris(t);
89
90 if (is_on) {
91 position[2] = game.map->getHeight(position[0], position[1]) + radius;
92 Coord3d v = player->position - position;
93 double dist = length(v);
94 if (dist < radius + player->radius) {
95 Coord3d signPos = position;
96 signPos[2] += 1.0;
97
98 /* Explanations of modpills shown after taking them. Note that only bad
99 ones have an exclamation mark after them */
100 const char *modExplanations[NUM_MODS] = {
101 _("Speed ball"), _("Extra jump"), _("Spikes"), _("Glass ball"),
102 _("Dizzy!"), _("Freeze!"), _("Floating"), _("Extra life"),
103 _("Small ball"), _("Large ball"), _("Nitro")};
104 game.add(new Sign(game, modExplanations[kind], 6.0, 1.0, 60.0, signPos));
105
106 if (kind == MOD_EXTRA_LIFE) {
107 player->lives = std::min(4, player->lives + 1);
108 } else {
109 if (time >= 0.0)
110 player->modTimeLeft[kind] += time;
111 else
112 player->modTimeLeft[kind] = -1.0;
113 }
114
115 if (kind == MOD_FROZEN) MainMode::mainMode->flash = 2.0;
116
117 if (kind == MOD_EXTRA_LIFE)
118 playEffect(SFX_GOT_LIFE);
119 else if (isGoodPill[kind])
120 playEffect(SFX_GOT_GOODPILL);
121 else
122 playEffect(SFX_GOT_BADPILL);
123
124 is_on = false;
125 if (!resurrecting) remove();
126 timeLeft = (Real)resurrecting;
127 }
128 }
129 }
130
die(int)131 void ModPill::die(int /*how*/) {
132 is_on = false;
133 if (!resurrecting) remove();
134 }
135