2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef _GD_CAVE_RENDERED
18 #define _GD_CAVE_RENDERED
25 #include "cave/cavebase.hpp"
26 #include "cave/helper/caverandom.hpp"
27 #include "cave/helper/cavesound.hpp"
28 #include "cave/particle.hpp"
30 #define GD_REDRAW (1<<10)
31 /// These are states of the magic wall.
32 /// @todo ezt nem kéne plainolddatába rakni?
34 GD_MW_DORMANT
, ///< Starting with this.
35 GD_MW_ACTIVE
, ///< Boulder or diamond dropped into.
36 GD_MW_EXPIRED
///< Turned off after magic_wall_milling_time.
39 /// These are states of the player.
41 GD_PL_NOT_YET
, ///< Not yet living. Beginning of cave time.
42 GD_PL_LIVING
, ///< Ok.
43 GD_PL_TIMEOUT
, ///< Time is up
44 GD_PL_DIED
, ///< Died.
45 GD_PL_EXITED
///< Exited the cave, proceed to next one
50 GD_AM_SLEEPING
, ///< sleeping - not yet let out.
51 GD_AM_AWAKE
, ///< living, growing
52 GD_AM_TOO_BIG
, ///< grown too big, will convert to stones
53 GD_AM_ENCLOSED
, ///< enclosed, will convert to diamonds
60 class CaveRendered
: public CaveBase
{
62 GdElementEnum
player_eat_element(GdElementEnum element
);
63 void play_sound_of_element(GdElementEnum element
, int x
, int y
, bool particles
= true);
64 void add_particle_set(int x
, int y
, GdElementEnum particletype
);
66 void cell_explode(int x
, int y
, GdElementEnum explode_to
);
67 void creature_explode(int x
, int y
, GdElementEnum explode_to
);
68 void nitro_explode(int x
, int y
);
69 void voodoo_explode(int x
, int y
);
70 void cell_explode_skip_voodoo(int x
, int y
, GdElementEnum expl
);
71 void ghost_explode(int x
, int y
);
72 void bomb_explode(int x
, int y
);
73 void explode(int x
, int y
);
74 void explode(int x
, int y
, GdDirectionEnum dir
);
76 bool explodes_by_hit(int x
, int y
, GdDirectionEnum dir
) const;
77 bool non_explodable(int x
, int y
) const;
78 bool amoeba_eats(int x
, int y
, GdDirectionEnum dir
) const;
79 bool sloped(int x
, int y
, GdDirectionEnum dir
, GdDirectionEnum slop
) const;
80 bool sloped_for_bladder(int x
, int y
, GdDirectionEnum dir
) const;
81 bool blows_up_flies(int x
, int y
, GdDirectionEnum dir
) const;
82 bool rotates_ccw(int x
, int y
) const;
83 bool is_player(int x
, int y
) const;
84 bool is_player(int x
, int y
, GdDirectionEnum dir
) const;
85 bool can_be_hammered(int x
, int y
, GdDirectionEnum dir
) const;
86 bool is_first_stage_of_explosion(int x
, int y
) const;
87 bool moved_by_conveyor_top(int x
, int y
, GdDirectionEnum dir
) const;
88 bool moved_by_conveyor_bottom(int x
, int y
, GdDirectionEnum dir
) const;
89 bool is_scanned(int x
, int y
) const;
90 bool is_scanned(int x
, int y
, GdDirectionEnum dir
) const;
91 bool is_like_element(int x
, int y
, GdDirectionEnum dir
, GdElementEnum e
) const;
92 bool is_like_space(int x
, int y
, GdDirectionEnum dir
=MV_STILL
) const;
93 bool is_like_dirt(int x
, int y
, GdDirectionEnum dir
=MV_STILL
) const;
95 GdElementEnum
get(int x
, int y
) const;
96 GdElementEnum
get(int x
, int y
, GdDirectionEnum dir
) const;
97 void store(int x
, int y
, GdElementEnum element
, bool disable_particle
= false);
98 void store(int x
, int y
, GdDirectionEnum dir
, GdElementEnum element
);
99 void store_no_scanned(int x
, int y
, GdElementEnum element
);
100 void move(int x
, int y
, GdDirectionEnum dir
, GdElementEnum element
);
101 void next(int x
, int y
);
102 void unscan(int x
, int y
);
105 CaveRendered(CaveStored
const &cave
, int level
, int seed
);
106 void create_map(CaveStored
const &data
, int level
);
108 void setup_for_game();
109 void count_diamonds();
110 void set_ckdelay_extra_for_animation();
112 /* game playing helpers */
113 void draw_indexes(CaveMap
<int> &gfx_buffer
, CaveMap
<bool> const &covered
, bool bonus_life_flash
, int animcycle
, bool hate_invisible_outbox
);
114 int time_visible(int internal_time
) const;
115 void set_seconds_sound();
116 void sound_play(GdSound sound
, int x
, int y
);
118 GdDirectionEnum
iterate(GdDirectionEnum player_move
, bool player_fire
, bool suicide
);
119 void store_rc(int x
, int y
, GdElementEnum element
, CaveObject
const *order
);
121 bool do_teleporter(int px
, int py
, GdDirectionEnum player_move
);
122 bool do_push(int x
, int y
, GdDirectionEnum player_move
, bool player_fire
);
124 void do_start_fall(int x
, int y
, GdDirectionEnum falling_direction
, GdElementEnum falling_element
);
125 bool do_fall_try_crush_voodoo(int x
, int y
, GdDirectionEnum fall_dir
);
126 bool do_fall_try_eat_voodoo(int x
, int y
, GdDirectionEnum fall_dir
);
127 bool do_fall_try_crack_nut(int x
, int y
, GdDirectionEnum fall_dir
, GdElementEnum bouncing
);
128 bool do_fall_try_magic(int x
, int y
, GdDirectionEnum fall_dir
, GdElementEnum magic
);
129 bool do_fall_try_crush(int x
, int y
, GdDirectionEnum fall_dir
);
130 void do_fall_roll_or_stop(int x
, int y
, GdDirectionEnum fall_dir
, GdElementEnum bouncing
);
133 CaveMap
<CaveObject
*> objects_order
; ///< two-dimensional map of cave; each cell is a pointer to the drawing object, which created this element. NULL if map or random.
134 CaveMap
<int> hammered_reappear
; ///< integer map of cave; if non-zero, a brick wall will appear there
135 CaveMap
<GdElementEnum
> map
; ///< cave map
137 // Variables for random number generation
138 GdInt render_seed
; ///< the seed value, which was used to render the cave, is saved here. will be used by record&playback
139 RandomGenerator random
; ///< random number generator of rendered cave
140 C64RandomGenerator c64_rand
; ///< used for predictable random generator during the game.
142 GdBool hatched
; ///< hatching has happened. (timers may run, ...)
143 GdBool gate_open
; ///< self-explaining
144 GdInt rendered_on
; ///< rendered at level x (0 is level1, 4 is level5)
145 GdInt timing_factor
; ///< number of "milliseconds" in each second :) 1000 for ntsc, 1200 for pal.
147 GdInt speed
; ///< Time between game cycles in ms
148 GdInt ckdelay
; ///< a ckdelay value for the level this cave is rendered for
150 GdInt hatching_delay_frame
; ///< frames remaining till hatching.
151 GdInt hatching_delay_time
; ///< time remaining (milliseconds) till hatching
152 GdInt time_bonus
; ///< bonus time for clock collected.
153 GdInt time_penalty
; ///< Time penalty when voodoo destroyed.
154 GdInt time
; ///< milliseconds remaining to finish cave
155 GdInt timevalue
; ///< points for remaining seconds - for current level
156 GdInt diamonds_needed
; ///< diamonds needed to open outbox
157 GdInt diamonds_collected
; ///< diamonds collected
158 GdInt skeletons_collected
; ///< number of skeletons collected
159 GdInt gate_open_flash
; ///< flashing of screen when gate opens, it lasts two iterations
160 GdInt amoeba_time
; ///< Amoeba growing slow (low probability, default 3%) for milliseconds. After that, fast growth default (25%)
161 GdInt amoeba_2_time
; ///< Amoeba growing slow (low probability, default 3%) for milliseconds. After that, fast growth default (25%)
162 GdInt amoeba_max_count
; ///< selected amoeba 1 threshold for this level
163 GdInt amoeba_2_max_count
; ///< selected amoeba 2 threshold for this level
164 AmoebaState amoeba_state
; ///< state of amoeba 1
165 AmoebaState amoeba_2_state
; ///< state of amoeba 2
166 GdInt magic_wall_time
; ///< magic wall 'on' state for seconds
167 GdProbability slime_permeability
; ///< true random slime
168 GdInt slime_permeability_c64
; ///< Appearing in bd 2
169 MagicWallState magic_wall_state
; ///< State of magic wall
170 PlayerState player_state
; ///< Player state. not yet living, living, exited...
171 GdInt player_seen_ago
; ///< player was seen this number of scans ago
172 GdBool kill_player
; ///< Voodoo died, or used pressed escape to restart level.
173 GdBool sweet_eaten
; ///< player ate sweet, he's strong. prob_sweet applies, and also able to push chasing stones
174 GdInt player_x
, player_y
; ///< Coordinates of player (for scrolling)
175 enum { PlayerMemSize
=16 };
176 GdInt player_x_mem
[PlayerMemSize
], player_y_mem
[PlayerMemSize
]; ///< coordinates of player, for chasing stone
177 GdInt key1
, key2
, key3
; ///< The player is holding this number of keys of each color
178 GdBool diamond_key_collected
; ///< Key collected, so trapped diamonds convert to diamonds
179 GdBool inbox_flash_toggle
; ///< negated every scan. helps drawing inboxes, and making players be born at different times.
180 GdInt biters_wait_frame
; ///< number of frames to wait until biters will move again
181 GdInt replicators_wait_frame
; ///< number of frames to wait until replicators are activated again
182 GdInt creatures_direction_will_change
; ///< creatures automatically change direction every x seconds
184 GdInt gravity_will_change
; ///< gravity will change in this number of milliseconds
185 GdBool gravity_disabled
; ///< when the player is stirring the pot, there is no gravity.
186 GdDirectionEnum gravity_next_direction
; ///< next direction when the gravity changes. will be set by the player "getting" a gravity switch
187 GdBool got_pneumatic_hammer
; ///< true if the player has a pneumatic hammer
188 GdInt pneumatic_hammer_active_delay
; ///< number of frames to wait, till pneumatic hammer will destroy the wall
190 GdDirectionEnum last_direction
; ///< last direction player moved. used by draw routines
191 GdDirectionEnum last_horizontal_direction
; ///< last horizontal direction, the player has moved. used by drawing routines
192 GdBool player_blinking
; ///< Player is blinking at the moment. Used by drawing routines
193 GdBool player_tapping
; ///< Player is tapping with his legs. Used by drawing routines
195 GdBool voodoo_touched
;
197 SoundWithPos sound1
, sound2
, sound3
; ///< sound set for 3 channels after each iteration
198 std::list
<ParticleSet
> particles
;
199 GdColor dirt_particle_color
, diamond_particle_color
, stone_particle_color
,
200 explosion_particle_color
, magic_wall_particle_color
;
202 /* these should be inside some context variable */
203 GdInt score
; ///< Score got this frame.
204 GdInt ckdelay_current
; ///< ckdelay value for the current iteration
205 GdInt ckdelay_extra_for_animation
; ///< bd1 and similar engines had animation bits in cave data, to set which elements to animate (firefly, butterfly, amoeba). animating an element also caused some delay each frame; according to my measurements, around 2.6 ms/element.
208 unsigned gd_cave_adler_checksum(const CaveRendered
&cave
);
209 void gd_cave_adler_checksum_more(const CaveRendered
&cave
, unsigned &a
, unsigned &b
);
210 int gd_cave_check_replays(CaveStored
&cave
, bool report
, bool remove
, bool repair
);