home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / DNDOOR46.ZIP / DNDS3.BAS < prev    next >
BASIC Source File  |  2001-07-11  |  117KB  |  2,380 lines

  1.  Rem * Filename: dnds3.bas Version: v4.6 r1.0
  2.  Rem * This subprogram contains most of the attack and player death routines.
  3.  
  4.  Rem $Include: 'dnddoor.inc'
  5.  
  6.  Rem * routine to attack a monster, or object.
  7.  Rem * input variables:
  8.  Rem *   Parsed.Command1 - contains the attack target.
  9.  Rem *   Room - contains room number user is in.
  10.  Rem * work variables:
  11.  Rem *   Prefix1 - contains prefix to target (he/the/it).
  12.  Rem *   (constants) - command numbers.
  13.  
  14. Sub Attack.Monster
  15.  On Local Error Resume Next ' local error resume
  16.  Prefix1=Nul ' reset target prefix
  17.  Monster.Number=False ' reset monster target number
  18.  If Room=1 Then ' compare room number
  19.     Outpt="This is a safe haven!" ' make message
  20.     Call IO.O ' send message
  21.     Exit Sub ' exit routine
  22.  Endif ' end compare room number
  23.  Call Check.Room.Objects ' verify target is an object in room
  24.  If Index.Number Then ' compare object index
  25.     If ObjectRecord.JailTrap Then ' check object jails attacker
  26.        Call Jail ' routine to send player to jail room
  27.     Else ' compare check jail object
  28.        Outpt="Nothing happens.." ' make message
  29.        Call IO.O ' send message
  30.     Endif ' end compare jail object
  31.     Exit Sub ' exit routine
  32.  Endif ' end compare object index
  33.  Previous.Command=False ' reset number of previous attack command
  34.  If Intoxicated>False Then ' compare player is drunk
  35.     Outpt="You are too drunk to fight!" ' make message
  36.     Call IO.O ' send message
  37.     Exit Sub ' exit routine
  38.  Endif ' end compare drunk player
  39.  Call Check.Monster ' verify target is monster
  40.  If Monster.Number=False Then ' check monster index
  41.     If Parser=False Then ' verify command type
  42.        Call Get.Last.Monster(Monster.Found) ' routine to get default monster
  43.        If Monster.Found Then ' check monster exists
  44.           Parsed.Command1=Last.Monster ' store monster name
  45.        Endif ' end check monster
  46.     Endif ' end verufy command
  47.     If Monster.Number=False Then ' verify target found
  48.        Outpt="You can't attack that!" ' make message
  49.        Call IO.O ' send message
  50.        Exit Sub ' exit routine
  51.     Endif ' end verify target
  52.  Endif ' end compare monster target
  53.  If MonsterArray(Monster.Number).Jail Then ' verify monster jails attacker
  54.     Call Jail ' routine to send player to jail room
  55.     Exit Sub ' exit routine
  56.  Endif ' end verify jail monster
  57.  Call The.Or.An ' routine to get prefix
  58.  Outpts=MonsterArray(Monster.Number).MonsterName ' store monster target name
  59.  Outpts=Rtrim$(Outpts) ' trim monster name
  60.  Outpts=Lcase$(Outpts) ' lowercase monster name
  61.  Select Case Last.Command.Number ' make selection of attack command number
  62.  Case Charm ' charm
  63.     If UserRecord.ClassType=Lady Then ' compare class type of player
  64.        If MonsterArray(Monster.Number).Magic<=True Then ' check magic monster
  65.           Outpt="Didn't work!" ' make message
  66.           Call IO.O ' send message
  67.           Exit Sub ' exit routine
  68.        Endif ' end check magic monster
  69.        If Int(Rnd*10+4)>UserRecord.Beauty Then ' calculate lady hits
  70.           Outpt="Didn't work!" ' make message
  71.           Call IO.O ' send message
  72.           Exit Sub ' exit routine
  73.        Endif ' end calculate hits
  74.        MonsterArray(Monster.Number).Magic=5 ' update monster befuddle rounds
  75.        Outpt="It worked!" ' make message
  76.        Call IO.O ' send message
  77.        Exit Sub ' exit routine
  78.     Endif ' end compare class type
  79.     Outpt="Your class does not allow that!" ' make message
  80.     Call IO.O ' send message
  81.     Exit Sub ' exit routine
  82.  Case Beguile ' beguile
  83.     If UserRecord.ClassType=Lady Then ' compare class type of player
  84.        If Int(Rnd*12+5)>(UserRecord.Beauty+UserRecord.Glamour) Then ' calculate
  85.           Outpt="Didn't work!" ' make message
  86.           Call IO.O ' send message
  87.           Exit Sub ' exit routine
  88.        Endif ' end calculate monster death
  89.        Call Monster.Died ' calculated monster died
  90.        Exit Sub ' exit routine
  91.     Endif ' end compare class type
  92.     Outpt="Your class does not allow that!" ' make message
  93.     Call IO.O ' send message
  94.     Exit Sub ' exit routine
  95.  Case Circled ' circle
  96.     If MonsterArray(Monster.Number).Magic<=True Then ' compare magic monster
  97.        Outpt="Didn't work!" ' make message
  98.        Call IO.O ' send message
  99.        Exit Sub ' exit routine
  100.     Endif ' end compare magic monster
  101.     ' compute
  102.     Calculate#=(Rnd*5+UserRecord.Level)>MonsterArray(Monster.Number).Level
  103.     If Calculate# Then ' compare circle monster
  104.        Previous.Command=True ' reset previous attack command number
  105.        MonsterArray(Monster.Number).Magic=4 ' update befuddle monster rounds
  106.        Outpt="It worked!" ' make message
  107.        Call IO.O ' send message
  108.        Exit Sub ' exit routine
  109.     Endif ' end compare circled monster
  110.     Outpt="Didn't work!" ' make message
  111.     Call IO.O ' send message
  112.     Exit Sub ' exit routine
  113.  Case Feint ' feint
  114.     If MonsterArray(Monster.Number).Magic<=True Then ' compare magic monster
  115.        Outpt="Didn't work!" ' make message
  116.        Call IO.O ' send message
  117.        Exit Sub ' exit routine
  118.     Endif ' end compare magic monster
  119.     Calculate#=UserRecord.Stats(4)>(Rnd*5+MonsterArray(Monster.Number).Level/2)
  120.     If Calculate# Then ' compare calculated befuddle
  121.        Previous.Command=Last.Command.Number ' store last command number
  122.        MonsterArray(Monster.Number).Magic=3 ' update monster befuddle rounds
  123.        Outpt="It worked!" ' make message
  124.        Call IO.O ' send message
  125.        Exit Sub ' exit routine
  126.     Endif ' end compare calculation
  127.     Outpt="Didn't work!" ' make message
  128.     Call IO.O ' send message
  129.     Exit Sub ' exit routine
  130.  Case Resist, Parry ' parry, resist
  131.     Previous.Command=Last.Command.Number ' store last command number
  132.     Outpt="It worked!" ' make message
  133.     Call IO.O ' send message
  134.     Exit Sub ' exit routine
  135.  Case Turn ' turn
  136.     Magic.Spell=12 ' force turn spell cast
  137.  Case Bemuse ' bemuse
  138.     If UserRecord.ClassType=Lady Then ' compare player class type
  139.        If MonsterArray(Monster.Number).LevelDrain Then ' check monster type
  140.           Outpt="Didn't work!" ' make message
  141.           Call IO.O ' send message
  142.           Exit Sub ' exit routine
  143.        Endif ' end compare class type
  144.        If Int(Rnd*8+5)>UserRecord.Glamour Then ' calculate lady level drain
  145.           Outpt="Didn't work!" ' make message
  146.           Call IO.O ' send message
  147.           Exit Sub ' exit routine
  148.        Endif ' end calculate level drain
  149.        MonsterArray(Monster.Number).Level=MonsterArray(Monster.Number).Level-1
  150.        Outpt="You drain a level from the "+Outpts+"!" ' decrement monster level
  151.        Call IO.O ' send message
  152.        If MonsterArray(Monster.Number).Level<=False Then ' check monster level
  153.           Outpt="You killed the "+Outpts+"!" ' make message
  154.           Call IO.O ' send message
  155.           Call Monster.Died ' routine for dead monster
  156.           Exit Sub ' exit routine
  157.        Endif ' end compare dead monster
  158.     Endif ' end compare lady class
  159.     Outpt="Your class does not allow that!" ' make message
  160.     Call IO.O ' send message
  161.     Exit Sub ' exit routine
  162.  Case Befuddle ' befuddle
  163.     If MonsterArray(Monster.Number).Magic<=True Then ' compare magic monster
  164.        Outpt="Didn't work!" ' make message
  165.        Call IO.O ' send message
  166.        Exit Sub ' exit routine
  167.     Endif ' end compare magic monster
  168.     If (UserRecord.Stats(3)+UserRecord.Stats(4))> _
  169.     (Rnd*10+MonsterArray(Monster.Number).Level/2) Then ' calculate befuddle
  170.        Previous.Command=True ' reset previous command number
  171.        MonsterArray(Monster.Number).Magic=6 ' update monster befuddle rounds
  172.        Outpt="It worked!" ' make message
  173.        Call IO.O ' send message
  174.        Exit Sub ' exit routine
  175.     Endif ' end calculate befuddle
  176.     Outpt="Didn't work!" ' make message
  177.     Call IO.O ' send message
  178.     Exit Sub ' exit routine
  179.  Case Lunge, Dodge ' lunge, dodge
  180.     If Weapon5 Then ' verify player holding shield
  181.        Weapon3=False ' reset shield
  182.        Weapon5=False ' reset shield
  183.        Outpt="You return your shield!" ' make message
  184.        Call IO.O ' send message
  185.     Endif ' end verify shield
  186.  Case Beat, Punch ' beat, punch
  187.     If Weapon6 Then ' verify holding weapon
  188.        Weapon2=False ' reset weapon
  189.        Weapon6=False ' reset weapon
  190.        Weapon10=False ' reset weapon
  191.        Outpt="You return your weapon!" ' make message
  192.        Call IO.O ' send message
  193.     Endif ' end verify weapon
  194.  Case Shield, Guard ' shield, guard
  195.     If Weapon3 Then ' verify holding shield
  196.        Previous.Command=True ' reset previous command
  197.        Outpt="It worked!" ' make message
  198.        Call IO.O ' send message
  199.        Exit Sub ' exit routine
  200.     Endif ' end verify shield
  201.     Previous.Command=False ' reset previous command
  202.     Outpt="You are not holding a shield!" ' make error message
  203.     Call IO.O ' send message
  204.     Exit Sub ' exit routine
  205.  End Select ' end select command number
  206.  Select Case Magic.Spell ' select attack of spell number
  207.  Case Poison ' poison spell
  208.     If MonsterArray(Monster.Number).Poison Then ' check monster is poisoned
  209.        Outpt="Didn't work!" ' make message
  210.        Call IO.O ' send message
  211.        Exit Sub ' exit routine
  212.     Endif ' end check monster
  213.     If Rnd>.5 Then ' random chance
  214.        Outpt="Didn't work!" ' make message
  215.        Call IO.O ' send message
  216.        Exit Sub ' exit routine
  217.     Endif ' end random chance
  218.     ' poison monster rounds
  219.     MonsterArray(Monster.Number).Poison=UserRecord.Level
  220.     Outpt="You poison the "+Outpts+"!" ' make message
  221.     Call IO.O ' send message
  222.     Exit Sub ' exit routine
  223.  Case LevelDrain ' leveldrain spell
  224.     If MonsterArray(Monster.Number).LevelDrain Then ' check monster is undead
  225.        Outpt="Didn't work!" ' make message
  226.        Call IO.O ' send message
  227.        Exit Sub ' exit routine
  228.     Endif ' end check monster
  229.     If Rnd>.5 Then ' random chance
  230.        Outpt="Didn't work!" ' make message
  231.        Call IO.O ' send message
  232.        Exit Sub ' exit routine
  233.     Endif ' end check random chance
  234.     MonsterArray(Monster.Number).Level=MonsterArray(Monster.Number).Level-1
  235.     Outpt="You drain a level from the "+Outpts+"!" ' decrement monster level
  236.     Call IO.O ' send message
  237.     If MonsterArray(Monster.Number).Level<=False Then ' check monster level
  238.        Outpt="You killed the "+Outpts+"!" ' make message
  239.        Call IO.O ' send message
  240.        Call Monster.Died ' routine for dead monster
  241.     Endif ' end check monster level
  242.     Exit Sub ' exit routine
  243.  Case Befuddled ' befuddle spell
  244.     If MonsterArray(Monster.Number).Magic<=True Then ' check magic monster
  245.        Outpt="Didn't work!" ' make message
  246.        Call IO.O ' send message
  247.        Exit Sub ' exit routine
  248.     Endif ' end check magic monster
  249.     If Rnd>.5 Then ' random chance
  250.        Outpt="Didn't work!" ' make message
  251.        Call IO.O ' send message
  252.     Endif ' end chance
  253.     MonsterArray(Monster.Number).Magic=4 ' update monster befuddle rounds
  254.     Outpt="It worked!" ' make message
  255.     Call IO.O ' send message
  256.     Exit Sub ' exit routine
  257.  Case TurnUndead ' turn undead spell
  258.     ' check monster undead
  259.     If MonsterArray(Monster.Number).LevelDrain=False Then
  260.        Outpt="That's not undead!" ' make message
  261.        Call IO.O ' send message
  262.        Exit Sub ' exit routine
  263.     Endif ' end check monster
  264.     Calculate#=(Rnd*UserRecord.Level+2)>MonsterArray(Monster.Number).Level
  265.     If Calculate# Then ' calculate cast spell
  266.        Outpt="You damned the "+Outpts+"!" ' make message
  267.        Call IO.O ' send message
  268.        MonsterArray(Monster.Number).Level=MonsterArray(Monster.Number).Level-1
  269.        Outpt="You drain a level from the "+Outpts+"!" ' decrement monster level
  270.        Call IO.O ' send message
  271.        If MonsterArray(Monster.Number).Level<=False Then ' check monster level
  272.           Outpt="You killed the "+Outpts+"!" ' make message
  273.           Call IO.O ' send message
  274.           Call Monster.Died ' routine for dead monster
  275.           Exit Sub ' exit routine
  276.        Endif ' end check monster level
  277.     Endif ' end calculate undead spell
  278.     Outpt="Didn't work!" ' make message
  279.     Call IO.O ' send message
  280.     Exit Sub ' exit routine
  281.  Case Intoxicate ' intoxicate spell
  282.     If MonsterArray(Monster.Number).Magic<=True Then ' check magic monster
  283.        Intoxicated=UserRecord.Level ' store intoxicated rounds counter
  284.        Outpt="You just became very drunk!" ' make message
  285.        Call IO.O ' send message
  286.        Exit Sub ' exit routine
  287.     Endif ' end check magic monster
  288.     If Rnd>.5 Then ' random chance
  289.        Outpt="Didn't work!" ' make message
  290.        Call IO.O ' send message
  291.        Exit Sub ' exit routine
  292.     Endif ' end check chance
  293.     MonsterArray(Monster.Number).Magic=3 ' update monster befuddle rounds
  294.     Outpt="It worked!" ' make message
  295.     Call IO.O ' send message
  296.     Exit Sub ' exit routine
  297.  End Select ' end selection of magic spell number
  298.  If Magic.Spell=False Then ' compare spell being cast
  299.     If UserRecord.Fatigue<=False Then ' check player fatigue
  300.        UserRecord.Fatigue=False ' reset fatigue
  301.        Outpt="You are too exhausted to fight!" ' make message
  302.        Call IO.O ' send message
  303.        Exit Sub ' exit routine
  304.     Endif ' end check player fatigue
  305.     ' normal attack can't hit magical monsters, only spells can
  306.     If MonsterArray(Monster.Number).Magic<=True Then ' check magic monster
  307.        Outpt="A magical force prevents your attack!" ' make message
  308.        Call IO.O ' send message
  309.        Exit Sub ' exit routine
  310.     Endif ' end check magic monster
  311.  Endif ' end compare spell being cast
  312.  ' nonplayers can't be attacked by normal weapons or spells.
  313.  ' check permanent nonplayer
  314.  If MonsterArray(Monster.Number).Permanent<True Then
  315.     Outpt="A mysterious force prevents your attack!" ' make message
  316.     Call IO.O ' send message
  317.     Exit Sub ' exit routine
  318.  Endif ' end check nonplayer
  319.  ' calculate miss on monster
  320.  Calculate#=(Rnd*10+MonsterArray(Monster.Number).Level/10)>UserRecord.Stats(4)
  321.  If Calculate# Then ' player missed
  322.     If Magic.Spell Then ' check spell being cast
  323.        Outpt="You missed!" ' spell missed message
  324.        Call IO.O ' send output message
  325.        Exit Sub ' exit routine
  326.     Endif ' end check spell being cast
  327.     ' attacking with a weapon
  328.     Calculate#=(Rnd*10)>UserRecord.Stats(1) ' calculate fumble
  329.     If Calculate# Then ' fumbled
  330.        Call Fumble ' routine to drop weapon, shield
  331.     Endif ' end fumble check
  332.     Outpt="You missed the "+Outpts+"!" ' make miss message
  333.     Call IO.O ' send output message
  334.     Exit Sub ' exit routine
  335.  Endif ' end check player missed
  336.  ' calculate attack weapon bonus multiplier
  337.  If Magic.Spell=False Then ' verify attack by weapon, not spell
  338.     Outpt=Nul ' reset output string
  339.     Multiplier=1 ' reset multiplier
  340.     Select Case Weapon2 ' select type of weapon being held
  341.     Case False ' no weapon being held
  342.        Outpt="Punch!" ' punch with fists
  343.     Case Else ' weapon is being held
  344.        Select Case Rnd ' select random chance
  345.        Case Is>.96 ' highest probability
  346.           Outpt="Deathly damage!" ' make damage message
  347.           Multiplier=4 ' set multiplier
  348.        Case Is>.91 ' median probability
  349.           Outpt="Triple damage!" ' make damage message
  350.           Multiplier=3 ' set multiplier
  351.        Case Is>.86 ' lowest probability
  352.           Outpt="Double damage!" ' make damage message
  353.           Multiplier=2 ' set multiplier
  354.        End Select ' end selection of random chance for weapon
  355.     End Select ' end selection of weapon type
  356.  Endif ' end verify weapon attack
  357.  Select Case Last.Command.Number ' selection of attack command number
  358.  Case Killed ' kill
  359.     If Outpt<>Nul Then ' check bonus hit string
  360.        Call IO.O ' send bonus output message
  361.     Endif ' end check bonus flag
  362.  Case Lunge, Dodge ' lunge, dodge
  363.     Multiplier=2 ' store lunge/dodge multiplier
  364.     Previous.Command=Last.Command.Number ' store last command attack number
  365.  Case Backstab ' backstab
  366.     If Hidden.Player Then ' verify player hidden for backstab
  367.        Multiplier=Multiplier+1 ' increment hit multiplier
  368.     Else ' player not hidden
  369.        Outpt="The "+Outpts+" sees you!" ' make message
  370.        Call IO.O ' send message
  371.        Multiplier=Multiplier-1 ' decrement multiplier
  372.     Endif ' end verify hidden player
  373.  Case Thrust ' thrust
  374.     Multiplier=Multiplier+1 ' increment hit multiplier for thrust
  375.     Previous.Command=Last.Command.Number ' store last command attack number
  376.  Case Charge ' charge
  377.     Outpt="Argh! You charge towards the "+Outpts+"!" ' make hit message
  378.     Call IO.O ' send hit message
  379.     Multiplier=Multiplier+1 ' increment hit multiplier
  380.     Previous.Command=Last.Command.Number ' store last command attack number
  381.  Case Counter ' counter
  382.     Multiplier=Multiplier+1 ' increment multiplier for counter attack
  383.  Case Pummel ' pummel
  384.     Outpt="Your fists fly at the monster!" ' make hit message
  385.     Call IO.O ' send hit message
  386.     Multiplier=2 ' set hit multiplier
  387.  Case Beat, Punch ' beat, punch
  388.     Multiplier=2 ' set hit multiplier
  389.     Previous.Command=Last.Command.Number ' store last command attack number
  390.  Case Bewitch ' bewitch
  391.     Multiplier=Multiplier+1 ' increment hit multiplier for bewitch attack
  392.     Previous.Command=Last.Command.Number ' store last command attack number
  393.  Case Bewilder ' bewilder
  394.     Multiplier=Multiplier+1 ' increment hit multiplier for bewilder attack
  395.     Previous.Command=Last.Command.Number ' store last command attack number
  396.  End Select ' end selection of attack command number
  397.  If Magic.Spell=False Then ' verify weapon being used, not spell cast
  398.     If Weapon2 Then ' check player holding weapon
  399.        ' decrement weapon strikes remaining.
  400.        ' store weapon strikes remainig
  401.        Charges.Number=UserRecord.Charges(Weapon6)
  402.        If Charges.Number>False Then ' check weapon strikes remaining
  403.           Charges.Number=Charges.NUmber-1 ' decrement weapon strikes
  404.        Endif ' end check strikes remaining
  405.        ' store weapon strikes in user record
  406.        UserRecord.Charges(Weapon6)=Charges.Number
  407.        If Charges.Number=False Then ' verify weapon strikes
  408.           Call Read.Record(TreasureFile,UserRecord.Inv(Weapon6)) ' get record
  409.           Inpt=TreasureRecord.ShortName ' store weapon mnemonic
  410.           Inpt=Rtrim$(Inpt) ' trim mnemonic
  411.           Inpt=Lcase$(Inpt) ' lowercase mnemonic
  412.           Outpt="Your "+Inpt+" breaks in half!" ' make weapon message
  413.           Call IO.O ' send weapon message
  414.           Call Discard.Inventory(Weapon6,False) ' weapon falls to ground
  415.        Endif ' end verify remaining weapon strikes
  416.     Endif ' end check player holding weapon
  417.  Endif ' end verify weapon being used
  418.  Magic.Spell=True ' reset spell cast flag
  419.  Call Hit.Monster ' get actual hits on monster
  420. End Sub ' end routine to attack monster
  421.  
  422.  Rem * routine to send player to jail room number.
  423.  
  424. Sub Jail
  425.  On Local Error Resume Next ' local error resume
  426.  Outpt="You were just thrown in jail!" ' make message
  427.  Call IO.O ' send jail message
  428.  Next.Room=1 ' reset player room number
  429.  Call Enter.Room ' send player to jail room
  430. End Sub ' end routine to jail player
  431.  
  432.  Rem * routine to decrease the number of monsters in the room.
  433.  
  434. Sub Reduce.Monsters
  435.  On Local Error Resume Next ' local error resume
  436.  Inpt=Parsed.Command1 ' store command parameter
  437.  Inpt=Rtrim$(Inpt) ' trim command parameter
  438.  New.Monsters=Int(Val(Inpt)) ' convert parameter to integer
  439.  ' compare number to reduce
  440.  If New.Monsters>=False And New.Monsters<Number.Monsters Then
  441.     Number.Monsters=New.Monsters ' reduce monsters in room
  442.     Outpt="Number of Monsters reduced to:"+Str$(Number.Monsters)+".."
  443.     Call IO.O ' send monsters reduced message
  444.  Endif ' end compare number to reduce
  445. End Sub ' end routine to decrease monsters in room
  446.  
  447.  Rem * routine to kill off a monster.
  448.  
  449. Sub Kill.Monster
  450.  On Local Error Resume Next ' local error resume
  451.  Monster.Number=False ' reset monster number
  452.  Call Check.Monster ' get monster number from command parameter
  453.  If Monster.Number Then ' compare monster name found to kill
  454.     Graphics.Off=True ' reset color
  455.     Outpt="Evil Laughter Sounds From Above..." ' make message
  456.     Call IO.O ' send message
  457.     Outpt="   A Bolt Of Lightning Strikes..." ' make message
  458.     Call IO.O ' send message
  459.     Graphics.Off=False ' reset color
  460.     Outpt="The "+Outpts+" was just struck dead!" ' make monster died message
  461.     Call IO.O ' send monster died message
  462.     Call Monster.Died ' kill monster
  463.     Exit Sub ' exit routine
  464.  Endif ' end compare monster name
  465.  Outpt="You can't kill that!" ' make error message
  466.  Call IO.O ' send error message
  467. End Sub ' end routine to kill monster
  468.  
  469.  Rem * routine to attack monster.
  470.  Rem * input variables:
  471.  Rem *   Monster.Number - number of monster in array to attack.
  472.  Rem *   Outpts - name of monster being attacked.
  473.  Rem * processing variables:
  474.  Rem *   Calculate# - maximum possible hits on monster.
  475.  
  476. Sub Hit.Monster
  477.  On Local Error Resume Next ' local error resume
  478.  Hidden.Player=False ' reset hidden player
  479.  If Last.Command.Number=PsiMode Then ' compare attack type
  480.     ' calculate hits on monster for psionic attack
  481.     Calculate#=Cdbl(Int(Rnd*UserRecord.Stats(2)+UserRecord.Stats(3)* _
  482.     (Psi.Attack.Mode+Multiplier)))
  483.  Else ' compare attack type
  484.     ' calculate hits on monster for normal attack
  485.     Calculate#=Cdbl(Int((Rnd*UserRecord.Stats(1)+UserRecord.Level/2)* _
  486.     (Multiplier+(UserRecord.Weapons(UserRecord.Proficiency)/100))+Weapon2))
  487.  Endif ' end compare attack type
  488.  Magic.Spell=False ' reset magic spell being used to attack
  489.  If Calculate#<=False Then ' check hits are zero
  490.     Outpt="You missed!" ' make missed message
  491.     Call IO.O ' send missed message
  492.     Exit Sub ' exit routine
  493.  Endif ' end check hits
  494.  Outpt="You hit the "+Outpts+" for"+Str$(Calculate#)+" hits!" ' hits message
  495.  Call IO.O ' send hits message
  496.  Call Monster.Flees(Ran.Away) ' check if monster flees
  497.  If Ran.Away Then ' compare flee
  498.     Call Monster.Died ' routine for dead monster
  499.     Exit Sub ' exit routine
  500.  Endif ' end compare flee
  501.  ' magical monsters don't attack until hit.
  502.  ' check magical monster attacked
  503.  If MonsterArray(Monster.Number).Magic=True Then
  504.     MonsterArray(Monster.Number).Magic=-2 ' set magical monster to attack also
  505.  Endif ' end check attacking a magical monster
  506.  ' decrement the hits on the monster
  507.  MonsterArray(Monster.Number).Hits=MonsterArray(Monster.Number).Hits-Calculate#
  508.  If MonsterArray(Monster.Number).Hits<=False Then ' check monster still alive
  509.     Outpt="You just killed the "+Outpts+"!" ' make message
  510.     Call IO.O ' send message
  511.     Call Monster.Died ' routine for dead monster
  512.  Endif ' end check live monster
  513. End Sub ' end routine to attack monster
  514.  
  515.  Rem * routine to calculate hits causes monster to run.
  516.  Rem * output variables:
  517.  Rem *   Ran.Away - true if monster flees.
  518.  Rem * input variables:
  519.  Rem *   Outpts - name of monster.
  520.  
  521. Sub Monster.Flees(Ran.Away)
  522.  On Local Error Resume Next ' local error resume
  523.  Ran.Away=False ' reset return variable
  524.  If MonsterArray(Monster.Number).Magic>=False Then ' nonmagical monster
  525.     If MonsterArray(Monster.Number).Permanent=False Then ' nonpermanent monster
  526.        ' calculate hits on monster
  527.        If MonsterArray(Monster.Number).Hits-Calculate#>False Then
  528.           ' calculate 25% of hits
  529.           If Calculate#>(MonsterArray(Monster.Number).Hits*.75) Then
  530.              Outpt="The "+Outpts+" flees from your attack!" ' make message
  531.              Call IO.O ' send message
  532.              MonsterArray(Monster.Number).Experience= _
  533.              Int(MonsterArray(Monster.Number).Experience/2) ' half experience
  534.              Ran.Away=True ' reset return variable
  535.           Endif ' end calculate hits on monster is 25%
  536.        Endif ' end check if monster has hits remaining after attack
  537.     Endif ' end verify permanent monster
  538.  Endif ' end verify magical monster
  539. End Sub ' end routine to check monster flees
  540.  
  541.  Rem * routine for dead monster.
  542.  Rem * input variables:
  543.  Rem *   Monster.Number - index of monster to array.
  544.  Rem * processing variables:
  545.  Rem *   Monsters.Killed - total monsters killed by player this session.
  546.  Rem *   Choice - index of monster file.
  547.  Rem *   Weapon2, Weapon10 - proficiency calculations.
  548.  
  549. Sub Monster.Died
  550.  On Local Error Resume Next ' local error resume
  551.  ' check permanent nonplayer
  552.  If MonsterArray(Monster.Number).Permanent<True Then
  553.     Call Remove.Monster ' nonplayer only leaves room
  554.     Exit Sub ' exit routine
  555.  Endif ' end check nonplayer
  556.  Graphics.Off=True ' reset color
  557.  Last.Command.Number=False ' reset last attack command number
  558.  Outpt="On it you find " ' format message prefix
  559.  Carriage.Return=True ' disable cr/lf
  560.  Call IO.O ' send message prefix
  561.  Number.Items=False ' number of items
  562.  ' loop through monster array for all treasure to leave on ground
  563.  For Treasure.Index=1 To 5 ' loop through monster inventory
  564.     ' get next inventory
  565.     Treasure.Number=MonsterArray(Monster.Number).Treasure(Treasure.Index)
  566.     If Treasure.Number>False And _
  567.     Treasure.Number<=Lof(TreasureFile)/Len(TreasureRecord) Then ' file bounds
  568.        Call Read.Record(TreasureFile,Treasure.Number) ' get treasure record
  569.        Call TreasureCharges(Charges.Amount) ' routine to get treasure charges
  570.        ' add inventory to ground
  571.        Call Add.Room.Treasure(Treasure.Number,Charges.Amount,False,Item.Added)
  572.        If Item.Added Then ' compare return variable to add to room
  573.           Carriage.Return=True ' disable cr/lf
  574.           Call IO.O ' send message of previous treasure name
  575.           ' format treasure name
  576.           Outpt=Rtrim$(TreasureRecord.TreasureName)+", "
  577.           Number.Items=Number.Items+1 ' increment number of items
  578.        Endif ' end compare reutnr variable
  579.     Endif ' end compare file bounds
  580.  Next ' end loop through monster inventory
  581.  If Number.Items=False Then ' compare number of items
  582.     Outpt="nothing.." ' format message
  583.  Else ' compare items
  584.     Outpt=Left$(Outpt,Len(Outpt)-2)+"." ' strip comma, add period
  585.     If Number.Items>1 Then ' compare more than one item
  586.        Outpt="and "+Outpt ' append to message
  587.     Endif ' end compare number of items
  588.  Endif ' end compare number of items
  589.  Call IO.O ' send last part of message
  590.  Call Share.Room.Record(Room) ' write the room record
  591.  Monsters.Killed=Monsters.Killed+1 ' increment player monsters killed session
  592.  ' increment player record
  593.  UserRecord.MonstersKilled=UserRecord.MonstersKilled+1
  594.  Choice=MonsterIndex(Monster.Number) ' store monster record number
  595.  If MonsterArray(Monster.Number).Permanent=True Then ' check permanent monster
  596.     Call Read.Record(MonsterFile,Choice) ' get permanent monster record
  597.     MonsterRecord.Permanent=False ' clear permanent monster flag
  598.     Call Share.Record(MonsterFile,Choice) ' put permanent monster record
  599.  Endif ' end check permanent monster
  600.  If Weapon2 And Weapon10 Then ' check player is holding a weapon
  601.     ' calculate difference between player and monster level
  602.     Level=MonsterArray(Monster.Number).Level-UserRecord.Level
  603.     If Level>False Then ' check level is positive
  604.        ' store player weapon proficiency number
  605.        Proficient.Weapon=UserRecord.Proficiency
  606.        ' check player is holding a weapon in his weapon proficiency
  607.        If Weapon10=Proficient.Weapon Then
  608.           Level=Level*10 ' compute proficiency for kill
  609.        Else ' compare weapon proficiency for weapon held
  610.           Level=Level*5 ' compute proficiency for kill
  611.        Endif ' end compare weapon proficiency held
  612.        If Level>100 Then ' check calculated proficiency over 100 percent
  613.           Level=100 ' reset to 100 percent
  614.        Endif ' end check maximum proficiency percent
  615.        ' compare to current
  616.        If Level>UserRecord.Weapons(Proficient.Weapon) Then
  617.           ' proficiency, store new percent
  618.           UserRecord.Weapons(Proficient.Weapon)=Level
  619.           Outpt="Your "+Weapon.Type.Name(Proficient.Weapon)+ _
  620.           " weapon proficiency is now"+Str$(Level)+" percent!" ' make message
  621.           Call IO.O ' send weapon message
  622.        Endif ' end check maximum percent
  623.     Endif ' end check attack level
  624.  Endif ' end check player holding weapon
  625.  Exp.Points#=MonsterArray(Monster.Number).Experience ' store monster experience
  626.  Gold.Points#=MonsterArray(Monster.Number).Gold ' store monster gold
  627.  If Gold.Points#<=False Then ' compare monster gold
  628.     Gold.Points#=10 ' set to minimum
  629.  Endif ' end compare monster gold
  630.  Outpt="You gained"+Str$(Exp.Points#)+" experience points" ' make message
  631.  If Gold.Points#>False Then ' compare gold
  632.     Outpt=Outpt+" and"+Str$(Gold.Points#)+" gold" ' append gold message
  633.  Endif ' end compare gold
  634.  Outpt=Outpt+"!" ' append message
  635.  Call IO.O ' send experience and gold message
  636.  UserRecord.Gold=UserRecord.Gold+Gold.Points# ' increment player gold
  637.  ' increment player experience
  638.  UserRecord.Experience=UserRecord.Experience+Exp.Points#
  639.  Call Remove.Monster ' take monster out of active monster array
  640.  If UserRecord.Level>False Then ' verify player level
  641.     ' calculate experience needed to reach next level
  642.     Call Experience(Exp.Required#)
  643.     If UserRecord.Experience>=Exp.Required# Then ' compare player experience
  644.        Call Gold(Gold.Required#) ' routine calculates gold needed for level
  645.        If UserRecord.Gold>=Gold.Required# Then ' compare to player gold
  646.           Call Train.Stats ' routine to train for next level
  647.        Endif ' end check player gold required
  648.     Endif ' end check player experience required
  649.  Endif ' end check player level
  650. End Sub ' end monster death routine
  651.  
  652.  Rem * routine to remove a monster from the monster arrays.
  653.  Rem * input variables:
  654.  Rem *   Monster.Number - number of monster to remove.
  655.  Rem * output variables:
  656.  Rem *   Number.Monsters - number of monster currently in room.
  657.  
  658. Sub Remove.Monster
  659.  On Local Error Resume Next ' local error resume
  660.  ' loop through monster array from monster to remove
  661.  For Array.Index=Monster.Number To 19 ' pack array
  662.     ' move next array element
  663.     MonsterIndex(Array.Index)=MonsterIndex(Array.Index+1)
  664.     ' move next array element
  665.     MonsterArray(Array.Index)=MonsterArray(Array.Index+1)
  666.  Next ' end loop through all monsters in arrays
  667.  Number.Monsters=Number.Monsters-1 ' decrement number of monsters in room
  668.  If Number.Monsters<False Then ' compare number of monsters in room
  669.     Number.Monsters=False ' reset numberof monsters to zero
  670.  Endif ' end compare number of monsters
  671. End Sub ' end routine to remove a monster
  672.  
  673.  Rem * routine for monsters to attack player.
  674.  
  675. Sub Monster.Attack
  676.  On Local Error Resume Next ' local error resume
  677.  Monster.Cycle=Monster.Cycle+1 ' increment attack counter
  678.  If Monster.Cycle>=Room.Monster.Rate Then ' compare attack counter to
  679.     Monster.Cycle=False ' room monster attack rate counter, reset to zero
  680.  Endif ' end compare rate counters
  681.  If Number.Monsters=False Then ' check monsters in room
  682.     Exit Sub ' exit routine if no monsters
  683.  Endif ' end check monsters in room
  684.  If Room=1 Then ' check player in safe room
  685.     Exit Sub ' exit routine for safe room
  686.  Endif ' end check player in safe room
  687.  For Monster.Number=1 To Number.Monsters ' loop through all monsters in room
  688.     ' get monster befuddle rounds
  689.     Inactive.Rounds=MonsterArray(Monster.Number).Magic
  690.     If Inactive.Rounds>=False Then ' compare number of befuddle rounds
  691.        If UserRecord.Stats(6)<=1 Then ' check player piety
  692.           Inactive.Rounds=False ' monsters attack on sight for low piety
  693.        Endif ' end check player piety
  694.        ' compare inactive befuddle rounds for monster
  695.        If Inactive.Rounds>False Then
  696.           Inactive.Rounds=Inactive.Rounds-1 ' decrement befuddle rounds
  697.        Endif ' end compare monster befuddle rounds
  698.        ' store monster befuddle rounds
  699.        MonsterArray(Monster.Number).Magic=Inactive.Rounds
  700.     Endif ' end compare number of monster befuddle rounds
  701.     If Inactive.Rounds<True Then ' check if magical monster is attacking
  702.        ' reset befuddle rounds remaining for monster to zero
  703.        Inactive.Rounds=False
  704.     Endif ' end check magical monster is attacking
  705.     ' routine for monster hit regeneration
  706.     If MonsterArray(Monster.Number).Magic<=True Then ' check magical monster
  707.        If MonsterArray(Monster.Number).Level>=15 Then ' check monster level
  708.           If Monster.Cycle=False Then ' compare room monster update rate
  709.              Calculate#=MonsterArray(Monster.Number).Hits ' store monster hits
  710.              ' regenrate hits by ten percent
  711.              Calculate#=Cdbl(Int(Calculate#+Calculate#*.1))
  712.              ' store new monster hits
  713.              MonsterArray(Monster.Number).Hits=Calculate#
  714.           Endif ' end compare room monster update rate
  715.        Endif ' end check monster level
  716.     Endif ' end check magical monster
  717.     ' continue with monster attack if player is not hidden,
  718.     ' and monster is not befuddled.
  719.     ' continue with monster attack
  720.     If Hidden.Player=False And Inactive.Rounds=False Then
  721.        Outpts=MonsterArray(Monster.Number).MonsterName ' store monster name
  722.        Outpts=Rtrim$(Outpts) ' trim monster name
  723.        Outpts=Lcase$(Outpts) ' lowercase monster name
  724.        ' compute monster attack multiplier is monster level plus one
  725.        Multiplier=MonsterArray(Monster.Number).Level+1 ' compute multiplier
  726.        If MonsterArray(Monster.Number).Poison Then ' check monster is poisonous
  727.           ' compute random chance of monster poison percent
  728.           If Rnd<(MonsterArray(Monster.Number).PoisonPercent/100) Then
  729.              Outpt="The "+Outpts+" casts a poison spell!" ' make message
  730.              Call IO.O ' send poison message
  731.              ' check player is wearing antipoison ring
  732.              If Weapon8=1 Then ' check for ring
  733.                 Ring.Charges=UserRecord.Charges(Weapon7) ' store ring strikes
  734.                 ' decrement strikes
  735.                 Ring.Charges=Ring.Charges-MonsterArray(Monster.Number).Level
  736.                 If Ring.Charges<False Then ' compare strikes remaining
  737.                    Ring.Charges=False ' store zero strikes
  738.                 Endif ' end compare strikes
  739.                 ' store strikes in record
  740.                 UserRecord.Charges(Weapon7)=Ring.Charges
  741.                 Outpt="Your ring absorbs the poison spell!" ' make message
  742.                 Call IO.O ' send ring protection message
  743.                 If Ring.Charges=False Then ' compare ring charges remaining
  744.                    Outpt="Your ring disintegrated!" ' make message
  745.                    Call IO.O ' send ring message
  746.                    Call Discard.Inventory(Weapon7,True) ' ring falls to ground
  747.                 Endif ' end compare ring charges
  748.              Else ' check for ring
  749.                 UserRecord.Poison=True ' reset user poisoned flag
  750.                 Outpt="You've been poisoned!" ' make message
  751.                 Call IO.O ' send poisoned message
  752.              Endif ' end compare ring
  753.           Endif ' end compute monster poisons
  754.        Endif ' end compare monster is poisonous
  755.        ' check monster is undead
  756.        If MonsterArray(Monster.Number).LevelDrain Then
  757.           ' compute random chance vs. undead monster leveldrain percent
  758.           If Rnd<(MonsterArray(Monster.Number).DrainPercent/100) Then ' compute
  759.              Outpt="The "+Outpts+" casts a level drain spell!" ' message
  760.              Call IO.O ' send level drain message
  761.              ' check player is wearing anti level drain ring
  762.              If Weapon8=2 Then ' check for ring
  763.                 Ring.Charges=UserRecord.Charges(Weapon7) ' store ring strikes
  764.                 ' decrement ring charges
  765.                 Ring.Charges=Ring.Charges-MonsterArray(Monster.Number).Level
  766.                 If Ring.Charges<False Then ' compare strikes
  767.                    Ring.Charges=False ' reset ring strikes
  768.                 Endif ' end compare strikes
  769.                 ' store srikes in record
  770.                 UserRecord.Charges(Weapon7)=Ring.Charges
  771.                 Outpt="Your ring absorbs the level drain!" ' make message
  772.                 Call IO.O ' send ring message
  773.                 If Ring.Charges=False Then ' check ring charges
  774.                    Outpt="Your ring disintegrated!" ' make message
  775.                    Call IO.O ' send ring charges message
  776.                    Call Discard.Inventory(Weapon7,True) ' ring falls to ground
  777.                 Endif ' end check remaining ring charges
  778.              Else ' check player wearing ring
  779.                 UserRecord.Level=UserRecord.Level-1 ' decrement player level
  780.                 Call New.Stats ' get updated statistics
  781.                 Outpt="You've been drained a level!" ' make message
  782.                 Call IO.O ' send leveldrain message
  783.                 If UserRecord.Level<=False Then ' compare player level to dead
  784.                    UserRecord.Level=1 ' reset player level
  785.                    Call The.Or.An ' get monster prefix
  786.                    ' store message for death routine
  787.                    Message1="You were just killed by "+Prefix1+" "+Outpts+"!"
  788.                    Call Player.Died ' routine for dead player
  789.                    Exit For ' exit monster attack loop
  790.                 Endif ' end compare player level
  791.              Endif ' end check player has ring
  792.           Endif ' end compute random chance
  793.        Endif ' end check monster is undead
  794.        Magic.Spell=False ' reset magic spell being cast
  795.        ' get monster spell cast number
  796.        Spell.Number=MonsterArray(Monster.Number).Spell
  797.        ' file bounds
  798.        If Spell.Number>False And _
  799.        Spell.Number<=Lof(SpellFile)/Len(SpellRecord) Then
  800.           Call Read.Record(SpellFile,Spell.Number) ' get spell record
  801.           Magic.Spell=SpellRecord.SpellType ' store monster spell cast type
  802.           Multiplier=Int(MonsterArray(Monster.Number).Level) ' calculate spell
  803.           Multiplier=Multiplier+Int(SpellRecord.Level/2+.5) ' attack multiplier
  804.           If Magic.Spell=Offense Then ' compare spell type to offense attack
  805.              ' compute random chance to monster spell percent
  806.              If Rnd<(MonsterArray(Monster.Number).SpellPercent/100) Then
  807.                 ' make message of spell monster casts
  808.                 Outpt="The "+Outpts+" casts a "+ _
  809.                 Rtrim$(SpellRecord.SpellName)+" spell!" ' message
  810.                 Call IO.O ' send cast message
  811.                 ' check player is wearing antispell ring
  812.                 If Weapon8=3 Then ' check ring
  813.                    ' check ring is generic antispell or the spell cast
  814.                    If Weapon9=True Or Weapon9=Spell.Number Then ' check ring
  815.                       ' store ring strikes
  816.                       Ring.Charges=UserRecord.Charges(Weapon7)
  817.                       ' subtract spell level
  818.                       Ring.Charges=Ring.Charges-SpellRecord.Level
  819.                       If Ring.Charges<False Then ' compare strikes
  820.                          Ring.Charges=False ' reset strikes
  821.                       Endif ' end compare strikes
  822.                       UserRecord.Charges(Weapon7)=Ring.Charges ' store strikes
  823.                       Outpt="Your ring absorbs the spell!" ' make message
  824.                       Call IO.O ' send ring message
  825.                       ' check remaining ring charges
  826.                       If Ring.Charges=False Then ' compare
  827.                          Outpt="Your ring disintegrated!" ' make message
  828.                          Call IO.O ' send ring message
  829.                          Call Discard.Inventory(Weapon7,True) ' falls to ground
  830.                       Endif ' end compare ring charges
  831.                    Endif ' end ring type
  832.                 Endif ' end check ring
  833.              Endif ' end computer random chance
  834.           Endif ' end compare spell attack type
  835.        Endif ' end check spell file bounds
  836.        ' check if monster is poisoned
  837.        If MonsterArray(Monster.Number).Poison>False Then ' check poisoned
  838.           If Monster.Cycle=False Then ' compare rounds counter
  839.              ' decrement monster poisoned rounds counter
  840.              MonsterArray(Monster.Number).Poison= _
  841.              MonsterArray(Monster.Number).Poison-1 ' decrement
  842.              Outpt="Poison drains the "+Outpts+"!" ' make message
  843.              Call IO.O ' send poisoned message
  844.              ' calculate hits on monster from poison.
  845.              ' store monster hits
  846.              Monster.Hits#=MonsterArray(Monster.Number).Hits
  847.              ' store monster level
  848.              Monster.Level#=MonsterArray(Monster.Number).Level
  849.              ' compute poison
  850.              Poison.Hits#=Int(UserRecord.Level*UserRecord.Stats(7))
  851.              ' compute poison
  852.              Monster.Hits#=Int(Monster.Hits#-Poison.Hits#/Monster.Level#)
  853.              ' store monster hits
  854.              MonsterArray(Monster.Number).Hits=Monster.Hits#
  855.              ' check monster hits
  856.              If MonsterArray(Monster.Number).Hits<=False Then
  857.                 Outpt="The "+Outpts+" died from poison!" ' make message
  858.                 Call IO.O ' send died message
  859.                 Call Monster.Died ' routine for dead monster
  860.                 Exit For ' exit monster attack routine
  861.              Endif ' end check monster hits
  862.           Endif ' end compare rounds counter
  863.        Endif ' end check monster is poisoned
  864.        ' calculate monster misses
  865.        Calculate#=(UserRecord.Stats(4)/2)> _
  866.        (Rnd*10+MonsterArray(Monster.Number).Level/10) ' calculate miss
  867.        If Calculate# Then ' compare miss equation
  868.           Outpt="The "+Outpts+" fumbled!" ' make message
  869.           Call IO.O ' send missed message
  870.        Else ' compare miss
  871.           If Previous.Command=True Then ' compare previous attack command type
  872.              Multiplier=Multiplier-1 ' decrement monster multiplier
  873.              Previous.Command=False ' reset last attack command type
  874.           Endif ' end compare previous attack command type
  875.           ' compare psionic monster
  876.           If MonsterArray(Monster.Number).Psionic=False Then ' compare
  877.              ' calculate normal hits on player
  878.              Calculate#=Cdbl(Int(Rnd*(MonsterArray(Monster.Number).Hits/10- _
  879.              (Weapon1+Weapon3)/2)*Multiplier))
  880.           Else ' calculate psionic hits on player
  881.              ' calculate psionic hits on player
  882.              Calculate#=Cdbl(Int(Rnd*(MonsterArray(Monster.Number).Hits/10- _
  883.              Psi.Defense.Mode)*MonsterArray(Monster.Number).Psionic))
  884.           Endif ' end compare attack type
  885.           Call The.Or.An ' get prefix of monster name
  886.           Prefix1="The " ' reset prefix
  887.           Call Get.Hits(Calculate#) ' routine to hit player
  888.           If Calculate#=True Then ' return variable for dead player
  889.              Exit For ' exit monster attack loop
  890.           Endif ' end check dead player
  891.        Endif ' end compare monster miss equation
  892.     Endif ' end compare monster befuddle rounds
  893.  Next ' end loop through all monsters in room
  894. End Sub ' end routine for monster attacks
  895.  
  896.  Rem * routine to hit player.
  897.  Rem * input variables:
  898.  Rem *   Calculate# - actual hits.
  899.  Rem * output variables:
  900.  Rem *   Calculate# - true if player died.
  901.  
  902. Sub Get.Hits(Calculate#)
  903.  On Local Error Resume Next ' local error resume
  904.  ' selecting the previous attack command player used modifies the actual
  905.  ' hits by the type of attack, and reduces or increases the actual hits
  906.  Select Case Previous.Command ' select the previous attack command
  907.  Case Lunge ' lunge
  908.     Calculate#=Calculate#-UserRecord.Stats(4)/2-UserRecord.Stats(1)/2
  909.  Case Dodge ' dodge
  910.     Calculate#=Calculate#-(UserRecord.Stats(4)+UserRecord.Stats(1))/2
  911.  Case Feint ' feint
  912.     Calculate#=Calculate#-UserRecord.Stats(4)/2-UserRecord.Stats(1)
  913.  Case Parry ' parry
  914.     Calculate#=Calculate#-UserRecord.Stats(4)-UserRecord.Stats(1)
  915.  Case Thrust ' thrust
  916.     Calculate#=Calculate#+UserRecord.Stats(4)/2+UserRecord.Stats(1)
  917.  Case Charge ' charge
  918.     Calculate#=Calculate#+UserRecord.Stats(4)+UserRecord.Stats(1)
  919.  Case Resist ' resist
  920.     Calculate#=Calculate#-UserRecord.Stats(1)/2
  921.  Case Beat ' beat
  922.     Calculate#=Calculate#+UserRecord.Stats(4)/2+UserRecord.Stats(1)/2
  923.  Case Punch ' punch
  924.     Calculate#=Calculate#+(UserRecord.Stats(4)+UserRecord.Stats(1))/2
  925.  Case Bewitch ' bewitch
  926.     Calculate#=Int(Calculate#/2)-UserRecord.Beauty
  927.  Case Bewilder ' bewilder
  928.     Calculate#=Int(Calculate#/2)-UserRecord.Glamour
  929.  End Select ' end selection of previous attack command
  930.  If Calculate#<=False Then ' compare hits on player to miss
  931.     Outpt=Prefix1+Outpts+" missed!" ' make message
  932.     Call IO.O ' send miss message
  933.     Calculate#=False ' return value for live player
  934.     Exit Sub ' exit routine
  935.  Endif ' end compare hits to miss
  936.  If Monster.Number Then ' check monster is attacking
  937.     If Magic.Spell=False Then ' check monster using spell
  938.        Outpt=Prefix1+Outpts+" attacks you" ' make attack message
  939.        ' check monster using psionic
  940.        If MonsterArray(Monster.Number).Psionic Then
  941.           Outpt=Outpt+" with psionics" ' append psionic attack message
  942.        Endif ' end compare monster using psionics
  943.        Outpt=Outpt+"!" ' append exclamation
  944.        Call IO.O ' send attack message
  945.     Endif ' end compare monster using spell
  946.  Endif ' end compare monster attacking
  947.  If UserRecord.Invisible Then ' check player is invisible
  948.     Outpt="Your invisibility protects you!" ' make message
  949.     Call IO.O ' send invisible message
  950.     Calculate#=False ' return value for live player
  951.     Exit Sub ' exit routine
  952.  Endif ' end compare invisible player
  953.  If Vehicle2 Then ' check if player is using a vehicle
  954.     If Rnd>.75 Then ' random chance vehicle is hit
  955.        Call Read.Record(TreasureFile,Vehicle3) ' get vehicle treasure record
  956.        Inpt=TreasureRecord.ShortName ' store vehicle name
  957.        Inpt=Rtrim$(Inpt) ' trim name
  958.        Inpt=Lcase$(Inpt) ' lowercase name
  959.        Outpt=Prefix1+Outpts+" hits your "+Inpt+" for"+Str$(Calculate#)+" hits!"
  960.        Call IO.O ' send message of hits on vehicle
  961.        Vehicle2=Vehicle2-Calculate# ' decrement vehicle hits
  962.        If Vehicle2<=False Then ' compare remaining vehicle hits
  963.           RoomRecord.Treasure(Vehicle1)=Vehicle3 ' put vehicle in room
  964.           RoomRecord.Treasure(Vehicle1)=False ' reset vehicle hits
  965.           Vehicle2=False ' remove vehicle from player
  966.           Vehicle3=False ' remove vehicle from player
  967.           Outpt=Prefix1+Outpts+" damaged your "+Inpt+"!" ' make message
  968.           Call IO.O ' send vehicle message
  969.        Endif ' end compare vehicle hits
  970.     Endif ' end random chance to hit vehicle
  971.     Calculate#=False ' return value for live player
  972.     Exit Sub ' exit routine
  973.  Endif ' end check player using vehicle
  974.  Outpt=Prefix1+Outpts+" hits you for"
  975.  Call Hit.Player(Calculate#) ' routine to decrement hits on player statistics
  976.  If UserRecord.Vitality=False Then ' check player vitality remaining
  977.     Calculate#=True ' set player died flag
  978.     Exit Sub ' exit routine
  979.  Endif ' end check player died
  980.  Calculate#=False ' return value for live player
  981.  If Weapon3 Then ' check player holding shield
  982.     ' store shield strikes remaining
  983.     Charges.Number=UserRecord.Charges(Weapon5)
  984.     If Charges.Number>False Then ' check shield strikes
  985.        Charges.Number=Charges.Number-1 ' decrement shield strikes
  986.     Endif ' end check shield strikes
  987.     ' store shield strikes in user record
  988.     UserRecord.Charges(Weapon5)=Charges.Number
  989.     If Charges.Number=False Then ' compare shield charges
  990.        ' get shield treasure record
  991.        Call Read.Record(TreasureFile,UserRecord.Inv(Weapon5))
  992.        Inpt=TreasureRecord.ShortName ' store treasure name
  993.        Inpt=Rtrim$(Inpt) ' trim name
  994.        Inpt=Lcase$(Inpt) ' lowercase name
  995.        Outpt="Your "+Inpt+" breaks in half!" ' make message
  996.        Call IO.O ' send weapon message
  997.        Call Discard.Inventory(Weapon5,False) ' shield falls to ground
  998.     Endif ' end compare remaining shield charges
  999.  Endif ' end check player holding shield
  1000.  If Weapon1 Then ' check player is holding a armor
  1001.     Charges.Number=UserRecord.Charges(Weapon4) ' store armor strikes remaining
  1002.     If Charges.Number>False Then ' compare armor strikes
  1003.        Charges.Number=Charges.Number-1 ' decrement armor strikes
  1004.     Endif ' end compare armor strikes
  1005.     ' store armor strikes in user record
  1006.     UserRecord.Charges(Weapon4)=Charges.Number
  1007.     If Charges.Number=False Then ' check armor strikes remaining
  1008.        ' get treasure armor record
  1009.        Call Read.Record(TreasureFile,UserRecord.Inv(Weapon4))
  1010.        Inpt=TreasureRecord.ShortName ' store treasure name
  1011.        Inpt=Rtrim$(Inpt) ' trim name
  1012.        Inpt=Lcase$(Inpt) ' lowercase name
  1013.        Outpt="Your "+Inpt+" crumbles!" ' make message
  1014.        Call IO.O ' send armor message
  1015.        Call Discard.Inventory(Weapon4,False) ' falls to ground
  1016.     Endif ' end compare remaining armor charges
  1017.  Endif ' end check player holding armor
  1018. End Sub ' end routine to get hits on player
  1019.  
  1020.  Rem * routine to decrement hits on player from fatigue and vitality.
  1021.  Rem * input variables:
  1022.  Rem *   Hit.Points - hits to subtract, positive from fatigue,
  1023.  Rem *   negative from vitality.
  1024.  
  1025. Sub Hit.Player(Hit.Points#)
  1026.  On Local Error Resume Next ' local error resume
  1027.  If Hit.Points#>False Then ' check decrement from fatigue
  1028.     If UserRecord.Fatigue-Hit.Points#>=False Then ' compare the decrement
  1029.        ' subtract from fatigue
  1030.        UserRecord.Fatigue=UserRecord.Fatigue-Hit.Points#
  1031.        Outpt=Outpt+Str$(Hit.Points#)+" fatigue points!" ' make message
  1032.        Call IO.O ' send hits message
  1033.        Exit Sub ' exit routine
  1034.     Endif ' end compare the decrement
  1035.     ' get the difference from hits on fatigue
  1036.     Hit.Points#=Hit.Points#-UserRecord.Fatigue
  1037.     If UserRecord.Fatigue>False Then ' compare hits to fatigue remaining
  1038.        Outpt=Outpt+Str$(UserRecord.Fatigue)+" fatigue and" ' make message
  1039.     Endif ' end compare fatigue message, remaining difference hits vitlaity
  1040.     UserRecord.Fatigue=False ' reset player fatigue to zero
  1041.  Endif ' end decrement from fatigue
  1042.  Hit.Points#=Abs(Hit.Points#) ' convert hits on vitality to positive integer
  1043.  If Hit.Points#>False Then ' compare vitiality hits
  1044.     Outpt=Outpt+Str$(Hit.Points#)+" vitality points!" ' make message
  1045.     Call IO.O ' send hits message
  1046.     If UserRecord.Vitality-Hit.Points#<=False Then ' compare the decrement
  1047.        UserRecord.Vitality=False ' reset vitality
  1048.        Message1="You were just killed!" ' make died routine message
  1049.        Call Player.Died ' routine for dead player
  1050.        Exit Sub ' exit routine
  1051.     Endif ' end compare vitality decrement
  1052.     ' decrement player vitality
  1053.     UserRecord.Vitality=UserRecord.Vitality-Hit.Points#
  1054.  Endif ' end compare vitality hits
  1055. End Sub ' end routine to decrement hits on player
  1056.  
  1057.  Rem * routine to fumble weapon and shield from player to ground.
  1058.  
  1059. Sub Fumble
  1060.  On Local Error Resume Next ' local error resume
  1061.  If Weapon2 Or Weapon3 Then ' check if holding weapon or shield
  1062.     Outpt="You fumbled! " ' make first message
  1063.     Inpt="You dropped your " ' make second part of message
  1064.     Graphics.Off=True ' reset color
  1065.     Carriage.Return=True ' disable cr/lf
  1066.     Call IO.O ' send first fumble message
  1067.     If Weapon3 Then ' check shield being held
  1068.        ' get shield treasure record
  1069.        Call Read.Record(TreasureFile,UserRecord.Inv(Weapon5))
  1070.        Treasure.Name$=TreasureRecord.ShortName ' get treasure name
  1071.        Treasure.Name$=Rtrim$(Treasure.Name$) ' trim name
  1072.        Treasure.Name$=Lcase$(Treasure.Name$) ' lowercase name
  1073.        Call Discard.Inventory(Weapon5,False) ' falls to ground
  1074.        If Weapon2 Then ' check weapon also being held
  1075.           Outpt=" and "+Treasure.Name$ ' make next part of message
  1076.        Else ' check weapon
  1077.           Outpt=Inpt+Treasure.Name$+"!" ' make message for shield only
  1078.        Endif ' end check weapon being held
  1079.     Endif ' end check shield held
  1080.     If Weapon2 Then ' check weapon being held
  1081.        ' get weapon treasure record
  1082.        Call Read.Record(TreasureFile,UserRecord.Inv(Weapon6))
  1083.        Treasure.Name$=TreasureRecord.ShortName ' get treasure name
  1084.        Treasure.Name$=Rtrim$(Treasure.Name$) ' trim name
  1085.        Treasure.Name$=Lcase$(Treasure.Name$) ' lowercase name
  1086.        Outpt=Inpt+Treasure.Name$+Outpt+"!" ' make last part of message
  1087.        Call Discard.Inventory(Weapon6,False) ' falls to ground
  1088.     Endif ' end check weapon held
  1089.     Call IO.O ' send fumble message
  1090.     Graphics.Off=False ' reset color
  1091.  Endif
  1092. End Sub ' end routine to fumble weapon and shield
  1093.  
  1094.  Rem * routine to get permanent monster encounters in a room.
  1095.  Rem * input variables:
  1096.  Rem *   Room - number of room player is currently in.
  1097.  
  1098. Sub Encounter.Permanent
  1099.  On Local Error Resume Next ' local error resume
  1100.  ' loop through all nonplayer records
  1101.  For Monster.Index=1 To Lof(NonPlayerFile)/Len(MonsterRecord)
  1102.     Call Read.Record(NonPlayerFile,Monster.Index) ' get nonplayer record
  1103.     ' store nonplayer room
  1104.     Monster.Rooms$=","+Rtrim$(MonsterRecord.PluralName)+","
  1105.     Player.Room$=","+Mid$(Str$(Room),2)+"," ' store current room
  1106.     ' verify nonplayer in current room
  1107.     If Instr(Monster.Rooms$,Player.Room$) Then
  1108.        If Number.Monsters<20 Then ' check maximum monsters in room
  1109.           Number.Monsters=Number.Monsters+1 ' increment monsters in room
  1110.           MonsterIndex(Number.Monsters)=Monster.Index ' store nonplayer index
  1111.           MonsterArray(Number.Monsters)=MonsterRecord ' store nonplayer record
  1112.           MonsterArray(Number.Monsters).Magic=True ' set magical monster
  1113.           MonsterArray(Number.Monsters).Permanent=-2 ' set nonplayer flag
  1114.        Endif ' end check maximum monsters
  1115.     Endif ' end verify current room
  1116.  Next ' end loop through nonplayer records
  1117.  If RoomRecord.MonsterClass Then ' check room monster class number
  1118.     For Monsters=1 To 10 ' loop through room monsterclass monsters
  1119.        ' get monster number
  1120.        Choice=Monster.Class(RoomRecord.MonsterClass,Monsters)
  1121.        If Choice>False And _
  1122.        Choice<=Lof(MonsterFile)/Len(MonsterRecord) Then ' bounds
  1123.           Call Read.Record(MonsterFile,Choice) ' get monster record
  1124.           If MonsterRecord.Permanent=True Then ' check if monster permanent
  1125.              Number.Appearing=1 ' set number of monsters to appear to one
  1126.              Call Get.Monster.Stats ' get the monster
  1127.           Endif ' end check permanent monster
  1128.        Endif ' end check file bounds
  1129.     Next ' end loop through room monsterclass
  1130.  Endif ' end check room monster class number
  1131. End Sub ' end routine to get permanent monsters
  1132.  
  1133.  Rem * routine to get one monster.
  1134.  Rem * input variables:
  1135.  Rem *   Parsed.Command1 - name or number of monster.
  1136.  Rem * working variables:
  1137.  Rem *   Choice - is the monster number.
  1138.  
  1139. Sub Summon.Monster
  1140.  On Local Error Resume Next ' local error resume
  1141.  If Room=1 Then ' check player in safe room
  1142.     Exit Sub ' exit routine for safe room
  1143.  Endif ' end check player in safe room
  1144.  Choice=False ' reset monster number
  1145.  Inpt=Parsed.Command1 ' store command parameter
  1146.  Call Parse.Num(Inpt,Parse.Value) ' parse number
  1147.  Parse.Count=False ' reset monster found counter
  1148.  For Monster.Index=1 To Lof(MonsterFile)/Len(MonsterRecord) 'loop through file
  1149.     Call Read.Record(MonsterFile,Monster.Index) ' get monster record
  1150.     ' compare monster record name to input monster name,
  1151.     ' truncated to input length
  1152.     If Left$(MonsterRecord.MonsterName,Len(Inpt))=Inpt Then ' compare
  1153.        Parse.Count=Parse.Count+1 ' increment monster found counter
  1154.        ' compare parsed number of monster to search for
  1155.        If Parse.Value=False Or Parse.Count=Parse.Value Then ' compare
  1156.           Exit For ' exit routine
  1157.        Endif ' end compare counters
  1158.     Endif ' end compare monster names
  1159.  Next ' end loop through monster file
  1160.  If Parse.Count=False Then ' check monster found
  1161.     Monster.Index=Int(Val(Inpt)) ' convert input to integer
  1162.     ' file bounds
  1163.     If Monster.Index>False And _
  1164.     Monster.Index<=Lof(MonsterFile)/Len(MonsterRecord) Then
  1165.        Choice=Monster.Index ' store monster number
  1166.     Endif ' end check file bounds
  1167.  Else ' check file bounds
  1168.     Choice=Monster.Index ' store monster number
  1169.  Endif  ' end check file bounds
  1170.  If Choice>False Then ' check monster number found
  1171.     Call Get.Monster ' get the monster
  1172.  Endif ' end check monster number found
  1173. End Sub ' end routine to get a monster
  1174.  
  1175.  Rem * routine to get a random monster.
  1176.  Rem * processing variables:
  1177.  Rem *   Choice - is the monster number.
  1178.  
  1179. Sub Call.Monster
  1180.  On Local Error Resume Next ' local error resume
  1181.  If Room=1 Then ' check player in safe room
  1182.     Exit Sub ' exit routine for safe room
  1183.  Endif ' end check player in safe room
  1184.  If RoomRecord.MonsterClass Then ' check room monster class
  1185.     If RoomRecord.MonsterClass<=Monclass.Max Then ' check monsterclass bounds
  1186.        ' calculate a random monster from the room monsterclass
  1187.        Choice=Monster.Class(RoomRecord.MonsterClass,Int(Rnd*10+1)) ' random
  1188.        Call Get.Monster ' get the monster
  1189.     Endif ' end check monsterclass bounds
  1190.  Endif ' end check room monster class
  1191. End Sub ' end routine to get a random monster
  1192.  
  1193.  Rem * routine to get a random monster from the room monster class, cmoputed
  1194.  Rem * from the monster encounter round rate counter, and the monster
  1195.  Rem * percentage.
  1196.  Rem * input variables:
  1197.  Rem *   Room - number of the current room.
  1198.  Rem *   Monster.Rate1 - counter of rounds from file.
  1199.  Rem *   Monster.Rate2 - counter of rounds for monster rate.
  1200.  
  1201. Sub Encounter.Monster
  1202.  On Local Error Resume Next ' local error resume
  1203.  If Room=1 Then ' check safe room
  1204.     Exit Sub ' exit routine
  1205.  Endif ' end check safe room
  1206.  Monster.Class=RoomRecord.MonsterClass ' store room monster class
  1207.  ' check monster class
  1208.  If Monster.Class>False And Monster.Class<=Monclass.Max Then
  1209.     If Monster.Rate1=MaxInt Then ' check rate counter maximum integer
  1210.        Monster.Rate1=1 ' reset rate counter
  1211.     Else ' check rate
  1212.        Monster.Rate1=Monster.Rate1+1 ' increment rate
  1213.     Endif ' end check room monster counter rate
  1214.     For Monsters=1 To 10 ' loop through monsters with specified percentages
  1215.        If Monster.Rate(Monster.Class,Monsters) Then ' check monster rate
  1216.           ' verify monster rate equals room rate
  1217.           If Monster.Rate1/Monster.Rate(Monster.Class,Monsters)= _
  1218.           Int(Monster.Rate1/Monster.Rate(Monster.Class,Monsters)) Then
  1219.              ' verify random monster rate percentage
  1220.              If Rnd<(Monster.Percent(Monster.Class,Monsters)/100) Then ' verify
  1221.                 ' store monster number
  1222.                 Choice=Monster.Class(Monster.Class,Monsters)
  1223.                 Call Get.Monster ' get the monster
  1224.              Endif ' end verify random rate
  1225.           Endif ' end verify monster rate percent
  1226.        Endif ' end check monster rate
  1227.     Next ' end loop through monster percentages
  1228.     Monster.Rate2=Monster.Rate2+1 ' increment monster rate for room
  1229.     If Monster.Rate2>=Room.Monster.Rate Then ' check monster rate
  1230.        Monster.Rate2=False ' reset monster rate
  1231.        Choice=Monster.Class(Monster.Class,Int(Rnd*10+1)) ' get random monster
  1232.        If MonsterRecord.Rate=False Then ' verify monster has specific rate
  1233.           If Rnd<.5 Then ' random chance for encounter
  1234.              Call Get.Monster ' get the monster
  1235.           Endif ' end random chance
  1236.        Endif ' end verify monster specific rate
  1237.     Endif ' end monster rate
  1238.  Endif ' end check room has monster class
  1239. End Sub ' end routine to random monster from rates and percentages
  1240.  
  1241.  Rem * routine to get monsters.
  1242.  Rem * input variables:
  1243.  Rem *   Choice - the number of the monster record.
  1244.  Rem * processing variables:
  1245.  Rem *   Number.Appearing - number of monsters to encounter.
  1246.  
  1247. Sub Get.Monster
  1248.  On Local Error Resume Next ' local error resume
  1249.  If Choice>False And _
  1250.  Choice<=Lof(MonsterFile)/Len(MonsterRecord) Then ' file bounds
  1251.     Call Read.Record(MonsterFile,Choice) ' get the monster record
  1252.     If MonsterRecord.Permanent=False Then ' verify monster not permanent
  1253.        ' calculate random number of monsters to encounter
  1254.        Number.Appearing=Int(Rnd*MonsterRecord.NumberAppearing)+1 ' calculate
  1255.        While Number.Appearing+Number.Monsters>20 ' loop to compare maximum
  1256.           Number.Appearing=Number.Appearing-1 ' monsters in room, decrementing
  1257.        Wend ' number appearing while room maximum is not exceeded
  1258.        Select Case Number.Appearing ' selection of number encountered
  1259.        Case 0 ' number appearing is greater than room can hold
  1260.           Exit Sub ' exit routine
  1261.        Case 1 ' format message for one monster
  1262.           ' compare monster name starting with a vowel
  1263.           If Instr("aeiou",Left$(MonsterRecord.MonsterName,1)) Then
  1264.              Outpt="an " ' format prefix to monster name
  1265.           Else ' check vowel
  1266.              Outpt="a " ' format prefix to monster name
  1267.           Endif ' end compare monster name
  1268.           Outpt=" "+Outpt+Rtrim$(MonsterRecord.MonsterName)
  1269.        Case Else ' format message for many monsters
  1270.           Outpt=Str$(Number.Appearing)+" "+Rtrim$(MonsterRecord.PluralName)
  1271.        End Select ' end selection of monsters appearing
  1272.        Outpt="You encounter"+Outpt+"!" ' make message
  1273.        Call IO.O ' send encounter message
  1274.        Call Get.Monster.Stats ' add the monster to the arrays
  1275.     Endif ' end verify not permanent
  1276.  Endif ' end check file bounds
  1277. End Sub ' end routine to get monsters
  1278.  
  1279.  Rem * routine to store monster statistics for encountered monster number.
  1280.  Rem * input variables:
  1281.  Rem *   Choice - is the monster number to the monster file.
  1282.  Rem *   Number.Appearing - the number of monsters of type choice to encounter.
  1283.  
  1284. Sub Get.Monster.Stats
  1285.  On Local Error Resume Next ' local error resume
  1286.  If Number.Monsters>=20 Then ' check room is full of monsters
  1287.     Exit Sub ' exit routine
  1288.  Endif ' end check room full
  1289.  For Monsters=1 To Number.Appearing ' loop through all number appearing
  1290.     If Number.Monsters<20 Then ' check room full of monsters
  1291.        Number.Monsters=Number.Monsters+1 ' increment the number of monsters
  1292.        MonsterIndex(Number.Monsters)=Choice ' store the monster record choice
  1293.        MonsterArray(Number.Monsters)=MonsterRecord ' store the monster record
  1294.        If MonsterArray(Number.Monsters).Psionic Then ' verify psionic monster
  1295.           ' get monster psionic spell number
  1296.           Spell.Number=MonsterArray(Number.Monsters).PsionicSpell
  1297.           MonsterArray(Number.Monsters).Psionic=False ' spell from array and
  1298.           If Spell.Number>False And _
  1299.           Spell.Number<=Lof(SpellFile)/Len(SpellRecord) Then ' reset with
  1300.              ' psionic spell number from spell file
  1301.              Call Read.Record(SpellFile,Spell.Number)
  1302.              If SpellRecord.Psionic Then ' check spell record is psionic
  1303.                 If SpellRecord.PsionicMode=1 Then ' check psionic is offense
  1304.                    ' store the psionic spell level in the monster array
  1305.                    MonsterArray(Number.Monsters).Psionic=SpellRecord.Level
  1306.                 Endif ' end check spell psionic type
  1307.              Endif ' end check spell is psionic
  1308.           Endif ' end check spell file bounds
  1309.        Endif ' end check monster is psionic
  1310.        If MonsterArray(Number.Monsters).Permanent=False Then ' check permanent
  1311.           For Treasure.Index=1 To 5 ' loop through all monster inventory
  1312.              If Rnd>.75 Then ' random chance
  1313.                 ' clear monster treasure element
  1314.                 MonsterArray(Number.Monsters).Treasure(Treasure.Index)=False
  1315.              Endif ' end random chance
  1316.           Next ' end loop through monster inventory
  1317.        Endif ' end check nonpermanent monster
  1318.     Endif ' end check maximum room monsters
  1319.  Next ' end loop through number appearing of monster type choice
  1320.  Action.Number=RoomRecord.Action ' store room action number
  1321.  ' check file bounds
  1322.  If Action.Number>False And _
  1323.  Action.Number<=Lof(ActionFile)/Len(ActionRecord) Then
  1324.     Call Read.Record(ActionFile,Action.Number) ' read action record
  1325.     ' check room action to monster choice
  1326.     If ActionRecord.MonsterTrigger=Choice Then
  1327.        ' check room action not talk activated
  1328.        If ActionRecord.MonsterTalk=False Then
  1329.           Action1$="As you step forward," ' make action message one
  1330.           Action2$="The monster hits you for" ' make action message two
  1331.           ' routine to activate actions by specific trigger
  1332.           Call Actions(Action1$,Action2$)
  1333.        Endif ' end check room action
  1334.     Endif ' end check room has monster trigger
  1335.  Endif ' end check file bounds
  1336. End Sub ' end routine to store encountered monster statistics
  1337.  
  1338.  Rem * routine for dead player.
  1339.  
  1340. Sub Player.Died
  1341.  On Local Error Resume Next ' local error resume
  1342.  UserRecord.Poison=False ' reset player poisoned
  1343.  Vehicle2=False ' reset vehicle
  1344.  Vehicle3=False ' reset vehicle
  1345.  Weapon1=False ' reset weapons, shield, armor, and rings being held/worn
  1346.  Weapon2=False ' reset weapons, shield, armor, and rings being held/worn
  1347.  Weapon3=False ' reset weapons, shield, armor, and rings being held/worn
  1348.  Weapon4=False ' reset weapons, shield, armor, and rings being held/worn
  1349.  Weapon5=False ' reset weapons, shield, armor, and rings being held/worn
  1350.  Weapon6=False ' reset weapons, shield, armor, and rings being held/worn
  1351.  Weapon7=False ' reset weapons, shield, armor, and rings being held/worn
  1352.  Weapon8=False ' reset weapons, shield, armor, and rings being held/worn
  1353.  Weapon9=False ' reset weapons, shield, armor, and rings being held/worn
  1354.  Weapon10=False ' reset weapons, shield, armor, and rings being held/worn
  1355.  UserRecord.MonstersKilled=False ' reset user score
  1356.  If Normal.User=False Then ' check player is Asst. DM or DM or Sysop
  1357.     Outpt=Message1 ' copy death message
  1358.     Call IO.O ' send death message
  1359.     Outpt="You were resurrected!" ' make message
  1360.     Call IO.O ' send message
  1361.     Next.Room=1 ' reset room number
  1362.     Number.Monsters=False ' reset number of monsters in room
  1363.     Call Enter.Room ' send player to room one
  1364.     Exit Sub ' exit routine
  1365.  Endif ' end compare normal user type
  1366.  ' rest of death routine for normal users
  1367.  Stat.Amount=UserRecord.Stats(5) ' store player constitution
  1368.  If Stat.Amount>1 Then ' check constitution positive
  1369.     UserRecord.Stats(5)=Stat.Amount-1 ' store decremented player constitution
  1370.  Endif ' end check constitution
  1371.  Stat.Amount=UserRecord.Stats(6) ' store player piety
  1372.  If Stat.Amount>1 Then ' check piety positive
  1373.     UserRecord.Stats(6)=Stat.Amount-1 ' store player decremented piety
  1374.  Endif ' end check piety
  1375.  If Rnd>.5 Then ' random chance for statistic decrement
  1376.     Stat.Number=Int(Rnd*4+1) ' choose random statistic to decrement
  1377.     Stat.Amount=UserRecord.Stats(Stat.Number) ' store random statistic
  1378.     If Stat.Amount>1 Then ' compare to positive value
  1379.        ' store player decremented statistic
  1380.        UserRecord.Stats(Stat.Number)=Stat.Amount-1
  1381.     Endif ' end compare value
  1382.  Endif ' end random chance
  1383.  Number.Monsters=False ' reset room monsters
  1384.  UserRecord.Poison=False ' reset player poisoned flag
  1385.  Weight=False ' reset player inventory weight
  1386.  For Array.Index=1 To 20 ' loop through player inventory
  1387.     Charges.Number=UserRecord.Charges(Array.Index) ' store inventory charges
  1388.     Index.Number=UserRecord.Inv(Array.Index) ' store inventory number
  1389.     If Index.Number Then ' verify inventory
  1390.        ' falls to ground
  1391.        Call Add.Room.Treasure(Index.Number,Charges.Number,False,Item.Added)
  1392.        If Item.Added=False Then ' return variable for full room
  1393.           Exit For ' exit inventory loop
  1394.        Endif ' end check return variable
  1395.     Endif ' end check inventory
  1396.  Next ' end loop through player inventory
  1397.  For Array.Index=1 To 20 ' loop through player inventory
  1398.     UserRecord.Inv(Array.Index)=False ' set inventory to zero
  1399.     UserRecord.Charges(Array.Index)=False ' set inventory to zero
  1400.  Next ' end loop through inventory
  1401.  Room=1 ' reset player room number
  1402.  Next.Room=1 ' reset next room entry number
  1403.  Outpt=Message1 ' copy death message
  1404.  Call IO.O ' send death message
  1405.  ' calculate player constitution roll
  1406.  Level=UserRecord.Level ' store user level
  1407.  Calculate#=(Int(Rnd*10+10)+UserRecord.Stats(5))>20 ' calculate
  1408.  If Calculate#=False Then ' compare constitution roll
  1409.     Outpt="Constitution roll failed!" ' make message
  1410.     Call IO.O ' send fail message
  1411.     Outpt="You were not resurrected!" ' make message
  1412.     Call IO.O ' send fail message
  1413.     Level=Int(Level/2-.5) ' player loses half levels
  1414.  Else ' end compare constitution roll
  1415.     ' player survives constitution roll
  1416.     Outpt="You were resurrected!" ' make message
  1417.     Call IO.O ' send message
  1418.     If UserRecord.Stats(6)<=1 Then ' compare piety
  1419.        Outpt="Except your piety failed!" ' player loses roll anyway
  1420.        Call IO.O ' send fail message
  1421.        Level=Int(Level/2-.5) ' player loses half levels
  1422.     Else ' compare piety
  1423.        Level=Level-1 ' decrement player level by one
  1424.     Endif ' end compare piety
  1425.  Endif ' end compare constitution roll
  1426.  If Level<False Then ' compare level
  1427.     Level=False ' reset level
  1428.  Endif ' end compare level
  1429.  UserRecord.Level=Level ' store user level
  1430.  Call More.Prompt ' pause for next screen
  1431.  Call Enter.Room ' routine to move player to room number
  1432.  Call Zero.Stats ' routine to clear player statistics
  1433. End Sub ' end routine for dead player
  1434.  
  1435.  Rem * routine to clear player statistics for death.
  1436.  
  1437. Sub Zero.Stats
  1438.  On Local Error Resume Next ' local error resume
  1439.  Call Experience(Calculate#) ' calculate new experience
  1440.  Calculate#=Calculate#-Int(Calculate#/10) ' calculate decremented experience
  1441.  If Calculate#<UserRecord.Experience Then ' compare new experience
  1442.     UserRecord.Experience=Calculate# ' reset experience
  1443.  Endif ' end compare new experience
  1444.  Call Gold(Calculate#) ' calculate new gold
  1445.  Calculate#=Calculate#-Int(Calculate#/10) ' calculate decremented gold
  1446.  If Calculate#<UserRecord.Gold Then ' compare new gold
  1447.     UserRecord.Gold=Calculate# ' reset player gold
  1448.  Endif ' end compare new gold
  1449.  Call New.Stats ' get new statistics for level
  1450.  UserRecord.Flags=UserRecord.Flags And Not Wished ' clear player flags
  1451.  UserRecord.Flags=UserRecord.Flags And Not Rerolled ' clear player flags
  1452.  UserRecord.Flags=UserRecord.Flags And Not Alignmented ' clear player flags
  1453.  For Stats=1 To 7 ' loop through player statistics
  1454.     If UserRecord.Stats(Stats)<=False Then ' compare statistcis to zero
  1455.        UserRecord.Stats(Stats)=1 ' reset statistic
  1456.     Endif ' end compare player statistics
  1457.  Next ' end loop through player statistics
  1458.  Call Put.User.Record ' store player record
  1459. End Sub ' end routine to clear dead player
  1460.  
  1461.  Rem * routine for player to learn a spell chant.
  1462.  Rem * processing variables:
  1463.  Rem *   Learned.Spells - array of 0s and 1s of learned spells.
  1464.  Rem * input variables:
  1465.  Rem *   Parsed.Command1 - contains name of spell to learn.
  1466.  
  1467. Sub Learn.Spell
  1468.  On Local Error Resume Next ' local error resume
  1469.  Spell.Found=False ' flag for spell name found
  1470.  For Spell.Number=1 To Lof(SpellFile)/Len(SpellRecord) ' loop through spells
  1471.     Call Read.Record(SpellFile,Spell.Number) ' get next spell record
  1472.     ' compare spell name with command parameter
  1473.     If Rtrim$(SpellRecord.SpellName)=Lcase$(Parsed.Command1) Then ' compare
  1474.        Spell.Found=True ' set spell flag found
  1475.        Exit For ' exit spell file loop
  1476.     Endif ' end compare spell names
  1477.  Next ' end loop through spell file
  1478.  If Spell.Found=False Then ' compare spell flag
  1479.     Outpt="You can't learn that spell!" ' make message
  1480.     Call IO.O ' send error message
  1481.     Exit Sub ' exit routine
  1482.  Endif ' end compare spell flag
  1483.  If Spell.Number>1024 Then ' compare spell maximum
  1484.     Outpt="You can't learn that spell!" ' make message
  1485.     Call IO.O ' send error message
  1486.     Exit Sub ' exit routine
  1487.  Endif ' end compare spell flag
  1488.  Outpt="Enter chant to learn: " ' format input prompt
  1489.  Call IO.I ' get input spell chant
  1490.  Inpt=Ucase$(Inpt) ' uppercase spell chant input
  1491.  If Rtrim$(SpellRecord.Chant)<>Inpt Then ' compare spell chant entered
  1492.     Outpt="Wrong spell chant!" ' make message
  1493.     Call IO.O ' send error message
  1494.     Exit Sub ' exit routine
  1495.  Endif ' end compare spell chants
  1496.  ' check length of learned spell flags
  1497.  If Spell.Number>Len(Learned.Spells) Then
  1498.     ' append 0s to learned spells
  1499.     Learned.Spells=Learned.Spells+String$(Spell.Number-Len(Learned.Spells),"0")
  1500.  Endif ' end check length of learned spells flags
  1501.  Mid$(Learned.Spells,Spell.Number,1)="1" ' set flag for spell learned
  1502.  Outpt="You now memorize the spell!" ' make message
  1503.  Call IO.O ' send spell message
  1504. End Sub ' end routine to learn spell
  1505.  
  1506.  Rem * routine for preprocessing spell casting.
  1507.  Rem * input variables:
  1508.  Rem *   Require.Chant - set to true if entering the spell chant is required.
  1509.  Rem * output variables:
  1510.  Rem *   Spell.Cast.Type - set to 1=use command, 2=scroll used, 4=cast command.
  1511.  Rem *   Spell.Number - number of the spell being used.
  1512.  Rem *   Spell.Chant - true if spell being used w/o chant.
  1513.  
  1514. Sub Cast.Spell(Require.Chant)
  1515.  On Local Error Resume Next ' local error resume
  1516.  If Weapon2 Then ' check player is holding a weapon
  1517.     Outpt="You must return your weapon first!" ' make message
  1518.     Call IO.O ' send message
  1519.     Exit Sub ' exit routine
  1520.  Endif ' end check weapon held
  1521.  Spell.Cast.Type=False ' reset casting variables
  1522.  Spell.Number=False ' reset casting variables
  1523.  Spell.Chant=False ' reset casting variables
  1524.  If Require.Chant Then ' check if chant required
  1525.     If UserRecord.Magic=False Then ' verify spell points remaining
  1526.        Outpt="You have no more spell points!" ' make message
  1527.        Call IO.O ' send message
  1528.        Exit Sub ' exit routine
  1529.     Endif ' end verify spell points
  1530.     Outpt="Chant? " ' format input prompt
  1531.     Call IO.I ' get player input
  1532.     Inpt=Ucase$(Inpt) ' uppercase input
  1533.     Chant.Found=False ' set spell chant found flag
  1534.     ' loop through all spell records
  1535.     For Spell.Number=1 To Lof(SpellFile)/Len(SpellRecord)
  1536.        Call Read.Record(SpellFile,Spell.Number) ' get spell record
  1537.        Spell.Chant$=SpellRecord.Chant ' store spell chant
  1538.        Spell.Chant$=Rtrim$(Spell.Chant$) ' trim chant
  1539.        Spell.Chant$=Ucase$(Spell.Chant$) ' uppercase chant
  1540.        If Spell.Chant$=Inpt Then ' compare chants
  1541.           If SpellRecord.Psionic=False Then ' check for psionic spell
  1542.              Chant.Found=True ' set spell chant found flag
  1543.              Exit For ' exit spell file loop
  1544.           Endif ' end check psionic spell
  1545.        Endif ' end compare chants
  1546.        Spell.Chant$=SpellRecord.SpellName ' store spell name
  1547.        Spell.Chant$=Rtrim$(Spell.Chant$) ' trim name
  1548.        Spell.Chant$=Ucase$(Spell.Chant$) ' uppercase name
  1549.        If Spell.Chant$=Inpt Then ' compare spell names
  1550.           If SpellRecord.Psionic=False Then ' check for psionic spell
  1551.              ' check learned spells bounds
  1552.              If Spell.Number>1024 Then ' compare spell maximum
  1553.                 Exit For ' exit spell file loop
  1554.              Endif ' end compare spell maximum
  1555.              If Spell.Number<=Len(Learned.Spells) Then
  1556.                 ' check learned flag
  1557.                 If Mid$(Learned.Spells,Spell.Number,1)="1" Then
  1558.                    Chant.Found=True ' set spell chant found flag
  1559.                    Exit For ' exit spell file loop
  1560.                 Endif ' end check learned flag
  1561.              Endif ' end check bounds
  1562.           Endif ' end check for psionic spell
  1563.        Endif ' end compare spell names
  1564.     Next ' end loop through spell file
  1565.     If Chant.Found=False Then ' check spell chant found flag
  1566.        Outpt="Wrong spell chant!" ' make message
  1567.        Call IO.O ' send message
  1568.        Exit Sub ' exit routine
  1569.     Endif ' end check spell chant flag
  1570.     Spell.Cast.Type=Cast.Spell.Type ' store spell type being used
  1571.  Else ' compare chant required
  1572.     Call Find.Inventory ' check magic device being used
  1573.     If Index.Number=False Then ' verify device used
  1574.        Outpt="You can't use that!" ' make message
  1575.        Call IO.O ' send message
  1576.        Exit Sub ' exit routine
  1577.     Endif ' end verify device
  1578.     If TreasureRecord.Potion Then ' check device type
  1579.        Outpt="You can't use that!" ' make message
  1580.        Call IO.O ' send message
  1581.        Exit Sub ' exit routine
  1582.     Endif ' end check device type
  1583.     If TreasureRecord.Edible Then ' check device type
  1584.        Outpt="You can't use that!" ' make message
  1585.        Call IO.O ' send message
  1586.        Exit Sub ' exit routine
  1587.     Endif ' end check device
  1588.     If TreasureRecord.Scroll Then ' check device type
  1589.        Outpt="The scroll disintegrated!" ' make message
  1590.        Call IO.O ' send message
  1591.        Call Discard.Inventory(Array.Number,True) ' remove item from inventory
  1592.        Spell.Cast.Type=Scroll.Spell.Type ' store spell type being used
  1593.     Else ' check device type
  1594.        If TreasureRecord.Spell=False Then ' check device type spell type
  1595.           Outpt="That's not a magical device!" ' make message
  1596.           Call IO.O ' send message
  1597.           Exit Sub ' exit routine
  1598.        Endif ' end check device/spell type
  1599.        If UserRecord.Charges(Array.Number)=False Then ' compare spell charges
  1600.           Outpt="You can't, it's empty!" ' make message
  1601.           Call IO.O ' send message
  1602.           Exit Sub ' exit routine
  1603.        Endif ' end check spell charges
  1604.        Charges.Number=UserRecord.Charges(Array.Number) ' store spell charges
  1605.        Charges.Number=Charges.Number-1 ' decrement charges
  1606.        If Charges.Number<False Then ' compare zero
  1607.           Charges.Number=False ' set to zero
  1608.        Endif ' end compare zero
  1609.        UserRecord.Charges(Array.Number)=Charges.Number ' store spell charges
  1610.        Spell.Cast.Type=Use.Spell.Type ' store spell type being used
  1611.     Endif ' end compare device type
  1612.     Spell.Number=TreasureRecord.Spell ' store spell type
  1613.     Spell.Chant=True ' no chant required flag
  1614.  Endif ' end compare chant required
  1615.  Call Read.Record(SpellFile,Spell.Number) ' get the spell record being used
  1616.  Magic.Spell=SpellRecord.SpellType ' store the spell type being used
  1617.  Multiplier=SpellRecord.Level ' store the spell level
  1618.  Index.Number=False ' reset target variable
  1619.  If Parser Then ' check for second command parameter
  1620.     Parsed.Command1=Parsed.Command2 ' store second parameter
  1621.     Call Numeric ' get pound sign number
  1622.     Call Examine.Treasure ' check for treasure target
  1623.     If Index.Number=False Then ' treasure target found
  1624.        Call Num ' decrement target number
  1625.        Call Examine.Objects ' check for object target
  1626.        If Index.Number>False Then ' check object target found
  1627.           Outpt="Wrong spell target for chant" ' make message
  1628.           Call IO.O ' send message
  1629.           Exit Sub ' exit sub
  1630.        Endif ' end check object target
  1631.     Endif ' end check target
  1632.  Endif ' end check second parameter
  1633.  Call Magic(Spell.Chant) ' routine to use the magic spell
  1634. End Sub ' end spell preprocessing routine
  1635.  
  1636.  Rem * routine to cast a magic spell.
  1637.  Rem * input variables:
  1638.  Rem *   Magic.Spell - number of the spell type.
  1639.  Rem *   Chant.Used - true if spell being used w/o chant
  1640.  Rem *   Spell.Cast.Type - set to 1=use command, 2=scroll used, 4=cast command.
  1641.  Rem *   Spell.Number - number of the spell being used.
  1642.  Rem *   Index.Number - type of spell target.
  1643.  
  1644. Sub Magic(Chant.Used)
  1645.  On Local Error Resume Next ' local error resume
  1646.  Select Case Index.Number ' selection of the target type
  1647.  Case Is>False ' target is an item of treasure
  1648.     Select Case Magic.Spell ' selection of spell type for target of treasure
  1649.     Case Enchant ' enchant
  1650.        If TreasureRecord.Spell=False Then ' check treasure target spell type
  1651.           Outpt="Wrong spell target for chant!" ' make message
  1652.           Call IO.O ' send message
  1653.           Exit Sub ' exit routine
  1654.        Endif ' end check treasure target spell type
  1655.     Case Vigor  ' vigor
  1656.        If TreasureRecord.Vehicle=False Then ' check treasure target vehicle
  1657.           Outpt="Wrong spell target for chant!" ' make message
  1658.           Call IO.O ' send message
  1659.           Exit Sub ' exit routine
  1660.        Endif ' end check treasure target vehicle type
  1661.     Case Else ' check target type
  1662.        If Magic.Spell<>Hiding Then ' check spell type on treasure target
  1663.           Outpt="Wrong spell target for chant!" ' make message
  1664.           Call IO.O ' send message
  1665.           Exit Sub ' exit routine
  1666.        Endif ' end check treasure target type
  1667.     End Select ' end selection of target spell type
  1668.  Case False ' target is not an item of treasure
  1669.     If Parser Then ' check target parameter flag
  1670.        Select Case Magic.Spell ' selection of spells w/ targets
  1671.        Case Offense, Poison, LevelDrain, Befuddled, TurnUndead, Intoxicate
  1672.           Index.Number=False
  1673.        Case Else ' spell w/o target
  1674.           Outpt="Wrong spell target for chant!" ' make message
  1675.           Call IO.O ' send message
  1676.           Exit Sub ' exit routine
  1677.        End Select ' end spell type selection
  1678.     Endif ' end check target parameter
  1679.  End Select ' end target selection type
  1680.  If Chant.Used=False Then ' check spell usage type
  1681.     If Multiplier>UserRecord.Level Then ' compare spell level to player level
  1682.        Outpt="You are not high enough level to cast the spell!" ' message
  1683.        Call IO.O ' send message
  1684.        Exit Sub ' exit routine
  1685.     Endif ' end check spell/player levels
  1686.     If UserRecord.Magic=False Then ' check player magic points remaining
  1687.        Outpt="You have no more spell points!" ' make message
  1688.        Call IO.O ' send message
  1689.        Exit Sub ' exit routine
  1690.     Endif ' end check player magic points
  1691.     ' verify spell can be cast by player class type
  1692.     If (SpellRecord.ClassType And 2^UserRecord.ClassType)=False Then ' verify
  1693.        If Normal.User=True Then ' check player is Asst. DM/DM/Sysop
  1694.           Outpt="Your class can't cast that spell!" ' make message
  1695.           Call IO.O ' send message
  1696.           Exit Sub ' exit routine
  1697.        Endif ' end check player type
  1698.     Endif ' end verify spell type
  1699.     Charges.Number=UserRecord.Magic ' get player magic points
  1700.     ' decrement magic points by spell level
  1701.     Charges.Number=Charges.Number-Multiplier
  1702.     If Charges.Number<False Then ' check zero
  1703.        Charges.Number=False ' set to zero
  1704.     Endif ' end compare zero
  1705.     UserRecord.Magic=Charges.Number ' store player magic points remaining
  1706.  Endif ' end check spell usage type
  1707.  ' check spell ingredients.
  1708.  ' verify spell type uses ingredients
  1709.  If SpellRecord.SpellFlag And Spell.Cast.Type Then
  1710.     For Spell.Index=1 To 5 ' loop through spell ingredients
  1711.        ' get treasure ingredient number
  1712.        Ingredient.Number=SpellRecord.Ingred(Spell.Index)
  1713.        If Ingredient.Number>False And _
  1714.        Ingredient.Number<=Lof(TreasureFile)/Len(TreasureRecord) Then ' bounds
  1715.           Player.Ingredient=False ' player has ingredient flag
  1716.           For Array.Index=1 To 20 ' loop through player inventory
  1717.              ' check player inventory
  1718.              If UserRecord.Inv(Array.Index)=Ingredient.Number Then
  1719.                 Player.Ingredient=True ' set ingredient flag
  1720.                 Exit For ' exit player inventory loop
  1721.              Endif ' end check player inventory is ingredient
  1722.           Next ' end loop through player inventory
  1723.           ' get treasure ingredient record
  1724.           Call Read.Record(TreasureFile,Ingredient.Number)
  1725.           If Player.Ingredient=False Then ' check player has ingredient flag
  1726.              Outpt="You don't have the correct spell ingredients!" ' message
  1727.              Call IO.O ' send message
  1728.              Inpt=TreasureRecord.TreasureName ' get treasure name
  1729.              Inpt=Rtrim$(Inpt) ' trim name
  1730.              Inpt=Lcase$(Inpt) ' lowercase name
  1731.              Outpt="You need "+Inpt+"!" ' make message
  1732.              Call IO.O ' send ingredient message
  1733.              Exit Sub ' exit routine
  1734.           Endif ' end check player ingredient flag
  1735.           ' check ingredient charges
  1736.           If UserRecord.Charges(Array.Index)=False Then
  1737.              Inpt=TreasureRecord.ShortName ' get treasure name
  1738.              Inpt=Rtrim$(Inpt) ' trim name
  1739.              Inpt=Lcase$(Inpt) ' lowercase name
  1740.              Outpt="The "+Inpt+" are used up!" ' make message
  1741.              Call IO.O ' send ingredient message
  1742.              Exit Sub ' exit routine
  1743.           Endif ' end check inrgedient charges
  1744.           ' decrement player ingredient charges
  1745.           UserRecord.Charges(Array.Index)=UserRecord.Charges(Array.Index)-1
  1746.        Endif ' end check file bounds
  1747.     Next ' end loop through spell ingredients
  1748.  Endif ' end verify spell requires ingredients
  1749.  Spell.Name$=SpellRecord.SpellName ' get spell name being cast
  1750.  Spell.Name$=Rtrim$(Spell.Name$) ' trim name
  1751.  Spell.Name$=Lcase$(Spell.Name$) ' lowercase name
  1752.  If Instr("aeiou",Left$(Spell.Name$,1)) Then ' check spell vowel
  1753.     Spell.Name$=" an "+Spell.Name$ ' append vowel
  1754.  Else ' check vowel
  1755.     Spell.Name$=" a "+Spell.Name$ ' append vowel
  1756.  Endif ' end check vowel spelling
  1757.  Outpt=SpellRecord.Desc ' get spell long cast description
  1758.  Outpt=Rtrim$(Outpt) ' trim description
  1759.  If Outpt=Nul Then ' check description length
  1760.     Outpt="You cast"+Spell.Name$+" spell!" ' make default cast description
  1761.  Endif ' end check description length
  1762.  Call IO.O ' send spell cast message
  1763.  Call Read.Room.Record(Room) ' get current room record
  1764.  Action.Number=RoomRecord.Action ' get room action number
  1765.  ' check file bounds
  1766.  If Action.Number>False And _
  1767.  Action.Number<=Lof(ActionFile)/Len(ActionRecord) Then
  1768.     Call Read.Record(ActionFile,Action.Number) ' read action record
  1769.     If ActionRecord.SpellTrigger=Spell.Number Then ' check for spell trigger
  1770.        Action1$="As the spell is cast," ' action message
  1771.        Action2$="You are hit for" ' action message
  1772.        Call Actions(Action1$,Action2$) ' routine for activated action
  1773.     Endif ' end check room for action triggered
  1774.  Endif ' end check file bounds
  1775.  ' check for magic traps in room
  1776.  For Array.Index=1 To 20 ' loop through room treasure
  1777.     If RoomRecord.Flags(Array.Index)=Magic.Trap Then ' check room for trap
  1778.        If RoomRecord.Treasure(Array.Index)=True Then ' check trap triggered
  1779.           If UserRecord.Stats(2)<Int(Rnd*6+10) Then ' random chance for trap
  1780.              ' hits on player for magical trap
  1781.              Calculate#=Cdbl(Int(Rnd*10+UserRecord.Level)* _
  1782.              RoomRecord.TreCharges(Array.Index))
  1783.              RoomRecord.Treasure(Array.Index)=False ' reset room trap
  1784.              RoomRecord.TreCharges(Array.Index)=False ' reset room trap
  1785.              RoomRecord.Flags(Array.Index)=False ' reset room trap
  1786.              Call Share.Room.Record(Room) ' write new room record
  1787.              Outpt="You triggered a magical trap!" ' message
  1788.              Call IO.O ' send trap message
  1789.              Outpt="The trap hit you for" ' hits message
  1790.              Call Hit.Player(Calculate#) ' routine to hit player
  1791.              Exit For ' exit room trap loop
  1792.           Endif ' end random chance
  1793.        Endif ' end trap trigger
  1794.     Endif ' end room trap
  1795.  Next ' end loop through room
  1796.  ' selections of the actual spell cast subroutines
  1797.  Select Case Magic.Spell ' select the spell type number
  1798.  Case Offense, Poison, LevelDrain, Befuddled, TurnUndead, Intoxicate
  1799.    Call Attack.Monster ' spell cast on monster target
  1800.  Case Enchant ' enchant (heal magic points)
  1801.     If Index.Number>False Then ' enchant on a target
  1802.        Call Read.Record(SpellFile,TreasureRecord.Spell) ' get target spell
  1803.        If SpellRecord.SpellType=4 Then ' compare target to wish device
  1804.           Outpt="You can't recharge that!" ' make message
  1805.           Call IO.O ' send message
  1806.           Exit Sub ' exit routine
  1807.        Endif ' end compare wish item
  1808.        Calculate#=UserRecord.Charges(Array.Number) ' get charges of item
  1809.        Calculate#=Calculate#+UserRecord.Level ' calculate new item charges
  1810.        If Calculate#>MaxInt Then ' compare maximum integer
  1811.           Calculate#=MaxInt ' reduce to maximum integer
  1812.        Endif ' end compare maximum integer
  1813.        ' compare maximum treasure charges
  1814.        If Calculate#>TreasureRecord.Charges Then
  1815.           ' reduce to maximum treasure charges
  1816.           Calculate#=TreasureRecord.Charges
  1817.        Endif ' end compare charges
  1818.        UserRecord.Charges(Array.Number)=Cint(Calculate#) ' store new charges
  1819.        Outpt="You recharge it!" ' make message
  1820.        Call IO.O ' send message
  1821.     Else ' compare enchant on a target
  1822.        ' calculate player enchant
  1823.        Calculate#=UserRecord.Magic+UserRecord.Level+Multiplier ' calculate
  1824.        If Calculate#>MaxInt Then ' compare maximum integer
  1825.           Calculate#=MaxInt ' set to maximum integer
  1826.        Endif ' end compare maximum integer
  1827.        UserRecord.Magic=Cint(Calculate#) ' store player magic points
  1828.        Call New.Stats ' update player statistics
  1829.        Outpt="You now have"+Str$(UserRecord.Magic)+" magic points!" ' message
  1830.        Call IO.O ' send message
  1831.     Endif ' end compare enchant target
  1832.  Case Bless ' bless (heal piety)
  1833.     Outpt="Nothing happened.." ' default bless message
  1834.     If UserRecord.Stats(6)<MaxStat Then ' compare player piety points
  1835.        UserRecord.Stats(6)=UserRecord.Stats(6)+1 ' increment player piety
  1836.        Outpt="You feel a magical glow about you!" ' message
  1837.     Endif ' end compare piety
  1838.     Call IO.O ' send piety message
  1839.  Case Wish ' wish
  1840.     ' compare spell cast type
  1841.     If Spell.Cast.Type=Use.Spell.Type Or Spell.Cast.Type= _
  1842.     Scroll.Spell.Type Then ' compare
  1843.        ' reset player wish flag
  1844.        UserRecord.Flags=UserRecord.Flags And Not Wished ' reset
  1845.     Endif ' end compare spell cast type
  1846.     Graphics.Off=True ' reset color
  1847.     Outpt="The Ghods thunder.." ' message
  1848.     Call IO.O ' send ghod message
  1849.     Outpt="   What do you wish for?" ' format input prompt
  1850.     Graphics.Off=False ' reset color
  1851.     Call IO.I ' get player input
  1852.     Stored.Parsed.Command2=Inpt ' store item wish name
  1853.     Parsed.Command1=Stored.Parsed.Command2 ' store item wish name
  1854.     Call Numeric ' parse out pound sign
  1855.     Inpt=Parsed.Command1 ' store parsed item wish name
  1856.     Inpt=Lcase$(Inpt) ' lowercase item
  1857.     Call Drop(False) ' routine to get item from treasure file
  1858.  Case Vigor ' vigor (heal fatigue)
  1859.     If Index.Number>False Then ' check treasure target
  1860.        Call Read.Room.Record(Room) ' get current room
  1861.        Calculate#=RoomRecord.TreCharges(Array.Number) ' get vehicle hits
  1862.        Calculate#=Calculate#+UserRecord.Level*2 ' increment vehicle hits
  1863.        If Calculate#>MaxInt Then ' compare maximum integer
  1864.           Calculate#=MaxInt ' reset to maximum integer
  1865.        Endif ' end compare maximum integer
  1866.        Vehicle.Hits=Cint(Calculate#) ' convert to integer
  1867.        ' compare maximum vehicle hits
  1868.        If Vehicle.Hits>TreasureRecord.VehicleHits Then
  1869.           ' reset to maximum vehicle hits
  1870.           Vehicle.Hits=TreasureRecord.VehicleHits
  1871.        Endif ' end compare vehicle hits
  1872.        ' store new vehicle hits
  1873.        RoomRecord.TreCharges(Array.Number)=Vehicle.Hits
  1874.        Call Share.Room.Record(Room) ' write room record
  1875.        Outpts=TreasureRecord.ShortName ' get vehicle name
  1876.        Outpts=Rtrim$(Outpts) ' trim name
  1877.        Outpts=Lcase$(Outpts) ' lowercase name
  1878.        Outpt="The "+Outpts+" now has"+Str$(Vehicle.Hits)+" hits!" ' message
  1879.        Call IO.O ' send healed vehicle message
  1880.     Else ' compare target
  1881.        ' calculate player fatigue increase
  1882.        Calculate#=UserRecord.Fatigue+UserRecord.Level+Multiplier ' calculate
  1883.        If Calculate#>MaxInt Then ' compare to max integer
  1884.           Calculate#=MaxInt ' set to max integer
  1885.        Endif ' end compare max integer
  1886.        UserRecord.Fatigue=Cint(Calculate#) ' set player fatigue to new value
  1887.        Call New.Stats ' routine to update player statistics
  1888.        Outpt="You now have"+Str$(UserRecord.Fatigue)+" fatigue points!"
  1889.        Call IO.O ' send vigor message
  1890.     Endif ' end compare target
  1891.  Case Heal ' (heal vitality)
  1892.     ' calculate player vitality increase
  1893.     Calculate#=UserRecord.Vitality+UserRecord.Level+Multiplier ' calculate
  1894.     If Calculate#>MaxInt Then ' compare to max integer
  1895.        Calculate#=MaxInt ' set to max integer
  1896.     Endif ' end compare max integer
  1897.     UserRecord.Vitality=Cint(Calculate#) ' store new vitality
  1898.     Call New.Stats ' routine to update player statistics
  1899.     Outpt="You now have"+Str$(UserRecord.Vitality)+" vitality points!"
  1900.     Call IO.O ' send new vitality message
  1901.  Case CurePoison ' cure poison
  1902.     Outpt="Nothing happened.." ' default message
  1903.     If UserRecord.Poison Then ' check player is poisoned
  1904.        UserRecord.Poison=False ' clear player poisoned flag
  1905.        Outpt="The poison disappeared!" ' message
  1906.     Endif ' end check player poisoned
  1907.     Call IO.O ' send poison message
  1908.  Case Teleport ' teleport spell
  1909.     Next.Room=SpellRecord.Teleport ' copy teleportation room ro next room
  1910.     Teleported=True ' set teleporting flag
  1911.     Call Enter.Room ' routine to move player to new room
  1912.  Case PassDoor ' open nearby doors
  1913.     Pass.Door=True ' set passdoor flag
  1914.     Outpt="You hear a click!" ' passdoor message
  1915.     Call IO.O ' send passdoor message
  1916.  Case Conjure ' call up random monster
  1917.     For Array.Index=1 To Monclass.Max ' loop through all monster classes
  1918.        ' get a random monster choice
  1919.        Choice=Monster.Class(Array.Index,Int(Rnd*10+1))
  1920.        If Choice Then ' verify choice exists
  1921.           Call Read.Record(MonsterFile,Choice) ' get monster record
  1922.           ' compare monster to player level
  1923.           If MonsterRecord.Level=UserRecord.Level Then ' compare
  1924.              Call Get.Monster ' get the monster
  1925.              Exit Sub ' exit routine
  1926.           Endif ' end compare levels
  1927.        Endif ' end verify choice
  1928.     Next ' end loop through monster classes
  1929.     Outpt="Nothing conjures.." ' default message
  1930.     Call IO.O ' send message
  1931.  Case Psionic ' psionics
  1932.     Outpt="You can't cast a psi spell!" ' error message
  1933.     Call IO.O ' send error message
  1934.  Case DetectLock ' detect hidden or invisible doors
  1935.     For Array.Index=1 To 20 ' loop through room objects
  1936.        Object.Number=RoomRecord.Object(Array.Index) ' get room object nummber
  1937.        If Object.Number>False And _
  1938.        Object.Number<=Lof(ObjectFile)/Len(ObjectRecord) Then ' file bounds
  1939.           Call Read.Record(ObjectFile,Object.Number) ' get object record
  1940.           ' compare object invisible or hidden
  1941.           If ObjectRecord.Invisible Or ObjectRecord.Hidden Then ' compare
  1942.              Outpt="You detect hidden objects here!" ' display message
  1943.              Call IO.O ' send message
  1944.              Exit Sub ' exit routine
  1945.           Endif ' end compare object type
  1946.        Endif ' end check file bounds
  1947.     Next ' end loop through room objects
  1948.     Outpt="You detect nothing.." ' default message
  1949.     Call IO.O ' send message
  1950.  Case DetectEvil ' determine which direction the highest class monsters are
  1951.     High.Class=False ' highest monster class so far
  1952.     Monster.Direction=False ' direction of monster class
  1953.     For Direction.Number=1 To 12 ' loop through all room directions
  1954.        Call Read.Room.Record(Room) ' get current room record
  1955.        ' get next room direction
  1956.        Next.Direction!=RoomRecord.Direct(Direction.Number)
  1957.        If Next.Direction! Then ' compare room direction
  1958.           Call Read.Room.Record(Next.Direction!) ' get next room record
  1959.           ' compare monster class higher
  1960.           If RoomRecord.MonsterClass>High.Class Then ' compare
  1961.              High.Class=RoomRecord.MonsterClass ' store higher monster class
  1962.              Monster.Direction=Direction.Number ' store direction
  1963.           Endif ' end compare monster class
  1964.        Endif ' end compare room direction
  1965.     Next ' end loop through room directions
  1966.     Call Read.Room.Record(Room) ' get current room number
  1967.     If Monster.Direction Then ' verify room direction found w/ monsters
  1968.        ' make display message with room direction
  1969.        Outpt="You detect evil going "+Rtrim$(Direction(Monster.Direction))+"!"
  1970.     Else ' verify direction
  1971.        Outpt="You detect no evil presence.." ' make display message
  1972.     Endif ' end verify room direction
  1973.     Call IO.O ' send display message
  1974.  Case DetectTrap ' find traps in room objects
  1975.     For Array.Index=1 To 20 ' loop through room objects
  1976.        Object.Number=RoomRecord.Object(Array.Index) ' get object number
  1977.        If Object.Number>False And _
  1978.        Object.Number<=Lof(ObjectFile)/Len(ObjectRecord) Then ' file bounds
  1979.           Call Read.Record(ObjectFile,Object.Number) ' get object record
  1980.           If ObjectRecord.Trap Then ' verify object is a trap
  1981.              Outpt="You detect traps here!" ' make display message
  1982.              Call IO.O ' send display message
  1983.              Exit Sub ' exit routine
  1984.           Endif ' end verify object trap
  1985.        Endif ' end check file bounds
  1986.     Next ' end loop through room objects
  1987.     Outpt="You detect nothing.." ' make default display message
  1988.     Call IO.O ' send default message
  1989.  Case SetTrap ' sets a magical trap in room
  1990.     Trap.Set=False ' room full flag
  1991.     For Treasure.Number=1 To 20 ' loop through room treasure
  1992.        ' check empty treasure in room
  1993.        If RoomRecord.Treasure(Treasure.Number)=False Then
  1994.           Trap.Set=True ' set room full flag
  1995.           Exit For ' exit loop
  1996.        Endif ' end check empty treasure
  1997.     Next ' end loop room
  1998.     If Trap.Set=False Then ' check room full flag
  1999.        Outpt="You didn't set the trap!" ' make display message
  2000.        Call IO.O ' send message
  2001.        Exit Sub ' exit routine
  2002.     Endif ' end check room flag
  2003.     If UserRecord.Stats(2)<Int(Rnd*5+5) Then ' calculate random percent
  2004.        Outpt="You didn't set the trap!" ' make display message
  2005.        Call IO.O ' send message
  2006.        Exit Sub ' exit routine
  2007.     Endif ' end calculate percent
  2008.     ' calculate trap percent
  2009.     If UserRecord.Stats(2)+UserRecord.Stats(3)<Int(Rnd*10+5) Then ' calculate
  2010.        Outpt="The trap explodes in your face!" ' make display message
  2011.        Call IO.O ' send message
  2012.        Calculate#=Cdbl(Int(Rnd*10+2)*UserRecord.Level) ' get hits on player
  2013.        Outpt="The trap hit you for" ' death message
  2014.        Call Hit.Player(Calculate#) ' routine to hit player
  2015.        Exit Sub ' exit routine
  2016.     Endif ' end trap percent
  2017.     RoomRecord.Treasure(Treasure.Number)=True ' set the trap activated
  2018.     RoomRecord.TreCharges(Treasure.Number)=UserRecord.Level ' set trap level
  2019.     RoomRecord.Flags(Treasure.Number)=Magic.Trap ' set trap flag
  2020.     Call Share.Room.Record(Room) ' write room record
  2021.     Outpt="You set a magical trap!" ' make display message
  2022.     Call IO.O ' send message
  2023.  Case Hiding ' spell to hide an item in room
  2024.     Item.Hidden=False ' room full flag
  2025.     For Array.Index=1 To 20 ' loop through room treasure
  2026.        ' found empty room treasure
  2027.        If RoomRecord.Treasure(Array.Index)=False Then
  2028.           Item.Hidden=True ' set room full flag
  2029.           Exit For ' exit loop
  2030.        Endif ' end check empty treasure
  2031.     Next ' end loop through room
  2032.     If Item.Hidden=False Then ' check room full flag
  2033.        Outpt="You didn't hide the object!" ' make display message
  2034.        Call IO.O ' send message
  2035.        Exit Sub ' exit routine
  2036.     Endif ' end check room full flag
  2037.     If UserRecord.Stats(2)<Int(Rnd*5+4) Then ' calculate random percent
  2038.        Outpt="You didn't hide the object!" ' make display message
  2039.        Call IO.O ' send message
  2040.        Exit Sub ' exit routine
  2041.     Endif ' end random percent
  2042.     ' remove item from player inventory
  2043.     Call Discard.Inventory(Array.Number,True)
  2044.     RoomRecord.Treasure(Array.Index)=Index.Number ' add item to room
  2045.     ' add item charges to room
  2046.     RoomRecord.TreCharges(Array.Index)=Charges.Number
  2047.     RoomRecord.Flags(Array.Index)=Magically.Hidden ' set magically hidden flag
  2048.     Call Share.Room.Record(Room) ' write room record
  2049.     Outpt="You hide the object magically!" ' make display message
  2050.     Call IO.O ' send message
  2051.  Case Search ' displays magically hidden objects in room
  2052.     Graphics.Off=True ' reset color
  2053.     Outpt="You find " ' make first string part
  2054.     Carriage.Return=True ' disable cr/lf
  2055.     Call IO.O ' send output
  2056.     Items.Displayed=False ' items displayed counter
  2057.     Item.Displayed=False ' item displayed flag
  2058.     Outpt=Nul ' reset output string
  2059.     For Array.Index=1 To 20 ' loop through room treasure
  2060.        Inpt=Nul ' next item string
  2061.        ' check hidden flag
  2062.        If RoomRecord.Flags(Array.Index)=Magically.Hidden Then
  2063.           ' store treasure number
  2064.           Treasure.Number=RoomRecord.Treasure(Array.Index)
  2065.           If Treasure.Number>False And _
  2066.           Treasure.Number<=Lof(TreasureFile)/Len(TreasureRecord) Then ' bounds
  2067.              Call Read.Record(TreasureFile,Treasure.Number) ' get treasure
  2068.              Inpt=TreasureRecord.TreasureName ' store treasure name
  2069.              Inpt=Rtrim$(Inpt)+"[inv]" ' append treasure name
  2070.           Endif ' end check file bounds
  2071.        Endif ' end check treasure magically hidden flag
  2072.        If Outpt<>Nul And Inpt<>Nul Then ' check next output item
  2073.           Carriage.Return=True ' disable cr/lf
  2074.           Call IO.O ' send item to output
  2075.           ' increment items displayed counter
  2076.           Items.Displayed=Items.Displayed+1
  2077.        Endif ' end check output item
  2078.        If Inpt<>Nul Then ' check last item output
  2079.           Item.Displayed=True ' set item displayed flag
  2080.           Outpt=Inpt+", " ' append comma
  2081.        Endif ' end check items
  2082.     Next ' end loop through room
  2083.     If Item.Displayed=False Then ' check item displayed flag
  2084.        Outpt="nothing special.." ' default display message
  2085.     Endif ' end check item flag
  2086.     If Item.Displayed And Outpt<>Nul Then ' check item flag
  2087.        Outpt=Left$(Outpt,Len(Outpt)-2)+"." ' trim comma, add period
  2088.        If Items.Displayed>1 Then ' check number of items displayed
  2089.           Outpt="and "+Outpt ' append to string
  2090.        Endif ' end check item number
  2091.     Endif ' end check items
  2092.     Call IO.O ' send output
  2093.     Graphics.Off=False ' reset color
  2094.  Case Invisibility ' normal player invisibility spell
  2095.     Level=Int((UserRecord.Level+2)/Room.Health.Rate) ' calculate percent
  2096.     If Level>False Then ' check percent for invisibility
  2097.        Invisible=Level ' set invisibility counter
  2098.        UserRecord.Invisible=True ' set player record invisible flag
  2099.        Outpt="You are now invisible!" ' make display message
  2100.     Else ' check invisible percent
  2101.        Outpt="Didn't work!" ' default display message
  2102.     Endif ' end check invisible percent
  2103.     Call IO.O ' send display message
  2104.  Case Identify ' spell to display monster stattistics
  2105.     Parsed.Command1=Last.Monster ' get parameter in monster name
  2106.     Call Check.Monster ' check monster name
  2107.     If Monster.Number=False Then ' compare monster number found
  2108.        Outpt="You are not fighting a monster now!" ' make error message
  2109.        Call IO.O ' send message
  2110.        Exit Sub ' exit routine
  2111.     Endif ' end compare monster number
  2112.     Graphics.Off=True ' reset color
  2113.     Call The.Or.An ' get prefix
  2114.     Outpts=MonsterArray(Monster.Number).MonsterName ' store monster name
  2115.     Outpts=Rtrim$(Outpts) ' trim name
  2116.     Outpts=Lcase$(Outpts) ' lowercase name
  2117.     Level=MonsterArray(Monster.Number).Level ' store monster level
  2118.     ' format message with monster to player level
  2119.     Outpt="You are fighting "+Prefix1+Outpts+ _
  2120.     "(level"+Str$((Level-1)*2+1)+" to"+Str$(Level*2)+")"
  2121.     Call IO.O ' send level message
  2122.     Outpt="It has"+Str$(MonsterArray(Monster.Number).Hits)+" hits."
  2123.     Call IO.O ' display message of monster hit points
  2124.     Outpt="It has"+Str$(MonsterArray(Monster.Number).Experience)+" experience."
  2125.     Call IO.O ' display message of monster experience
  2126.     Outpt="It has"+Str$(MonsterArray(Monster.Number).Gold)+" gold."
  2127.     Call IO.O ' display message of monster gold
  2128.     Spell.Number=MonsterArray(Monster.Number).Spell ' get monster spell type
  2129.     ' file bounds
  2130.     If Spell.Number>False And _
  2131.     Spell.Number<=Lof(SpellFile)/Len(SpellRecord) Then
  2132.        Call Read.Record(SpellFile,Spell.Number) ' get spell record
  2133.        ' format message with spell monster can cast
  2134.        Outpt="It can cast "+Rtrim$(SpellRecord.SpellName)+" spells."
  2135.        Call IO.O ' send spell message
  2136.     Endif ' end check file bounds
  2137.     If MonsterArray(Monster.Number).Poison Then ' check poisonous monster
  2138.        Outpt="It can poison." ' make message
  2139.        Call IO.O ' send message
  2140.     Endif ' end check poisonous monster
  2141.     If MonsterArray(Monster.Number).LevelDrain Then ' check undead monster
  2142.        Outpt="It can drain levels." ' make message
  2143.        Call IO.O ' send message
  2144.     Endif ' end check undead monster
  2145.     If MonsterArray(Monster.Number).Psionic Then ' check psionic monster
  2146.        Outpt="It can cast psi spells." ' make message
  2147.        Call IO.O ' send message
  2148.     Endif ' end check psionic monster
  2149.     If MonsterArray(Monster.Number).Magic Then ' compare magical monster
  2150.        Outpt="It's magical." ' make message
  2151.        Call IO.O ' send message
  2152.     Endif ' end check magical monster
  2153.     If MonsterArray(Monster.Number).Block Then ' check monster blocks
  2154.        Outpt="It blocks exits." ' make message
  2155.        Call IO.O ' send message
  2156.     Endif ' end check monster blocks
  2157.     If MonsterArray(Monster.Number).Prevent Then ' check monster takes
  2158.        Outpt="It prevents treasure take." ' make message
  2159.        Call IO.O ' send message
  2160.     Endif ' end check monster takes
  2161.     If MonsterArray(Monster.Number).Follow Then ' check monster follows
  2162.        Outpt="It follows users." ' make message
  2163.        Call IO.O ' send message
  2164.     Endif ' end check monster follows
  2165.     If MonsterArray(Monster.Number).Jail Then ' check monster jails
  2166.        Outpt="It jails attacker." ' make message
  2167.        Call IO.O ' send message
  2168.     Endif ' end check monster jails
  2169.     If MonsterArray(Monster.Number).Teleport Then ' check monster teleports
  2170.        Outpt="It can teleport." ' make message
  2171.        Call IO.O ' send message
  2172.     Endif ' end check monster teleports
  2173.     Graphics.Off=False ' reset color
  2174.  Case Enlighten ' locates hidden objects in room
  2175.     Graphics.Off=True ' reset color
  2176.     Outpt="You see " ' make first output string
  2177.     Carriage.Return=True ' disable cr/lf
  2178.     Call IO.O ' output first string
  2179.     Items.Displayed=False ' items displayed counter
  2180.     Item.Displayed=False ' item displayed flag
  2181.     Outpt=Nul ' reset output string
  2182.     For Array.Index=1 To 20 ' loop through room treasure
  2183.        Inpt=Nul ' reset last item string
  2184.        ' compare item hidden
  2185.        If RoomRecord.Flags(Array.Index)=Hidden.Object Then
  2186.           ' store treasure number
  2187.           Treasure.Number=RoomRecord.Treasure(Array.Index)
  2188.           If Treasure.Number>False And _
  2189.           Treasure.Number<=Lof(TreasureFile)/Len(TreasureRecord) Then ' bounds
  2190.              Call Read.Record(TreasureFile,Treasure.Number) ' get treasure
  2191.              Inpt=TreasureRecord.TreasureName ' get treasure name
  2192.              Inpt=Rtrim$(Inpt)+"[inv]" ' append to name
  2193.           Endif ' end check file bounds
  2194.        Endif ' end compare hidden item
  2195.        If Outpt<>Nul And Inpt<>Nul Then ' check next item display
  2196.           Carriage.Return=True ' disable cr/lf
  2197.           Call IO.O ' send item display
  2198.           ' increment items displayed counter
  2199.           Items.Displayed=Items.Displayed+1
  2200.        Endif ' end check items
  2201.        If Inpt<>Nul Then ' check last item displayed
  2202.           Item.Displayed=True ' set item displayed flag
  2203.           Outpt=Inpt+", " ' append comma
  2204.        Endif ' end check item
  2205.     Next ' end loop through room
  2206.     If Item.Displayed=False Then ' check item displayed flag
  2207.        Outpt="nothing special.." ' make message
  2208.     Endif ' end check item display flag
  2209.     If Item.Displayed And Outpt<>Nul Then ' check items displayed
  2210.        Outpt=Left$(Outpt,Len(Outpt)-2)+"." ' trim comma, add period
  2211.        If Items.Displayed>1 Then ' check number of items
  2212.           Outpt="and "+Outpt ' append to string
  2213.        Endif ' end check number of items
  2214.     Endif ' end check items
  2215.     Call IO.O ' send last output string
  2216.     Graphics.Off=False ' reset color
  2217.  Case Illuminate ' searches room for magic traps
  2218.     Graphics.Off=True ' reset color
  2219.     Outpt="You see " ' set first output string
  2220.     Carriage.Return=True ' disable cr/lf
  2221.     Call IO.O ' send first string
  2222.     Items.Displayed=False ' set items displayed counter
  2223.     Item.Displayed=False ' set item displayed flag
  2224.     Outpt=Nul ' reset first item string
  2225.     For Array.Index=1 To 20 ' loop through all room treasure
  2226.        Inpt=Nul ' set next item displayed
  2227.        ' compare treasure magic trap
  2228.        If RoomRecord.Flags(Array.Index)=Magic.Trap Then
  2229.           If RoomRecord.Treasure(Array.Index)=True Then ' check trap active
  2230.              Inpt="a magical trap " ' make display message
  2231.              ' append magic trap hits to message
  2232.              Inpt=Inpt+"["+ _
  2233.              Mid$(Str$(RoomRecord.TreCharges(Array.Index)),2)+" hits]"
  2234.           Endif ' end check active trap
  2235.        Endif ' end compare magic trap
  2236.        If Outpt<>Nul And Inpt<>Nul Then ' check next item display
  2237.           Carriage.Return=True ' disable cr/lf
  2238.           Call IO.O ' send item output
  2239.           ' increment items displayed counter
  2240.           Items.Displayed=Items.Displayed+1
  2241.        Endif ' end check next item
  2242.        If Inpt<>Nul Then ' check items
  2243.           Item.Displayed=True ' set item displayed flag
  2244.           Outpt=Inpt+", " ' append comma
  2245.        Endif ' end check items
  2246.     Next ' end loop through room
  2247.     If Item.Displayed=False Then ' compare item displayed flag
  2248.        Outpt="nothing special.." ' make display message
  2249.     Endif ' end check item displayed flag
  2250.     If Outpt<>Nul Then ' check last item
  2251.        Outpt=Left$(Outpt,Len(Outpt)-2)+"." ' trim comma, add period
  2252.        If Items.Displayed>1 Then ' check number of items displayed
  2253.           Outpt="and "+Outpt ' append to string
  2254.        Endif ' end check number of items
  2255.     Endif ' end check items
  2256.     Call IO.O ' send last string
  2257.     Graphics.Off=False ' reset color
  2258.  Case Psyche ' heal psionic points
  2259.     ' calculate psionic points
  2260.     Calculate#=UserRecord.Psionic+UserRecord.Level+Multiplier ' calculate
  2261.     If Calculate#>MaxInt Then ' check max integer
  2262.        Calculate#=MaxInt ' set to max integer
  2263.     Endif ' end check max integer
  2264.     UserRecord.Psionic=Cint(Calculate#) ' store players new psionic points
  2265.     Call New.Stats ' routine to update player statistics
  2266.     Outpt="You now have"+Str$(UserRecord.Psionic)+" psionic points!" ' message
  2267.     Call IO.O ' send display message
  2268.  Case Else ' any other spell type
  2269.     Outpt="You can't cast that spell!" ' make error message
  2270.     Call IO.O ' send message
  2271.  End Select ' end selection of spell type number
  2272. End Sub ' end routine to cast magic spell
  2273.  
  2274.  Rem * routine to use psionic spell.
  2275.  Rem * processing variables:
  2276.  Rem *   Psi.Mode.Type - psi mode 1 or 2 (attack/defense).
  2277.  Rem * output variables:
  2278.  Rem *   Psi.Attack.Mode - level of psi spell.
  2279.  Rem *   Psi.Defense.Mode - level of psi spell.
  2280.  
  2281. Sub Psi.Mode
  2282.  On Local Error Resume Next ' local error resume
  2283.  Select Case Lcase$(Parsed.Command1) ' selection of command parameter
  2284.  Case "attack" ' attack command
  2285.     Psi.Mode.Type=PsiAttack ' store psi attack
  2286.  Case "defense" ' defense command
  2287.     Psi.Mode.Type=PsiDefense ' store psi defense
  2288.  Case Else ' other
  2289.     Outpt="You can only use psi mode attack or defense!" ' make message
  2290.     Call IO.O ' send error message
  2291.     Exit Sub ' exit routine
  2292.  End Select ' end psi type selection
  2293.  Outpt="Psi spell? " ' format input prompt
  2294.  Call IO.I ' get input
  2295.  Inpt=Ucase$(Inpt) ' uppercase input
  2296.  Inpt=Rtrim$(Inpt) ' trim input
  2297.  Spell.Found=False ' psi spell found flag
  2298.  ' loop through all spell records
  2299.  For Spell.Number=1 To Lof(SpellFile)/Len(SpellRecord)
  2300.     Call Read.Record(SpellFile,Spell.Number) ' get spell record
  2301.     Outpt=SpellRecord.Chant ' store spell chant
  2302.     Outpt=Rtrim$(Outpt) ' trim chant
  2303.     If Outpt=Inpt Then ' compare chant to input chant
  2304.        If SpellRecord.Psionic Then ' check spell is psi spell
  2305.           Spell.Found=True ' set psi spell flag found
  2306.           Exit For ' exit spell file loop
  2307.        Endif ' end check psi spell
  2308.     Endif ' end check chants
  2309.  Next ' end spell file loop
  2310.  If Spell.Found=False Then ' check psi spell found flag
  2311.     Outpt="Unknown psi spell!" ' make message
  2312.     Call IO.O ' send error message
  2313.     Exit Sub ' exit routine
  2314.  Endif ' end check psi spell flag
  2315.  Spell.Name$=SpellRecord.SpellName ' store psi spell name
  2316.  Spell.Name$=Rtrim$(Spell.Name$) ' trim name
  2317.  Spell.Name$=Lcase$(Spell.Name$) ' lowercase name
  2318.  If Psi.Mode.Type<>SpellRecord.PsionicMode Then ' verify psi spell mode
  2319.     Outpt="Incorrect spell for psi mode!" ' make message
  2320.     Call IO.O ' send error message
  2321.     Exit Sub ' exit routine
  2322.  Endif ' end verify psi spell mode
  2323.  Level=SpellRecord.Level ' store psi spell level
  2324.  If UserRecord.Psionic<=False Then ' check player psionic points remaining
  2325.     Outpt="You have no more psi points!" ' make message
  2326.     Call IO.O ' send error message
  2327.     Exit Sub ' exit routine
  2328.  Endif ' end check player psionic points
  2329.  Charges.Number=UserRecord.Psionic ' store player psionic points remaining
  2330.  ' decrement player psionic points by level of psi spell
  2331.  Charges.Number=Charges.Number-Level
  2332.  If Charges.Number<False Then ' compare to zero
  2333.     Charges.Number=False ' reset to zero
  2334.  Endif ' end compare zero
  2335.  UserRecord.Psionic=Charges.Number ' store player psionic points remaining
  2336.  Outpt="You cast a "+Spell.Name$+" psi spell!" ' make message
  2337.  Call IO.O ' send psi spell cast message
  2338.  Select Case Psi.Mode.Type ' selection of psi spell type
  2339.  Case PsiAttack ' attack mode
  2340.     Psi.Attack.Mode=Level ' set psi attack mode to psi spell level
  2341.     Parsed.Command1=Last.Monster ' store last monster attacked
  2342.     Call Attack.Monster ' attack monster
  2343.  Case PsiDefense ' defense mode
  2344.     Psi.Defense.Mode=Level ' set psi defense mode to psi spell level
  2345.     Outpt="Your psi defense mode is now active!" ' make message
  2346.     Call IO.O ' send psi message
  2347.  End Select ' end selection of psi spell type
  2348. End Sub ' end routine to cast a psi spell
  2349.  
  2350.  Rem * routine to get default monster name
  2351.  Rem * output variables:
  2352.  Rem *   Monster.Found - true for the first monster
  2353.  Rem *   Monster.Number - index of monster
  2354.  Rem *   Last.Monster - name of monster
  2355.  
  2356. Sub Get.Last.Monster(Monster.Found)
  2357.  On Local Error Resume Next ' local error resume
  2358.  Monster.Found=False ' reset return flag
  2359.  For Array.Number=1 To Number.Monsters ' search through monsters in room
  2360.     If MonsterArray(Array.Number).Magic>=False Then ' check monster magical
  2361.        If MonsterArray(Array.Number).Permanent>=True Then ' check permanent
  2362.           Word.Parse1=False ' reset parsing flag
  2363.           Word.Parse2=False ' reset parsing flag
  2364.           Outpts=MonsterArray(Array.Number).MonsterName ' get monster name
  2365.           Outpts=Rtrim$(Outpts) ' trim name
  2366.           Outpts=Ucase$(Outpts) ' uppercase name
  2367.           Word.Parse1=Instr(Word.Parse1+1,Outpts," ") ' search for space
  2368.           While Word.Parse1 ' loop while spaces
  2369.              Word.Parse2=Word.Parse1 ' store monster name parse
  2370.              Word.Parse1=Instr(Word.Parse1+1,Outpts," ") ' check spaces
  2371.           Wend ' end loop while spaces
  2372.           Monster.Found=True ' set return flag
  2373.           Monster.Number=Array.Number ' store monster array index
  2374.           Last.Monster=Mid$(Outpts,Word.Parse2+1) ' store monster name
  2375.           Exit Sub ' exit routine
  2376.        Endif ' end check permanent monster
  2377.     Endif ' end check magic monster
  2378.  Next ' end search through room
  2379. End Sub ' end routine to get first monster name
  2380.