X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fbd_caveengine.c;h=3019aeca80dea04636e5379ab4978c992781eb56;hb=0f4ca4876cd7e3ac7f05620a6d048f5cd7dac294;hp=407c7b1ee9dcb3ed668432cd059281222daf7577;hpb=76903990771e961a2d32af364dead8462b9526e7;p=rocksndiamonds.git diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 407c7b1e..3019aeca 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -135,29 +135,51 @@ static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) switch (element) { case O_NUT: + gd_sound_play(cave, GD_S_NUT_FALLING, element, x, y); + break; + case O_NUT_F: - gd_sound_play(cave, GD_S_NUT, element, x, y); + gd_sound_play(cave, GD_S_NUT_IMPACT, element, x, y); break; case O_STONE: + gd_sound_play(cave, GD_S_STONE_FALLING, element, x, y); + break; + case O_STONE_F: + gd_sound_play(cave, GD_S_STONE_IMPACT, element, x, y); + break; + case O_FLYING_STONE: + gd_sound_play(cave, GD_S_FLYING_STONE_FALLING, element, x, y); + break; + case O_FLYING_STONE_F: + gd_sound_play(cave, GD_S_FLYING_STONE_IMPACT, element, x, y); + break; + case O_MEGA_STONE: + gd_sound_play(cave, GD_S_MEGA_STONE_FALLING, element, x, y); + break; + case O_MEGA_STONE_F: - case O_WAITING_STONE: - case O_CHASING_STONE: - gd_sound_play(cave, GD_S_STONE, element, x, y); + gd_sound_play(cave, GD_S_MEGA_STONE_IMPACT, element, x, y); break; case O_NITRO_PACK: + gd_sound_play(cave, GD_S_NITRO_PACK_FALLING, element, x, y); + break; + case O_NITRO_PACK_F: - gd_sound_play(cave, GD_S_NITRO, element, x, y); + gd_sound_play(cave, GD_S_NITRO_PACK_IMPACT, element, x, y); break; case O_FALLING_WALL: + gd_sound_play(cave, GD_S_FALLING_WALL_FALLING, element, x, y); + break; + case O_FALLING_WALL_F: - gd_sound_play(cave, GD_S_FALLING_WALL, element, x, y); + gd_sound_play(cave, GD_S_FALLING_WALL_IMPACT, element, x, y); break; case O_H_EXPANDING_WALL: @@ -170,10 +192,19 @@ static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) break; case O_DIAMOND: + gd_sound_play(cave, GD_S_DIAMOND_FALLING_RANDOM, element, x, y); + break; + case O_DIAMOND_F: + gd_sound_play(cave, GD_S_DIAMOND_IMPACT_RANDOM, element, x, y); + break; + case O_FLYING_DIAMOND: + gd_sound_play(cave, GD_S_FLYING_DIAMOND_FALLING_RANDOM, element, x, y); + break; + case O_FLYING_DIAMOND_F: - gd_sound_play(cave, GD_S_DIAMOND_RANDOM, element, x, y); + gd_sound_play(cave, GD_S_FLYING_DIAMOND_IMPACT_RANDOM, element, x, y); break; case O_BLADDER_SPENDER: @@ -181,7 +212,7 @@ static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) break; case O_PRE_CLOCK_1: - gd_sound_play(cave, GD_S_BLADDER_CONVERT, element, x, y); + gd_sound_play(cave, GD_S_BLADDER_CONVERTING, element, x, y); break; case O_SLIME: @@ -193,25 +224,77 @@ static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) break; case O_ACID: - gd_sound_play(cave, GD_S_ACID_SPREAD, element, x, y); + gd_sound_play(cave, GD_S_ACID_SPREADING, element, x, y); break; case O_BLADDER: - gd_sound_play(cave, GD_S_BLADDER_MOVE, element, x, y); + gd_sound_play(cave, GD_S_BLADDER_MOVING, element, x, y); break; case O_BITER_1: case O_BITER_2: case O_BITER_3: case O_BITER_4: - gd_sound_play(cave, GD_S_BITER_EAT, element, x, y); + gd_sound_play(cave, GD_S_BITER_EATING, element, x, y); break; case O_DIRT_BALL: + gd_sound_play(cave, GD_S_DIRT_BALL_FALLING, element, x, y); + break; + case O_DIRT_BALL_F: + gd_sound_play(cave, GD_S_DIRT_BALL_IMPACT, element, x, y); + break; + case O_DIRT_LOOSE: + gd_sound_play(cave, GD_S_DIRT_LOOSE_FALLING, element, x, y); + break; + case O_DIRT_LOOSE_F: - gd_sound_play(cave, GD_S_DIRT_BALL, element, x, y); + gd_sound_play(cave, GD_S_DIRT_LOOSE_IMPACT, element, x, y); + break; + + default: + /* do nothing. */ + break; + } +} + +/* play sound of given element being pushed. */ +static void play_sound_of_element_pushing(GdCave *cave, GdElement element, int x, int y) +{ + switch (element) + { + case O_NUT: + gd_sound_play(cave, GD_S_NUT_PUSHING, element, x, y); + break; + + case O_STONE: + gd_sound_play(cave, GD_S_STONE_PUSHING, element, x, y); + break; + + case O_FLYING_STONE: + gd_sound_play(cave, GD_S_FLYING_STONE_PUSHING, element, x, y); + break; + + case O_MEGA_STONE: + gd_sound_play(cave, GD_S_MEGA_STONE_PUSHING, element, x, y); + break; + + case O_WAITING_STONE: + gd_sound_play(cave, GD_S_WAITING_STONE_PUSHING, element, x, y); + break; + + case O_CHASING_STONE: + gd_sound_play(cave, GD_S_CHASING_STONE_PUSHING, element, x, y); + break; + + case O_NITRO_PACK: + gd_sound_play(cave, GD_S_NITRO_PACK_PUSHING, element, x, y); + break; + + case O_BLADDER: + gd_sound_play(cave, GD_S_BLADDER_PUSHING, element, x, y); break; default: @@ -220,6 +303,38 @@ static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) } } +static inline int getx(const GdCave *cave, const int x, const int y) +{ + return cave->getx(cave, x, y); +} + +static inline int gety(const GdCave *cave, const int x, const int y) +{ + return cave->gety(cave, x, y); +} + +/* perfect (non-lineshifting) GET x/y functions; returns range corrected x/y position */ +static inline int getx_perfect(const GdCave *cave, const int x, const int y) +{ + return (x + cave->w) % cave->w; +} + +static inline int gety_perfect(const GdCave *cave, const int x, const int y) +{ + return (y + cave->h) % cave->h; +} + +/* line shifting GET x/y function; returns range corrected x/y position */ +static inline int getx_shift(const GdCave *cave, int x, int y) +{ + return (x + cave->w) % cave->w; +} + +static inline int gety_shift(const GdCave *cave, int x, int y) +{ + return ((x < 0 ? y - 1 : x >= cave->w ? y + 1 : y) + cave->h) % cave->h; +} + static inline GdElement *getp(const GdCave *cave, const int x, const int y) { return cave->getp(cave, x, y); @@ -406,11 +521,24 @@ static inline boolean is_element_dir(const GdCave *cave, const int x, const int static inline boolean is_space_dir(const GdCave *cave, const int x, const int y, const GdDirection dir) { - GdElement e = get_dir(cave, x, y, dir)&O_MASK; + GdElement e = get_dir(cave, x, y, dir) & O_MASK; return (e == O_SPACE || e == O_LAVA); } +static inline void store_dir_buffer(GdCave *cave, const int x, const int y, const GdDirection dir) +{ + /* raw values without range correction */ + int raw_x = x + gd_dx[dir]; + int raw_y = y + gd_dy[dir]; + /* final values with range correction */ + int new_x = getx(cave, raw_x, raw_y); + int new_y = gety(cave, raw_x, raw_y); + int new_dir = (dir > GD_MV_TWICE ? dir - GD_MV_TWICE : dir); + + game_bd.game->dir_buffer[new_y][new_x] = new_dir; +} + /* store an element at the given position */ static inline void store(GdCave *cave, const int x, const int y, const GdElement element) { @@ -436,13 +564,15 @@ static inline void store_sc(GdCave *cave, const int x, const int y, const GdElem static inline void store_dir(GdCave *cave, const int x, const int y, const GdDirection dir, const GdElement element) { - store(cave, x + gd_dx[dir], y + gd_dy[dir], element|SCANNED); + store_dir_buffer(cave, x, y, dir); + store(cave, x + gd_dx[dir], y + gd_dy[dir], element | SCANNED); } /* store an element to a neighbouring cell */ static inline void store_dir_no_scanned(GdCave *cave, const int x, const int y, const GdDirection dir, const GdElement element) { + store_dir_buffer(cave, x, y, dir); store(cave, x + gd_dx[dir], y + gd_dy[dir], element); } @@ -488,7 +618,7 @@ static void creature_explode(GdCave *cave, int x, int y, GdElement explode_to) /* the processing of an explosion took pretty much time: processing 3x3 = 9 elements */ cave->ckdelay += 1200; - gd_sound_play(cave, GD_S_EXPLOSION, get(cave, x, y), x, y); + gd_sound_play(cave, GD_S_EXPLODING, get(cave, x, y), x, y); for (yy = y - 1; yy <= y + 1; yy++) for (xx = x - 1; xx <= x + 1; xx++) @@ -501,7 +631,7 @@ static void nitro_explode(GdCave *cave, int x, int y) /* the processing of an explosion took pretty much time: processing 3x3 = 9 elements */ cave->ckdelay += 1200; - gd_sound_play(cave, GD_S_NITRO_EXPLOSION, get(cave, x, y), x, y); + gd_sound_play(cave, GD_S_NITRO_PACK_EXPLODING, get(cave, x, y), x, y); for (yy = y - 1; yy <= y + 1; yy++) for (xx = x - 1; xx <= x + 1; xx++) @@ -520,7 +650,7 @@ static void voodoo_explode(GdCave *cave, int x, int y) /* the processing of an explosion took pretty much time: processing 3x3 = 9 elements */ cave->ckdelay += 1000; - gd_sound_play(cave, GD_S_VOODOO_EXPLOSION, get(cave, x, y), x, y); + gd_sound_play(cave, GD_S_VOODOO_EXPLODING, get(cave, x, y), x, y); if (cave->voodoo_any_hurt_kills_player) cave->voodoo_touched = TRUE; @@ -555,7 +685,7 @@ static void explode_try_skip_voodoo(GdCave *cave, const int x, const int y, cons /* X shaped ghost explosion; does not touch voodoo! */ static void ghost_explode(GdCave *cave, const int x, const int y) { - gd_sound_play(cave, GD_S_GHOST_EXPLOSION, get(cave, x, y), x, y); + gd_sound_play(cave, GD_S_GHOST_EXPLODING, get(cave, x, y), x, y); /* the processing of an explosion took pretty much time: processing 5 elements */ cave->ckdelay += 650; @@ -570,7 +700,7 @@ static void ghost_explode(GdCave *cave, const int x, const int y) /* +shaped bomb explosion; does not touch voodoo! */ static void bomb_explode(GdCave *cave, const int x, const int y) { - gd_sound_play(cave, GD_S_BOMB_EXPLOSION, get(cave, x, y), x, y); + gd_sound_play(cave, GD_S_BOMB_EXPLODING, get(cave, x, y), x, y); /* the processing of an explosion took pretty much time: processing 5 elements */ cave->ckdelay += 650; @@ -673,8 +803,7 @@ static void explode(GdCave *cave, int x, int y) } } -static void inline -explode_dir(GdCave *cave, const int x, const int y, GdDirection dir) +static void inline explode_dir(GdCave *cave, const int x, const int y, GdDirection dir) { explode(cave, x + gd_dx[dir], y + gd_dy[dir]); } @@ -685,7 +814,7 @@ explode_dir(GdCave *cave, const int x, const int y, GdDirection dir) returns other element if something other appears there and he can't move. cave pointer is needed to know the diamond values. */ -static GdElement player_get_element (GdCave* cave, const GdElement object, int x, int y) +static GdElement player_get_element(GdCave* cave, const GdElement object, int x, int y) { int i; @@ -693,43 +822,43 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x { case O_DIAMOND_KEY: cave->diamond_key_collected = TRUE; - gd_sound_play(cave, GD_S_DIAMOND_KEY_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_DIAMOND_KEY_COLLECTING, object, x, y); return O_SPACE; /* KEYS AND DOORS */ case O_KEY_1: - gd_sound_play(cave, GD_S_KEY_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_KEY_COLLECTING, object, x, y); cave->key1++; return O_SPACE; case O_KEY_2: - gd_sound_play(cave, GD_S_KEY_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_KEY_COLLECTING, object, x, y); cave->key2++; return O_SPACE; case O_KEY_3: - gd_sound_play(cave, GD_S_KEY_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_KEY_COLLECTING, object, x, y); cave->key3++; return O_SPACE; case O_DOOR_1: if (cave->key1 == 0) return object; - gd_sound_play(cave, GD_S_DOOR_OPEN, object, x, y); + gd_sound_play(cave, GD_S_DOOR_OPENING, object, x, y); cave->key1--; return O_SPACE; case O_DOOR_2: if (cave->key2 == 0) return object; - gd_sound_play(cave, GD_S_DOOR_OPEN, object, x, y); + gd_sound_play(cave, GD_S_DOOR_OPENING, object, x, y); cave->key2--; return O_SPACE; case O_DOOR_3: if (cave->key3 == 0) return object; - gd_sound_play(cave, GD_S_DOOR_OPEN, object, x, y); + gd_sound_play(cave, GD_S_DOOR_OPENING, object, x, y); cave->key3--; return O_SPACE; @@ -777,22 +906,22 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x case O_DIRT_SLOPED_DOWN_RIGHT: case O_DIRT_BALL: case O_DIRT_LOOSE: - gd_sound_play(cave, GD_S_WALK_EARTH, object, x, y); + gd_sound_play(cave, GD_S_DIRT_WALKING, object, x, y); return O_SPACE; case O_SWEET: - gd_sound_play(cave, GD_S_SWEET_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_SWEET_COLLECTING, object, x, y); cave->sweet_eaten = TRUE; return O_SPACE; case O_PNEUMATIC_HAMMER: - gd_sound_play(cave, GD_S_PNEUMATIC_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_PNEUMATIC_COLLECTING, object, x, y); cave->got_pneumatic_hammer = TRUE; return O_SPACE; case O_CLOCK: /* bonus time */ - gd_sound_play(cave, GD_S_CLOCK_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_CLOCK_COLLECTING, object, x, y); cave->time += cave->time_bonus * cave->timing_factor; if (cave->time > cave->max_time * cave->timing_factor) cave->time -= cave->max_time * cave->timing_factor; @@ -803,7 +932,8 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x case O_FLYING_DIAMOND: // prevent diamond sounds for O_SKELETON (see below) if (x != -1 && y != -1) - gd_sound_play(cave, GD_S_DIAMOND_COLLECT, object, x, y); + gd_sound_play(cave, (object == O_DIAMOND ? GD_S_DIAMOND_COLLECTING : + GD_S_FLYING_DIAMOND_COLLECTING), object, x, y); cave->score += cave->diamond_value; cave->diamonds_collected++; @@ -816,8 +946,8 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x cave->diamond_value = cave->extra_diamond_value; cave->gate_open_flash = 1; - cave->sound3 = GD_S_CRACK; - gd_sound_play(cave, GD_S_CRACK, O_OUTBOX, x, y); + cave->sound3 = GD_S_CRACKING; + gd_sound_play(cave, GD_S_CRACKING, O_OUTBOX, x, y); } return O_SPACE; @@ -829,7 +959,7 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x player_get_element(cave, O_DIAMOND, -1, -1); /* _after_ calling get_element for the fake diamonds, so we overwrite its sounds */ - gd_sound_play(cave, GD_S_SKELETON_COLLECT, object, x, y); + gd_sound_play(cave, GD_S_SKELETON_COLLECTING, object, x, y); return O_SPACE; case O_OUTBOX: @@ -839,7 +969,7 @@ static GdElement player_get_element (GdCave* cave, const GdElement object, int x case O_SPACE: case O_LAVA: /* player goes into lava, as if it was space */ - gd_sound_play(cave, GD_S_WALK_EMPTY, object, x, y); + gd_sound_play(cave, GD_S_EMPTY_WALKING, object, x, y); return O_SPACE; default: @@ -974,7 +1104,7 @@ static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, bool { /* if decided that he will be able to push, */ store_dir(cave, x, y, GD_MV_TWICE + player_move, what); - play_sound_of_element(cave, what, x, y); + play_sound_of_element_pushing(cave, what, x, y); result = TRUE; } } @@ -1045,7 +1175,7 @@ static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, bool } if (result) - play_sound_of_element(cave, O_BLADDER, x, y); + play_sound_of_element_pushing(cave, O_BLADDER, x, y); } break; @@ -1066,7 +1196,7 @@ static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, bool /* yes, so push. */ store_dir(cave, x, y, player_move + GD_MV_TWICE, O_BOX); result = TRUE; - gd_sound_play(cave, GD_S_BOX_PUSH, what, x, y); + gd_sound_play(cave, GD_S_BOX_PUSHING, what, x, y); } break; @@ -1202,7 +1332,7 @@ static boolean do_fall_try_crack_nut(GdCave *cave, int x, int y, store(cave, x, y, bouncing); store_dir(cave, x, y, fall_dir, cave->nut_turns_to_when_crushed); - gd_sound_play(cave, GD_S_NUT_CRACK, O_NUT, x, y); + gd_sound_play(cave, GD_S_NUT_CRACKING, O_NUT, x, y); return TRUE; } @@ -1434,9 +1564,17 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* set cave get function; to implement perfect or lineshifting borders */ if (cave->lineshift) + { cave->getp = getp_shift; + cave->getx = getx_shift; + cave->gety = gety_shift; + } else + { cave->getp = getp_perfect; + cave->getx = getx_perfect; + cave->gety = gety_perfect; + } /* increment this. if the scan routine comes across player, clears it (sets to zero). */ if (cave->player_seen_ago < 100) @@ -1480,7 +1618,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, if (cave->hammered_reappear[y][x] == 0) { store(cave, x, y, O_BRICK); - gd_sound_play(cave, GD_S_WALL_REAPPEAR, O_BRICK, x, y); + gd_sound_play(cave, GD_S_WALL_REAPPEARING, O_BRICK, x, y); } } } @@ -1517,7 +1655,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, { /* if we find a scanned element, change it to the normal one, and that's all. */ /* this is required, for example for chasing stones, which have moved, always passing slime! */ - if (get(cave, x, y)&SCANNED) + if (get(cave, x, y) & SCANNED) { store(cave, x, y, get(cave, x, y) & ~SCANNED); @@ -1586,15 +1724,18 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* try to push element; if successful, break */ push = do_push(cave, x, y, player_move, player_fire); if (push) + { remains = O_SPACE; + } else + { switch (what) { case O_BOMB: /* if its a bomb, remember he now has one. */ /* we do not change the "remains" and "what" variables, so that part of the code will be ineffective */ - gd_sound_play(cave, GD_S_BOMB_COLLECT, what, x, y); + gd_sound_play(cave, GD_S_BOMB_COLLECTING, what, x, y); store_dir(cave, x, y, player_move, O_SPACE); if (player_fire) @@ -1635,9 +1776,10 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, default: /* get element - process others. if cannot get, player_get_element will return the same */ - remains = player_get_element (cave, what, x, y); + remains = player_get_element(cave, what, x, y); break; } + } if (remains != what || remains == O_SPACE) { @@ -1689,7 +1831,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* placed bomb, he is normal player again */ store(cave, x, y, O_PLAYER); - gd_sound_play(cave, GD_S_BOMB_PLACE, O_BOMB, x, y); + gd_sound_play(cave, GD_S_BOMB_PLACING, O_BOMB, x, y); } break; } @@ -1702,7 +1844,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* player fire is false... */ if (do_push(cave, x, y, player_move, FALSE)) + { remains = O_SPACE; + } else { switch (what) @@ -3386,7 +3530,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, if (cave->gravity_will_change == 0) { cave->gravity = cave->gravity_next_direction; - gd_sound_play(cave, GD_S_GRAVITY_CHANGE, O_GRAVITY_SWITCH, -1, -1); /* takes precedence over amoeba and magic wall sound */ + gd_sound_play(cave, GD_S_GRAVITY_CHANGING, O_GRAVITY_SWITCH, -1, -1); /* takes precedence over amoeba and magic wall sound */ } } @@ -3495,7 +3639,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, cave->creatures_backwards = !cave->creatures_backwards; } - gd_sound_play(cave, GD_S_CRACK, O_INBOX, -1, -1); + gd_sound_play(cave, GD_S_CRACKING, O_INBOX, -1, -1); } /* for biters */