-+-+-+-+-+-+-+-+ START OF PART 19 -+-+-+-+-+-+-+-+ X `09`09`09`5Bsword,hafted_weapon,pole_arm`5D)) then X`09`09tot_tohit := tot_tohit - 4 X`09else if ((py.misc.pclass = 8) and (equipment`5BEquipment_primary`5D.tval V in X `09`09`09`5Bhafted_weapon,maul,pole_arm`5D)) then X`09`09tot_tohit := tot_tohit - 3; X X `7B Fix for arrows`7D X`09if (equipment`5BEquipment_primary`5D.tval in `5Bsling_ammo,bolt,arrow`5D) V then X`09 blows := 1; X`09tot_tohit := tot_tohit + py.misc.ptohit; X`7B stopped from killing town creatures?? `7D X`09if ((uand(c_list`5Ba_mptr`5D.cmove,%X'00004000')=0) or (randint(100)<-py. Vmisc.rep)) then X`09 mean_jerk_flag := true X`09else X`09 mean_jerk_flag := get_yes_no('Are you sure you want to?'); X`09if mean_jerk_flag then X`09`7B Loop for number of blows, trying to hit the critter... `7D X`09 with py.misc do X`09 repeat X`09 if (player_test_hit(bth,lev,tot_tohit,c_list`5Ba_mptr`5D.ac,false)) t Vhen X`09 begin X`09`09if backstab_flag then X`09`09 writev(out_val,'You backstab ',m_name,'!') X`09`09else X`09`09 writev(out_val,'You hit ',m_name,'.'); X`09`09msg_print(out_val); X`09`09with equipment`5BEquipment_primary`5D do X`09`09 begin X`09`09 if (tval > 0) then `7B Weapon? `7D X`09`09 begin X`09`09`09i3 := damroll(damage); X`09`09`09i3 := tot_dam(equipment`5BEquipment_primary`5D,i3,c_list`5Ba_mptr`5 VD); X`09`09`09is_sharp := (tval <> bow_crossbow_or_sling) and X`09`09`09`09(uand(flags2,sharp_worn_bit) <> 0); X`09`09`09crit_mult := critical_blow(weight,tot_tohit,is_sharp,false); X`09`09`09if backstab_flag then X`09`09`09 i3 := i3 * ((py.misc.lev div 7) + 1); X`09`09`09if (py.misc.pclass = 1) then X`09`09`09 i3 := i3 + (py.misc.lev div 3); X`09`09`09i3 := i3 + (i3 + 5) * crit_mult; X`09`09 end X`09`09 else `7B Bare hands!? `7D X`09`09 begin X`09`09`09if (py.misc.pclass = 10) then X`09`09`09 begin X`09`09`09 i3 := randint((4 + 2*py.misc.lev) div 3); X`09`09`09 crit_mult := critical_blow(12000,0,false,false); X`09`09`09 if (randint(crit_mult+2) > 2) then X`09`09`09`09do_stun(a_cptr,-10,2); X`09`09`09 i3 := i3 + (i3 + 5) * crit_mult; X`09`09`09 end X`09`09`09else X`09`09`09 begin X`09`09`09 i3 := damroll(bare_hands); X`09`09`09 crit_mult := critical_blow(1,0,false,false); X`09`09`09 i3 := i3 + (i3 + 5) * crit_mult; X`09`09`09 end; X`09`09 end; X`09`09 end; X`09`09i3 := i3 + ptodam; X`09`09if (i3 < 0) then i3 := 0; X`09`7B See if we done it in... `7D X`09`09with m_list`5Ba_cptr`5D do X`09`09 if (mon_take_hit(a_cptr,i3) > 0) then X`09`09 begin X`09`09 msg_print('You have slain '+m_name+'.'); X`09`09 blows := 0; X`09`09 py_attack := false; X`09`09 end X`09`09 else X`09`09 py_attack := true; `7B If creature hit, but alive...`7D X`09`09 with equipment`5BEquipment_primary`5D do X `7B Use missiles up`7D X`09`09 if (tval in `5Bsling_ammo,bolt,arrow`5D) then X`09`09 begin X`09`09`09number := number - 1; X`09`09`09if (number <= 0) then X`09`09`09 begin X`09`09`09 inven_weight := inven_weight - weight; X`09`09`09 prt_weight; X`09`09`09 equip_ctr := equip_ctr - 1; X`09`09`09 inven_temp`5E.data := equipment`5BEquipment_primary`5D; X`09`09`09 equipment`5BEquipment_primary`5D := blank_treasure; X`09`09`09 py_bonuses(inven_temp`5E.data,-1); X`09`09`09 end; X`09`09 end; X`09 end X`09 else X`09 begin X`09`09writev(out_val,'You miss ',m_name,'.'); X`09`09msg_print(out_val); X`09 end; X`09 blows := blows - 1; X`09 until (blows < 1) X end; X X X`09`7B Finds range of item in inventory list `09`09-RAK-`09`7D X `5Bglobal,psect(moria$code)`5D function find_range( X`09`09`09item_val`09: obj_set; X`09`09`09inner`09`09: boolean; X`09`09`09var first`09: treas_ptr; X`09`09`09var count`09: integer) : boolean; X var X`09`09flag : boolean; X`09`09ptr`09`09: treas_ptr; X begin X`09count := 0; X`09ptr := inventory_list; X`09flag := false; X`09first := nil; X`09change_all_ok_stats(false,false); X`09while (ptr <> nil) do X`09 begin X`09 if (ptr`5E.data.tval in item_val) and X`09 ((ptr`5E.is_in = false) or inner) and X`09 ((ptr`5E.insides = 0) or (ptr`5E.data.tval <> bag_or_sack)) then X`09 begin X`09 if (not(flag)) then X`09 begin X`09`09 flag := true; X`09`09 first := ptr; X`09 end; X`09`09ptr`5E.ok := true; X`09`09count := count + 1; X`09 end; X`09 ptr := ptr`5E.next; X`09 end; X`09find_range := flag; X end; X X `5Bglobal,psect(moria$code)`5D function player_test_hit(bth,level,pth,ac V : integer; was_fired : boolean) : boolean; X`09var i1 : integer; X`09begin X`09 if (search_flag) then search_off; X`09 if (py.flags.rest > 0) then rest_off; X`09 i1 := bth + pth*bth_plus_adj; X`09 if was_fired then X`09 i1 := i1 + (level*class`5Bpy.misc.pclass`5D.mbthb) div 2 X`09 else X`09 i1 := i1 + (level*class`5Bpy.misc.pclass`5D.mbth) div 2; X`09 if (randint(i1) > ac) then X`09 player_test_hit := true X`09 else if (randint(20) = 1) then X`09 player_test_hit := true X`09 else player_test_hit := false; X`09end; X X`09`7B Attacker's level and pluses, defender's AC`09`09-RAK-`09`7D X `5Bglobal,psect(moria$code)`5D function test_hit(bth,level,pth,ac : inte Vger) : boolean; X var X`09`09i1 : integer; X begin X`09if (search_flag) then X`09 search_off; X`09if (py.flags.rest > 0) then X`09 rest_off; X`09i1 := bth + level*bth_lev_adj + pth*bth_plus_adj; X`7B hits if above ac or 1 in 20. OOK! `7D X`09test_hit := (randint(i1) > ac) or (randint(20) = 1); X end; X X X`09`7B Deletes a monster entry from the level`09`09-RAK-`09`7D X `5Bglobal,psect(moria$code)`5D procedure delete_monster(i2 : integer); X var X`09`09i1,i3 : integer; X begin X`09i3 := m_list`5Bi2`5D.nptr; X`09if (muptr = i2) then X`09 muptr := i3 X`09else X`09 begin X`09 i1 := muptr; X`09 while (m_list`5Bi1`5D.nptr <> i2) do X`09 i1 := m_list`5Bi1`5D.nptr; X`09 m_list`5Bi1`5D.nptr := i3; X`09 end; X`09with m_list`5Bi2`5D do X`09 begin X`09 cave`5Bfy,fx`5D.cptr := 0; X`09 if (ml) then X`09 with cave`5Bfy,fx`5D do X`09`09if ((pl) or (tl)) then X`09`09 lite_spot(fy,fx) X`09`09else X`09`09 unlite_spot(fy,fx); X`09 pushm(i2); X`09 end; X`09mon_tot_mult := mon_tot_mult - 1; X end; X X X`09`7B Creates objects nearby the coordinates given`09`09-RAK-`09`7D X`09`7B BUG: Because of the range, objects can actually be placed into`7D X`09`7B areas closed off to the player, this is rarely noticable,`7D X`09`7B and never a problem to the game. `7D X `5Bglobal,psect(moria$code)`5D procedure summon_object(y,x,num,typ : integ Ver); X var X`09i1,i2,i3 : integer; X begin X repeat X`09i1 := 0; X`09repeat X`09 i2 := y - 3 + randint(5); X`09 i3 := x - 3 + randint(5); X`09 if (in_bounds(i2,i3)) then X`09 if (los(y,x,i2,i3)) then`09`7BOOK!`7D X`09 with cave`5Bi2,i3`5D do X`09 if (fval in floor_set) then X`09`09if (tptr = 0) then X`09`09 begin X`09`09 case typ of `7B Select type of object `7D X`09`09 1 : place_object(i2,i3); X`09`09 2 : place_gold(i2,i3); X`09`09 3 : if (randint(100) < 50) then X`09`09`09 place_object(i2,i3) X`09`09`09 else X`09`09`09 place_gold(i2,i3); X`09`09 otherwise ; X`09`09 end; X`09`09 if (test_light(i2,i3)) then X`09`09 lite_spot(i2,i3); X`09`09 i1 := 10; X`09`09 end; X`09 i1 := i1 + 1; X`09until (i1 > 10); X`09num := num - 1; X until (num = 0); X end; X X X`09`7B Prompt for what type of money to use`09`09`09-DMF-`09`7D X `5Bglobal,psect(moria$code)`5D function get_money_type( X`09`09`09prompt`09`09: string; X`09`09`09var back`09: boolean; X`09`09`09no_check`09: boolean) : integer; X var X`09 out_val`09: string; X`09 comma_flag`09: boolean; X`09 test_flag`09: boolean; X`09 com_val`09: integer; X X`09procedure prompt_money(str : vtype); X`09 begin X`09 if (comma_flag) then X`09`09out_val := out_val + ', '; X`09 out_val := out_val + str; X`09 comma_flag := true; X`09 end; X X begin X`09 with py.misc do X`09 begin X`09 out_val := prompt; X`09 comma_flag := false; X`09 test_flag := false; X`09 if (money`5B6`5D > 0) or (no_check) then prompt_money('ithril'); X`09 if (money`5B5`5D > 0) or (no_check) then prompt_money('

latinum'); X`09 if (money`5B4`5D > 0) or (no_check) then prompt_money('old'); X`09 if (money`5B3`5D > 0) or (no_check) then prompt_money('ilver'); X`09 if (money`5B2`5D > 0) or (no_check) then prompt_money('opper'); X`09 if (money`5B1`5D > 0) or (no_check) then prompt_money('ron'); X`09 prt(out_val,1,1); X`09 back := true; X`09 repeat X`09 inkey(command); X`09 com_val := ord(command); X`09 case com_val of X`09`090,3,25,26,27 : begin X`09`09`09`09test_flag := true; X`09`09`09`09back := false; X`09`09`09 end; X`09`09109`09: test_flag := (mithril > 0) or (no_check); X`09`09112`09: test_flag := (platinum > 0) or (no_check); X`09`09103`09: test_flag := (gold > 0) or (no_check); X`09`09115`09: test_flag := (silver > 0) or (no_check); X`09`09 99`09: test_flag := (copper > 0) or (no_check); X`09`09105`09: test_flag := (iron > 0) or (no_check); X`09 otherwise ; X`09 end; X`09 until (test_flag); X`09 end; X`09 get_money_type := com_val; X end; X X `7B Sets the weight of the money type passed. `7D X`5Bglobal,psect(moria$code)`5D function coin_stuff( X`09`09`09typ `09`09: char; `7B Initial of coin metal `7D X`09`09`09var type_num : integer) : boolean; X`09begin X`09 coin_stuff := true; X`09 case (typ) of X`09`09'm' : type_num := mithril; X`09`09'p' : type_num := platinum; X`09 `09'g' : type_num := gold; X`09`09's' : type_num := silver; X`09`09'c' : type_num := copper; X`09`09'i' : type_num := iron; X`09`09otherwise coin_stuff := false; X`09 end; X`09end; X X`5Bglobal,psect(moria$code)`5D function set_money( X`09`09`09`09typ : char; `7B Initial of money type `7D X`09`09`09`09coin_num : integer `7B Number of coins `7D X`09`09`09`09`09`09) : boolean; X`09begin X`09 set_money := true; X`09 with py.misc do X`09 case (typ) of X`09`09'm' : money`5Bmithril`5D := coin_num; X`09`09'p' : money`5Bplatinum`5D := coin_num; X`09`09'g' : money`5Bgold`5D := coin_num; X`09`09's' : money`5Bsilver`5D := coin_num; X`09`09'c' : money`5Bcopper`5D := coin_num; X`09`09'i' : money`5Biron`5D := coin_num; X`09`09otherwise set_money := false; X`09 end; X`09end; X X X`09`7B Given speed, returns number of moves this turn.`09-RAK-`09`7D X`09`7B NOTE: Player must always move at least once per iteration, `7D X`09`7B a slowed player is handled by moving monsters faster `7D X `5Bglobal,psect(moria$code)`5D function movement_rate( X`09`09cspeed,mon`09`09: integer) : integer; X var X`09`09final_rate`09: integer; `7B final speed as integer `7D X`09`09c_rate,py_rate`09: integer; `7B rate (0,1,2,3) = (0,1/4,1/2,1) X`09`09`09`09`09 in wrong element `7D X begin X`09with m_list`5Bmon`5D do X`09 with c_list`5Bmptr`5D do X`09 with cave`5Bfy,fx`5D do X`09 if (fval in earth_set) <> (uand(cmove,%X'00000010') = 0) then X`09`09 c_rate := INT(uand(cmove,%X'00000300') div 256) X`09 else X`09`09c_rate := 3; X`09if (c_rate = 3) then c_rate := 4; X`09py_rate := py.flags.move_rate; X`09if (cspeed > 0) then X`09 c_rate := c_rate * cspeed X`09else X`09 py_rate := py_rate * (2-cspeed); X final_rate := c_rate div py_rate; X`09if ((c_rate * turn) mod py_rate < c_rate mod py_rate) then X`09 final_rate := final_rate + 1; X `7B if player resting, max monster move = 1 `7D X`09if ((final_rate > 1) and (py.flags.rest > 0)) then`09 X`09 movement_rate := 1 X`09else X`09 movement_rate := final_rate; X end; X X X `5Bglobal,psect(moria$code)`5D procedure get_player_move_rate; X var cur_swim : integer; X begin X`09with py.flags do X`09 if (cave`5Bchar_row,char_col`5D.fval in earth_set) then`20 X`09 move_rate := 4 X`09 else X`09 begin X`09`09cur_swim := ((swim + randint(5) - 1) div 5); X`09`09if (cur_swim <= -2) then move_rate := 0 X`09`09else if (cur_swim = -1) then move_rate := 1 X`09`09else if (cur_swim = 0) then move_rate := 2 X`09`09else if (cur_swim = 1) then move_rate := 4 X`09`09else move_rate := 8; X`09 end; X end;`09 `20 X X X`7BBLEGGA`7D X X`09`7B Lose experience hack for lose_exp breath`09`09-RAK-`09`7D X`5Bglobal,psect(moria$code)`5D procedure xp_loss(amount : integer); X var X`09i1,i2 : integer; X`09av_hp,lose_hp : integer; X`09av_mn,lose_mn : integer; X`09flag : boolean; X begin X amount := (py.misc.exp div 100) * mon$drain_life; X with py.misc do X`09begin X`09 msg_print('You feel your life draining away!'); X`09 if (amount > exp) then X`09 exp := 0 X`09 else X`09 exp := exp - amount; X`09 i1 := 1; X`09 while (trunc(player_exp`5Bi1`5D*expfact) <= exp) do X`09 i1 := i1 + 1; X`09 i2 := lev - i1; X`09 while (i2 > 0) do X`09 begin X`09 av_hp := trunc(mhp/lev); X`09 av_mn := trunc(mana/lev); X`09 lev := lev - 1; X`09 i2 := i2 - 1; X`09 lose_hp := randint(av_hp*2-1); X`09 lose_mn := randint(av_mn*2-1); X`09 mhp := mhp - lose_hp; X`09 mana := mana - lose_mn; X`09 if (mhp < 1) then mhp := 1; X`09 if (mana < 0) then mana := 0; X`09 with class`5Bpclass`5D do X`09`09if (mspell or pspell or dspell or bspell or mental) then X`09`09 begin X`09`09 i1 := 32; X`09`09 flag := false; X`09`09 repeat X`09`09 i1 := i1 - 1; X`09`09 if (magic_spell`5Bpclass,i1`5D.learned) then X`09`09`09flag := true; X`09`09 until((flag) or (i1 < 2)); X`09`09 if (flag) then X`09`09 begin X`09`09`09magic_spell`5Bpclass,i1`5D.learned := false; X`09`09`09if (mspell) then X`09`09`09 msg_print('You have forgotten a magic spell!') X`09`09`09else if (pspell) then X`09`09`09 msg_print('You have forgotten a prayer!') X`09`09`09else if (bspell) then X`09`09`09 msg_print('You have forgotten a song!') X`09`09`09else`20 +-+-+-+-+-+-+-+- END OF PART 19 +-+-+-+-+-+-+-+-