X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=4d71c89aa190dddb244c4d818230e530447a6ac9;hb=a5f961c9d6d0ef7f1b69478b6ec20fbac09548b9;hp=489c476b30e431b297f420e71a904557873a4662;hpb=a8613c2d9809cf90870f7c33b6fda80957241827;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 489c476b..4d71c89a 100644 --- a/src/game.c +++ b/src/game.c @@ -53,6 +53,9 @@ #define USE_UFAST_PLAYER_EXIT_BUGFIX (USE_NEW_STUFF * 1) +#define USE_GFX_RESET_ONLY_WHEN_MOVING (USE_NEW_STUFF * 1) +#define USE_GFX_RESET_PLAYER_ARTWORK (USE_NEW_STUFF * 1) + /* for DigField() */ #define DF_NO_PUSH 0 @@ -142,7 +145,7 @@ #define GET_DX_FROM_DIR(d) ((d) == MV_LEFT ? -1 : (d) == MV_RIGHT ? 1 : 0) #define GET_DY_FROM_DIR(d) ((d) == MV_UP ? -1 : (d) == MV_DOWN ? 1 : 0) -#define INIT_GFX_RANDOM() (SimpleRND(1000000)) +#define INIT_GFX_RANDOM() (GetSimpleRandom(1000000)) #define GET_NEW_PUSH_DELAY(e) ( (element_info[e].push_delay_fixed) + \ RND(element_info[e].push_delay_random)) @@ -176,7 +179,7 @@ (e) == EL_TRIGGER_CE_SCORE ? (ch)->actual_trigger_ce_score : \ (e) == EL_CURRENT_CE_VALUE ? (cv) : \ (e) == EL_CURRENT_CE_SCORE ? (cs) : \ - (e) >= EL_LAST_CE_8 && (e) <= EL_NEXT_CE_8 ? \ + (e) >= EL_PREV_CE_8 && (e) <= EL_NEXT_CE_8 ? \ RESOLVED_REFERENCE_ELEMENT(be, e) : \ (e)) @@ -2445,6 +2448,13 @@ void InitGame() } } +#if 1 + UnmapAllGadgets(); + + MapGameButtons(); + MapTapeButtons(); +#endif + game.restart_level = FALSE; } @@ -2671,12 +2681,14 @@ void GameWon() static int game_over_delay = 0; int game_over_delay_value = 50; - /* do not start end game actions before the player stops moving (to exit) */ - if (local_player->MovPos) - return; - if (!local_player->LevelSolved_GameEnd) { + int i; + + /* do not start end game actions before the player stops moving (to exit) */ + if (local_player->MovPos) + return; + local_player->LevelSolved_GameEnd = TRUE; local_player->LevelSolved_SaveTape = tape.recording; local_player->LevelSolved_SaveScore = !tape.playing; @@ -2684,6 +2696,10 @@ void GameWon() if (tape.auto_play) /* tape might already be stopped here */ tape.auto_play_level_solved = TRUE; +#if 1 + TapeStop(); +#endif + game_over_delay = game_over_delay_value; time = time_final = (level.time == 0 ? TimePlayed : TimeLeft); @@ -2730,6 +2746,19 @@ void GameWon() DrawLevelField(ExitX, ExitY); } + for (i = 0; i < MAX_PLAYERS; i++) + { + struct PlayerInfo *player = &stored_player[i]; + + if (player->present) + { + RemovePlayer(player); + + /* player disappears */ + DrawLevelField(player->jx, player->jy); + } + } + PlaySound(SND_GAME_WINNING); } @@ -2770,9 +2799,15 @@ void GameEnd() if (local_player->LevelSolved_SaveTape) { +#if 0 TapeStop(); +#endif +#if 1 + SaveTapeChecked(tape.level_nr); /* ask to save tape */ +#else SaveTape(tape.level_nr); /* ask to save tape */ +#endif } if (level_editor_test_game) @@ -2971,22 +3006,33 @@ static void ResetRandomAnimationValue(int x, int y) void InitMovingField(int x, int y, int direction) { int element = Feld[x][y]; + int move_stepsize = getElementMoveStepsize(x, y); int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int newx = x + dx; int newy = y + dy; + boolean is_moving = (move_stepsize != 0); /* moving or being moved */ + boolean continues_moving = (WasJustMoving[x][y] && direction == MovDir[x][y]); - if (!WasJustMoving[x][y] || direction != MovDir[x][y]) + /* reset animation only for moving elements that change direction of moving + (else CEs with property "can move" / "not moving" are reset each frame) */ +#if USE_GFX_RESET_ONLY_WHEN_MOVING + if (is_moving && !continues_moving) + ResetGfxAnimation(x, y); +#else + if (!continues_moving) ResetGfxAnimation(x, y); +#endif MovDir[x][y] = direction; GfxDir[x][y] = direction; - GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ? + GfxAction[x][y] = (!is_moving ? ACTION_WAITING : + direction == MV_DOWN && CAN_FALL(element) ? ACTION_FALLING : ACTION_MOVING); /* this is needed for CEs with property "can move" / "not moving" */ - if (getElementMoveStepsize(x, y) != 0) /* moving or being moved */ + if (is_moving) { if (Feld[newx][newy] == EL_EMPTY) Feld[newx][newy] = EL_BLOCKED; @@ -7198,7 +7244,7 @@ static void CloseAllOpenTimegates() } } -void EdelsteinFunkeln(int x, int y) +void DrawTwinkleOnField(int x, int y) { if (!IN_SCR_FIELD(SCREENX(x), SCREENY(y)) || IS_MOVING(x, y)) return; @@ -7207,7 +7253,7 @@ void EdelsteinFunkeln(int x, int y) return; if (MovDelay[x][y] == 0) /* next animation frame */ - MovDelay[x][y] = 11 * !SimpleRND(500); + MovDelay[x][y] = 11 * !GetSimpleRandom(500); if (MovDelay[x][y] != 0) /* wait some time before next frame */ { @@ -7869,6 +7915,11 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) (level.use_artwork_element[i] ? level.artwork_element[i] : stored_player[i].element_nr); +#if USE_GFX_RESET_PLAYER_ARTWORK + if (stored_player[i].artwork_element != artwork_element) + stored_player[i].Frame = 0; +#endif + stored_player[i].artwork_element = artwork_element; SetPlayerWaiting(&stored_player[i], FALSE); @@ -8672,11 +8723,11 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->frame_counter_bored = FrameCounter + game.player_boring_delay_fixed + - SimpleRND(game.player_boring_delay_random); + GetSimpleRandom(game.player_boring_delay_random); player->frame_counter_sleeping = FrameCounter + game.player_sleeping_delay_fixed + - SimpleRND(game.player_sleeping_delay_random); + GetSimpleRandom(game.player_sleeping_delay_random); InitPlayerGfxAnimation(player, ACTION_WAITING, move_dir); } @@ -8732,10 +8783,10 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + - SimpleRND(graphic_info[special_graphic].anim_delay_random); + GetSimpleRandom(graphic_info[special_graphic].anim_delay_random); player->post_delay_counter = graphic_info[special_graphic].post_delay_fixed + - SimpleRND(graphic_info[special_graphic].post_delay_random); + GetSimpleRandom(graphic_info[special_graphic].post_delay_random); player->special_action_sleeping = special_action; } @@ -8758,16 +8809,16 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) if (player->anim_delay_counter == 0 && player->post_delay_counter == 0) { int special_action = - ACTION_BORING_1 + SimpleRND(player->num_special_action_bored); + ACTION_BORING_1 + GetSimpleRandom(player->num_special_action_bored); int special_graphic = el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + - SimpleRND(graphic_info[special_graphic].anim_delay_random); + GetSimpleRandom(graphic_info[special_graphic].anim_delay_random); player->post_delay_counter = graphic_info[special_graphic].post_delay_fixed + - SimpleRND(graphic_info[special_graphic].post_delay_random); + GetSimpleRandom(graphic_info[special_graphic].post_delay_random); player->special_action_bored = special_action; } @@ -9413,7 +9464,7 @@ void GameActions_RND() DrawLevelGraphicAnimationIfNeeded(x, y, graphic); if (IS_GEM(element) || element == EL_SP_INFOTRON) - EdelsteinFunkeln(x, y); + DrawTwinkleOnField(x, y); } else if ((element == EL_ACID || element == EL_EXIT_OPEN || @@ -12413,14 +12464,55 @@ void RequestQuitGame(boolean ask_if_really_quit) /* ------------------------------------------------------------------------- */ -/* game engine snapshot handling */ +/* random generator functions */ +/* ------------------------------------------------------------------------- */ + +unsigned int InitEngineRandom_RND(long seed) +{ + game.num_random_calls = 0; + +#if 0 + unsigned int rnd_seed = InitEngineRandom(seed); + + printf("::: START RND: %d\n", rnd_seed); + + return rnd_seed; +#else + + return InitEngineRandom(seed); + +#endif + +} + +unsigned int RND(int max) +{ + if (max > 0) + { + game.num_random_calls++; + + return GetEngineRandom(max); + } + + return 0; +} + + +/* ------------------------------------------------------------------------- */ +/* game engine snapshot handling functions */ /* ------------------------------------------------------------------------- */ #define ARGS_ADDRESS_AND_SIZEOF(x) (&(x)), (sizeof(x)) struct EngineSnapshotInfo { + /* runtime values for custom element collect score */ int collect_score[NUM_CUSTOM_ELEMENTS]; + + /* runtime values for group element choice position */ + int choice_pos[NUM_GROUP_ELEMENTS]; + + /* runtime values for belt position animations */ int belt_graphic[4 * NUM_BELT_PARTS]; int belt_anim_mode[4 * NUM_BELT_PARTS]; }; @@ -12459,7 +12551,18 @@ static void SaveEngineSnapshotValues_RND() int i, j; for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - engine_snapshot_rnd.collect_score[i] = element_info[i].collect_score; + { + int element = EL_CUSTOM_START + i; + + engine_snapshot_rnd.collect_score[i] = element_info[element].collect_score; + } + + for (i = 0; i < NUM_GROUP_ELEMENTS; i++) + { + int element = EL_GROUP_START + i; + + engine_snapshot_rnd.choice_pos[i] = element_info[element].group->choice_pos; + } for (i = 0; i < 4; i++) { @@ -12477,10 +12580,22 @@ static void SaveEngineSnapshotValues_RND() static void LoadEngineSnapshotValues_RND() { + unsigned long num_random_calls = game.num_random_calls; int i, j; for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - element_info[i].collect_score = engine_snapshot_rnd.collect_score[i]; + { + int element = EL_CUSTOM_START + i; + + element_info[element].collect_score = engine_snapshot_rnd.collect_score[i]; + } + + for (i = 0; i < NUM_GROUP_ELEMENTS; i++) + { + int element = EL_GROUP_START + i; + + element_info[element].group->choice_pos = engine_snapshot_rnd.choice_pos[i]; + } for (i = 0; i < 4; i++) { @@ -12492,6 +12607,21 @@ static void LoadEngineSnapshotValues_RND() graphic_info[graphic].anim_mode = anim_mode; } } + + if (level.game_engine_type == GAME_ENGINE_TYPE_RND) + { + InitRND(tape.random_seed); + for (i = 0; i < num_random_calls; i++) + RND(1); + } + + if (game.num_random_calls != num_random_calls) + { + Error(ERR_RETURN, "number of random calls out of sync"); + Error(ERR_RETURN, "number of random calls should be %d", num_random_calls); + Error(ERR_RETURN, "number of random calls is %d", game.num_random_calls); + Error(ERR_EXIT, "this should not happen -- please debug"); + } } static void SaveEngineSnapshotBuffer(void *buffer, int size)