1 /** 2 ** Animate.h - Animated game objects. 3 ** 4 ** Written: 7/27/2000 - JSF 5 **/ 6 7 /* 8 Copyright (C) 2000 Jeffrey S. Freedman 9 10 This program is free software; you can redistribute it and/or 11 modify it under the terms of the GNU General Public License 12 as published by the Free Software Foundation; either version 2 13 of the License, or (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 */ 24 25 #ifndef INCL_ANIMATE 26 #define INCL_ANIMATE 1 27 28 #include "iregobjs.h" 29 #include "miscinf.h" 30 31 /* 32 * A class for playing sound effects that get updated by position 33 * and distance. Adds itself to time-queue, deletes itself when done. 34 */ 35 class Object_sfx : public Time_sensitive, public Game_singletons { 36 Game_object_weak obj; // Object that caused the sound. 37 Tile_coord last_pos; 38 int sfx; // ID of sound effect being played. 39 int channel; // Channel of sfx being played. 40 void stop_playing(); 41 Object_sfx(Game_object *o, int sfx); 42 protected: 43 void dequeue() override; 44 public: 45 static void Play(Game_object *o, int sfx, int delay = 20); 46 void stop(); get_sfxnum()47 int get_sfxnum() { 48 return sfx; 49 } 50 void handle_event(unsigned long time, uintptr udata) override; 51 }; 52 53 /* 54 * A class for playing sound effects when certain objects are nearby. 55 */ 56 class Shape_sfx : public Game_singletons { 57 const Game_object *obj; // Object that caused the sound. 58 const SFX_info *sfxinf; 59 int channel[2]; // ID of sound effect being played. 60 int distance; // Distance in tiles from Avatar. 61 int dir; // Direction (0-15) from Avatar. 62 int last_sfx; // For playing sequential sfx ranges. 63 bool looping; // If the SFX should loop until stopped. 64 public: 65 // Create & start playing sound. Shape_sfx(Game_object * o)66 Shape_sfx(Game_object *o) 67 : obj(o), distance(0), last_sfx(-1) { 68 channel[0] = channel[1] = -1; 69 sfxinf = obj->get_info().get_sfx_info(); 70 if (sfxinf) 71 last_sfx = 0; 72 set_looping(); // To avoid including sfxinf.h. 73 } get_sfxnum()74 int get_sfxnum() { 75 return last_sfx; 76 } get_distance()77 int get_distance() { 78 return distance; 79 } 80 void update(bool play); // Set to new object. 81 void set_looping(); 82 void stop(); 83 }; 84 85 /* 86 * An animator: 87 */ 88 class Animator : public Time_sensitive, public Game_singletons { 89 protected: 90 Game_object *obj; // Object we're controlling. 91 unsigned char deltax, deltay; // If wiggling, deltas from 92 // original position. 93 bool animating; // 1 if animation turned on. 94 Shape_sfx *objsfx; 95 void start_animation(); 96 public: Animator(Game_object * o)97 Animator(Game_object *o) 98 : obj(o), deltax(0), deltay(0), animating(false) { 99 objsfx = new Shape_sfx(obj); 100 } 101 static Animator *create(Game_object *ob); 102 ~Animator() override; want_animation()103 void want_animation() { // Want animation on. 104 if (!animating) 105 start_animation(); 106 } stop_animation()107 void stop_animation() { 108 animating = false; 109 } get_deltax()110 int get_deltax() { 111 return deltax; 112 } get_deltay()113 int get_deltay() { 114 return deltay; 115 } 116 virtual int get_framenum(); activate_animator()117 virtual void activate_animator() { 118 } deactivate_animator()119 virtual void deactivate_animator() { 120 } 121 }; 122 123 /* 124 * Animate by going through frames. 125 */ 126 class Frame_animator : public Animator { 127 const Animation_info *aniinf; 128 unsigned short first_frame; // Initial frame of animation cycle 129 unsigned short currpos; // Current position in the animation. 130 unsigned short nframes; // Number of frames in cycle. 131 unsigned short frame_counter; // When to increase frame. 132 unsigned int created; // Time created 133 unsigned short last_shape; // To check if we need to re init 134 unsigned short last_frame; // To check if we need to re init 135 void Initialize(); 136 public: 137 Frame_animator(Game_object *o); 138 int get_next_frame(); 139 // For Time_sensitive: 140 void handle_event(unsigned long time, uintptr udata) override; get_framenum()141 int get_framenum() override { 142 return obj->get_framenum(); 143 } 144 }; 145 146 /* 147 * Just play SFX. 148 */ 149 class Sfx_animator : public Animator { 150 public: 151 Sfx_animator(Game_object *o); 152 // For Time_sensitive: 153 void handle_event(unsigned long time, uintptr udata) override; 154 }; 155 156 /* 157 * Animate by going through frames, but only do the lower frames once. 158 */ 159 class Field_frame_animator : public Frame_animator { 160 bool activated; // Time to check for damage. 161 public: 162 friend class Field_object; 163 Field_frame_animator(Game_object *o); 164 // For Time_sensitive: 165 void handle_event(unsigned long time, uintptr udata) override; activate_animator()166 void activate_animator() override { 167 activated = true; 168 } deactivate_animator()169 void deactivate_animator() override { 170 activated = false; 171 } 172 }; 173 174 /* 175 * Animate by wiggling. 176 */ 177 class Wiggle_animator : public Animator { 178 public: Wiggle_animator(Game_object * o)179 Wiggle_animator(Game_object *o) : Animator(o) 180 { } 181 // For Time_sensitive: 182 void handle_event(unsigned long time, uintptr udata) override; 183 }; 184 185 /* 186 * An object that cycles through its frames, or wiggles if just one 187 * frame. The base class is for those in U7chunks. 188 */ 189 class Animated_object : public Terrain_game_object { 190 Animator *animator; // Controls animation. 191 public: 192 Animated_object(int shapenum, int framenum, unsigned int tilex, 193 unsigned int tiley, unsigned int lft = 0); 194 ~Animated_object() override; 195 // Render. 196 void paint() override; 197 // +++++Needed on this one: 198 // Get coord. where this was placed. get_original_tile_coord()199 Tile_coord get_original_tile_coord() const override { 200 return get_tile() + 201 Tile_coord(-animator->get_deltax(), 202 -animator->get_deltay(), 0); 203 } 204 }; 205 206 /* 207 * An object that cycles through its frames, or wiggles if just one 208 * frame. This is the IREG version. 209 */ 210 class Animated_ireg_object : public Ireg_game_object { 211 Animator *animator; // Controls animation. 212 public: 213 Animated_ireg_object(int shapenum, int framenum, unsigned int tilex, 214 unsigned int tiley, unsigned int lft = 0); 215 ~Animated_ireg_object() override; 216 // Render. 217 void paint() override; 218 // Get coord. where this was placed. get_original_tile_coord()219 Tile_coord get_original_tile_coord() const override { 220 return get_tile() + 221 Tile_coord(-animator->get_deltax(), 222 -animator->get_deltay(), 0); 223 } 224 225 // Write out to IREG file. 226 void write_ireg(ODataSource *out) override; 227 }; 228 229 /* 230 * An object that cycles through its frames, or wiggles if just one 231 * frame. This is the IFIX version. 232 */ 233 class Animated_ifix_object : public Ifix_game_object { 234 Animator *animator; // Controls animation. 235 public: 236 Animated_ifix_object(int shapenum, int framenum, unsigned int tilex, 237 unsigned int tiley, unsigned int lft = 0); 238 ~Animated_ifix_object() override; 239 // Render. 240 void paint() override; 241 // Get coord. where this was placed. get_original_tile_coord()242 Tile_coord get_original_tile_coord() const override { 243 return get_tile() + 244 Tile_coord(-animator->get_deltax(), 245 -animator->get_deltay(), 0); 246 } 247 248 void write_ifix(ODataSource *ifix, bool v2) override; 249 }; 250 #endif 251 252 253