top of page
Search
Writer's pictureTom Grove

Monsters and Room Rendering

Get Room Dimensions for either the current room ( 800 ) or the room passed in LR ( 840 ).

800 LL = KR: GOTO 850
840 LL = LR
850 V3 =  PEEK (X1 + LL) + 128 *  PEEK (X1 + Q + LL):V4 =  PEEK (X2 + LL) + 128 *  PEEK (X2 + Q + LL):W3 =  PEEK (Y1 + LL) + 128 *  PEEK (Y1 + Q + LL):W4 =  PEEK (Y2 + LL) + 128 *  PEEK (Y2 + Q + LL): IF LL <  > KR THEN  RETURN 
860 V1 = V3:V2 = V4:W1 = W3:W2 = W4: RETURN 

Get Monster name. Monster names are stored in a string table at the end of the data file.

880 K = 0:MO = KA + 2121: FOR LL = 1 TO MQ:L =  PEEK (K + MO):K = K + L + 1: NEXT LL:K = K - L - 1:A$ = "": FOR LL = 1 TO L:A$ = A$ +  CHR$ ( PEEK (K + MO + LL)): NEXT LL: RETURN

Get starting location, facing direction and wandering monster probability. This probability goes up slightly on higher levels ( 25% on levels 2 and 3, 30% on 4 ).


Set up player state. XA and YA are initialised to the players starting point in the dungeon, max hit points ( PH ) is set to constitution, current hit points (PC) set to max.

1200 XA =  PEEK (KA + 2236):YA =  PEEK (KA + 2237):KF =  PEEK (KA + 2238):PW =  PEEK (KA + 2235):EX =  PEEK (KB + 3) * 65536 +  PEEK (KB + 2) * 256 +  PEEK (KB + 1)
1210 MM = 4:PH =  PEEK (KB + 24):PC = PH:PB =  PEEK (KB + 18):PA =  PEEK (KB + 19):PS =  PEEK (KB):AA =  PEEK (KB + 8):TA = 100:AS =  PEEK (KB + 23) / 10:WM =  PEEK (KB + 7):SE =  PEEK (KB + 9) * 4:WT = AS * AS * 100:WC =  PEEK (KB + 12):SM =  PEEK (KB + 10): RETURN 

Draw room in LR. The game keeps track of the currently visible rooms, and this code returns if the room is known to be visible. Otherwise it draws the room and its exits.

3010-3014 draws the vertical walls, whereas 3020-3034 draws the horizontal ones. At 3011 we check to see if a vertical wall is completely open ( i.e. the exit covers the full height ) in which case nothing is drawn. 3013 draws an open entrance or door. The code for horizontal walls is similar.

3000  IF  PEEK (KA + LR - 61) = 1 THEN  RETURN 
3001  GOSUB 840:XX = V4 - XB - 2: IF V3 - XB >  - 1 AND V4 - XB < 49 AND YB - W3 >  - 1 AND YB - W4 < 49 THEN  POKE KA + LR - 61,1
3010  FOR K = 1 TO 3 STEP 2:NN = LR + K * Q:YY = YB - W3: IF NS = K THEN 3014
3011 I1 = 3:L = W3 - W4: IF  PEEK (D2 + NN) -  PEEK (D1 + NN) + 4 = L THEN 3014
3012  GOSUB 100
3013 I1 = 5 - 2 *  PEEK (NT + NN): IF I1 >  = 0 AND I1 < 5 THEN YY = YB - W4 -  PEEK (D2 + NN):L =  PEEK (D2 + NN) -  PEEK (D1 + NN): GOSUB 120
3014 XX = V3 - XB: NEXT K
3020 YY = YB - W3: FOR K = 0 TO 2 STEP 2:NN = LR + K * Q: IF NS = K THEN 3034
3025 I1 = 1:XX = V3 - XB:L = 2 * (V4 - V3): IF  PEEK (D2 + NN) -  PEEK (D1 + NN) + 4 = L / 2 THEN 3034
3030  GOSUB 140:I1 = 2 -  PEEK (NT + NN): IF I1 >  = 0 AND I1 < 2 THEN XX = V3 - XB +  PEEK (D1 + NN):L = 2 * ( PEEK (D2 + NN) -  PEEK (D1 + NN)): GOSUB 150
3034 YY = YB - W4 - 2: NEXT K: RETURN 

Draw the current room. If the room isn't already visible because the player has walked off of the screen, reset the view. This involves clearing the left half of the display via the short machine code routine ( the CALL 7936) and clearing the array of visible rooms. The view origin (XB,YB) is then initialised to the room's min coord. This is then adjusted to allow for any open exits ( 4002).

If a room contains a monster, we set it up here ( routine at 4500 ) and set a flag ( NB ) to indicate that a monster is present. If the room does not contain a monster, we try and generate a wandering monster ( routine at 4800 ). Up to 12 monsters are defined following the trap definitions. A monster's level provides its offsensive and defensive bonuses. Monster's can make multiple attacks - usually monsters that make multiple attacks are swarms of some kind. Type seems indicate that the monster is undead - in ToA nothing mechanical changes with lesser undead such as zombies, and skeletons. Greater undead, ( Type 2) however, are resistant to non-magical weapons and can drain a player's energy. Damage scales the damage a monster does. Monster Armor functions like player armor and absorbs a certain amount of damage. Intelligence, for want of a better term, indicates how open to negotiation a monster is. It is unclear what UR was intended to have been used for - prehaps some kind of magic ( or other? ) resistance.

{
    // UL
    byte Level[12];
    
    // UA
    byte NumberOfAttack[12];
    
    // UP
    byte HitPoints[12];
    
    // US: Lesser or Greater Undead
    byte Type[12];
    
    // UD
    byte Damage[12];
    
    // UC
    byte Armor[12];
    
    // UR
    byte Unused[12];
    
    // UI
    byte Intelligence[12];
}

Each of the twelve monsters has an associated shape. Below are the monsters from the fourth level of the dungeon. Four of these shapes are the same - these are Antmen, the hostile humanoids who appear on all levels of the dungeon. There are many different types of ant person - but they are all indistinguishable to humans ( i.e. they share the same images ).


Some examples. A weak but fast moving giant mosquito from the 1st level.


Giant Mosquitos - have a three or four foot wingspan and maneuver their slender bodies about rapidly through the air. They insert their proboscises into their prey and drain the body fluids. ( Level:1 Attacks: 1 Hp: 4 Damage: 5 Armor: 1 Int:0 Speed:11 )

A dangerous, but slow moving, jelly from the 2nd level


Jellies - are formless masses of translucent jelly about three feet high and six or eight feet across; their touch dissolves flesh. They have no socially redeeming value.

( Level:4 Attacks: 1 Hp: 18 Damage: 6 Armor: 0 Int:0 Speed:2 )


A nest of (strangely intelligent?) centipedes. Weak, but make a large number of attacks. These are spawned in a 1st level trap.


Centipedes - This represents a nest of the little buggers such as might take up residence under a chest or in some remote crevice. Their bites are mildly poisonous.

( Level:1 Attacks: 6 Hp: 1 Damage: 7 Armor:1 Int: 4 Speed:3 )


Next the right hand status column is refreshed ( 4006 ) and the monster is drawn if one is present ( 4010 ). Finally, the room and its neighbours are drawn,

4000 LR = KR: GOSUB 800: GOSUB 16000: IF  PEEK (KA + KR - 61) = 1 THEN 4006
4001  CALL 7936: GOSUB 80
4002 XB = V1:YB = W1: IF  PEEK (NT + LR + 3 * Q) = 1 THEN XB = XB - (48 - V2 + V1) / 2: IF  PEEK (NT + LR + Q) = 1 THEN XB = XB + (V1 - XB) / 2
4003  IF  PEEK (NT + LR) = 1 THEN YB = YB + 48 - W1 + W2: IF  PEEK (NT + LR + 2 * Q) = 1 THEN YB = YB - (YB - W1) / 2
4004 QY = 72: GOSUB 15010:XL = XA - V1:YL = YA - W2: IF  PEEK (MT + KR) > 0 AND  PEEK (MN + KR) > 0 THEN  GOSUB 4500:NB = 1: GOTO 4006
4005  GOSUB 4800
4006 QX = 255:QY = 0:Q$ =  STR$ (KR): GOSUB 15000: GOSUB 75:QX = 249:QY = 8:Q$ =  STR$ ( INT (100 * PC / PH + .5)) + "%": GOSUB 15000: GOSUB 75:QX = 249:QY = 16:Q$ =  STR$ ( INT (TA)) + "%": GOSUB 15000: GOSUB 75
4007 QX = 249:QY = 24:Q$ =  STR$ (WC): GOSUB 15000: GOSUB 75: GOSUB 73: GOSUB 74:QX = 195:QY = 96:Q$ =  STR$ (KC): GOSUB 15000: GOSUB 75
4010  IF NB > 0 THEN  GOSUB 300
4020 NS = 5: IF IB = 3 THEN 4050
4030  FOR IR = 0 TO 3:I = KR + IR * Q: IF  PEEK (NT + I) = 1 AND  PEEK (NO + I) > 0 THEN LR =  PEEK (NO + I): GOSUB 3000
4040  NEXT IR
4050 LR = KR: GOSUB 3000: GOSUB 200: GOSUB 679: RETURN 

Setup Monster

4500 MQ =  PEEK (MT + KR):MW = 0:ML =  PEEK (UL + MQ):MA =  PEEK (UA + MQ):MP =  PEEK (UP + MQ):MS =  PEEK (UV + MQ):MD =  PEEK (UD + MQ):MH =  PEEK (UC + MQ):MR = 0: GOSUB 880:IH = 0
4520 XM =  RND (1) * (V2 - V1 - 8) + 4:YM =  RND (1) * (W1 - W2 - 8) + 4
4530 QX = 195:QY = 72:Q$ = A$: GOSUB 15010: GOSUB 75
4550 MF =  RND (1) * 4: RETURN 

Spawn wandering monster. We roll at d100 - if this is lower than the wandering probability obtained from the data file, then we draw a random encounter from the table in the data file. On the first level, this table, which follows the monster definitions, is:


Wandering Probability: 20%


0-19 MOSQUITO

20-21 FIRE BEETLE

22-51 SWAMP RAT

52-71 SKELETON

72-99 ANT MAN


The 20% probability is the probability that a monster will be found in an empty room. A reduced probability ( 4850 ) is used as a per-turn check.

4800 L =  RND (1) * 100: IF L > PW THEN NB = 0:A$ = "": RETURN 
4810 L =  RND (1) * 100:LS = 0:NB = 1: FOR I = 1 TO Q1:LS = LS +  PEEK (UW + I): IF L < LS THEN 4830
4820  NEXT I
4830  POKE MT + KR,I: POKE MN + KR,1:MQ = I:ML =  PEEK (UL + I):MA =  PEEK (UA + I):MP =  PEEK (UP + I):MS =  PEEK (UV + I):MD =  PEEK (UD + I):MH =  PEEK (UC + I): GOSUB 880:IH = 0: GOSUB 4520: RETURN 
4850 L =  RND (1) * 100: IF L < PW / 6 THEN 4810
4851  RETURN 
17 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)....

Comments


bottom of page