From: Holger Schemel Date: Tue, 24 Aug 1999 00:48:27 +0000 (+0200) Subject: rnd-19990824-1-src X-Git-Tag: 1.4.0^2~21 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=0a4bbe85a69ae2fc05d05c2e1fee44f2b1c44134;p=rocksndiamonds.git rnd-19990824-1-src --- diff --git a/src/editor.c b/src/editor.c index fdef6f27..95af5494 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1071,10 +1071,10 @@ int editor_element[] = EL_LIGHT_SWITCH_OFF, EL_LIGHT_SWITCH_ON, - EL_FORCE_FIELD, + EL_FORCE_FIELD_PASSIVE, EL_EXTRA_TIME, EL_LEERRAUM, - EL_LEERRAUM, + EL_FORCE_FIELD_ACTIVE, /* EL_CHAR('D'), diff --git a/src/game.c b/src/game.c index fc0d6476..96fa706f 100644 --- a/src/game.c +++ b/src/game.c @@ -102,6 +102,7 @@ /* forward declaration for internal use */ static void CheckGravityMovement(struct PlayerInfo *); +static void KillHeroUnlessForceField(struct PlayerInfo *); static void MapGameButtons(); static void HandleGameButtons(struct GadgetInfo *); @@ -475,6 +476,9 @@ void InitGame() player->last_jx = player->last_jy = 0; player->jx = player->jy = 0; + player->force_field_passive_time_left = 0; + player->force_field_active_time_left = 0; + DigField(player, 0, 0, 0, 0, DF_NO_PUSH); SnapField(player, 0, 0); @@ -1240,10 +1244,22 @@ void Explode(int ex, int ey, int phase, int mode) if (IS_MASSIVE(element) || element == EL_BURNING) continue; + if (IS_PLAYER(x, y) && FORCE_FIELD_ON(PLAYERINFO(x, y))) + { + if (IS_ACTIVE_BOMB(element)) + { + /* re-activate things under the bomb like gate or penguin */ + Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_LEERRAUM); + Store[x][y] = 0; + } + + continue; + } + if (element == EL_EXPLODING) element = Store2[x][y]; - if (IS_PLAYER(ex, ey)) + if (IS_PLAYER(ex, ey) && !FORCE_FIELD_ON(PLAYERINFO(ex, ey))) { switch(StorePlayer[ex][ey]) { @@ -1344,7 +1360,7 @@ void Explode(int ex, int ey, int phase, int mode) int element = Store2[x][y]; if (IS_PLAYER(x, y)) - KillHero(PLAYERINFO(x, y)); + KillHeroUnlessForceField(PLAYERINFO(x, y)); else if (IS_EXPLOSIVE(element)) { Feld[x][y] = Store2[x][y]; @@ -1444,8 +1460,10 @@ void Bang(int x, int y) else PlaySoundLevel(x, y, SND_ROAAAR); +#if 0 if (IS_PLAYER(x, y)) /* remove objects that might cause smaller explosion */ element = EL_LEERRAUM; +#endif switch(element) { @@ -1473,7 +1491,10 @@ void Bang(int x, int y) case EL_PINGUIN: case EL_BIRNE_AUS: case EL_BIRNE_EIN: - Explode(x, y, EX_PHASE_START, EX_CENTER); + if (IS_PLAYER(x, y)) + Explode(x, y, EX_PHASE_START, EX_NORMAL); + else + Explode(x, y, EX_PHASE_START, EX_CENTER); break; default: Explode(x, y, EX_PHASE_START, EX_NORMAL); @@ -1686,7 +1707,7 @@ void Impact(int x, int y) if (element == EL_TROPFEN && (lastline || object_hit)) /* acid drop */ { if (object_hit && IS_PLAYER(x, y+1)) - KillHero(PLAYERINFO(x, y+1)); + KillHeroUnlessForceField(PLAYERINFO(x, y+1)); else if (object_hit && (smashed == EL_MAULWURF || smashed == EL_PINGUIN)) Bang(x, y+1); else @@ -1719,7 +1740,7 @@ void Impact(int x, int y) if (IS_PLAYER(x, y+1)) { - KillHero(PLAYERINFO(x, y+1)); + KillHeroUnlessForceField(PLAYERINFO(x, y+1)); return; } else if (smashed == EL_MAULWURF || smashed == EL_PINGUIN) @@ -1889,10 +1910,10 @@ void TurnRound(int x, int y) TestIfBadThingHitsOtherBadThing(x, y); if (IN_LEV_FIELD(right_x, right_y) && - IS_FREE_OR_PLAYER(right_x, right_y)) + IS_FREE(right_x, right_y)) MovDir[x][y] = right_dir; else if (!IN_LEV_FIELD(move_x, move_y) || - !IS_FREE_OR_PLAYER(move_x, move_y)) + !IS_FREE(move_x, move_y)) MovDir[x][y] = left_dir; if (element == EL_KAEFER && MovDir[x][y] != old_move_dir) @@ -1906,10 +1927,10 @@ void TurnRound(int x, int y) TestIfBadThingHitsOtherBadThing(x, y); if (IN_LEV_FIELD(left_x, left_y) && - IS_FREE_OR_PLAYER(left_x, left_y)) + IS_FREE(left_x, left_y)) MovDir[x][y] = left_dir; else if (!IN_LEV_FIELD(move_x, move_y) || - !IS_FREE_OR_PLAYER(move_x, move_y)) + !IS_FREE(move_x, move_y)) MovDir[x][y] = right_dir; if ((element == EL_FLIEGER || @@ -2496,12 +2517,20 @@ void StartMoving(int x, int y) Moving2Blocked(x, y, &newx, &newy); /* get next screen position */ - if (IS_ENEMY(element) && IS_PLAYER(newx, newy)) + if (IS_ENEMY(element) && IS_PLAYER(newx, newy) && + !FORCE_FIELD_ON(PLAYERINFO(newx, newy))) { + +#if 1 + TestIfBadThingHitsHero(x, y); + return; +#else /* enemy got the player */ MovDir[x][y] = 0; KillHero(PLAYERINFO(newx, newy)); return; +#endif + } else if ((element == EL_MAULWURF || element == EL_PINGUIN || element == EL_ROBOT || element == EL_SONDE) && @@ -3977,8 +4006,10 @@ void GameActions() CloseSwitchgate(x, y); else if (element == EL_EXTRA_TIME) DrawGraphicAnimation(x, y, GFX_EXTRA_TIME, 6, 4, ANIM_NORMAL); - else if (element == EL_FORCE_FIELD) - DrawGraphicAnimation(x, y, GFX_FORCE_FIELD, 6, 4, ANIM_NORMAL); + else if (element == EL_FORCE_FIELD_PASSIVE) + DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_PASSIVE, 6, 4, ANIM_NORMAL); + else if (element == EL_FORCE_FIELD_ACTIVE) + DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_ACTIVE, 6, 4, ANIM_NORMAL); if (game.magic_wall_active) { @@ -4061,11 +4092,22 @@ void GameActions() } } - if (TimeFrames >= (1000 / GameFrameDelay) && !tape.pausing) + if (TimeFrames >= (1000 / GameFrameDelay)) { TimeFrames = 0; TimePlayed++; + for (i=0; i 0) + stored_player[i].force_field_active_time_left--; + } + } + if (tape.recording || tape.playing) DrawVideoDisplay(VIDEO_STATE_TIME_ON, TimePlayed); @@ -4223,7 +4265,14 @@ boolean MoveFigureOneStep(struct PlayerInfo *player, BuryHero(player); } else - KillHero(player); + { +#if 1 + TestIfBadThingHitsHero(new_jx, new_jy); +#else + if (player->force_field_time_left == 0) + KillHero(player); +#endif + } return MF_MOVING; } @@ -4537,7 +4586,14 @@ void TestIfGoodThingHitsBadThing(int goodx, int goody) if (killx != goodx || killy != goody) { if (IS_PLAYER(goodx, goody)) - KillHero(PLAYERINFO(goodx, goody)); + { + struct PlayerInfo *player = PLAYERINFO(goodx, goody); + + if (player->force_field_active_time_left > 0) + Bang(killx, killy); + else if (player->force_field_passive_time_left == 0) + KillHero(player); + } else Bang(goodx, goody); } @@ -4592,7 +4648,14 @@ void TestIfBadThingHitsGoodThing(int badx, int bady) if (killx != badx || killy != bady) { if (IS_PLAYER(killx, killy)) - KillHero(PLAYERINFO(killx, killy)); + { + struct PlayerInfo *player = PLAYERINFO(killx, killy); + + if (player->force_field_active_time_left > 0) + Bang(badx, bady); + else if (player->force_field_passive_time_left == 0) + KillHero(player); + } else Bang(killx, killy); } @@ -4662,10 +4725,20 @@ void KillHero(struct PlayerInfo *player) if (IS_PFORTE(Feld[jx][jy])) Feld[jx][jy] = EL_LEERRAUM; + /* deactivate force field (else Bang()/Explode() would not work right) */ + player->force_field_passive_time_left = 0; + player->force_field_active_time_left = 0; + Bang(jx, jy); BuryHero(player); } +static void KillHeroUnlessForceField(struct PlayerInfo *player) +{ + if (!FORCE_FIELD_ON(player)) + KillHero(player); +} + void BuryHero(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; @@ -4787,8 +4860,16 @@ int DigField(struct PlayerInfo *player, PlaySoundStereo(SND_GONG, PSND_MAX_RIGHT); break; - case EL_FORCE_FIELD: + case EL_FORCE_FIELD_PASSIVE: + RemoveField(x, y); + player->force_field_passive_time_left += 10; + PlaySoundLevel(x, y, SND_PONG); + break; + + case EL_FORCE_FIELD_ACTIVE: RemoveField(x, y); + player->force_field_passive_time_left += 10; + player->force_field_active_time_left += 10; PlaySoundLevel(x, y, SND_PONG); break; diff --git a/src/main.c b/src/main.c index dac98c0f..daa34081 100644 --- a/src/main.c +++ b/src/main.c @@ -463,7 +463,7 @@ char *element_info[] = "white door", /* 260 */ "gray door (opened by white key)", "white key", - "force field", + "force field (passive)", "extra time", "switch gate (open)", "switch gate (closed)", @@ -517,10 +517,11 @@ char *element_info[] = "mole (starts moving down)", "steel wall (slanted)", "invisible sand", - "-", - "-", - "-", - "-", /* 320 */ + "dx unknown 15", + "dx unknown 42", + "dx unknown 229", + "dx unknown 233", /* 320 */ + "force field (active, kills enemies)", "-", "-", "-", diff --git a/src/main.h b/src/main.h index 5cfda96e..9ae8be87 100644 --- a/src/main.h +++ b/src/main.h @@ -191,6 +191,7 @@ typedef unsigned char byte; #define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing &&!(x).pausing) #define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_SPIELER1]) +#define FORCE_FIELD_ON(p) ((p)->force_field_passive_time_left > 0) /* Pixmaps with graphic file */ #define PIX_BACK 0 @@ -353,6 +354,8 @@ struct PlayerInfo int key[4]; int dynamite; int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl; + int force_field_passive_time_left; + int force_field_active_time_left; }; struct LevelInfo @@ -850,7 +853,7 @@ extern char *element_info[]; #define EL_DOOR_WHITE 260 #define EL_DOOR_WHITE_GRAY 261 #define EL_KEY_WHITE 262 -#define EL_FORCE_FIELD 263 +#define EL_FORCE_FIELD_PASSIVE 263 #define EL_EXTRA_TIME 264 #define EL_SWITCHGATE_OPEN 265 #define EL_SWITCHGATE_CLOSED 266 @@ -904,6 +907,11 @@ extern char *element_info[]; #define EL_MOLE_DOWN 314 #define EL_STEEL_SLANTED 315 #define EL_SAND_INVISIBLE 316 +#define EL_DX_UNKNOWN_15 317 +#define EL_DX_UNKNOWN_42 318 +#define EL_DX_UNKNOWN_229 319 +#define EL_DX_UNKNOWN_233 320 +#define EL_FORCE_FIELD_ACTIVE 321 /* "real" (and therefore drawable) runtime elements */ #define EL_SIEB_LEER 500 @@ -1321,7 +1329,8 @@ extern char *element_info[]; #define GFX_STEEL_SLANTED (GFX_START_ROCKSDC + 15 * DC_PER_LINE + 5) #define GFX_EXTRA_TIME (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 8) -#define GFX_FORCE_FIELD (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8) +#define GFX_FORCE_FIELD_PASSIVE (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8) +#define GFX_FORCE_FIELD_ACTIVE (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8) /* graphics from "RocksFont" */ #define GFX_CHAR_START (GFX_START_ROCKSFONT) @@ -1379,6 +1388,10 @@ extern char *element_info[]; #define GFX_MOLE_RIGHT GFX_CHAR_FRAGE #define GFX_MOLE_UP GFX_CHAR_FRAGE #define GFX_MOLE_DOWN GFX_CHAR_FRAGE +#define GFX_DX_UNKNOWN_15 GFX_CHAR_FRAGE +#define GFX_DX_UNKNOWN_42 GFX_CHAR_FRAGE +#define GFX_DX_UNKNOWN_229 GFX_CHAR_FRAGE +#define GFX_DX_UNKNOWN_233 GFX_CHAR_FRAGE /* the names of the sounds */ #define SND_ALCHEMY 0 diff --git a/src/tools.c b/src/tools.c index 41fd86eb..4403a9ce 100644 --- a/src/tools.c +++ b/src/tools.c @@ -44,6 +44,8 @@ extern boolean wait_for_vsync; /* forward declaration for internal use */ static int getGraphicAnimationPhase(int, int, int); +static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int, + int, int, int); static void UnmapToolButtons(); static void HandleToolButtons(struct GadgetInfo *); @@ -604,6 +606,10 @@ void DrawPlayer(struct PlayerInfo *player) DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING); + if (FORCE_FIELD_ON(player)) + DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, GFX_FUNKELN_BLAU, + 3, 8, ANIM_OSCILLATE); + if (player->Pushing && player->GfxPos) { int px = SCREENX(next_jx), py = SCREENY(next_jy); @@ -732,6 +738,17 @@ void DrawGraphicAnimationThruMask(int x, int y, int graphic, DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING); } +static void DrawGraphicAnimationShiftedThruMask(int sx, int sy, + int sxx, int syy, + int graphic, + int frames, int delay, + int mode) +{ + int phase = getGraphicAnimationPhase(frames, delay, mode); + + DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING); +} + void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y) { if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) @@ -2487,7 +2504,8 @@ int el2gfx(int element) case EL_DOOR_WHITE: return GFX_DOOR_WHITE; case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY; case EL_KEY_WHITE: return GFX_KEY_WHITE; - case EL_FORCE_FIELD: return GFX_FORCE_FIELD; + case EL_FORCE_FIELD_PASSIVE:return GFX_FORCE_FIELD_PASSIVE; + case EL_FORCE_FIELD_ACTIVE: return GFX_FORCE_FIELD_ACTIVE; case EL_EXTRA_TIME: return GFX_EXTRA_TIME; case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN; case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED; @@ -2541,6 +2559,10 @@ int el2gfx(int element) case EL_MOLE_DOWN: return GFX_MOLE_DOWN; case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED; case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE; + case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15; + case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42; + case EL_DX_UNKNOWN_229: return GFX_DX_UNKNOWN_229; + case EL_DX_UNKNOWN_233: return GFX_DX_UNKNOWN_233; default: {