1
0
vt100-games/LadderTP/LADMAIN.PAS

222 lines
6.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
Note that this code makes free use of the dreaded GOTO command.
}
VAR
msecs, bonusTimeTicks, moveInterval, x, y : INTEGER;
ch : CHAR;
rockPtr : RockPointerType;
LABEL
restartGame, restartLevel, newLevel;
BEGIN { MAIN }
dispensers := NIL; { initialize our linked lists for dispenser }
m.Rocks := NIL; { and rocks }
lastScore := -1;
playSpeed := 1;
ReadDataFile;
restartGame:
m.LadsRemaining := 5;
m.Level := 1;
m.Score := 0;
levelCycle := 1;
displayLevel := 1;
nextNewLad := 100;
CursOn;
Randomize;
MainMenu;
moveInterval := ReadmsWait[playSpeed];
ClrScr;
CursOff;
newLevel:
{ Load a level and show it }
LoadMap(ladXY, dispensers, numDispensers);
restartLevel:
m.RemainingBonusTime := m.InitialBonusTime - 2 * (levelCycle - 1);
InitActor(lad, ALAD, ladXY);
DisperseRocks;
{ Show the initial map on screen }
DrawMap;
msecs := 0;
bonusTimeTicks := 0;
WHILE TRUE DO BEGIN
Delay(1);
msecs := Succ(msecs);
IF msecs >= moveInterval THEN BEGIN
{ move the Lad and rocks every X milliseconds }
msecs := 0;
bonusTimeTicks := bonusTimeTicks + moveInterval;
IF bonusTimeticks >= BonusTimeDecInterval THEN BEGIN
{ every 3 seconds, decrement the bonus time/time remaining value }
bonusTimeTicks := bonusTimeTicks - BonusTimeDecInterval;;
m.RemainingBonusTime := Pred(m.RemainingBonusTime);
GotoXY(74, 21);
Write(m.RemainingBonusTime : 2);
IF m.RemainingBonusTime <=0 THEN BEGIN
{ died: do the animation and check if we still have lives left }
IF LadDeath THEN
GOTO restartLevel;
GOTO restartGame;
END;
END;
IF m.AnyRocksPending THEN BEGIN
{ pending rocks? see if it's time to start moving }
rockPtr := m.Rocks;
m.AnyRocksPending := FALSE;
WHILE rockPtr <> NIL DO BEGIN
IF (rockPtr^.Dir = PENDING) THEN
IF (Random(10) = 0) THEN
rockPtr^.DirRequest := FALLING
ELSE
m.AnyRocksPending := TRUE;
rockPtr := rockPtr^.Next;
END;
END;
{ Move the lad according to players wishes }
IF (lad.Dir <> STOPPED) OR (lad.DirRequest <> NONE) THEN BEGIN
x := lad.X; y := lad.Y;
GotoXY(x, y); Write(m.Field[y][x]);
MoveActor(lad);
GotoXY(lad.X, lad.Y); Write(lad.Ch);
IF (x <> lad.X) AND (y = lad.Y) THEN BEGIN
{ get rid of disappearing flooring }
IF m.Field[y + 1][x] = '-' THEN BEGIN
m.Field[y + 1][x] := ' ';
GotoXY(x, y + 1); Write(' ');
END;
END;
CASE m.Field[lad.Y][lad.X] OF
'$' : BEGIN { at the Gold: level done }
UpdateScore(ScoreMoney);
displayLevel := Succ(displayLevel);
IF (m.Level > levelCycle) OR (m.Level = NumLevels) THEN BEGIN
{ done with current cycle, recycle to 1st level }
m.Level := 1;
levelCycle := SUCC(levelCycle);
END ELSE BEGIN
m.Level := Succ(m.Level);
END;
GOTO newLevel;
END;
'^': BEGIN { death by fire }
IF LadDeath THEN
GOTO restartLevel;
GOTO restartGame;
END;
'&': BEGIN
{ found a statue, adjust the score, remove the statue }
UpdateScore(ScoreStatue);
m.Field[lad.Y][lad.X] := ' ';
END;
'.': BEGIN {trampoline: choose a random direction }
CASE Random(5) OF
0: BEGIN
lad.Dir := LEFT;
lad.DirRequest := NONE;
lad.JumpStep := 0;
END;
1: BEGIN
lad.Dir := RIGHT;
lad.DirRequest := NONE;
lad.JumpStep := 0;
END;
2: BEGIN
lad.Dir := JUMPUP;
lad.DirRequest := STOPPED;
lad.JumpStep := 1;
END;
3: BEGIN
lad.Dir := JUMPLEFT;
lad.DirRequest := LEFT;
lad.JumpStep := 1;
END;
4: BEGIN
lad.Dir := JUMPRIGHT;
lad.DirRequest := RIGHT;
lad.JumpStep := 1;
END;
END;
END;
END;
END; { of Lad movement handler -------------------------- }
{ Move the rock(s) }
rockPtr := m.Rocks;
WHILE rockPtr <> NIL DO BEGIN
{ Don't draw the rock if it's pending }
IF rockPtr^.Dir <> PENDING THEN BEGIN
IF Collision(rockPtr) THEN
IF LadDeath THEN
GOTO restartLevel
ELSE
GOTO restartGame;
x := rockPtr^.X;
y := rockPtr^.Y;
GotoXY(x, y);
Write(m.Field[y][x]);
END;
MoveActor(rockPtr^);
{ Don't draw the rock if it's pending }
IF rockPtr^.Dir <> PENDING THEN BEGIN
IF Collision(rockPtr) THEN
IF LadDeath THEN
GOTO restartlevel
ELSE
GOTO restartGame;
GotoXY(rockPtr^.X, rockPtr^.Y);
Write(rockPtr^.Ch);
END;
rockPtr := rockPtr^.Next;
END; { of rock movement handler ------------------------- }
{ end of tick handler =================================== }
END;
IF KeyPressed THEN BEGIN
Read(Kbd, ch);
ch := UpCase(ch);
IF ch = leftKey THEN BEGIN
lad.DirRequest := LEFT
END ELSE IF ch = rightKey THEN BEGIN
lad.DirRequest := RIGHT
END ELSE IF ch = upKey THEN BEGIN
lad.DirRequest := UP
END ELSE IF ch = downKey THEN BEGIN
lad.DirRequest := DOWN
END ELSE IF ch = ' ' THEN BEGIN
lad.DirRequest := JUMP;
END ELSE IF ch = #$1B THEN BEGIN
CursOn;
GotoXY(1, 23); Write('Type RETURN to continue: ');
REPEAT
WHILE NOT KeyPressed DO;
Read(Kbd, ch);
UNTIL ch IN [#$0D, #$03];
IF ch = #$03 THEN { ^C goes back to main menu }
GOTO restartGame;
GotoXY(1, 23); ClrEOL;
CursOff;
END ELSE IF ch = #$03 THEN BEGIN
GOTO restartGame
END ELSE BEGIN
lad.DirRequest := STOPPED
END;
END; { of keypress handler ================================ }
END;
END.