1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
|
/*
* effects.h - Special effects.
*
* Copyright (C) 2000-2001 The Exult Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef EFFECTS_H
#define EFFECTS_H 1
#include <string>
#include "tqueue.h"
#include "tiles.h"
#include "singles.h"
class Xform_palette;
class PathFinder;
class Game_object;
class Game_window;
class Image_window8;
class Shape_frame;
class Actor;
class Special_effect;
class Text_effect;
/*
* Manage special effects.
*/
class Effects_manager
{
Game_window *gwin; // Handy pointer.
Special_effect *effects; // Sprite effects, projectiles, etc.
Text_effect *texts; // Text snippets.
public:
Effects_manager(Game_window *g) : gwin(g), effects(0), texts(0)
{ }
~Effects_manager();
// Add text item.
void add_text(const char *msg, Game_object *item);
void add_text(const char *msg, int x, int y);
void center_text(const char *msg);
void add_effect(Special_effect *effect);
void add_text_effect(Text_effect *txt);
void remove_text_effect(Game_object *item);
// Remove text item & delete it.
void remove_effect(Special_effect *effect);
void remove_text_effect(Text_effect *txt);
void remove_all_effects(bool repaint=false);
void remove_text_effects();
// Remove just the weather.
void remove_weather_effects(int dist = 0);
int get_weather(); // Get # of last weather added.
void paint(); // Draw all sprites/proj./weather.
void paint_text(); // Draw text.
};
/*
* Base class for special-effects:
*/
class Special_effect : public Time_sensitive, public Game_singletons
{
Special_effect *next, *prev; // All of them are chained together.
public:
friend class Effects_manager;
Special_effect() : next(0), prev(0)
{ }
virtual ~Special_effect()
{ }
// Render.
virtual void paint();
virtual int is_weather() // Need to distinguish weather.
{ return 0; }
};
/*
* An animation from 'sprites.vga':
*/
class Sprites_effect : public Special_effect
{
protected:
ShapeID sprite;
//int sprite_num; // Which one.
//int frame_num; // Current frame.
int frames; // # frames.
Game_object *item; // Follows this around if not null.
Tile_coord pos; // Position within world.
int xoff, yoff; // Offset from position in pixels.
int deltax, deltay; // Add to xoff, yoff on each frame.
void add_dirty(int frnum);
public:
Sprites_effect(int num, Tile_coord p, int dx = 0, int dy = 0,
int delay = 0);
Sprites_effect(int num, Game_object *it,
int xf, int yf, int dx, int dy);
// For Time_sensitive:
virtual void handle_event(unsigned long time, long udata);
// Render.
virtual void paint();
};
/*
* An explosion.
*/
class Explosion_effect : public Sprites_effect
{
Game_object *explode; // What's exploding, or 0.
int weapon; // Weapon to use for attack values.
public:
Explosion_effect(Tile_coord p, Game_object *exp, int delay = 0,
int weap = -1);
virtual void handle_event(unsigned long time, long udata);
};
/*
* A moving animation, followed by an 'attack' at the end, to
* implement Usecode intrinsic 0x41:
*/
class Projectile_effect : public Special_effect
{
Actor *attacker; // Source of attack/spell.
Game_object *target; // Target of path.
int projectile_shape; // Shape # of projectile/spell.
ShapeID sprite; // Sprite shape to display.
int weapon; // Shape # of firing weapon, or 0.
int frames; // # frames.
PathFinder *path; // Determines path.
Tile_coord pos; // Current position.
bool return_path; // Returning a boomerang.
bool no_blocking; // Don't get blocked by things.
// Add dirty rectangle.
void add_dirty();
void init(Tile_coord s, Tile_coord t);
public:
Projectile_effect(Actor *att, Game_object *to, int shnum,
int weap = 0);
// For missile traps:
Projectile_effect(Tile_coord s, Tile_coord d, int shnum, int weap);
Projectile_effect(Tile_coord s, Game_object *to, int shnum, int weap,
bool retpath = false);
~Projectile_effect();
// For Time_sensitive:
virtual void handle_event(unsigned long time, long udata);
// Render.
virtual void paint();
};
/*
* 'Death Vortex', from the spell. (Maybe this could be a
* Sprites_effect.)
*/
class Death_vortex : public Special_effect
{
ShapeID vortex;
Actor *target; // We'll follow this around if not 0.
Tile_coord pos; // Current position.
int frames; // # frames.
uint32 stop_time; // Time in 1/1000 secs. to stop.
uint32 next_damage_time; // When to check for NPC's beneath us.
int add_dirty();
public:
Death_vortex(Game_object *trg, Tile_coord tp);
// For Time_sensitive:
virtual void handle_event(unsigned long time, long udata);
// Render.
virtual void paint();
};
/*
* A text object is a message that stays on the screen for just a couple
* of seconds. These are all kept in a single list, and managed by
* Game_window.
*/
class Text_effect : public Time_sensitive, public Game_singletons
{
Text_effect *next, *prev; // All of them are chained together.
std::string msg; // What to print.
Game_object *item; // Item text is on. May be null.
Tile_coord pos; // Position to display it at.
short width, height; // Dimensions of rectangle.
int num_ticks; // # ticks passed.
void add_dirty();
void init();
public:
friend class Effects_manager;
Text_effect(const std::string &m, Game_object *it);
Text_effect(const std::string &m, int t_x, int t_y);
// At timeout, remove from screen.
virtual void handle_event(unsigned long curtime, long udata);
// Render.
virtual void paint();
// Check for matching item.
int is_text(Game_object *it)
{ return it == item; }
};
/*
* Weather.
*/
class Weather_effect : public Special_effect
{
protected:
uint32 stop_time; // Time in 1/1000 secs. to stop.
int num; // Weather ID (0-6), or -1.
Tile_coord eggloc; // Location of egg that started this.
public:
Weather_effect(int duration, int delay, int n, Game_object *egg = 0);
virtual ~Weather_effect()
{ }
// Avatar out of range?
int out_of_range(Tile_coord& avpos, int dist);
virtual int is_weather()
{ return 1; }
int get_num() { return num; }
};
/*
* A raindrop:
*/
class Raindrop
{
unsigned char oldpix; // Pixel originally on screen.
unsigned char yperx; // Move this many y-pixels for each x.
long ax, ay; // Coords. where drawn in abs. pixels.
public:
Raindrop() : oldpix(0xff), yperx(1), ax(-1), ay(-1)
{ }
void paint(Image_window8 *iwin, int scrolltx, int scrollty,
Xform_palette& xform);
// Move to next position.
void next(Image_window8 *iwin, int scrolltx, int scrollty,
Xform_palette& xform, int w, int h);
void next_random(Image_window8 *iwin, int scrolltx, int scrollty,
Xform_palette& xform, int w, int h);
};
/*
* Raining.
*/
class Rain_effect : public Weather_effect
{
protected:
#define MAXDROPS 200
Raindrop drops[MAXDROPS]; // Drops moving down the screen.
int num_drops; // # to actually use.
public:
Rain_effect(int duration, int delay = 0,
int ndrops = MAXDROPS, int n = -1, Game_object *egg = 0)
: Weather_effect(duration, delay, n, egg),
num_drops(ndrops)
{ }
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
// Render.
virtual void paint();
};
/*
* Lightning.
*/
class Lightning_effect : public Weather_effect
{
static int active; // Just want one at a time.
bool flashing; // Lightning palette is set.
friend class Storm_effect;
public:
Lightning_effect(int duration, int delay = 0)
: Weather_effect(duration, delay, -1), flashing(false)
{ }
~Lightning_effect();
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
};
/*
* Storm.
*/
class Storm_effect : public Weather_effect
{
int start; // 1 to start storm.
public:
Storm_effect(int duration, int delay = 0, Game_object *egg = 0);
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
virtual ~Storm_effect();
};
/*
* Ambrosia's 'twinkling rain'.
*/
class Sparkle_effect : public Rain_effect
{
public:
Sparkle_effect(int duration, int delay = 0, Game_object *egg = 0)
// Weather #3.
: Rain_effect(duration, delay, 50, 3, egg)
{ }
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
};
/*
* A single cloud (sprite shape 2):
*/
class Cloud
{
ShapeID cloud;
long wx, wy; // Position within world.
short deltax, deltay; // How to move.
int count; // Counts down to 0.
int max_count;
uint32 start_time; // When to start.
static int randcnt; // For generating random times.
void set_start_pos(Shape_frame *shape, int w, int h, int& x, int& y);
public:
Cloud(short dx, short dy);
// Move to next position & paint.
void next(Game_window *gwin, unsigned long curtime, int w, int h);
void paint();
};
/*
* Clouds.
*/
class Clouds_effect : public Weather_effect
{
int num_clouds;
Cloud **clouds; // ->clouds.
public:
Clouds_effect(int duration, int delay = 0, Game_object *egg = 0);
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
// Render.
virtual void paint();
virtual ~Clouds_effect()
{ delete [] clouds; }
};
/*
* Earthquakes. +++++Might make this a Weather_effect.
*/
class Earthquake : public Time_sensitive
{
int len; // From Usecode intrinsic.
int i; // Current index.
public:
Earthquake(int l) : len(l), i(0)
{
}
// Execute when due.
virtual void handle_event(unsigned long curtime, long udata);
};
/*
* A fire field that dies out after a few seconds.
*/
class Fire_field_effect : public Special_effect
{
Game_object *field; // What we create.
public:
Fire_field_effect(Tile_coord t);
virtual void handle_event(unsigned long curtime, long udata);
};
#endif
|