games@tekred.TEK.COM (07/29/88)
Submitted by: "James E. Wilson" <wilson@ji.berkeley.edu> Comp.sources.games: Volume 5, Issue 52 Archive-name: umoria2/Part18 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 18 (of 18)." # Contents: spells.c # Wrapped by billr@saab on Wed Jul 13 11:18:40 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'spells.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'spells.c'\" else echo shar: Extracting \"'spells.c'\" \(56166 characters\) sed "s/^X//" >'spells.c' <<'END_OF_FILE' X#include <stdio.h> X X#include "constants.h" X#include "config.h" X#include "types.h" X#include "externs.h" X X#ifdef USG X#include <string.h> X#else X#include <strings.h> X#endif X X#ifdef sun /* correct SUN stupidity in the stdio.h file */ Xchar *sprintf(); X#endif X Xextern char cur_char2(); X X/* Following are spell procedure/functions -RAK- */ X/* These routines are commonly used in the scroll, potion, wands, and */ X/* staves routines, and are occasionally called from other areas. */ X/* Now included are creature spells also... -RAK */ X Xmonster_name (m_name, m_ptr, r_ptr) Xchar *m_name; Xmonster_type *m_ptr; Xcreature_type *r_ptr; X{ X if ((!m_ptr->ml) || (py.flags.blind > 0) || X ((0x10000 & r_ptr->cmove) && (!py.flags.see_inv))) X (void) strcpy (m_name, "It"); X else X (void) sprintf (m_name, "The %s", r_ptr->name); X} X Xlower_monster_name (m_name, m_ptr, r_ptr) Xchar *m_name; Xmonster_type *m_ptr; Xcreature_type *r_ptr; X{ X if ((!m_ptr->ml) || (py.flags.blind > 0) || X ((0x10000 & r_ptr->cmove) && (!py.flags.see_inv))) X (void) strcpy (m_name, "it"); X else X (void) sprintf (m_name, "the %s", r_ptr->name); X} X X/* Sleep creatures adjacent to player -RAK- */ Xint sleep_monsters1(y, x) Xint y, x; X{ X register int i, j; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X int sleep; X vtype out_val; X vtype m_name; X X sleep = FALSE; X for (i = y-1; i <= y+1; i++) X for (j = x-1; j <= x+1; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X X monster_name (m_name, m_ptr, r_ptr); X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) || X (0x1000 & r_ptr->cdefense)) X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X else X { X sleep = TRUE; X m_ptr->csleep = 500; X (void) sprintf(out_val, "%s falls asleep.", m_name); X msg_print(out_val); X } X } X } X return(sleep); X} X X/* Detect any treasure on the current panel -RAK- */ Xint detect_treasure() X{ X register int i, j; X register int detect; X register cave_type *c_ptr; X X detect = FALSE; X for (i = panel_row_min; i <= panel_row_max; i++) X for (j = panel_col_min; j <= panel_col_max; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X if (t_list[c_ptr->tptr].tval == 100) X if (!test_light(i, j)) X { X lite_spot(i, j); X c_ptr->tl = TRUE; X detect = TRUE; X } X } X return(detect); X} X X X/* Detect all objects on the current panel -RAK- */ Xint detect_object() X{ X register int i, j; X register int detect; X register cave_type *c_ptr; X X detect = FALSE; X for (i = panel_row_min; i <= panel_row_max; i++) X for (j = panel_col_min; j <= panel_col_max; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X if (t_list[c_ptr->tptr].tval < 100) X if (!test_light(i, j)) X { X lite_spot(i, j); X c_ptr->tl = TRUE; X detect = TRUE; X } X } X return(detect); X} X X X/* Locates and displays traps on current panel -RAK- */ Xint detect_trap() X{ X register int i, j; X int detect; X register cave_type *c_ptr; X register treasure_type *t_ptr; X X detect = FALSE; X for (i = panel_row_min; i <= panel_row_max; i++) X for (j = panel_col_min; j <= panel_col_max; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X if (t_list[c_ptr->tptr].tval == 101) X { X change_trap(i, j); X c_ptr->fm = TRUE; X detect = TRUE; X } X else if (t_list[c_ptr->tptr].tval == 2) X { X t_ptr = &t_list[c_ptr->tptr]; X known2(t_ptr->name); X } X } X return(detect); X} X X X/* Locates and displays all secret doors on current panel -RAK- */ Xint detect_sdoor() X{ X register int i, j; X register int detect; X register cave_type *c_ptr; X X detect = FALSE; X for (i = panel_row_min; i <= panel_row_max; i++) X for (j = panel_col_min; j <= panel_col_max; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X /* Secret doors */ X if (t_list[c_ptr->tptr].tval == 109) X { X c_ptr->fval = corr_floor3.ftval; X change_trap(i, j); X c_ptr->fm = TRUE; X detect = TRUE; X } X /* Staircases */ X else if ((t_list[c_ptr->tptr].tval == 107) || X (t_list[c_ptr->tptr].tval == 108)) X if (!c_ptr->fm) X { X c_ptr->fm = TRUE; X lite_spot(i, j); X detect = TRUE; X } X } X return(detect); X} X X X/* Locates and displays all invisible creatures on current panel -RAK-*/ Xint detect_invisible() X{ X register int i; X register int flag; X char tmp_str[2]; X register monster_type *m_ptr; X X flag = FALSE; X i = muptr; X while (i > 0) X { X m_ptr = &m_list[i]; X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) X if (0x10000 & c_list[m_ptr->mptr].cmove) X { X m_ptr->ml = TRUE; X tmp_str[0] = c_list[m_ptr->mptr].cchar; X tmp_str[1] = '\0'; X print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx); X flag = TRUE; X } X i = m_list[i].nptr; X } X if (flag) X { X msg_print("You sense the presence of invisible creatures!"); X /* make sure player sees the message */ X msg_print(" "); X msg_flag = FALSE; X } X return(flag); X} X X X/* Light an area: 1. If corridor light immediate area -RAK-*/ X/* 2. If room light entire room. */ Xint light_area(y, x) Xregister int y, x; X{ X register int i, j; X register int light; X X msg_print("You are surrounded by a white light."); X light = TRUE; X if (((cave[y][x].fval == 1) || (cave[y][x].fval == 2)) && (dun_level > 0)) X light_room(y, x); X else X for (i = y-1; i <= y+1; i++) X for (j = x-1; j <= x+1; j++) X if (in_bounds(i, j)) X { X if (!test_light(i, j)) X lite_spot(i, j); X cave[i][j].pl = TRUE; X } X return(light); X} X X X/* Darken an area, opposite of light area -RAK- */ Xint unlight_area(y, x) Xint y, x; X{ X register int i, j, k; X int tmp1, tmp2; X int start_row, start_col; X int end_row, end_col; X int flag; X int unlight; X register cave_type *c_ptr; X vtype out_val; X X flag = FALSE; X if (((cave[y][x].fval == 1) || (cave[y][x].fval == 2)) && (dun_level > 0)) X { X tmp1 = (SCREEN_HEIGHT/2); X tmp2 = (SCREEN_WIDTH /2); X start_row = (y/tmp1)*tmp1 + 1; X start_col = (x/tmp2)*tmp2 + 1; X end_row = start_row + tmp1 - 1; X end_col = start_col + tmp2 - 1; X for (i = start_row; i <= end_row; i++) X { X out_val[0] = '\0'; X k = 0; X for (j = start_col; j <= end_col; j++) X { X c_ptr = &cave[i][j]; X if ((c_ptr->fval == 1) || (c_ptr->fval == 2)) X { X c_ptr->pl = FALSE; X c_ptr->fval = 1; X if (!test_light(i, j)) X { X if (k == 0) X k = j; X (void) strcat(out_val, " "); X } X else if (k > 0) X { X flag = TRUE; X print(out_val, i, k); X out_val[0] = '\0'; X k = 0; X } X } X else if (k > 0) X { X flag = TRUE; X print(out_val, i, k); X out_val[0] = '\0'; X k = 0; X } X if (k > 0) X { X flag = TRUE; X print(out_val, i, k); X } X } X } X } X else X for (i = y-1; i <= y+1; i++) X for (j = x-1; j <= x+1; j++) X if (in_bounds(i, j)) X { X c_ptr = &cave[i][j]; X if ((c_ptr->fval == 4) || (c_ptr->fval == 5) || (c_ptr->fval ==6)) X if (c_ptr->pl) X { X c_ptr->pl = FALSE; X flag = TRUE; X } X if (flag) X { X msg_print("Darkness surrounds you..."); X unlight = TRUE; X } X } X else X unlight = FALSE; X return(unlight); X} X X X/* Map the current area plus some -RAK- */ Xint map_area() X{ X register cave_type *c_ptr; X register int i7, i8, n, m; X int i, j, k, l; X int map; X X map = TRUE; X i = panel_row_min - randint(10); X j = panel_row_max + randint(10); X k = panel_col_min - randint(20); X l = panel_col_max + randint(20); X for (m = i; m <= j; m++) X for (n = k; n <= l; n++) X if (in_bounds(m, n)) X if (set_floor(cave[m][n].fval)) X for (i7 = m-1; i7 <= m+1; i7++) X for (i8 = n-1; i8 <= n+1; i8++) X { X c_ptr = &cave[i7][i8]; X if (((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) || X (c_ptr->fval == 15)) X c_ptr->pl = TRUE; X else if (c_ptr->tptr != 0) X if ((t_list[c_ptr->tptr].tval >= 102) && X (t_list[c_ptr->tptr].tval <= 110) && X (t_list[c_ptr->tptr].tval != 106)) X c_ptr->fm = TRUE; X } X prt_map(); X return(map); X} X X X/* Identify an object -RAK- */ Xint ident_spell() X{ X int item_val; X vtype out_val, tmp_str; X int redraw; X int ident; X register treasure_type *i_ptr; X X ident = FALSE; X redraw = FALSE; X if (get_item(&item_val, "Item you wish identified?", X &redraw, 0, inven_ctr-1)) X { X i_ptr = &inventory[item_val]; X ident = TRUE; X identify(inventory[item_val]); X known2(i_ptr->name); X objdes(tmp_str, item_val, TRUE); X (void) sprintf(out_val, "%c%c %s", item_val+97, cur_char2(item_val), X tmp_str); X msg_print(out_val); X } X if (redraw) X { X /* make sure player sees message before draw cave erases it */ X msg_print(" "); X draw_cave(); X } X return(ident); X} X X X/* Get all the monsters on the level pissed off... -RAK- */ Xint aggravate_monster (dis_affect) Xint dis_affect; X{ X register int i; X int aggravate; X register monster_type *m_ptr; X X aggravate = TRUE; X i = muptr; X while (i > 0) X { X m_ptr = &m_list[i]; X m_ptr->csleep = 0; X if (m_ptr->cdis <= dis_affect) X if (m_ptr->cspeed < 2) X m_ptr->cspeed++; X i = m_list[i].nptr; X } X return(aggravate); X} X X X/* Surround the fool with traps (chuckle) -RAK- */ Xint trap_creation() X{ X register int i, j; X register int trap; X register cave_type *c_ptr; X X trap = TRUE; X for (i = char_row-1; i <= char_row+1; i++) X for (j = char_col-1; j <= char_col+1; j++) X { X c_ptr = &cave[i][j]; X if (set_floor(c_ptr->fval)) X { X if (c_ptr->tptr != 0) X (void) delete_object(i, j); X place_trap(i, j, 1, randint(MAX_TRAPA)-1); X } X } X return(trap); X} X X X/* Surround the player with doors... -RAK- */ Xint door_creation() X{ X register int i, j; X int k; X register int door; X register cave_type *c_ptr; X X door = TRUE; X for (i = char_row-1; i <= char_row+1; i++) X for (j = char_col-1; j <= char_col+1; j++) X if ((i != char_row) || (j != char_col)) X { X c_ptr = &cave[i][j]; X if (set_floor(c_ptr->fval)) X { X popt(&k); X if (c_ptr->tptr != 0) X (void) delete_object(i, j); X c_ptr->fopen = FALSE; X c_ptr->tptr = k; X t_list[k] = door_list[1]; X if (test_light(i, j)) X lite_spot(i, j); X } X } X return(door); X} X X X/* Destroys any adjacent door(s)/trap(s) -RAK- */ Xint td_destroy() X{ X register int i, j; X register int destroy; X register cave_type *c_ptr; X X destroy = FALSE; X for (i = char_row-1; i <= char_row+1; i++) X for (j = char_col-1; j <= char_col+1; j++) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X { X if (((t_list[c_ptr->tptr].tval >= 101) && X (t_list[c_ptr->tptr].tval <= 105) && X (t_list[c_ptr->tptr].tval != 103)) || X (t_list[c_ptr->tptr].tval == 109)) X { X if (delete_object(i, j)) X destroy = TRUE; X } X else if (t_list[c_ptr->tptr].tval == 2) X /* destroy traps on chest and unlock */ X t_list[c_ptr->tptr].flags &= 0xFF000000; X } X } X return(destroy); X} X X X/* Display all creatures on the current panel -RAK- */ Xint detect_monsters() X{ X register int i; X register int flag, detect; X char tmp_str[2]; X register monster_type *m_ptr; X X flag = FALSE; X i = muptr; X while (i > 0) X { X m_ptr = &m_list[i]; X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) X if ((0x10000 & c_list[m_ptr->mptr].cmove) == 0) X { X m_ptr->ml = TRUE; X tmp_str[0] = c_list[m_ptr->mptr].cchar; X tmp_str[1] = '\0'; X print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx); X flag = TRUE; X } X i = m_list[i].nptr; X } X if (flag) X { X msg_print("You sense the presence of monsters!"); X /* make sure player sees the message */ X msg_print(" "); X msg_flag = FALSE; X detect = TRUE; X } X detect = flag; X return(detect); X} X X X/* Leave a line of light in given dir, blue light can sometimes */ X/* hurt creatures... -RAK- */ Xlight_line(dir, y, x) Xint dir, y, x; X{ X register int i; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X char tmp_str[2]; X X while (cave[y][x].fopen){ X c_ptr = &cave[y][x]; X if (panel_contains(y, x)) X { X if ((!c_ptr->tl) && (!c_ptr->pl)) X if (c_ptr->fval == 2) X light_room(y, x); X else X lite_spot(y, x); X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X m_ptr->ml = TRUE; X tmp_str[0] = r_ptr->cchar; X tmp_str[1] = '\0'; X print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx); X monster_name (m_name, m_ptr, r_ptr); X if (0x0100 & r_ptr->cdefense) X { X (void) sprintf(out_val, "%s wails out in pain!", m_name); X msg_print(out_val); X i = mon_take_hit((int)c_ptr->cptr, damroll("2d8")); X if (i >= 0) X { X (void) sprintf(out_val, "%s dies in a fit of agony.", X m_name); X msg_print(out_val); X } X } X } X c_ptr->pl = TRUE; X } X (void) move(dir, &y, &x); X } X} X X X/* Light line in all directions -RAK- */ Xint starlite(y, x) Xregister int y, x; X{ X register int i; X X msg_print("The end of the staff bursts into a blue shimmering light."); X for (i = 1; i <= 9; i++) X if (i != 5) X light_line(i, y, x); X return(TRUE); X} X X X/* Disarms all traps/chests in a given direction -RAK- */ Xint disarm_all(dir, y, x) Xint dir, y, x; X{ X register cave_type *c_ptr; X register treasure_type *t_ptr; X register int i, oldy, oldx; X int disarm; X char *string; X X disarm = FALSE; X do X { X c_ptr = &cave[y][x]; X if (c_ptr->tptr != 0) X { X t_ptr = &t_list[c_ptr->tptr]; X if ((t_ptr->tval == 101) || (t_ptr->tval == 102)) X { X if (delete_object(y, x)) X disarm = TRUE; X } X else if (t_ptr->tval == 105) X { X t_ptr->p1 = 0; X } X else if (t_ptr->tval == 109) X { X c_ptr->fval = corr_floor3.ftval; X change_trap(y, x); X c_ptr->fm = TRUE; X disarm = TRUE; X } X else if (t_ptr->tval == 2) X if (t_ptr->flags != 0) X { X msg_print("Click!"); X t_ptr->flags = 0; X disarm = TRUE; X string = index(t_ptr->name, '('); X if (string) X i = strlen(t_ptr->name) - strlen(string); X else X i = -1; X if (i >= 0) X t_ptr->name[i] = '\0'; X (void) strcat(t_ptr->name, " (Unlocked)"); X known2(t_ptr->name); X } X } X oldy = y; X oldx = x; X (void) move(dir, &y, &x); X } X while (cave[oldy][oldx].fopen); X return(disarm); X} X X X/* Return flags for given type area affect -RAK- */ Xget_flags(typ, weapon_type, harm_type, destroy) Xint typ; Xint *weapon_type, *harm_type; Xint (**destroy)(); X{ X int set_null(), set_fire_destroy(), set_frost_destroy(); X int set_acid_destroy(), set_lightning_destroy(); X X switch(typ) X { X case 1: /* Lightning */ X *weapon_type = 0x00080000; X *harm_type = 0x0100; X *destroy = set_lightning_destroy; X break; X case 2: /* Poison Gas */ X *weapon_type = 0x00100000; X *harm_type = 0x0040; X *destroy = set_null; X break; X case 3: /* Acid */ X *weapon_type = 0x00200000; X *harm_type = 0x0080; X *destroy = set_acid_destroy; X break; X case 4: /* Frost */ X *weapon_type = 0x00400000; X *harm_type = 0x0010; X *destroy = set_frost_destroy; X break; X case 5: /* Fire */ X *weapon_type = 0x00800000; X *harm_type = 0x0020; X *destroy = set_fire_destroy; X break; X case 6: /* Holy Orb */ X *weapon_type = 0x00000000; X *harm_type = 0x0004; X *destroy = set_null; X break; X default: X *weapon_type = 0; X *harm_type = 0; X *destroy = set_null; X } X} X X X/* Shoot a bolt in a given direction -RAK- */ Xint fire_bolt(typ, dir, y, x, dam, bolt_typ) Xint typ, dir, y, x, dam; Xctype bolt_typ; X{ X int i, oldy, oldx, dist; X int weapon_type, harm_type; X int flag; X int (*dummy)(); X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X char tmp_str[2]; X X flag = FALSE; X get_flags(typ, &weapon_type, &harm_type, &dummy); X oldy = y; X oldx = x; X dist = 0; X do X { X (void) move(dir, &y, &x); X if (test_light(oldy, oldx)) X lite_spot(oldy, oldx); X else X unlite_spot(oldy, oldx); X dist++; X if (dist > OBJ_BOLT_RANGE) X flag = TRUE; X else X { X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X flag = TRUE; X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X /* light it up first, then check to see if visible */ X m_list[c_ptr->cptr].ml = TRUE; X lower_monster_name(m_name, m_ptr, r_ptr); X (void) sprintf(out_val, "The %s strikes %s.", bolt_typ, X m_name); X msg_print(out_val); X if (harm_type & r_ptr->cdefense) X dam = dam*2; X else if (weapon_type & r_ptr->spells) X dam = (dam/4.0); X i = mon_take_hit((int)c_ptr->cptr, dam); X monster_name(m_name, m_ptr, r_ptr); X if (i >= 0) X { X (void) sprintf(out_val, "%s dies in a fit of agony.", X m_name); X msg_print(out_val); X } X else X { X if (panel_contains(y, x)) X { X tmp_str[0] = c_list[m_ptr->mptr].cchar; X tmp_str[1] = '\0'; X print(tmp_str, y, x); X } X if (dam > 0) X { X (void) sprintf (out_val, "%s screams in agony.", X m_name); X msg_print (out_val); X } X } X } X else if (panel_contains(y, x)) X { X print("*", y, x); X /* show the bolt */ X put_qio(); X } X } X else X flag = TRUE; X } X oldy = y; X oldx = x; X } X while (!flag); X} X X X/* Shoot a ball in a given direction. Note that balls have an */ X/* area affect.... -RAK- */ Xint fire_ball(typ, dir, y, x, dam_hp, descrip) Xint typ, dir, y, x, dam_hp; Xctype descrip; X{ X register int i, j; X int dam, max_dis, thit, tkill, k; X int oldy, oldx, dist; X int weapon_type, harm_type; X int flag; X int (*destroy)(); X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X char tmp_str[2]; X X thit = 0; X tkill = 0; X max_dis = 2; X get_flags(typ, &weapon_type, &harm_type, &destroy); X flag = FALSE; X oldy = y; X oldx = x; X dist = 0; X do X { X (void) move(dir, &y, &x); X dist++; X if (test_light(oldy, oldx)) X lite_spot(oldy, oldx); X else X unlite_spot(oldy, oldx); X if (dist > OBJ_BOLT_RANGE) X flag = TRUE; X else X { X c_ptr = &cave[y][x]; X if ((!c_ptr->fopen) || (c_ptr->cptr > 1)) X { X flag = TRUE; X if (!c_ptr->fopen) X { X y = oldy; X x = oldx; X } X /* The ball hits and explodes... */ X /* The explosion... */ X for (i = y-max_dis; i <= y+max_dis; i++) X for (j = x-max_dis; j <= x+max_dis; j++) X if (in_bounds(i, j)) X if (distance(y, x, i, j) <= max_dis) X if (los(y, x, i, j)) /* FIXED BUG V4.5 */ X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X if ((*destroy)(t_list[c_ptr->tptr].tval)) X (void) delete_object(i, j); X if (c_ptr->fopen) X { X if (panel_contains(i, j)) print("*", i, j); X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X thit++; X dam = dam_hp; X if (harm_type & r_ptr->cdefense) X dam = dam*2; X else if (weapon_type & r_ptr->spells) X dam = dam / 4; X dam = (dam/(distance(i, j, y, x)+1)); X k = mon_take_hit((int)c_ptr->cptr, dam); X if (k >= 0) X tkill++; X else X { X if (panel_contains(i, j)) X { X tmp_str[0] = r_ptr->cchar; X tmp_str[1] = '\0'; X print(tmp_str, i, j); X m_ptr->ml = TRUE; X } X } X } X } X } X /* show ball of whatever */ X put_qio(); X X for (i = (y - 2); i <= (y + 2); i++) X for (j = (x - 2); j <= (x + 2); j++) X if (in_bounds(i, j)) X if (panel_contains(i, j)) X if (distance(y, x, i, j) <= max_dis) X { X c_ptr = &cave[i][j]; X if (test_light(i, j)) X lite_spot(i, j); X else if (c_ptr->cptr == 1) X lite_spot(i, j); X else if (c_ptr->cptr > 1) X if (m_list[c_ptr->cptr].ml) X lite_spot(i, j); X else X unlite_spot(i, j); X else X unlite_spot(i, j); X } X /* End explosion... */ X if (thit == 1) X { X (void) sprintf(out_val, X "The %s envelopes a creature!", X descrip); X msg_print(out_val); X } X else if (thit > 1) X { X (void) sprintf(out_val, X "The %s envelopes several creatures!", X descrip); X msg_print(out_val); X } X if (tkill == 1) X msg_print("There is a scream of agony!"); X else if (tkill > 1) X msg_print("There are several screams of agony!"); X /* End ball hitting... */ X } X else if (panel_contains(y, x)) X { X print("*", y, x); X /* show bolt */ X put_qio(); X } X oldy = y; X oldx = x; X } X } X while (!flag); X} X X X/* Breath weapon works like a fire_ball, but affects the player. */ X/* Note the area affect.... -RAK- */ Xbreath(typ, y, x, dam_hp, ddesc) Xint typ, y, x, dam_hp; Xchar *ddesc; X{ X register int i, j; X int dam, max_dis; X int weapon_type, harm_type; X int (*destroy)(); X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X X max_dis = 2; X get_flags(typ, &weapon_type, &harm_type, &destroy); X for (i = y-2; i <= y+2; i++) X for (j = x-2; j <= x+2; j++) X if (in_bounds(i, j)) X if (distance(y, x, i, j) <= max_dis) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X if ((*destroy)(t_list[c_ptr->tptr].tval)) X (void) delete_object(i, j); X if (c_ptr->fopen) X { X if (panel_contains(i, j)) X print("*", i, j); X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X dam = dam_hp; X if (harm_type & r_ptr->cdefense) X dam = dam*2; X else if (weapon_type & r_ptr->spells) X dam = (dam/4.0); X dam = (dam/(distance(i, j, y, x)+1)); X m_ptr->hp = m_ptr->hp - dam; X m_ptr->csleep = 0; X if (m_ptr->hp < 0) X { X monster_death((int)m_ptr->fy, (int)m_ptr->fx, X r_ptr->cmove); X delete_monster((int)c_ptr->cptr); X } X } X else if (c_ptr->cptr == 1) X { X dam = (dam_hp/(distance(i, j, y, x)+1)); X /* let's do at least one point of damage */ X /* prevents randint(0) problem with poison_gas, also */ X if (dam == 0) X dam = 1; X switch(typ) X { X case 1: light_dam(dam, ddesc); break; X case 2: poison_gas(dam, ddesc); break; X case 3: acid_dam(dam, ddesc); break; X case 4: cold_dam(dam, ddesc); break; X case 5: fire_dam(dam, ddesc); break; X } X } X } X } X /* show the ball of gas */ X put_qio(); X X for (i = (y - 2); i <= (y + 2); i++) X for (j = (x - 2); j <= (x + 2); j++) X if (in_bounds(i, j)) X if (panel_contains(i, j)) X if (distance(y, x, i, j) <= max_dis) X { X c_ptr = &cave[i][j]; X if (test_light(i, j)) X lite_spot(i, j); X else if (c_ptr->cptr == 1) X lite_spot(i, j); X else if (c_ptr->cptr > 1) X if (m_list[c_ptr->cptr].ml) X lite_spot(i, j); X else X unlite_spot(i, j); X else X unlite_spot(i, j); X } X} X X X/* Recharge a wand, staff, or rod. Sometimes the item breaks. -RAK-*/ Xint recharge(num) Xregister int num; X{ X int item_val; X int redraw; X register int res; X register treasure_type *i_ptr; X X res = FALSE; X redraw = FALSE; X if (get_item(&item_val, "Recharge which item?", &redraw, 0, inven_ctr-1)) X { X i_ptr = &inventory[item_val]; X if ((i_ptr->tval == 55) || (i_ptr->tval == 60) || (i_ptr->tval == 65)) X /* recharge I = recharge(20) = 1/6 failure */ X /* recharge II = recharge(60) = 1/10 failure */ X if (randint((num + 40)/10) == 1) X { X res = TRUE; X msg_print("There is a bright flash of light..."); X inven_destroy(item_val); X } X else X { X res = TRUE; X num = (num/(i_ptr->level+2)) + 1; X i_ptr->p1 += 2 + randint(num); X if (index(i_ptr->name, '^') == 0) X insert_str(i_ptr->name, " (%P1", "^ (%P1"); X } X } X if (redraw) X { X /* make sure player sees message before draw cave erases it */ X msg_print(" "); X draw_cave(); X } X return(res); X} X X X/* Increase or decrease a creatures hit points -RAK- */ Xint hp_monster(dir, y, x, dam) Xint dir, y, x, dam; X{ X register int i; X int flag; X int monster; X cave_type *c_ptr; X monster_type *m_ptr; X creature_type *r_ptr; X vtype out_val; X vtype m_name; X X monster = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X flag = TRUE; X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X monster = TRUE; X i = mon_take_hit((int)c_ptr->cptr, dam); X if (i >= 0) X { X (void) sprintf(out_val, "%s dies in a fit of agony.", X m_name); X msg_print(out_val); X } X else X { X if (dam > 0) X { X (void) sprintf(out_val, "%s screams in agony.", X m_name); X msg_print(out_val); X } X } X } X } X else X flag = TRUE; X } X while (!flag); X return(monster); X} X X X/* Drains life; note it must be living... -RAK- */ Xint drain_life(dir, y, x) Xint dir, y, x; X{ X register int i; X int flag; X int drain; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X drain = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X flag = TRUE; X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X if ((r_ptr->cdefense & 0x0008) == 0) X { X drain = TRUE; X monster_name (m_name, m_ptr, r_ptr); X i = mon_take_hit((int)c_ptr->cptr, 50); X if (i >= 0) X { X (void) sprintf(out_val, "%s dies in a fit of agony.", X m_name); X msg_print(out_val); X } X else X { X (void) sprintf(out_val, "%s screams in agony.", X m_name); X msg_print(out_val); X } X } X } X else X flag = TRUE; X } X } X while (!flag); X return(drain); X} X X X/* Increase or decrease a creatures speed -RAK- */ X/* NOTE: cannot slow a winning creature (BALROG) */ Xint speed_monster(dir, y, x, spd) Xint dir, y, x, spd; X{ X int speed; X int flag; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X speed = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X flag = TRUE; X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X if (spd > 0) X { X m_ptr->cspeed += spd; X m_ptr->csleep = 0; X (void) sprintf (out_val, "%s starts moving faster.", m_name); X msg_print (out_val); X speed = TRUE; X } X else if (randint(MAX_MONS_LEVEL) > r_ptr->level) X { X m_ptr->cspeed += spd; X m_ptr->csleep = 0; X (void) sprintf (out_val, "%s starts moving slower.", m_name); X msg_print (out_val); X speed = TRUE; X } X else X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X } X } X else X flag = TRUE; X } X while (!flag); X return(speed); X} X X X/* Confuse a creature -RAK- */ Xint confuse_monster(dir, y, x) Xint dir, y, x; X{ X int flag; X int confuse; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X confuse = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X flag = TRUE; X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) || X (0x1000 & r_ptr->cdefense)) X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X else X { X m_ptr->confused = TRUE; X confuse = TRUE; X m_ptr->csleep = 0; X (void) sprintf(out_val, "%s appears confused.", m_name); X msg_print(out_val); X } X } X } X else X flag = TRUE; X } X while (!flag); X return(confuse); X} X X X/* Sleep a creature... -RAK- */ Xint sleep_monster(dir, y, x) Xint dir, y, x; X{ X int flag; X int sleep; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X sleep = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X flag = TRUE; X monster_name (m_name, m_ptr, r_ptr); X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) || X (0x1000 & r_ptr->cdefense)) X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X else X { X m_ptr->csleep = 500; X sleep = TRUE; X (void) sprintf(out_val, "%s falls asleep.", m_name); X msg_print(out_val); X } X } X } X else X flag = TRUE; X } X while (!flag); X return(sleep); X} X X X/* Turn stone to mud, delete wall.... -RAK- */ Xint wall_to_mud(dir, y, x) Xint dir, y, x; X{ X int i; X vtype out_val, tmp_str; X register int flag; X int wall; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype m_name; X X wall = FALSE; X flag = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (in_bounds(y, x)) X { X if ((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) X { X flag = TRUE; X (void) twall(y, x, 1, 0); X if (test_light(y, x)) X { X msg_print("The wall turns into mud."); X wall = TRUE; X } X } X else if ((c_ptr->tptr != 0) && (!c_ptr->fopen)) X { X flag = TRUE; X if (panel_contains(y, x)) X if (test_light(y, x)) X { X inventory[INVEN_MAX] = t_list[c_ptr->tptr]; X objdes(tmp_str, INVEN_MAX, FALSE); X (void) sprintf(out_val, "The %s turns into mud.", tmp_str); X msg_print(out_val); X wall = TRUE; X } X (void) delete_object(y, x); X } X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X if (0x0200 & r_ptr->cdefense) X { X monster_name (m_name, m_ptr, r_ptr); X i = mon_take_hit((int)c_ptr->cptr, 100); X flag = TRUE; X if (i >= 0) X { X (void) sprintf(out_val, "%s dies in a fit of agony.", X m_name); X msg_print(out_val); X } X else X { X (void) sprintf(out_val, "%s wails out in pain!", m_name); X msg_print(out_val); X } X } X } X } X else X flag = TRUE; X } X while (!flag); X return(wall); X} X X X/* Destroy all traps and doors in a given direction -RAK- */ Xint td_destroy2(dir, y, x) Xint dir, y, x; X{ X register int destroy2; X register cave_type *c_ptr; X register treasure_type *t_ptr; X X destroy2 = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->tptr != 0) X { X t_ptr = &t_list[c_ptr->tptr]; X if ((t_ptr->tval == 2) || (t_ptr->tval == 101) || X (t_ptr->tval == 102) || (t_ptr->tval == 104) || X (t_ptr->tval == 105) || (t_ptr->tval == 109)) X { X if (delete_object(y, x)) X { X msg_print("There is a bright flash of light!"); X c_ptr->fopen = TRUE; X destroy2 = TRUE; X } X } X } X } X while (cave[y][x].fopen); X return(destroy2); X} X X X/* Polymorph a monster -RAK- */ X/* NOTE: cannot polymorph a winning creature (BALROG) */ Xint poly_monster(dir, y, x) Xint dir, y, x; X{ X int dist; X int flag; X int poly; X register cave_type *c_ptr; X register creature_type *r_ptr; X register monster_type *m_ptr; X vtype out_val; X vtype m_name; X X poly = FALSE; X flag = FALSE; X dist = 0; X do X { X (void) move(dir, &y, &x); X dist++; X if (dist <= OBJ_BOLT_RANGE) X { X c_ptr = &cave[y][x]; X if (c_ptr->fopen) X { X if (c_ptr->cptr > 1) X { X m_ptr = &m_list[c_ptr->cptr]; X r_ptr = &c_list[m_ptr->mptr]; X if (randint(MAX_MONS_LEVEL) > r_ptr->level) X { X flag = TRUE; X delete_monster((int)c_ptr->cptr); X place_monster(y, x, X randint(m_level[MAX_MONS_LEVEL]) - 1 + m_level[0], X FALSE); X if (panel_contains(y, x)) X if (test_light(y, x)) X poly = TRUE; X } X else X { X monster_name (m_name, m_ptr, r_ptr); X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X } X else X flag = TRUE; X } X } X else X flag = TRUE; X } X while (!flag); X return(poly); X} X X X/* Create a wall... -RAK- */ Xint build_wall(dir, y, x) Xint dir, y, x; X{ X register int i; X int build; X register cave_type *c_ptr; X X build = FALSE; X i = 0; X (void) move(dir, &y, &x); X while ((cave[y][x].fopen) && (i < 10)) X { X c_ptr = &cave[y][x]; X if (c_ptr->tptr != 0) X (void) delete_object(y, x); X if (c_ptr->cptr > 1) X /* what happens to this monster ? */ X (void) mon_take_hit((int)c_ptr->cptr, damroll("2d8")); X c_ptr->fval = rock_wall2.ftval; X c_ptr->fopen = rock_wall2.ftopen; X c_ptr->fm = FALSE; X if (test_light(y, x)) X lite_spot(y, x); X i++; X build = TRUE; X (void) move(dir, &y, &x); X } X return(build); X} X X X/* Replicate a creature -RAK- */ Xint clone_monster(dir, y, x) Xint dir, y, x; X{ X register int flag; X register int clone; X register cave_type *c_ptr; X X flag = FALSE; X clone = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->cptr > 1) X { X multiply_monster(y, x, (int)m_list[c_ptr->cptr].mptr, FALSE); X if (panel_contains(y, x)) X if (m_list[c_ptr->cptr].ml) X clone = TRUE; X flag = TRUE; X } X } X while ((cave[y][x].fopen) && (!flag)); X return(clone); X} X X X/* Move the creature record to a new location -RAK- */ Xteleport_away(monptr, dis) Xint monptr, dis; X{ X register int yn, xn, ctr; X register monster_type *m_ptr; X X m_ptr = &m_list[monptr]; X ctr = 0; X do X { X do X { X yn = m_ptr->fy + (randint(2*dis+1) - (dis + 1)); X xn = m_ptr->fx + (randint(2*dis+1) - (dis + 1)); X } X while (!in_bounds(yn, xn)); X ctr++; X if (ctr > 9) X { X ctr = 0; X dis += 5; X } X } X while ((!cave[yn][xn].fopen) || (cave[yn][xn].cptr != 0)); X move_rec((int)m_ptr->fy, (int)m_ptr->fx, yn, xn); X if (test_light((int)m_ptr->fy, (int)m_ptr->fx)) X lite_spot((int)m_ptr->fy, (int)m_ptr->fx); X m_ptr->fy = yn; X m_ptr->fx = xn; X m_ptr->ml = FALSE; X} X X X/* Teleport player to spell casting creature -RAK- */ Xteleport_to(ny, nx) Xint ny, nx; X{ X int dis, ctr, y, x; X register int i, j; X register cave_type *c_ptr; X X dis = 1; X ctr = 0; X do X { X y = ny + (randint(2*dis+1) - (dis + 1)); X x = nx + (randint(2*dis+1) - (dis + 1)); X ctr++; X if (ctr > 9) X { X ctr = 0; X dis++; X } X } X while ((!cave[y][x].fopen) || (cave[y][x].cptr >= 2)); X move_rec(char_row, char_col, y, x); X for (i = char_row-1; i <= char_row+1; i++) X for (j = char_col-1; j <= char_col+1; j++) X { X c_ptr = &cave[i][j]; X c_ptr->tl = FALSE; X if (!test_light(i, j)) X unlite_spot(i, j); X } X if (test_light(char_row, char_col)) X lite_spot(char_row, char_col); X char_row = y; X char_col = x; X move_char(5); X /* light creatures */ X creatures(FALSE); X} X X X/* Teleport all creatures in a given direction away -RAK- */ Xint teleport_monster(dir, y, x) Xint dir, y, x; X{ X register int flag; X register int teleport; X register cave_type *c_ptr; X X flag = FALSE; X teleport = FALSE; X do X { X (void) move(dir, &y, &x); X c_ptr = &cave[y][x]; X if (c_ptr->cptr > 1) X { X teleport_away((int)c_ptr->cptr, MAX_SIGHT); X teleport = TRUE; X } X } X while ((cave[y][x].fopen) && (!flag)); X return(teleport); X} X X X/* Delete all creatures within max_sight distance -RAK- */ X/* NOTE : Winning creatures cannot be genocided */ Xint mass_genocide() X{ X register int i, j; X int genocide; X register monster_type *m_ptr; X register creature_type *r_ptr; X X genocide = FALSE; X i = muptr; X while (i > 0) X { X m_ptr = &m_list[i]; X r_ptr = &c_list[m_ptr->mptr]; X j = m_ptr->nptr; X if (m_ptr->cdis <= MAX_SIGHT) X if ((r_ptr->cmove & 0x80000000) == 0) X { X delete_monster(i); X genocide = TRUE; X } X i = j; X } X return(genocide); X} X X X/* Delete all creatures of a given type from level. -RAK- */ X/* This does not keep creatures of type from appearing later. */ X/* NOTE : Winning creatures can not be genocided. */ Xint genocide() X{ X register int i, j; X char typ; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X X i = muptr; X if (get_com("What kind of creature shall be exterminated?", &typ)) X while (i > 0) X { X m_ptr = &m_list[i]; X r_ptr = &c_list[m_ptr->mptr]; X j = m_ptr->nptr; X if (typ == c_list[m_ptr->mptr].cchar) X if ((r_ptr->cmove & 0x80000000) == 0) X delete_monster(i); X else X { X /* genocide is a powerful spell, so we will let the player X know the names of the creatures he did not destroy, X this message makes no sense otherwise */ X (void) sprintf(out_val, "The %s is unaffected.", r_ptr->name); X msg_print(out_val); X } X i = j; X } X return(TRUE); X} X X X/* Change speed of any creature player can see.... -RAK- */ X/* NOTE: cannot slow a winning creature (BALROG) */ Xint speed_monsters(spd) Xint spd; X{ X register int i, j; X int speed; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X i = muptr; X speed = FALSE; X while (i > 0) X { X m_ptr = &m_list[i]; X j = m_ptr->nptr; X if (m_ptr->ml) X { X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X if (spd > 0) X { X m_ptr->cspeed += spd; X m_ptr->csleep = 0; X speed = TRUE; X (void) sprintf (out_val, "%s starts moving faster.", m_name); X msg_print (out_val); X } X else if (randint(MAX_MONS_LEVEL) > r_ptr->level) X { X m_ptr->cspeed += spd; X m_ptr->csleep = 0; X (void) sprintf (out_val, "%s starts moving slower.", m_name); X msg_print (out_val); X speed = TRUE; X } X else X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X } X i = j; X } X return(speed); X} X X X/* Sleep any creature that player can see -RAK- */ Xint sleep_monsters2() X{ X register int i, j; X int sleep; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X i = muptr; X sleep = FALSE; X while (i > 0) X { X m_ptr = &m_list[i]; X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X j = m_ptr->nptr; X if (m_ptr->ml) X { X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) || X (0x1000 & r_ptr->cdefense)) X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X else X { X m_ptr->csleep = 500; X (void) sprintf(out_val, "%s falls asleep.", m_name); X msg_print(out_val); X sleep = TRUE; X } X } X i = j; X } X return(sleep); X} X X X/* Polymorph any creature that player can see... -RAK- */ X/* NOTE: cannot polymorph a winning creature (BALROG) */ Xint mass_poly() X{ X register int i, j; X int y, x; X int mass; X register monster_type *m_ptr; X register creature_type *r_ptr; X X i = muptr; X mass = FALSE; X while (i > 0) X { X m_ptr = &m_list[i]; X j = m_ptr->nptr; X if (m_ptr->cdis < MAX_SIGHT) X { X r_ptr = &c_list[m_ptr->mptr]; X if ((r_ptr->cmove & 0x80000000) == 0) X { X y = m_ptr->fy; X x = m_ptr->fx; X delete_monster(i); X place_monster(y, x, randint(m_level[MAX_MONS_LEVEL]) - 1 X + m_level[0], FALSE); X mass = TRUE; X } X } X i = j; X } X return(mass); X} X X X/* Display evil creatures on current panel -RAK- */ Xint detect_evil() X{ X register int i; X int flag; X register monster_type *m_ptr; X char temp_str[2]; X X flag = FALSE; X i = muptr; X while (i > 0) X { X m_ptr = &m_list[i]; X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) X if (0x0004 & c_list[m_ptr->mptr].cdefense) X { X m_ptr->ml = TRUE; X temp_str[0] = c_list[m_ptr->mptr].cchar; X temp_str[1] = '\0'; X print(temp_str, (int)m_ptr->fy, (int)m_ptr->fx); X flag = TRUE; X } X i = m_list[i].nptr; X } X if (flag) X { X msg_print("You sense the presence of evil!"); X /* make sure player sees the message */ X msg_print(" "); X msg_flag = FALSE; X } X return(flag); X} X X X/* Change players hit points in some manner -RAK- */ Xint hp_player(num, kind) Xint num; Xchar *kind; X{ X register int res; X register struct misc *m_ptr; X X res = FALSE; X m_ptr = &py.misc; X if (num < 0) X { X take_hit(num, kind); X if (m_ptr->chp < 0) X msg_print("You feel your life slipping away!"); X res = TRUE; X } X else if (m_ptr->chp < m_ptr->mhp) X { X m_ptr->chp += (double)num; X if (m_ptr->chp > m_ptr->mhp) X m_ptr->chp = (double)m_ptr->mhp; X prt_chp(); X switch(num/5) X { X case 0: X msg_print("You feel a little better."); X break; X case 1: case 2: X msg_print("You feel better."); X break; X case 3: case 4: case 5: case 6: X msg_print("You feel much better."); X break; X default: X msg_print("You feel very good."); X break; X } X res = TRUE; X } X return(res); X} X X X/* Cure players confusion -RAK- */ Xint cure_confusion() X{ X register int cure; X register struct flags *f_ptr; X X cure = FALSE; X f_ptr = &py.flags; X if (f_ptr->confused > 1) X { X f_ptr->confused = 1; X cure = TRUE; X } X return(cure); X} X X X/* Cure players blindness -RAK- */ Xint cure_blindness() X{ X register int cure; X register struct flags *f_ptr; X X cure = FALSE; X f_ptr = &py.flags; X if (f_ptr->blind > 1) X { X f_ptr->blind = 1; X cure = TRUE; X } X return(cure); X} X X X/* Cure poisoning -RAK- */ Xint cure_poison() X{ X register int cure; X register struct flags *f_ptr; X X cure = FALSE; X f_ptr = &py.flags; X if (f_ptr->poisoned > 1) X { X f_ptr->poisoned = 1; X cure = TRUE; X } X return(cure); X} X X X/* Cure the players fear -RAK- */ Xint remove_fear() X{ X register int remove; X register struct flags *f_ptr; X X remove = FALSE; X f_ptr = &py.flags; X if (f_ptr->afraid > 1) X { X f_ptr->afraid = 1; X remove = TRUE; X } X return(remove); X} X X X/* This is a fun one. In a given block, pick some walls and */ X/* turn them into open spots. Pick some open spots and turn */ X/* them into walls. An "Earthquake" effect... -RAK- */ Xint earthquake() X{ X register int i, j; X register cave_type *c_ptr; X X for (i = char_row-8; i <= char_row+8; i++) X for (j = char_col-8; j <= char_col+8; j++) X if ((i != char_row) || (j != char_col)) X if (in_bounds(i, j)) X if (randint(8) == 1) X { X c_ptr = &cave[i][j]; X if (c_ptr->tptr != 0) X (void) delete_object(i, j); X if (c_ptr->cptr > 1) X /* what happens to this monster ? */ X (void) mon_take_hit((int)c_ptr->cptr, damroll("2d8")); X if ((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) X { X if (next_to4(i, j, 1, 2, -1) > 0) X { X c_ptr->fval = corr_floor2.ftval; X c_ptr->fopen = corr_floor2.ftopen; X } X else X { X c_ptr->fval = corr_floor1.ftval; X c_ptr->fopen = corr_floor1.ftopen; X } X if (test_light(i, j)) X unlite_spot(i, j); X c_ptr->pl = FALSE; X c_ptr->fm = FALSE; X if (c_ptr->tl) X lite_spot(i, j); X } X else if (set_floor(c_ptr->fval)) X { X switch(randint(10)) X { X case 1: case 2: case 3: case 4: case 5: X c_ptr->fval = rock_wall3.ftval; X c_ptr->fopen = rock_wall3.ftopen; X break; X case 6: case 7: case 8: X c_ptr->fval = rock_wall2.ftval; X c_ptr->fopen = rock_wall2.ftopen; X break; X case 9: case 10: X c_ptr->fval = rock_wall1.ftval; X c_ptr->fopen = rock_wall1.ftopen; X break; X } X c_ptr->fm = FALSE; X } X if (test_light(i, j)) X lite_spot(i, j); X } X return(TRUE); X} X X X/* Evil creatures don't like this... -RAK- */ Xint protect_evil() X{ X register struct flags *f_ptr; X X f_ptr = &py.flags; X f_ptr->protevil += randint(25) + 3*py.misc.lev; X return(TRUE); X} X X X/* Create some high quality mush for the player. -RAK- */ Xint create_food() X{ X register cave_type *c_ptr; X X c_ptr = &cave[char_row][char_col]; X if (c_ptr->tptr != 0) X { X /* take no action here, don't want to destroy object under player */ X msg_print ("There is already an object under you."); X /* set reset_flag so that scroll/spell points won't be used */ X reset_flag = TRUE; X } X else X { X place_object(char_row, char_col); X t_list[c_ptr->tptr] = mush; X } X return (TRUE); X} X X X/* Attempts to destroy a type of creature. Success depends on */ X/* the creatures level VS. the player's level -RAK- */ Xint dispell_creature(cflag, damage) Xint cflag; Xint damage; X{ X register int i, m_next; X vtype out_val; X register monster_type *m_ptr; X register creature_type *r_ptr; X register struct misc *p_ptr; X int dispel; X vtype m_name; X X i = muptr; X dispel = FALSE; X while (i > 0) X { X m_next = m_list[i].nptr; X m_ptr = &m_list[i]; X if (m_ptr->ml) X if (cflag & c_list[m_ptr->mptr].cdefense) X { X m_ptr->hp -= randint(damage); X m_ptr->csleep = 0; X r_ptr = &c_list[m_ptr->mptr]; X monster_name (m_name, m_ptr, r_ptr); X if (m_ptr->hp < 0) X { X (void) sprintf(out_val, "%s dissolves!", m_name); X msg_print(out_val); X monster_death((int)m_ptr->fy, (int)m_ptr->fx, X c_list[m_ptr->mptr].cmove); X p_ptr = &py.misc; X p_ptr->exp += ((r_ptr->mexp*(r_ptr->level/p_ptr->lev)) + 0.5); X delete_monster(i); X } X else X { X (void) sprintf(out_val, "%s shudders.", m_name); X msg_print(out_val); X } X dispel = TRUE; X } X i = m_next; X } X return(dispel); X} X X X/* Attempt to turn (confuse) undead creatures... -RAK- */ Xint turn_undead() X{ X register int i; X int turn_und; X register monster_type *m_ptr; X register creature_type *r_ptr; X vtype out_val; X vtype m_name; X X i = muptr; X turn_und = FALSE; X while (i > 0) X { X m_ptr = &m_list[i]; X r_ptr = &c_list[m_ptr->mptr]; X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) X if (m_ptr->ml) X if (0x0008 & r_ptr->cdefense) X { X monster_name (m_name, m_ptr, r_ptr); X if (((py.misc.lev+1) > r_ptr->level) || X (randint(5) == 1)) X { X (void) sprintf(out_val, "%s runs frantically!", m_name); X msg_print(out_val); X m_ptr->confused = TRUE; X turn_und = TRUE; X } X else X { X (void) sprintf(out_val, "%s is unaffected.", m_name); X msg_print(out_val); X } X } X i = m_list[i].nptr; X } X return(turn_und); X} X X X/* Leave a glyph of warding... Creatures will not pass over! -RAK-*/ Xint warding_glyph() X{ X int i; X register cave_type *c_ptr; X X c_ptr = &cave[char_row][char_col]; X if (c_ptr->tptr == 0) X { X popt(&i); X c_ptr->tptr = i; X t_list[i] = scare_monster; X } X return(TRUE); X} X X X/* Lose a strength point. -RAK- */ Xint lose_str() X{ X if (!py.flags.sustain_str) X { X py.stats.cstr = de_statp(py.stats.cstr); X msg_print("You feel very sick."); X prt_strength(); X /* adjust misc stats */ X py_bonuses(blank_treasure, 0); X } X else X msg_print("You feel sick for a moment, it passes."); X return(TRUE); X} X X X/* Lose an intelligence point. -RAK- */ Xint lose_int() X{ X if (!py.flags.sustain_int) X { X py.stats.cint = de_statp(py.stats.cint); X msg_print("You become very dizzy."); X prt_intelligence(); X } X else X msg_print("You become dizzy for a moment, it passes."); X return(TRUE); X} X X X/* Lose a wisdom point. -RAK- */ Xint lose_wis() X{ X if (!py.flags.sustain_wis) X { X py.stats.cwis = de_statp(py.stats.cwis); X msg_print("You feel very naive."); X prt_wisdom(); X } X else X msg_print("You feel naive for a moment, it passes."); X return(TRUE); X} X X X/* Lose a dexterity point. -RAK- */ Xint lose_dex() X{ X if (!py.flags.sustain_dex) X { X py.stats.cdex = de_statp(py.stats.cdex); X msg_print("You feel very sore."); X prt_dexterity(); X /* adjust misc stats */ X py_bonuses(blank_treasure, 0); X } X else X msg_print("You feel sore for a moment, it passes."); X return(TRUE); X} X X X/* Lose a constitution point. -RAK- */ Xint lose_con() X{ X if (!py.flags.sustain_con) X { X py.stats.ccon = de_statp(py.stats.ccon); X msg_print("You feel very sick."); X prt_constitution(); X } X else X msg_print("You feel sick for a moment, it passes."); X return(TRUE); X} X X X/* Lose a charisma point. -RAK- */ Xint lose_chr() X{ X if (!py.flags.sustain_chr) X { X py.stats.cchr = de_statp(py.stats.cchr); X msg_print("Your skin starts to itch."); X prt_charisma(); X } X else X msg_print("Your skin starts to itch, but feels better now."); X return(TRUE); X} X X X/* Lose experience -RAK- */ Xlose_exp(amount) Xint amount; X{ X register int i, j; X int av_hp, lose_hp; X int av_mn, lose_mn; X register struct misc *m_ptr; X register class_type *c_ptr; X int num_known, adjust, num_allowed, num_lose; X double avg_spells; X X m_ptr = &py.misc; X if (amount > m_ptr->exp) X m_ptr->exp = 0; X else X m_ptr->exp -= amount; X i = 1; X while ((player_exp[i-1]*m_ptr->expfact) <= m_ptr->exp) X i++; X j = m_ptr->lev - i; X while (j > 0) X { X av_hp = (int)((double)m_ptr->mhp/(double)m_ptr->lev + 0.5); X av_mn = (int)((double)m_ptr->mana/(double)m_ptr->lev + 0.5); X m_ptr->lev--; X j--; X lose_hp = randint(av_hp*2-1); X lose_mn = randint(av_mn*2-1); X m_ptr->mhp -= lose_hp; X m_ptr->mana -= lose_mn; X if (m_ptr->mhp < 1) m_ptr->mhp = 1; X if (m_ptr->mana < 0) m_ptr->mana = 0; X X /* perhaps lose some spells, depending on current int/wis and level */ X c_ptr = &class[m_ptr->pclass]; X if ((c_ptr->mspell) || (c_ptr->pspell)) X { X /* count spells known */ X num_known = 0; X for (i = 0; i < 31; i++) X if (magic_spell[m_ptr->pclass][i].learned) X num_known++; X X /* calculate number of spells allowed */ X if (c_ptr->mspell) X adjust = int_adj(); X else X adjust = wis_adj(); X switch (adjust) X { X case 0: avg_spells = 0.0; break; X case 1: avg_spells = 1.0; break; X case 2: avg_spells = 1.0; break; X case 3: avg_spells = 1.0; break; X case 4: avg_spells = 1.5; break; X case 5: avg_spells = 1.5; break; X case 6: avg_spells = 2.0; break; X case 7: avg_spells = 2.5; break; X default: avg_spells = 1.0; break; X } X num_allowed = (int)(m_ptr->lev * avg_spells + 0.5); X num_lose = num_known - num_allowed; X X /* forget spells until both: X number known is less than or equal to number allowed X and highest spell level is lower than or equal to player level */ X i = 30; X while (((magic_spell[m_ptr->pclass][i].slevel > m_ptr->lev) X || (num_lose > 0)) X && (i >= 0)) X { X if (magic_spell[m_ptr->pclass][i].learned) X { X magic_spell[m_ptr->pclass][i].learned = FALSE; X num_lose--; X if (c_ptr->mspell) X msg_print("You have forgotten a magic spell!"); X else X msg_print("You have forgotten a prayer!"); X } X i--; X } X } X } X if (m_ptr->chp > m_ptr->mhp) X m_ptr->chp = (double)m_ptr->mhp; X if (m_ptr->cmana > m_ptr->mana) X m_ptr->cmana = (double)m_ptr->mana; X (void) strcpy(m_ptr->title, player_title[m_ptr->pclass][m_ptr->lev-1]); X prt_experience(); X prt_mhp(); X prt_chp(); X prt_cmana(); X prt_level(); X prt_title(); X} X X X/* Slow Poison -RAK- */ Xint slow_poison() X{ X register int slow; X register struct flags *f_ptr; X X slow = FALSE; X f_ptr = &py.flags; X if (f_ptr->poisoned > 0) X { X f_ptr->poisoned = f_ptr->poisoned / 2.0; X if (f_ptr->poisoned < 1) f_ptr->poisoned = 1; X slow = TRUE; X msg_print("The effects of the poison has been reduced."); X } X return(slow); X} X X X/* Bless -RAK- */ Xint bless(amount) Xint amount; X{ X py.flags.blessed += amount; X return(TRUE); X} X X X/* Detect Invisible for period of time -RAK- */ Xdetect_inv2(amount) Xint amount; X{ X py.flags.detect_inv += amount; X} X X Xreplace_spot(y, x, typ) Xint y, x, typ; X{ X register cave_type *c_ptr; X X c_ptr = &cave[y][x]; X switch(typ) X { X case 1: case 2: case 3: X c_ptr->fval = corr_floor1.ftval; X c_ptr->fopen = corr_floor1.ftopen; X break; X case 4: case 7: case 10: X c_ptr->fval = rock_wall1.ftval; X c_ptr->fopen = rock_wall1.ftopen; X break; X case 5: case 8: case 11: X c_ptr->fval = rock_wall2.ftval; X c_ptr->fopen = rock_wall2.ftopen; X break; X case 6: case 9: case 12: X c_ptr->fval = rock_wall3.ftval; X c_ptr->fopen = rock_wall3.ftopen; X break; X } X c_ptr->pl = FALSE; X c_ptr->fm = FALSE; X if (c_ptr->tptr != 0) X (void) delete_object(y, x); X if (c_ptr->cptr > 1) X delete_monster((int)c_ptr->cptr); X} X X X/* The spell of destruction... -RAK- */ X/* NOTE : Winning creatures that are deleted will be considered */ X/* as teleporting to another level. This will NOT win the*/ X/* game... */ Xint destroy_area(y, x) Xregister int y, x; X{ X register int i, j, k; X X if (dun_level > 0) X { X for (i = (y-15); i <= (y+15); i++) X for (j = (x-15); j <= (x+15); j++) X if (in_bounds(i, j)) X if (cave[i][j].fval != 15) X { X k = distance(i, j, y, x); X if (k < 13) X replace_spot(i, j, randint(6)); X else if (k < 16) X replace_spot(i, j, randint(9)); X } X } X msg_print("There is a searing blast of light!"); X py.flags.blind += 10 + randint(10); X return(TRUE); X} X X X/* Enchants a plus onto an item... -RAK- */ Xint enchant(plusses) Xworlint *plusses; X{ X register int chance; X register int res; X X chance = 0; X res = FALSE; X if (*plusses > 0) X switch(*plusses) X { X case 1: chance = 040; break; X case 2: chance = 100; break; X case 3: chance = 200; break; X case 4: chance = 400; break; X case 5: chance = 600; break; X case 6: chance = 700; break; X case 7: chance = 800; break; X case 8: chance = 900; break; X case 9: chance = 950; break; X default: chance = 995; break; X } X if (randint(1000) > chance) X { X *plusses += 1; X res = TRUE; X } X return(res); X} X X X/* Removes curses from items in inventory -RAK- */ Xint remove_curse() X{ X register int i; X register int remove; X register treasure_type *i_ptr; X X remove = FALSE; X for (i = 22; i <= 31; i++) X { X i_ptr = &inventory[i]; X if (0x80000000 & i_ptr->flags) X { X i_ptr->flags &= 0x7FFFFFFF; X py_bonuses(blank_treasure, 0); X remove = TRUE; X } X } X return(remove); X} X X X/* Restores any drained experience -RAK- */ Xint restore_level() X{ X register int restore; X register struct misc *m_ptr; X X restore = FALSE; X m_ptr = &py.misc; X if (m_ptr->max_exp > m_ptr->exp) X { X restore = TRUE; X msg_print("You feel your life energies returning..."); X m_ptr->exp = m_ptr->max_exp; X prt_experience(); X } X return(restore); X} END_OF_FILE if test 56166 -ne `wc -c <'spells.c'`; then echo shar: \"'spells.c'\" unpacked with wrong size! fi # end of 'spells.c' fi echo shar: End of archive 18 \(of 18\). cp /dev/null ark18isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 18 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0