Entering combat: If C(63) is set (spc of current location in this case), choose the special monster appropriate to that spc. See "Legacy SPC.txt". Also skip choosing a random monster below. Choose random monster: Complicated shit rolling on monster table that we should probably just redo entirely: 4510 M=FNR(1,20) & // Weights chances of getting higher level undead to be nonlinear. \ IF M>6 THEN & GO TO 4530 & 4520 M=INT(RND^(2-.04*C(15))*6+1) & \ ON C(64) GOTO 4540,4542,4540 & // Weights chances of getting non-undead to be nonlinear 4530 M=6+INT(RND^(2-.04*C(15))*14+1) & // These next two lines start the whole process over if the // chosen monster is outside of the dungeon level range it // should appear on. 4540 IF MINDUNLVL(M)>C(15) THEN GOTO 4075 & 4542 IF MAXDUNLVL(M)= PlayerMaxHP*1.2 && PlayerCurrentHP > 1 If d20 <= PlayerCharisma "A level "; M1; M$; " takes one look at you..." SLEEP 1 "snarls and knocks you cold." PlayerCurrentHP /= 2 SLEEP 2 "You wake up feeling half dead." "It has stalked off." Abort (C(64)=1 & GOTO 8000) Roll monster hit points. M2,M2.OLD=FNR(M1,M(M)) "You have encountered a level";M1;M$ If cheat flag C(61) is true, "STR:"; M.STR; "ARM:"; M.ARM; "HITS:"; M2; "DIE:"; M(M) If silence spell is active, If d20 < 15 + (CharacterLevel-MonsterLevel) Player wins initiative (GO TO 4580) If d20 > (INT+DEX)/2 Player loses initiative (GO TO 5000) Player attack (4580): "Press (F)ight, (C)ast, or (E)vade: " (Cast is not shown for fighters) On invalid input: "The ";M$;" is not amused..." & GOTO 4580 If Evade is chosen: If d10 < 9 "Evade" else "Run away" Check to make sure there is actually a place to go: 4630 IF ((I(1) = 1. OR I(1) = 3.) AND (I(2) = 1. OR I(2) = 3.)) THEN & IF ((L%(C(16),C(17)+1) AND 1%) = 1%) THEN & IF ((L%(C(16)+1,C(17)) AND 4%) = 4%) THEN & PRINT "There's no where to go!" & \ GOTO 5000 & // Monster attack If 2d10 > DEX && sqrt(CloakPlus/25)*25 < d25 // Failed to evade. "You're rooted to the spot...the ";M$;" bites back!" (This message is shitty for monsters that don't bite, and confusing in general. Redo it.) Skip to 5000 // monster attack else "You made it!" /////////////////////////////////////////////////////////////////////////////// // This whole block appears to choose a valid random direction and moves there. 4670 I=FNR(1,4) & \ IF I=1 AND I(2)=1 THEN & GO TO 4670 & 4680 X=C(16) & // Player X \ Y=C(17) & // Player Y 4690 IF I=2 AND FNI1(L%(X,Y+1),1)=1 THEN & GO TO 4670 & 4700 IF I=3 AND FNI1(L%(X+1,Y),2)=1 THEN & GO TO 4670 & 4710 IF I=4 AND I(1)=1 THEN & GO TO 4670 & 4720 IF RND>.5 THEN & I(6),I(7),I(8)=0 & 4730 C(64)=3 & \ GOTO 3000 & // New Position /////////////////////////////////////////////////////////////////////////////// If Fight is chosen: "Fight" Calculate a hit percentile based on complicated formula: \ I1=(3 * C(5)) + C(1) ! 3% per DEX, 1% per STR. & + C(22) ! + 1% * weapon point. & + C(8) * (5 - C(7)) ! + 3, 4, or 5% per level & - M1 * (M(M) / 2) ! - 1...10% per Mlevel & \ I1=I1 + 5 IF (C(40) > 0) ! +5% for Pray Spell. & \ I1.OLD=I1 ! Remember this value. & \ I1=I1*((C(10) + C(11)) / (2 * C(10))) ! Deduct for hits taken. & (This is gnarly. We should replace it with BX-ish THAC0.) Throw DICE=d100. If debug/cheat mode C(61) is on: "CHANCE:"; I1; "["; I1.OLD; "] DICE:"; DICE & If DICE > complicated formula above "You missed" If DICE <= I1.OLD // Hits taken as per complicated formula. +" due to your weakened condition." Skip to monster attack (GOTO 5000) else Calculate damage from class and weapon+ D = d(8-(2*Class)) + WeaponPlus Add a random bonus for strength, or penalty for weakling. modifiedStrength = Strength Add 3 to modifiedStrength if Strength Spell is on. If modifiedStrength > 14 D += d(modifiedStrength-14) Else if modifiedStrength < 7 D -= d(7-modifiedStrength) if debug/cheat mode C(61) is on: "FORCE:"; D Deduct from damage twice, once for armor and once for shield. If M.ARM > 0 D -= d(M.ARM) + d(M.ARM) If D < 1 "It fends you off." Skip to monster attack (GOTO 5000) Else "You did";D;"points of damage" M2 -= D If monster dead (M2<=0) If d10 > 1 I(8)=0 // FIXME WTF is this? "It died..." I(6)=0 // FIXME WTF is this? Assign monster xp and roll treasure FIXME see below (GOTO 6915) Monster Attack: If monster is dragon 10% chance to breathe fire. "The ";M$;" breathes fire at you" SLEEP 2 damage = 2d20 + monsterLevel if d20 >= 17 - dex/2 "You partially dodge it" damage /= 2 else do normal attack. Calculate hit chance based on complicated formula. ----- 5050 I1=50 + M(M) + M.STR + M.ARM ! Chance is 50% + monster & +(C(7) * 10) ! Mage = +20% Cleric = +10%. & + M1 * (M(M) / 2) ! + 1..10% per M level & - C(8) * (5 - C(7)) ! - 3, 4, 5% per level. & \ I1=I1 - 10 IF (C(38) > 0) ! Protection Spell. & \ I1=I1 - 20 IF (C(39) > 0) ! Shield Spell. & \ I1=I1 - 10 IF (C(40) > 0) ! Pray Spell. & \ I1=I1 - (2 * (C(5) - 14)) IF (C(5) > 14) ! Dexterity Bonus. & \ I1.OLD=I1 & \ I1=I1*((M2.OLD + M2) / (2 * M2.OLD)) ! Deduct for hits taken & ----- Throw DICE = d100 if debug mode "CHANCE:"; I1; "["; I1.OLD; "] DICE:"; DICE if DICE > hit chance "It missed"; if chance within weakened range (DICE <= I1.OLD) +" due to its weakened condition"; +"." else // hit if monster is wraith, spectre, or vampire Figure and throw chance of level drain based on complicated formula and apply it. ----- I2=10 * (M - 3) ! Base chance. & \ I2=I2 - 5 IF (C(38) > 0) ! Protect from Evil. & \ I2=I2 - 5 IF (C(40) > 0) ! Pray Spell. & \ IF (FNR(1,100) <= I2) THEN & PRINT "The ";M$;" drains an energy level!" & \ C(9)=FNE(C(8))-1 & \ GOSUB 20600 & ----- damage = d(monsterHitDie) + monsterLevel if monster is balrog if d3 < 3 "The ";M$;" uses it's sword" else "The ";M$;" uses it's whip!" damage *= 1.5 if debug mode "FORCE:"; D damage -= d(shieldPlus) // reduce damage with shield. if damage <= 0 "You block with your shield." else { damage -= d(armorPlus) + 2 - class // class:Warrior=0,Cleric=1, Magician=2 if damage <= 0 "Your armor protects you." else { "It did";D;"points to you" currentHp -= damage if( currentHp <= 0 "You died!" break and jump to death handler (GOTO 13000) } } if monster is doppleganger { if d4 == 3 // wtf?? "The ";M$;" looks just like you" & if d20 < INT + characterLevel - monsterLevel "You see through it's trick" else "You're confused!" skip next player attack (GOTO 5000) } else if monster is harpie { if d3 != 1 // FIXME check this against source code. { "The ";M$;" charms you with her voice.." & if( d20 < WIS + characterLevel - monsterLevel "But you resist her death song" else "You're hopelessly in love" skip next player attack (GOTO 5000) } } If Cast is chosen: // FIXME Wtf is this?? // Has something to do with whether we redisplay Fight/Cast/Evade or go to the next round. 6005 H=0 & \ IF C(64)=3 THEN & H=1 & // AHA, this is used in some of the charm/hold spells. It must be a // monsterHeld flag, which if turned on prevents the monster from getting // its combat round. If character is Fighter "Fighters don't have spells stupid!!" break out of this prompt for spell level "Level:"; pressing return with no number aborts. On invalid input: "A number from 1 to 4 you jester" If no more spells of that level: "You have no more level";A;"spells" break out of all this. prompt for spell # "Spell # "; pressing return with no number aborts. pressing an out of range number (or any other key) displays spell list (GOSUB 20000) and reprompts deduct from spells of given level remaining. proc spell done. *MONSTER EXPERIENCE* exp = ( (monsterHitDice*monsterLevel) + (M.STR*M.ARM) ) * 10 / characterLevel "You got";E;"experience points" characterExperience += exp *DEATH* if class == cleric && lvl4SpellsRemaining > 0 try to raise dead (see below) else CHR$(10);CHR$(10);CHR$(10);"Another "; if characterLevel < 4 +"not so "; "mighty ";MID("Warrior Cleric Magician",C(7)*8+1,8);" bites the dust" & delete character record. "Do you wish to try again:"; y/n y = create character n = quit *RAISE DEAD* // FIXME check this for reducing CON score. And for which module it branches to. "RAISE DEAD!!!!" lvl4SpellsRemaining -- if CON == 0 || d10>CON "It failed!!" die else currentHp = d(maxHp) "You're alive with";C(11);"hit points," "and a constitution of ";C(4) continue playing. *QUIT* "Fare well, brave Sire" quit *LEVEL?* if exp < findExpForLevel(characterLevel) { "You went down a level!" // Deduct HP for lost level. tmp = d( 4 + 2 * (2-classNum) ) // Warrior=0,Cleric=1, Magician=2 if CON > 14 tmp -= CON-14 // Also remove bonus HP for CON bonus. "You lost";I1;"hit points" maxHP -= tmp currentHP -= tmp level -- if level < 1 || currentHP < 1 "You died!" die() return spellProgression() // Fix number of spells available due to lost level. } else if( exp >= findExpForLevel( level + 1 ) { "You went up a level!" // Add to HP tmp = d( 4 + 2*(2-classNum) ) // Warrior=0,Cleric=1, Magician=2 if( CON > 14 ) tmp += CON-14 // Bonus HP for high con score "You gain";I1;"hit point(s)" maxHP += tmp currentHP += tmp level ++ // If the character had enough exp for more than one level (exiting the // dungeon with a shitload of loot, for example), cap them to 1xp less // than they need for the next level. if exp >= findExpForLevel( level + 1 ) exp = findExpForLevel(level+1) - 1; spellProgression() // Fix number of spells available due to new level. } *SPELL PROGRESSION* if class == fighter return for( spellLvl=1; spellLvl<=4; spellLvl++ ) { // calculate number of spells based on class and level. if class == cleric numSpells = level - (spellLvl+1)/.75 + 1 if class == magician numSpells = level - spellLvl/.8 + 1 if numSpells < 0 numSpells = 0 // characters get two extra level 1 spells. if spellLvl == 1 numSpells += 2 // set remaining and max spells. spellsRemaining[spellLvl] += numSpells - maxSpells[spellLvl] // This looks janky at first glance, but it works maxSpells[spellLvl] = numSpells }