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
Comentarios