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