top of page
Search
Writer's pictureTom Grove

Movement And Combat

The game starts at 5000. The initial room is always room 1 and KR is set to this. The string O$ lists all the player actions. These can be found on the handy reference card packaged with the game.

5000 KR = 1:O$ = "RLATPFMGEV!HQSYDO": GOSUB 1200

This is taken from the C64 version, which is slightly later and has a couple of additional commands ( Inventory and Save ) which were not present in the earlier versions of the game. This handy A5 card would have been propped up next to the computer while playing the game.


Before entering the main loop at 5044, the initial room is drawn and a few variables are set up. At 5044 we wait for player input; if there is no input we jump to the monster logic at 7000. Otherwise, we check if the input is a movement distance ( 5045 ) and if so jump to the movement logic at 5100. If it is not, we switch on the input and jump to the appropriate logic.



5030  GOSUB 4000:S(1) = W1 - W2:S(2) = V2 - V1:S(3) = 0:S(4) = 0
5040 P(1) = XA - V1:P(2) = YA - W2:P(3) = P(1):P(4) = P(2):P(0) = P(2)
5044 X0 = XL:Y0 = YL:IA = 0: GOSUB 500:M = 0: FOR QY = 32 TO 48 STEP 8: GOSUB 15010: NEXT QY: IF L = 0 THEN 7000
5045 IA = 0: IF  ASC (C$) > 47 AND  ASC (C$) < 58 THEN 5100
5046  FOR I = 1 TO 17: IF C$ =  MID$ (O$,I,1) THEN  ON I GOTO 5300,5350,5390,5390,5390,5390,5390,5800,5700,5370,5900,6100,6200,6300,6140,5850,5600
5050  NEXT I: GOTO 5044

Movement code. TA is the current stamina; if this is less than 1 the player cannot move. IB is cleared to 0 - this is a flag used to assist with room rendering. The movement ( in feet ) is stored in M and checked against the room dimensions using the player's facing direction. If the player could leave the room as a result of this move IB is set to 1.

5100  IF TA < 1 THEN 5390
5105 M =  ASC (C$) - 48
5110 M1 = M:N =  PEEK (NP + KR):IB = 0: ON KF GOTO 5120,5210,5164,5250
5120  IF YA + M > W1 - 3 THEN M = W1 - 3 - YA:IB = 1
5150  GOTO 5281
5164 M =  - M:M1 = M: IF YA + M < W2 + 4 THEN M = W2 + 4 - YA:IB = 1
5180  GOTO 5281
5210  IF XA + M > V2 - 3 THEN M = V2 - 3 - XA:IB = 1
5240  GOTO 5281
5250 M =  - M:M1 = M: IF XA + M < V1 + 4 THEN M = V1 + 4 - XA:IB = 1
5270  GOTO 5281
5279  IF NB > 0 THEN 7000
5280  GOTO 7020

Commands 0-9. Apply movement. If IB is 0, then the player is still within the bounds of the current room so we can apply the movement. If the flag ( KA-86) is set, code at 5293 is used to reduce the cost of movement before stamina is updated. There is probably a bug here as, this flag never seems to be set. However, there is a flag at KA-87 ( also unused ) that is set when the player picks up magic boots, which one would imagine should have this effect.


A movement of 0 is handled the same as any other, but as it will have no stamina cost, this amounts to resting. Otherwise, stamina is drained and trying to move quickly while encumbered drains stamina quickly. This means it takes more turns to move through the dungeon, so increasing the chances of encountering a wandering monster.

If we get to 5283, the player has tried to move outside the bounds of the room. If there is an exit, we change rooms. If the new room has id 0, we have left the dungeon ( 5283).

5281  IF IB = 0 THEN 5291
5282 XL = XA - V1:YL = YA - W2: IF  PEEK (NT + KR + KF * Q - Q) <  > 1 THEN 5291
5283 L = KR + KF * Q - Q: IF P(KF) >  PEEK (D1 + L) AND P(KF) <  PEEK (D2 + L) THEN  GOSUB 345: GOSUB 82:NB = 0:IN = 0:KR =  PEEK (NO + L): GOSUB 800:IB = 2:M =  ABS (M) + 4: IF KR = 0 THEN 10000
5284  IF IB = 1 THEN 5291
5285  IF V1 - XB >  - 1 AND V2 - XB < 49 AND YB - W1 >  - 1 AND YB - W2 < 49 THEN IB = 3:S(1) = W1 - W2:S(2) = V2 - V1:M = M1: GOTO 5291
5286  IF KF = 1 THEN YA = W2 + 4: GOTO 5030
5287  IF KF = 3 THEN YA = W1 - 4: GOTO 5030
5288  IF KF = 2 THEN XA = V1 + 4
5289  IF KF <  > 2 THEN XA = V2 - 4
5290  GOTO 5030
5291  GOSUB 250: GOSUB 679: IF KF = 1 OR KF = 3 THEN YA = YA + M
5292  IF KF <  > 1 AND KF <  > 3 THEN XA = XA + M
5293  IF  PEEK (KA - 86) > 0 THEN M = M / 2
5294  GOSUB 200:P(1) = XA - V1:P(3) = P(1):P(2) = YA - W2:P(4) = P(2):P(0) = P(2): IF IB = 3 THEN LR = KR: GOSUB 4004:IB = 0: GOTO 5044
5295 XL = XA - V1:YL = YA - W2: GOSUB 695: IF L > 0 THEN  GOSUB 650: GOTO 7020
5296  GOTO 7000

Movement commands (R)ight,(L)eft and (V)olte Face. These update the facing direction and erase/draw the player shape.

5300  GOSUB 250:KF = KF + 1: IF KF > 4 THEN KF = 1
5310  GOSUB 200: GOTO 5044
5350  GOSUB 250:KF = KF - 1: IF KF < 1 THEN KF = 4
5360  GOSUB 200: GOTO 5044
5370  GOSUB 250:KF = KF - 2: IF KF < 1 THEN KF = KF + 4
5380  GOSUB 200: GOTO 5044

Attack commands (A)ttack, (T)hrust and (P)arry, (F)ire normal arrow and Fire (M)agic arrow. These actions are only possible if the player has enough stamina. The table below summarizes the important differences between these actions. Cost is the cost in Fatigue/Stamina - highest for thrust, low for parry and lowest for arrows. This is followed by an offensive bonus applied to the player attack, and a defensive bonus applied against the monster's attack. This supports some tactical play: parrying is less likely to hurt monsters, but allows stamina to recover. Thrusts conversely have a better chance of hurting monsters, but leave the player vulnerable if the attack does not kill the monster outright. Firing arrows, leaves the player very vulnerable to melee attacks.

Cost Attack Defence

Attack 10 0 0

Thrust 13 +3 -3

Parry 2 -6 +2

Arrow 1 N/A -5


5390  IF TA >  = 1 THEN IA = I - 2:IN = 0:KM = 0: ON IA GOTO 5400,5400,5400,5500,5490
5395 QY = 40:QX = 195:Q$ = "TOO TIRED": GOSUB 15010: GOSUB 75: GOTO 7000

The melee commands are all handled identically. First we check whether we are in melee range; if this is the case we perform an attack. We take our base to hit score ( this already incorporates the dexterity bonus, level bonus and any magical weapon bonus ) and adjust it by the monsters level ( monsters have no explicit AC-like stat - the monster level/3 is used to adjust the to-hit roll ) and the attack type bonus/penalty from the table above above. There is also an ego bonus that increases the more injured the player becomes - possibly to compensate for the feedback loop between stamina and health? We roll a d20 and compare to the target; if we roll over we hit the monster.


There is no separate damage roll. Instead the damage is set by the difference between the target and roll. This is scaled by AS - which is derived from strength and clamped by the weapon max damage. The actual damage is applied if the damage is greater than the monsters armor ( MH ) and either the monster is not one of the greater undead, or the player used a magical weapon ( arrow or sword ). This follows 1st edition D&D where the stronger undead - wraiths, specters, vampires - are immune to non-magical weapons.


The IN flag is set to 0, to indicate that the monster is now hostile, to allow for the case where the player attacked a friendly monster.

5400 HI = 0: IF  ABS (XL - XM) > 5 OR  ABS (YL - YM) > 5 THEN QX = 195:QY = 40:Q$ = "TOO FAR TO HIT": GOSUB 75: GOTO 7000
5430 M = TM(IA):K = 0: GOSUB 600:P = PB - ( PEEK (KB + 22) - 9) / 3 *  EXP ( - 2 * PC / PH) + ML / 3 - ZA(IA):R =  RND (1) * 20: IF R < P THEN QX = 195:QY = 40:Q$ = "SWISH": GOSUB 75: GOTO 6990
5435 AK = AS * (R - P + 1):QX = 195:QY = 40:Q$ = "CRUNCH!": GOSUB 75: IF AK > WM THEN AK = WM
5437  IF AK < MH THEN AK = MH
5440  IF  PEEK (US + MQ) <  > 2 OR  PEEK (KB + 10) > 0 AND IA < 3 OR IA = 5 THEN MP = MP - AK + MH:IN = 0
5450  GOTO 6990

Ranged attacks. There is no explicit to hit roll here - so long as the player positions themselves within in line with the monster, they will hit. There is a tolerance (I1) here that is greater for magical arrows.

5490 I1 = 5:KM = 5: IF  PEEK (KB + 14) <  = 0 THEN 7000
5495  POKE KB + 14, PEEK (KB + 14) - 1: GOSUB 74: GOTO 5505
5500 I1 = 3: IF  PEEK (KB + 13) <  = 0 THEN 7000
5502  POKE KB + 13, PEEK (KB + 13) - 1: GOSUB 73
5505  ON KF GOTO 5510,5550,5515,5555

Draw simple arrow animation.

5510 LY = YL + 2:UY = YM - 3:S = 1: GOTO 5520
5515 LY = YL - 2:UY = YM + 3:S =  - 1
5520 X = XL - 1: FOR Y = LY TO UY STEP S:I = 4 * (X + V1 - XB):J = 4 * (YB - Y - W2): FOR QI = 0 TO 1: HPLOT I + QI,J TO I + QI,J + 3: NEXT QI: HCOLOR= 4: FOR QI = 0 TO 1: HPLOT I + QI,J TO I + QI,J + 3: NEXT QI: HCOLOR= 7:X = X * 1: NEXT Y: GOTO 5580
5550 LX = XL + 1:UX = XM - 3:S = 1: GOTO 5560
5555 LX = XL - 3:UX = XM + 3:S =  - 1
5560 Y = YL - 1: FOR X = LX TO UX STEP S:I = 4 * (X + V1 - XB):J = 4 * (YB - Y - W2) - 3: FOR QI = 0 TO 1: HPLOT I + QI,J TO I + QI,J + 3: NEXT QI: HCOLOR= 4: FOR QI = 0 TO 1: HPLOT I + QI,J TO I + QI,J + 3: NEXT QI: HCOLOR= 7:X = X * 1: NEXT X

Apply damage is the arrow was close enough to the monster. As well as having a more generous tolerance, magical arrows also do more damage.

5580  IF  ABS (X - XM) < I1 AND  ABS (Y - YM) < I1 THEN QX = 195:QY = 40:Q$ = "THWUNK!": GOSUB 75:AK =  RND (1) * 7 + KM: GOTO 5437 5585 QX = 195:QY = 40:Q$ = "SSWHT!": GOSUB 75: GOTO 7000
14 views0 comments

Recent Posts

See All

Flying Shark : Object Logic

Every object has a type field ( 0x5 ) that selects a tick routine. The tick routine for a bomb power-up is shown below (link to video)....

Comentarios


bottom of page