home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-20 | 21.0 KB | 778 lines | [TEXT/PJMM] |
- unit Enemies;
-
- interface
- uses
- Sound, GameUtils;
-
- procedure UpdateEye;
- procedure UpdateTheHand;
- procedure RetractTheHand;
- procedure EnemyHitAStone (whichStone: Rect; which: Integer);
- procedure DoEnemyPlacement (who: Integer);
- procedure DeathToTheBeast (who: Integer);
- procedure PlayerBeastCollision (who: Integer);
- procedure HandleTheEnemies;
-
- implementation
-
- {=================================}
-
- procedure MoveEye;
- begin
- if (thePlayer.otherState) then
- Exit(MoveEye);
- with theEye do
- begin
- if thePlayer.dest.left < dest.left then
- begin
- dest.left := dest.left - 4;
- dest.right := dest.right - 4;
- end
- else
- begin
- dest.left := dest.left + 4;
- dest.right := dest.right + 4;
- end;
- if thePlayer.dest.top < dest.top then
- begin
- dest.top := dest.top - 2;
- dest.bottom := dest.bottom - 2;
- end
- else
- begin
- dest.top := dest.top + 2;
- dest.bottom := dest.bottom + 2;
- end;
- end;
- end;
-
- {=================================}
-
- procedure UpdateEye;
- var
- dummyRect, tempRect: Rect;
- begin
- with theEye do
- begin
- case mode of
- 1..3:
- begin
- mode := mode + 1;
- otherMode := 0;
- StrikeLightning(tempInt);
- end;
- 4..6:
- begin
- mode := mode + 1;
- otherMode := 1;
- end;
- 7..9:
- begin
- mode := mode + 1;
- otherMode := 2;
- end;
- 10..12:
- begin
- mode := mode + 1;
- otherMode := 3;
- end;
- 13..230:
- begin
- mode := mode + 1;
- otherMode := 4;
- MoveEye;
- end;
- 231..235:
- begin
- mode := mode + 1;
- otherMode := 3;
- MoveEye;
- end;
- 236..240:
- begin
- mode := mode + 1;
- otherMode := 2;
- MoveEye;
- end;
- 241..245:
- begin
- mode := mode + 1;
- otherMode := 1;
- MoveEye;
- end;
- 246..255:
- begin
- mode := mode + 1;
- otherMode := 0;
- MoveEye;
- end;
- 256..260:
- begin
- mode := mode + 1;
- otherMode := 1;
- MoveEye;
- end;
- 261..265:
- begin
- mode := mode + 1;
- otherMode := 2;
- MoveEye;
- end;
- 266..270:
- begin
- mode := mode + 1;
- otherMode := 3;
- MoveEye;
- end;
- 271:
- begin
- mode := 81;
- end;
- 272..275: {Here the eye is closing for good }
- begin {The eye will never even get to a }
- mode := mode + 1; {mode >= 272 unless the player }
- otherMode := 3; {manages to hit the eye while it is }
- MoveEye; {closing. }
- end;
- 276..280:
- begin
- mode := mode + 1;
- otherMode := 2;
- MoveEye;
- end;
- 281..285:
- begin
- mode := mode + 1;
- otherMode := 1;
- MoveEye;
- end;
- 286..290:
- begin
- mode := mode + 1;
- otherMode := 0;
- MoveEye;
- end;
- 291:
- begin
- UnionRect(oldDest, dest, wholeRect);
- CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
- mode := (levelOn * 10) - 300;
- if mode > -50 then
- mode := -50;
- dest := eyeRects[4];
- dest.left := dest.left - 80;
- dest.right := dest.right - 80;
- dest.top := dest.top + 120;
- dest.bottom := dest.bottom + 120;
- oldDest := dest;
- end;
-
- otherwise
- begin
- mode := mode + 1;
- if (mode = 0) then
- begin
- DoTheSound('lightning.snd', TRUE);
- dest := eyeRects[4];
- dest.left := dest.left - 43;
- dest.right := dest.right - 43;
- dest.top := dest.top + 70;
- dest.bottom := dest.bottom + 70;
- if (DoRandom(2) = 0) then
- begin
- dest.top := dest.top + 100;
- dest.bottom := dest.bottom + 100;
- StrikeLightning(lowerEye);
- tempInt := lowerEye;
- end
- else
- begin
- StrikeLightning(upperEye);
- tempInt := upperEye;
- end;
- oldDest := dest;
- end;
- Exit(UpdateEye);
- end;
- end;
- tempRect := dest;
- InsetRect(tempRect, 10, 5);
- if SectRect(tempRect, thePlayer.dest, dummyRect) then
- begin
- if otherMode = 4 then {The player is DEAD! }
- begin
- thePlayer.otherState := TRUE;
- DoTheSound('bird.snd', TRUE);
- end
- else if (mode <> 291) then {The player killed the eye!!! }
- begin
- DoTheSound('bonus.snd', TRUE);
- score := score + 2000;
- CheckExtraMortal;
- mode := 291;
- UnionRect(oldDest, dest, wholeRect);
- CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
- end;
- end;
- end;
- end;
-
- {=================================}
-
- procedure UpdateTheHand;
- var
- dummyRect, tempRect: Rect;
- begin
- if ((levelOn < 3) or (stonesSliding)) then
- Exit(UpdateTheHand);
- with theHand do
- begin
- state := TRUE;
- if mode = 0 then
- begin
- if (thePlayer.dest.left < dest.left) then
- begin
- dest.left := dest.left - 6;
- dest.right := dest.right - 6;
- end
- else
- begin
- dest.left := dest.left + 6;
- dest.right := dest.right + 6;
- end;
-
- if (thePlayer.dest.bottom < dest.top) then
- begin
- dest.top := dest.top - 3;
- dest.bottom := dest.bottom - 3;
- end
- else
- begin
- dest.top := dest.top + 1;
- dest.bottom := dest.bottom + 1;
- end;
-
- tempRect := dest;
- tempRect.right := tempRect.left + 40;
- if SectRect(tempRect, thePlayer.dest, dummyRect) and (thePlayer.dest.left < dest.left + 40) then
- begin
- DoTheSound('bird.snd', TRUE);
- mode := 1;
- OffsetRect(thePlayer.dest, dest.left - thePlayer.dest.left - (thePlayer.facing * 25), dest.top - thePlayer.dest.bottom);
- thePlayer.horiVel := 0;
- thePlayer.vertVel := 0;
- oldDirection := thePlayer.facing;
- end;
- end
- else
- begin
- OffsetRect(thePlayer.dest, (oldDirection - thePlayer.facing) * 25 - thePlayer.horiVel, -thePlayer.vertVel);
- if (thePlayer.vertVel < 0) and (DoRandom(levelOn div 5) = 0) then
- begin
- dest.top := dest.top - 2;
- dest.bottom := dest.bottom - 2;
- thePlayer.dest.top := thePlayer.dest.top - 2;
- thePlayer.dest.bottom := thePlayer.dest.bottom - 2;
- end
- else if (thePlayer.vertVel >= 0) then
- begin
- dest.top := dest.top + 1;
- dest.bottom := dest.bottom + 1;
- thePlayer.dest.top := thePlayer.dest.top + 1;
- thePlayer.dest.bottom := thePlayer.dest.bottom + 1;
- end;
- thePlayer.horiVel := 0;
- thePlayer.vertVel := 0;
- oldDirection := thePlayer.facing;
- end;
- if dest.top < 275 then
- begin
- dest.top := 275;
- mode := 0;
- end;
- DrawHand;
- oldDest := dest;
- end;
- end;
-
- {=================================}
-
- procedure RetractTheHand;
- begin
- with theHand do
- begin
- mode := 0;
- dest.top := dest.top + 1;
- dest.bottom := dest.bottom + 1;
- if dest.top > 337 then
- state := FALSE;
- DrawHand;
- oldDest := dest;
- end;
- end;
-
- {=================================}
-
- procedure EnemyHitAStone;
- var
- hori, vert: Integer;
- begin
- with theEnemies[which] do
- begin
- if (horiVel > 0) then
- begin
- if (dest.left < whichStone.left) then {hit the edge}
- begin
- dest.left := dest.left + whichStone.left - whichStone.right;
- dest.right := dest.right + whichStone.left - whichStone.right;
- horiVel := impacted[horiVel];
- end
- else
- begin
- if (vertVel < 0) then {hit coming up}
- begin
- vertVel := impacted[vertVel];
- dest.bottom := dest.bottom + whichStone.bottom - dest.top;
- dest.top := dest.top + whichStone.bottom - dest.top;
- end
- else
- begin
- if (mode < -1) then
- begin
- horiVel := (horiVel * 2) div 3;
- vertVel := impacted[vertVel];
- if (ABS(vertVel) < 3) then
- begin
- vertVel := 0;
- horiVel := 0;
- otherState := TRUE;
- end;
- dest.top := dest.top + whichStone.top - dest.bottom;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom;
- Exit(EnemyHitAStone);
- end;
- if (vertVel < 4) or (dest.right > whichStone.right) then
- begin
- vertVel := -3;
- dest.top := dest.top + whichStone.top - dest.bottom;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom;
- end
- else
- begin
- vertVel := 0;
- dest.top := dest.top + whichStone.top - dest.bottom - 10;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom - 10;
- mode := 1;
- hori := dest.left;
- vert := dest.top;
- SetRect(dest, 0, 0, 41, 42);
- dest.top := dest.top + vert;
- dest.bottom := dest.bottom + vert;
- dest.left := dest.left + hori;
- dest.right := dest.right + hori;
- end;
- end;
- end;
- end
- else
- begin
- if (dest.right > whichStone.right) then {hit the edge}
- begin
- dest.left := dest.left + whichStone.right - whichStone.left;
- dest.right := dest.right + whichStone.right - whichStone.left;
- horiVel := impacted[horiVel];
- end
- else
- begin
- if (vertVel < 0) then {hit coming up}
- begin
- vertVel := impacted[vertVel];
- dest.bottom := dest.bottom + whichStone.bottom - dest.top;
- dest.top := dest.top + whichStone.bottom - dest.top;
- end
- else
- begin
- if (mode < -1) then
- begin
- horiVel := (horiVel * 2) div 3;
- vertVel := impacted[vertVel];
- if (ABS(vertVel) < 3) then
- begin
- horiVel := 0;
- vertVel := 0;
- otherState := TRUE;
- end;
- dest.top := dest.top + whichStone.top - dest.bottom;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom;
- Exit(EnemyHitAStone);
- end;
- if (vertVel < 4) or (dest.left < whichStone.left) then
- begin
- vertVel := -3;
- dest.top := dest.top + whichStone.top - dest.bottom;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom;
- end
- else
- begin
- vertVel := 0;
- dest.top := dest.top + whichStone.top - dest.bottom - 10;
- dest.bottom := dest.bottom + whichStone.top - dest.bottom - 10;
- mode := 1;
- hori := dest.left;
- vert := dest.top;
- SetRect(dest, 0, 0, 41, 42);
- dest.top := dest.top + vert;
- dest.bottom := dest.bottom + vert;
- dest.left := dest.left + hori;
- dest.right := dest.right + hori;
- end;
- end;
- end;
- end;
- end;
- end;
-
- {=================================}
-
- procedure DoEnemyPlacement;
- var
- aNumber: Integer;
- begin
- with theEnemies[who] do
- begin
- otherState := FALSE;
- facing := DoRandom(2);
- aNumber := DoRandom(2);
- if (((levelOn + 1) div 5) = ((levelOn + 1) / 5)) then
- aNumber := 1;
- if facing = 0 then
- begin
- if aNumber = 0 then
- SetRect(dest, 50, 96, 91, 96)
- else
- SetRect(dest, 50, 212, 91, 212);
- end
- else
- begin
- if aNumber = 0 then
- SetRect(dest, 430, 96, 471, 96)
- else
- SetRect(dest, 430, 212, 471, 212);
- end;
- oldDest := dest;
- end;
- end;
- {=================================}
-
- procedure DeathToTheBeast;
- var
- tempRect: Rect;
- begin
- with theEnemies[who] do
- begin
- UnionRect(oldDest, dest, wholeRect);
- CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
- mode := DoRandom(50) + 50;
- vertVel := 0;
- horiVel := 0;
- DoEnemyPlacement(who);
- if (state) and (otherMode > 0) then
- begin
- otherMode := otherMode - 1;
- state := FALSE;
- end;
- beastsKilled := beastsKilled + 1;
- beastsActive := beastsActive - 1;
- if (beastsKilled >= totalToKill) then
- begin
- onward := TRUE;
- end;
- end;
- end;
-
- {=================================}
-
- procedure PlayerBeastCollision;
- var
- hori, vert: Integer;
- tempRect: Rect;
- begin
- with theEnemies[who] do
- begin
- if (mode < 0) then {You hit the enemy while in egg form! }
- begin
- DoTheSound('boom1.snd', TRUE);
- DeathToTheBeast(who); {So, get the beast killed and reset }
- score := score + 500; {That's 500 points for the player }
- CheckExtraMortal;
- Exit(PlayerBeastCollision); {All we need here }
- end;
- if ((thePlayer.dest.top > dest.top + 1) and (not thePlayer.otherState) and (mode > -1)) then
- begin {The beast killed you! }
- thePlayer.otherState := TRUE; {The player is dead }
- DoTheSound('boom2.snd', TRUE); {Make that death sound }
- end
- else
- begin
- if (dest.top > thePlayer.dest.top + 2) then
- begin {The player killed the beast!!! }
- score := score + 500 + (500 * otherMode); {Score based on what sphinx model }
- CheckExtraMortal;
- if (otherMode < 2) then
- begin
- otherMode := otherMode + 1; {Bump up the sphinx model }
- state := TRUE; {Let program remember this }
- end;
- DoTheSound('boom2.snd', TRUE); {Make that big boom sound }
- mode := DoRandom(200) - 350; {Enemy becomes an egg }
- hori := dest.left;
- vert := dest.top;
- SetRect(dest, 0, 0, 23, 23);
- if (vertVel <> 0) then
- begin
- dest.top := dest.top + vert + 25;
- dest.bottom := dest.bottom + vert + 25;
- dest.left := dest.left + hori;
- dest.right := dest.right + hori;
- end
- else
- begin
- dest.top := dest.top + vert;
- dest.bottom := dest.bottom + vert;
- dest.left := dest.left + hori;
- dest.right := dest.right + hori;
- end;
- end
- else
- begin {close - they bounced off each other }
- DoTheSound('screech.snd', TRUE); {Make that screeching sound }
- horiVel := impacted[horiVel];
- thePlayer.horiVel := impacted[thePlayer.horiVel];
- end;
- end;
- end;
- end;
-
- {=================================}
-
- procedure HandleTheEnemies;
- var
- onLand: Boolean;
- index, loop, hori, vert: Integer;
- dummyLong: LongInt;
- tempRect, dummyRect: Rect;
- begin
- for loop := 1 to numberOfEnemies do
- with theEnemies[loop] do
- begin
- case mode of
- -600..-2: {egg stage - hasn't hatched yet}
- begin
- mode := mode + 1;
- if (mode = -1) then
- DoTheSound('spawn.snd', TRUE);
- if (otherState) then {Has the egg stopped falling?}
- begin
- horiVel := horiVel * 2 div 3;
- onLand := FALSE;
- tempRect := dest;
- tempRect.left := tempRect.left + 10;
- tempRect.right := tempRect.right - 10;
- tempRect.top := tempRect.top + 2;
- tempRect.bottom := tempRect.bottom + 2;
-
- for index := startStone to numberOfStones do
- if (SectRect(tombRects[index], tempRect, dummyRect)) then
- onLand := TRUE;
- if (not onLand) then
- begin
- otherState := FALSE;
- vertVel := fallAmount;
- end;
- end
- else
- begin
- if (vertVel < (maxFall div 3)) then
- vertVel := vertVel + fallAmount;
- for index := startStone to numberOfStones do
- if SectRect(dest, tombRects[index], dummyRect) then
- EnemyHitAStone(dummyRect, loop);
- end;
- dest.left := dest.left + horiVel;
- dest.right := dest.right + horiVel;
- dest.top := dest.top + vertVel;
- dest.bottom := dest.bottom + vertVel;
- end;
-
- -1: {egg hatches!!!}
- begin
- dest.top := dest.top + growRate;
- if (dest.top >= dest.bottom) then
- begin
- dest.top := dest.bottom;
- dest.right := dest.left + 41;
- dest.left := dest.left - 10;
- dest.right := dest.right - 10;
- otherState := FALSE;
- mode := 6;
- end;
- end;
-
- 0..2: {if running along the ground}
- begin
- onLand := FALSE; {First, we assume the enemy is}
- tempRect.left := dest.left + 17; {no longer on land. Then we test}
- tempRect.right := dest.right - 17;{the enemies rect to see if it is}
- tempRect.top := dest.top + 2; {intersecting the ground.}
- tempRect.bottom := dest.bottom + 2;
-
- for index := startStone to numberOfStones do
- if (SectRect(tombRects[index], tempRect, dummyRect)) then
- onLand := TRUE; {Yes, enemy is still on land.}
- if (not onLand) or (DoRandom(6) = 0) then
- begin {If enemy is'nt still on the ledge...}
- mode := 4;
- dest.right := dest.left + 67;
- dest.bottom := dest.top + 36;
- vertVel := fallAmount;
- end
- else {in fact, we're on solid ground after all}
- begin
- horiVel := running[horiVel, facing, 0];
- mode := running[horiVel, facing, 1];
- end;
-
- dest.left := dest.left + horiVel;
- dest.right := dest.right + horiVel;
- dest.top := dest.top + vertVel;
- dest.bottom := dest.bottom + vertVel;
- end;
-
- 4..5: {else, the dude is in the air}
- begin
- horiVel := gliding[horiVel, facing];
-
- if ((thePlayer.dest.top > dest.top - 150) and (thePlayer.dest.top < dest.top + 20)) and (not thePlayer.otherState) then
- begin {the dude's gonna flap and turn to face you}
- mode := 5;
- vertVel := vertVel + enemyLift[otherMode];
- if (thePlayer.dest.left < dest.left) then
- facing := 1
- else
- facing := 0;
- end
- else
- begin
- if ((thePlayer.dest.top > dest.top + 20) and (not thePlayer.otherState) and (vertVel < maxFall)) then
- begin
- vertVel := vertVel + fallAmount;
- end
- else
- begin
- if (vertVel > 8) or (dest.bottom > 290) or (DoRandom(4) = 0) then
- begin {the dude's also gonna flap}
- mode := 5;
- vertVel := vertVel + enemyLift[otherMode];
- end
- else {the dude instead is just gliding}
- begin
- mode := 4;
- if (vertVel < maxFall) then
- vertVel := vertVel + fallAmount;
- end;
- end;
- end;
-
- dest.left := dest.left + horiVel;
- dest.right := dest.right + horiVel;
- dest.top := dest.top + vertVel;
- dest.bottom := dest.bottom + vertVel;
-
- for index := startStone to numberOfStones do
- begin
- if SectRect(dest, tombRects[index], dummyRect) then
- EnemyHitAStone(dummyRect, loop);
- end;
- end;
-
- 6:
- begin
- dest.top := dest.top - growRate;
- if ((dest.bottom - dest.top) >= 43) then
- begin
- dest.top := dest.bottom - 43;
- mode := 0;
- end;
- end;
-
- 7:
- begin
- if (beastsKilled + beastsActive) < totalToKill then
- begin
- DoTheSound('spawn.snd', TRUE);
- beastsActive := beastsActive + 1;
- mode := 6;
- end
- else
- mode := 500;
- end;
-
- 8..500:
- mode := mode - 1;
-
- otherwise
- begin
- mode := mode - 1;
- end;
- end; {end - case Mode}
-
- if ((not SectRect(dest, playRect, dummyRect)) and (mode <> 6)) and (mode <> -1) then
- begin
- if (dest.top > playRect.bottom) then
- begin
- DoTheSound('drip.snd', TRUE);
- DeathToTheBeast(loop);
- end
- else if (dest.top <= 0) then
- begin
- vertVel := impacted[vertVel];
- dest.bottom := dest.bottom - dest.top;
- dest.top := 0;
- end;
-
- if (dest.right < playRect.left) then {Wraparound routines }
- begin
- CopyBits(offVirginMap, mainWndo^.portBits, oldDest, oldDest, srcCopy, playRgn);
- dest.right := dest.right + 500;
- dest.left := dest.left + 500;
- oldDest := dest;
- end
- else if (dest.left > playRect.right) then
- begin
- CopyBits(offVirginMap, mainWndo^.portBits, oldDest, oldDest, srcCopy, playRgn);
- dest.left := dest.left - 500;
- dest.right := dest.right - 500;
- oldDest := dest;
- end;
- end; {if not SectRect}
-
- tempRect := dest;
- if (mode >= 0) then
- InsetRect(tempRect, 16, 6);
- if (SectRect(tempRect, thePlayer.dest, dummyRect) and (not thePlayer.otherState)) then
- PlayerBeastCollision(loop);
-
- end; {end - for loop}
-
- if (delayFor <> 0) then
- begin
- lastLoopTime := lastLoopTime + delayFor;
- repeat
- until (TickCount >= lastLoopTime);
- lastLoopTime := TickCount;
- end;
- end;
-
- {=================================}
-
- end.