-+-+-+-+-+-+-+-+ START OF PART 41 -+-+-+-+-+-+-+-+ X prt_rest; X with py.flags do X food_digested := food_digested + 1; X END; X`20 X`20 X`7B Attacker's level and pluses, defender's AC `7D X function test_hit(bth,level,pth,ac : integer) : boolean; X var X i1 : integer; X BEGIN X if (search_flag) then X search_off; X if (py.flags.rest > 0) then X rest_off; X i1 := bth + level*bth_lev_adj + pth*bth_plus_adj; X if (randint(i1) > ac) then `7B Normal hit `7D X test_hit := true X else if (randint(20) = 1) then `7B Always hit 1/20 `7D X test_hit := true X else `7B Missed `7D X test_hit := false; X END; X`20 X`20 X`7B Decreases players hit points and sets death flag if neccessary`7D X procedure take_hit(damage : integer; hit_from : vtype); X BEGIN X if (py.flags.invuln > 0) then damage := 0; X py.misc.chp := py.misc.chp - damage; X if (search_flag) then search_off; X if (py.flags.rest > 0) then rest_off; X flush; X if (py.misc.chp <= -1) then X BEGIN X if (not(death)) then X BEGIN `7B Hee, hee... Ain't I mean? `7D X death := true; X died_from := hit_from; X total_winner := false; X END; X moria_flag := true; X END X else X prt_chp; X END; X`20 X`20 X`7B Given speed, returns number of moves this turn. X NOTE: Player must always move at least once per iteration, X a slowed player is handled by moving monsters faster `7D X function movement_rate(speed : integer) : integer; X BEGIN X if (speed > 0) then X if (py.flags.rest > 0) then X movement_rate := 1 X else X movement_rate := speed X else X BEGIN X if ((turn mod (abs(speed) + 2)) = 0) then X movement_rate := 1 X else X movement_rate := 0; X END; X END; X`20 X`20 X`7B Regenerate hit points `7D X procedure regenhp(percent : real); X BEGIN X with py.misc do X chp := chp + mhp*percent + player$regen_hpbase; X END; X`20 X`20 X`7B Regenerate mana points `7D `20 X procedure regenmana(percent : real); X BEGIN X with py.misc do X cmana := cmana + mana*percent + player$regen_mnbase; X END; X`20 X`20 X`7B Change a trap from invisible to visible X Note: Secret doors are handled here `7D X procedure change_trap(y,x : integer); X var X i3 : integer; X BEGIN X with cave`5By,x`5D do X if (t_list`5Btptr`5D.tval in `5B101,109`5D) then X BEGIN X i3 := tptr; X place_trap(y,x,2,t_list`5Bi3`5D.subval); X pusht(i3); X lite_spot(y,x); X END; X END; X`20 X`20 X`7B Searches for hidden things.`7D X procedure search(y,x,chance : integer); X var X i1,i2 : integer; X BEGIN X with py.flags do X if (confused+blind > 0) then X chance := trunc(chance/10.0) X else if (no_light) then X chance := trunc(chance/5.0); X for i1 := (y - 1) to (y + 1) do X for i2 := (x - 1) to (x + 1) do X if (in_bounds(i1,i2)) then X if ((i1 <> y) or (i2 <> x)) then X if (randint(100) < chance) then X with cave`5Bi1,i2`5D do X`7B Search for hidden objects `7D X if (tptr > 0) then X with t_list`5Btptr`5D do X`7B Trap on floor? `7D if (tval = 101) then X BEGIN X msg_print('You have found ' + name + '. '); X change_trap(i1,i2); X find_flag := false; X END `20 X`7B Secret door? `7D else if (tval = 109) then X BEGIN X msg_print('You have found a secret door.'); X fval := corr_floor2.ftval; X change_trap(i1,i2); X find_flag := false; X END X`7B Chest is trapped? `7D else if (tval = 2) then X BEGIN X if (flags > 1) then X if (index(name,'`5E') > 0) then X BEGIN X known2(name); X msg_print('You have discovered a trap on the chest!'); X END; X END; X END; X`20 X`20 X`7B Turns off Find_flag if something interesting appears X BUG: Does not handle corridor/room corners, but I didn't want X to add a lot of checking for such a minor detail `7D X procedure area_affect(dir,y,x : integer); X var X z: array `5B1..3`5D of integer; X i1,row,col: integer; X BEGIN X if (cave`5By,x`5D.fval = 4) then X BEGIN X i1 := 0; X if (next_to4(y,x,`5B4,5,6`5D) > 2) then X find_flag := false; X END; X if ((find_flag) and (py.flags.blind < 1)) then X BEGIN X CASE dir of X 1 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 1; X z`5B3`5D := 3; X END; X 2 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 2; X z`5B3`5D := 6; X END; X 3 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 3; X z`5B3`5D := 6; X END; X 4 : BEGIN X z`5B1`5D := 8; X z`5B2`5D := 4; X z`5B3`5D := 2; X END; X 6 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 6; X z`5B3`5D := 8; X END; X 7 : BEGIN X z`5B1`5D := 8; X z`5B2`5D := 7; X z`5B3`5D := 4; X END; X 8 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 8; X z`5B3`5D := 6; X END; X 9 : BEGIN X z`5B1`5D := 8; X z`5B2`5D := 9; X z`5B3`5D := 6; X END; X END; X for i1 := 1 to 3 do X BEGIN X row := y; X col := x; X if (move(z`5Bi1`5D,row,col)) then X with cave`5Brow,col`5D do X BEGIN X`7B Empty doorways `7D if (fval = 5) then X find_flag := false; X`7B Objects player can see X Including doors `7D X if (find_flag) then X if (player_light) then X BEGIN X if (tptr > 0) then X if (not(t_list`5Btptr`5D.tval in `5B101,109`5D V)) then X find_flag := false; X END X else if ((tl) or (pl) or (fm)) then X if (tptr > 0) then X if (not(t_list`5Btptr`5D.tval in `5B101,109`5D)) V then X find_flag := false; X`7B Creatures `7D if (find_flag) then X if ((tl) or (pl) or (player_light)) then X if (cptr > 1) then X with m_list`5Bcptr`5D do X if (ml) then X find_flag := false; X END X END X END; X END; X`20 X`20 X`7B Picks new direction when in find mode `7D X function pick_dir(dir : integer) : boolean; X var X z: array `5B1..2`5D of integer; X i1,y,x : integer; X BEGIN X if ((find_flag) and (next_to4(char_row,char_col,corr_set) = 2)) then X BEGIN X CASE dir of X 1 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 4; X END; X 2 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 6; X END; X 3 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 6; X END; X 4 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 8; X END; X 6 : BEGIN X z`5B1`5D := 2; X z`5B2`5D := 8; X END; X 7 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 8; X END; X 8 : BEGIN X z`5B1`5D := 4; X z`5B2`5D := 6; X END; X 9 : BEGIN X z`5B1`5D := 6; X z`5B2`5D := 8; X END; X END; X pick_dir := false; X for i1 := 1 to 2 do X BEGIN X y := char_row; X x := char_col; X if (move(z`5Bi1`5D,y,x)) then X if (cave`5By,x`5D.fopen) then X BEGIN X pick_dir := true; X com_val := z`5Bi1`5D + 48 X END X END X END X else X BEGIN X pick_dir := false; X END; X END; X`20 X`20 X`7B AC gets worse X Note: This routine affects magical AC bonuses so that stores X can detect the damage. `7D X function minus_ac(typ_dam : integer) : boolean; X var X i1,i2 : integer; X tmp: array `5B1..5`5D of integer; X BEGIN X i1 := 0; X if (inventory`5B26`5D.tval > 0) then X BEGIN X i1 := i1 + 1; X tmp`5Bi1`5D := 26; X END; X if (inventory`5B27`5D.tval > 0) then X BEGIN X i1 := i1 + 1; X tmp`5Bi1`5D := 27; X END; X if (inventory`5B32`5D.tval > 0) then X BEGIN X i1 := i1 + 1; X tmp`5Bi1`5D := 32; X END; X if (inventory`5B28`5D.tval > 0) then X BEGIN X i1 := i1 + 1; X tmp`5Bi1`5D := 28; X END; X if (inventory`5B24`5D.tval > 0) then X BEGIN X i1 := i1 + 1; X tmp`5Bi1`5D := 24; X END; X minus_ac := false; X if (i1 > 0) then X BEGIN X i2 := tmp`5Brandint(i1)`5D; X with inventory`5Bi2`5D do X if (uand(flags,typ_dam) <> 0) then X BEGIN X objdes(out_val,i2,false); X msg_print('Your ' + out_val + ' resists damage!'); X minus_ac := true; X END X else if ((ac+toac) > 0) then X BEGIN X objdes(out_val,i2,false); X msg_print('Your ' + out_val + ' is damaged!'); X toac := toac - 1; X py_bonuses(blank_treasure,0); X minus_ac := true; X END X END X END; X`20 X`20 X`7B Corrode the unsuspecting person's armor `7D X procedure corrode_gas(kb_str : vtype); X BEGIN X if (not (minus_ac(%X'00100000'))) then X take_hit(randint(8),kb_str); X print_stat := uor(%X'0040',print_stat); X if (inven_damage(`5B23,33,34,35,65`5D,5) > 0) then X msg_print('There is an acrid smell coming from your pack.'); X END; X`20 X`20 X`7B Poison gas the idiot.`7D X procedure poison_gas(dam : integer; kb_str : vtype); X BEGIN X take_hit(dam,kb_str); X print_stat := uor(%X'0040',print_stat); X py.flags.poisoned := py.flags.poisoned + 12 + randint(dam); X END; X`20 X`20 X`7B Burn the fool up.`7D X procedure fire_dam(dam : integer; kb_str : vtype); X BEGIN X if (py.flags.fire_resist)then X dam := trunc(dam*0.5); X if (py.flags.resist_heat > 0) then X dam := trunc(dam*0.5); X take_hit(dam,kb_str); X print_stat := uor(%X'0080',print_stat); X if (inven_damage(`5B12,20,21,22,30,31,32,36,55,70,71`5D,3) > 0) then X msg_print('There is smoke coming from your pack!'); X END; X`20 X`20 X`7B Freeze him to death.`7D X procedure cold_dam(dam : integer; kb_str : vtype); X BEGIN X if (py.flags.cold_resist)then X dam := trunc(dam*0.5); X if (py.flags.resist_cold > 0) then X dam := trunc(dam*0.5); X take_hit(dam,kb_str); X print_stat := uor(%X'0080',print_stat); X if (inven_damage(`5B75,76`5D,5) > 0) then X msg_print('Something shatters inside your pack!'); X END; X`20 X`20 X`7B Lightning bolt the sucker away.`7D X procedure light_dam(dam : integer; kb_str : vtype); X BEGIN X if (py.flags.lght_resist) then X take_hit(trunc(dam*0.5),kb_str) X else X take_hit(dam,kb_str); X print_stat := uor(%X'0080',print_stat); X END; X`20 X`20 X`7B Throw acid on the hapless victim `7D X procedure acid_dam(dam : integer; kb_str : vtype); X var X flag: integer; X BEGIN X flag := 0; X if (minus_ac(%X'00100000')) then X flag := 1; X if (py.flags.acid_resist) then X flag := flag + 2; X CASE flag of X 0 : take_hit(dam,kb_str); +-+-+-+-+-+-+-+- END OF PART 41 +-+-+-+-+-+-+-+-