home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i038: umoria4 - single player dungeon simulation (ver. 5.5), Part06/39
- Message-ID: <3396@master.CNA.TEK.COM>
- Date: 20 Aug 92 18:02:48 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2078
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 38
- Archive-name: umoria4/Part06
- Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
- Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
-
-
-
- #! /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 6 (of 39)."
- # Contents: source/creature.c util/printit/pr_monst.c
- # Wrapped by billr@saab on Thu Aug 20 09:11:27 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'source/creature.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/creature.c'\"
- else
- echo shar: Extracting \"'source/creature.c'\" \(46325 characters\)
- sed "s/^X//" >'source/creature.c' <<'END_OF_FILE'
- X/* source/creature.c: handle monster movement and attacks
- X
- X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X#ifdef __TURBOC__
- X#include <stdio.h>
- X#include <stdlib.h>
- X#endif /* __TURBOC__ */
- X
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef USG
- X#ifndef ATARIST_MWC
- X#include <string.h>
- X#else
- Xchar *strcat();
- Xchar *strcpy();
- X#endif
- X#else
- X#include <strings.h>
- X#endif
- X
- X#if defined(LINT_ARGS)
- Xstatic int movement_rate(int16);
- Xstatic int check_mon_lite(int, int);
- Xstatic void get_moves(int, int *);
- Xstatic void make_attack(int);
- Xstatic void make_move(int, int *, int32u *);
- Xstatic void mon_cast_spell(int, int *);
- Xstatic void mon_move(int, int32u *);
- X#endif
- X
- X#ifdef ATARIST_TC
- X/* Include this to get prototypes for standard library functions. */
- X#include <stdlib.h>
- X#endif
- X
- X
- X/* Updates screen when monsters move about -RAK- */
- Xvoid update_mon(monptr)
- Xint monptr;
- X{
- X register int flag;
- X register cave_type *c_ptr;
- X register monster_type *m_ptr;
- X register creature_type *r_ptr;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X m_ptr = &m_list[monptr];
- X flag = FALSE;
- X if ((m_ptr->cdis <= MAX_SIGHT) &&
- X !(py.flags.status & PY_BLIND) &&
- X (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)))
- X {
- X /* Wizard sight. */
- X if (wizard)
- X flag = TRUE;
- X /* Normal sight. */
- X else if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
- X {
- X c_ptr = &cave[m_ptr->fy][m_ptr->fx];
- X r_ptr = &c_list[m_ptr->mptr];
- X if (c_ptr->pl || c_ptr->tl ||
- X (find_flag && m_ptr->cdis < 2 && player_light))
- X {
- X#ifdef ATARIST_MWC
- X holder = CM_INVISIBLE;
- X if ((holder & r_ptr->cmove) == 0)
- X#else
- X if ((CM_INVISIBLE & r_ptr->cmove) == 0)
- X#endif
- X flag = TRUE;
- X else if (py.flags.see_inv)
- X {
- X flag = TRUE;
- X#ifdef ATARIST_MWC
- X c_recall[m_ptr->mptr].r_cmove |= holder;
- X#else
- X c_recall[m_ptr->mptr].r_cmove |= CM_INVISIBLE;
- X#endif
- X }
- X }
- X /* Infra vision. */
- X else if ((py.flags.see_infra > 0) &&
- X (m_ptr->cdis <= py.flags.see_infra) &&
- X (CD_INFRA & r_ptr->cdefense))
- X {
- X flag = TRUE;
- X c_recall[m_ptr->mptr].r_cdefense |= CD_INFRA;
- X }
- X }
- X }
- X /* Light it up. */
- X if (flag)
- X {
- X if (!m_ptr->ml)
- X {
- X disturb (1, 0);
- X m_ptr->ml = TRUE;
- X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
- X screen_change = TRUE; /* notify inven_command */
- X }
- X }
- X /* Turn it off. */
- X else if (m_ptr->ml)
- X {
- X m_ptr->ml = FALSE;
- X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
- X screen_change = TRUE; /* notify inven_command */
- X }
- X}
- X
- X
- X/* Given speed, returns number of moves this turn. -RAK- */
- X/* NOTE: Player must always move at least once per iteration, */
- X/* a slowed player is handled by moving monsters faster */
- Xstatic int movement_rate(speed)
- Xregister int16 speed;
- X{
- X if (speed > 0)
- X {
- X if (py.flags.rest != 0)
- X return 1;
- X else
- X return speed;
- X }
- X else
- X {
- X /* speed must be negative here */
- X return ((turn % (2 - speed)) == 0);
- X }
- X}
- X
- X
- X/* Makes sure a new creature gets lit up. -CJS- */
- Xstatic int check_mon_lite(y, x)
- Xint y, x;
- X{
- X register int monptr;
- X
- X monptr = cave[y][x].cptr;
- X if (monptr <= 1)
- X return FALSE;
- X else
- X {
- X update_mon(monptr);
- X return m_list[monptr].ml;
- X }
- X}
- X
- X
- X/* Choose correct directions for monster movement -RAK- */
- Xstatic void get_moves(monptr, mm)
- Xint monptr;
- Xregister int *mm;
- X{
- X int y, ay, x, ax, move_val;
- X
- X y = m_list[monptr].fy - char_row;
- X x = m_list[monptr].fx - char_col;
- X if (y < 0)
- X {
- X move_val = 8;
- X ay = -y;
- X }
- X else
- X {
- X move_val = 0;
- X ay = y;
- X }
- X if (x > 0)
- X {
- X move_val += 4;
- X ax = x;
- X }
- X else
- X ax = -x;
- X /* this has the advantage of preventing the diamond maneuvre, also faster */
- X if (ay > (ax << 1))
- X move_val += 2;
- X else if (ax > (ay << 1))
- X move_val++;
- X switch(move_val)
- X {
- X case 0:
- X mm[0] = 9;
- X if (ay > ax)
- X {
- X mm[1] = 8;
- X mm[2] = 6;
- X mm[3] = 7;
- X mm[4] = 3;
- X }
- X else
- X {
- X mm[1] = 6;
- X mm[2] = 8;
- X mm[3] = 3;
- X mm[4] = 7;
- X }
- X break;
- X case 1: case 9:
- X mm[0] = 6;
- X if (y < 0)
- X {
- X mm[1] = 3;
- X mm[2] = 9;
- X mm[3] = 2;
- X mm[4] = 8;
- X }
- X else
- X {
- X mm[1] = 9;
- X mm[2] = 3;
- X mm[3] = 8;
- X mm[4] = 2;
- X }
- X break;
- X case 2: case 6:
- X mm[0] = 8;
- X if (x < 0)
- X {
- X mm[1] = 9;
- X mm[2] = 7;
- X mm[3] = 6;
- X mm[4] = 4;
- X }
- X else
- X {
- X mm[1] = 7;
- X mm[2] = 9;
- X mm[3] = 4;
- X mm[4] = 6;
- X }
- X break;
- X case 4:
- X mm[0] = 7;
- X if (ay > ax)
- X {
- X mm[1] = 8;
- X mm[2] = 4;
- X mm[3] = 9;
- X mm[4] = 1;
- X }
- X else
- X {
- X mm[1] = 4;
- X mm[2] = 8;
- X mm[3] = 1;
- X mm[4] = 9;
- X }
- X break;
- X case 5: case 13:
- X mm[0] = 4;
- X if (y < 0)
- X {
- X mm[1] = 1;
- X mm[2] = 7;
- X mm[3] = 2;
- X mm[4] = 8;
- X }
- X else
- X {
- X mm[1] = 7;
- X mm[2] = 1;
- X mm[3] = 8;
- X mm[4] = 2;
- X }
- X break;
- X case 8:
- X mm[0] = 3;
- X if (ay > ax)
- X {
- X mm[1] = 2;
- X mm[2] = 6;
- X mm[3] = 1;
- X mm[4] = 9;
- X }
- X else
- X {
- X mm[1] = 6;
- X mm[2] = 2;
- X mm[3] = 9;
- X mm[4] = 1;
- X }
- X break;
- X case 10: case 14:
- X mm[0] = 2;
- X if (x < 0)
- X {
- X mm[1] = 3;
- X mm[2] = 1;
- X mm[3] = 6;
- X mm[4] = 4;
- X }
- X else
- X {
- X mm[1] = 1;
- X mm[2] = 3;
- X mm[3] = 4;
- X mm[4] = 6;
- X }
- X break;
- X case 12:
- X mm[0] = 1;
- X if (ay > ax)
- X {
- X mm[1] = 2;
- X mm[2] = 4;
- X mm[3] = 3;
- X mm[4] = 7;
- X }
- X else
- X {
- X mm[1] = 4;
- X mm[2] = 2;
- X mm[3] = 7;
- X mm[4] = 3;
- X }
- X break;
- X }
- X}
- X
- X
- X/* Make an attack on the player (chuckle.) -RAK- */
- Xstatic void make_attack(monptr)
- Xint monptr;
- X{
- X int attype, adesc, adice, asides;
- X int i, j, damage, flag, attackn, notice, visible;
- X int32 gold;
- X int8u *attstr;
- X vtype cdesc, tmp_str, ddesc;
- X register creature_type *r_ptr;
- X monster_type *m_ptr;
- X register struct misc *p_ptr;
- X register struct flags *f_ptr;
- X register inven_type *i_ptr;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X if (death) /* don't beat a dead body! */
- X return;
- X
- X m_ptr = &m_list[monptr];
- X r_ptr = &c_list[m_ptr->mptr];
- X if (!m_ptr->ml)
- X (void) strcpy(cdesc, "It ");
- X else
- X (void) sprintf(cdesc, "The %s ", r_ptr->name);
- X /* For "DIED_FROM" string */
- X#ifdef ATARIST_MWC
- X holder = CM_WIN;
- X if (holder & r_ptr->cmove)
- X#else
- X if (CM_WIN & r_ptr->cmove)
- X#endif
- X (void) sprintf(ddesc, "The %s", r_ptr->name);
- X else if (is_a_vowel (r_ptr->name[0]))
- X (void) sprintf(ddesc, "an %s", r_ptr->name);
- X else
- X (void) sprintf (ddesc, "a %s", r_ptr->name);
- X /* End DIED_FROM */
- X
- X attackn = 0;
- X attstr = r_ptr->damage;
- X while ((*attstr != 0) && !death)
- X {
- X attype = monster_attacks[*attstr].attack_type;
- X adesc = monster_attacks[*attstr].attack_desc;
- X adice = monster_attacks[*attstr].attack_dice;
- X asides = monster_attacks[*attstr].attack_sides;
- X attstr++;
- X flag = FALSE;
- X if ((py.flags.protevil > 0) && (r_ptr->cdefense & CD_EVIL) &&
- X ((py.misc.lev + 1) > r_ptr->level))
- X {
- X if (m_ptr->ml)
- X c_recall[m_ptr->mptr].r_cdefense |= CD_EVIL;
- X attype = 99;
- X adesc = 99;
- X }
- X p_ptr = &py.misc;
- X switch(attype)
- X {
- X case 1: /*Normal attack */
- X if (test_hit(60, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 2: /*Lose Strength*/
- X if (test_hit(-3, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 3: /*Confusion attack*/
- X if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 4: /*Fear attack */
- X if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 5: /*Fire attack */
- X if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 6: /*Acid attack */
- X if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 7: /*Cold attack */
- X if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 8: /*Lightning attack*/
- X if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 9: /*Corrosion attack*/
- X if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 10: /*Blindness attack*/
- X if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 11: /*Paralysis attack*/
- X if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 12: /*Steal Money */
- X if ((test_hit(5, (int)r_ptr->level, 0, (int)py.misc.lev,
- X CLA_MISC_HIT))
- X && (py.misc.au > 0))
- X flag = TRUE;
- X break;
- X case 13: /*Steal Object */
- X if ((test_hit(2, (int)r_ptr->level, 0, (int)py.misc.lev,
- X CLA_MISC_HIT))
- X && (inven_ctr > 0))
- X flag = TRUE;
- X break;
- X case 14: /*Poison */
- X if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 15: /*Lose dexterity*/
- X if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 16: /*Lose constitution*/
- X if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 17: /*Lose intelligence*/
- X if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 18: /*Lose wisdom*/
- X if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 19: /*Lose experience*/
- X if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 20: /*Aggravate monsters*/
- X flag = TRUE;
- X break;
- X case 21: /*Disenchant */
- X if (test_hit(20, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 22: /*Eat food */
- X if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 23: /*Eat light */
- X if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT))
- X flag = TRUE;
- X break;
- X case 24: /*Eat charges */
- X if ((test_hit(15, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
- X CLA_MISC_HIT)) &&
- X (inven_ctr > 0)) /* check to make sure an object exists */
- X flag = TRUE;
- X break;
- X case 99:
- X flag = TRUE;
- X break;
- X default:
- X break;
- X }
- X if (flag)
- X {
- X /* can not strcat to cdesc because the creature may have
- X multiple attacks */
- X disturb (1, 0);
- X (void) strcpy(tmp_str, cdesc);
- X switch(adesc)
- X {
- X case 1: msg_print(strcat(tmp_str, "hits you.")); break;
- X case 2: msg_print(strcat(tmp_str, "bites you.")); break;
- X case 3: msg_print(strcat(tmp_str, "claws you.")); break;
- X case 4: msg_print(strcat(tmp_str, "stings you.")); break;
- X case 5: msg_print(strcat(tmp_str, "touches you.")); break;
- X#if 0
- X case 6: msg_print(strcat(tmp_str, "kicks you.")); break;
- X#endif
- X case 7: msg_print(strcat(tmp_str, "gazes at you.")); break;
- X case 8: msg_print(strcat(tmp_str, "breathes on you.")); break;
- X case 9: msg_print(strcat(tmp_str, "spits on you.")); break;
- X case 10: msg_print(strcat(tmp_str,"makes a horrible wail."));break;
- X#if 0
- X case 11: msg_print(strcat(tmp_str, "embraces you.")); break;
- X#endif
- X case 12: msg_print(strcat(tmp_str, "crawls on you.")); break;
- X case 13:
- X msg_print(strcat(tmp_str, "releases a cloud of spores.")); break;
- X case 14: msg_print(strcat(tmp_str, "begs you for money.")); break;
- X case 15: msg_print("You've been slimed!"); break;
- X case 16: msg_print(strcat(tmp_str, "crushes you.")); break;
- X case 17: msg_print(strcat(tmp_str, "tramples you.")); break;
- X case 18: msg_print(strcat(tmp_str, "drools on you.")); break;
- X case 19:
- X switch(randint(9))
- X {
- X case 1: msg_print(strcat(tmp_str, "insults you!")); break;
- X case 2:
- X msg_print(strcat(tmp_str, "insults your mother!")); break;
- X case 3:
- X msg_print(strcat(tmp_str, "gives you the finger!")); break;
- X case 4: msg_print(strcat(tmp_str, "humiliates you!")); break;
- X case 5: msg_print(strcat(tmp_str, "wets on your leg!")); break;
- X case 6: msg_print(strcat(tmp_str, "defiles you!")); break;
- X case 7: msg_print(strcat(tmp_str, "dances around you!"));break;
- X case 8:
- X msg_print(strcat(tmp_str, "makes obscene gestures!")); break;
- X case 9: msg_print(strcat(tmp_str, "moons you!!!")); break;
- X }
- X break;
- X case 99: msg_print(strcat(tmp_str, "is repelled.")); break;
- X default: break;
- X }
- X
- X notice = TRUE;
- X /* always fail to notice attack if creature invisible, set notice
- X and visible here since creature may be visible when attacking
- X and then teleport afterwards (becoming effectively invisible) */
- X if (!m_ptr->ml)
- X {
- X visible = FALSE;
- X notice = FALSE;
- X }
- X else
- X visible = TRUE;
- X
- X damage = damroll (adice, asides);
- X switch(attype)
- X {
- X case 1: /*Normal attack */
- X /* round half-way case down */
- X damage -= ((p_ptr->pac+p_ptr->ptoac) * damage) / 200;
- X take_hit(damage, ddesc);
- X break;
- X case 2: /*Lose Strength*/
- X take_hit(damage, ddesc);
- X if (py.flags.sustain_str)
- X msg_print("You feel weaker for a moment, but it passes.");
- X else if (randint(2) == 1)
- X {
- X msg_print("You feel weaker.");
- X (void) dec_stat (A_STR);
- X }
- X else
- X notice = FALSE;
- X break;
- X case 3: /*Confusion attack*/
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (randint(2) == 1)
- X {
- X if (f_ptr->confused < 1)
- X {
- X msg_print("You feel confused.");
- X f_ptr->confused += randint((int)r_ptr->level);
- X }
- X else
- X notice = FALSE;
- X f_ptr->confused += 3;
- X }
- X else
- X notice = FALSE;
- X break;
- X case 4: /*Fear attack */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (player_saves())
- X msg_print("You resist the effects!");
- X else if (f_ptr->afraid < 1)
- X {
- X msg_print("You are suddenly afraid!");
- X f_ptr->afraid += 3 + randint((int)r_ptr->level);
- X }
- X else
- X {
- X f_ptr->afraid += 3;
- X notice = FALSE;
- X }
- X break;
- X case 5: /*Fire attack */
- X msg_print("You are enveloped in flames!");
- X fire_dam(damage, ddesc);
- X break;
- X case 6: /*Acid attack */
- X msg_print("You are covered in acid!");
- X acid_dam(damage, ddesc);
- X break;
- X case 7: /*Cold attack */
- X msg_print("You are covered with frost!");
- X cold_dam(damage, ddesc);
- X break;
- X case 8: /*Lightning attack*/
- X msg_print("Lightning strikes you!");
- X light_dam(damage, ddesc);
- X break;
- X case 9: /*Corrosion attack*/
- X msg_print("A stinging red gas swirls about you.");
- X corrode_gas(ddesc);
- X take_hit(damage, ddesc);
- X break;
- X case 10: /*Blindness attack*/
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (f_ptr->blind < 1)
- X {
- X f_ptr->blind += 10 + randint((int)r_ptr->level);
- X msg_print("Your eyes begin to sting.");
- X }
- X else
- X {
- X f_ptr->blind += 5;
- X notice = FALSE;
- X }
- X break;
- X case 11: /*Paralysis attack*/
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (player_saves())
- X msg_print("You resist the effects!");
- X else if (f_ptr->paralysis < 1)
- X {
- X if (f_ptr->free_act)
- X msg_print("You are unaffected.");
- X else
- X {
- X f_ptr->paralysis = randint((int)r_ptr->level) + 3;
- X msg_print("You are paralyzed.");
- X }
- X }
- X else
- X notice = FALSE;
- X break;
- X case 12: /*Steal Money */
- X if ((py.flags.paralysis < 1) &&
- X (randint(124) < py.stats.use_stat[A_DEX]))
- X msg_print("You quickly protect your money pouch!");
- X else
- X {
- X gold = (p_ptr->au/10) + randint(25);
- X if (gold > p_ptr->au)
- X p_ptr->au = 0;
- X else
- X p_ptr->au -= gold;
- X msg_print("Your purse feels lighter.");
- X prt_gold();
- X }
- X if (randint(2) == 1)
- X {
- X msg_print("There is a puff of smoke!");
- X teleport_away(monptr, MAX_SIGHT);
- X }
- X break;
- X case 13: /*Steal Object */
- X if ((py.flags.paralysis < 1) &&
- X (randint(124) < py.stats.use_stat[A_DEX]))
- X msg_print("You grab hold of your backpack!");
- X else
- X {
- X i = randint(inven_ctr) - 1;
- X inven_destroy(i);
- X msg_print("Your backpack feels lighter.");
- X }
- X if (randint(2) == 1)
- X {
- X msg_print("There is a puff of smoke!");
- X teleport_away(monptr, MAX_SIGHT);
- X }
- X break;
- X case 14: /*Poison */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X msg_print("You feel very sick.");
- X f_ptr->poisoned += randint((int)r_ptr->level)+5;
- X break;
- X case 15: /*Lose dexterity */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (f_ptr->sustain_dex)
- X msg_print("You feel clumsy for a moment, but it passes.");
- X else
- X {
- X msg_print("You feel more clumsy.");
- X (void) dec_stat (A_DEX);
- X }
- X break;
- X case 16: /*Lose constitution */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (f_ptr->sustain_con)
- X msg_print("Your body resists the effects of the disease.");
- X else
- X {
- X msg_print("Your health is damaged!");
- X (void) dec_stat (A_CON);
- X }
- X break;
- X case 17: /*Lose intelligence */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X msg_print("You have trouble thinking clearly.");
- X if (f_ptr->sustain_int)
- X msg_print("But your mind quickly clears.");
- X else
- X (void) dec_stat (A_INT);
- X break;
- X case 18: /*Lose wisdom */
- X f_ptr = &py.flags;
- X take_hit(damage, ddesc);
- X if (f_ptr->sustain_wis)
- X msg_print("Your wisdom is sustained.");
- X else
- X {
- X msg_print("Your wisdom is drained.");
- X (void) dec_stat (A_WIS);
- X }
- X break;
- X case 19: /*Lose experience */
- X msg_print("You feel your life draining away!");
- X lose_exp(damage + (py.misc.exp / 100)*MON_DRAIN_LIFE);
- X break;
- X case 20: /*Aggravate monster*/
- X (void) aggravate_monster(20);
- X break;
- X case 21: /*Disenchant */
- X flag = FALSE;
- X switch(randint(7))
- X {
- X case 1: i = INVEN_WIELD; break;
- X case 2: i = INVEN_BODY; break;
- X case 3: i = INVEN_ARM; break;
- X case 4: i = INVEN_OUTER; break;
- X case 5: i = INVEN_HANDS; break;
- X case 6: i = INVEN_HEAD; break;
- X case 7: i = INVEN_FEET; break;
- X }
- X i_ptr = &inventory[i];
- X if (i_ptr->tohit > 0)
- X {
- X i_ptr->tohit -= randint(2);
- X /* don't send it below zero */
- X if (i_ptr->tohit < 0)
- X i_ptr->tohit = 0;
- X flag = TRUE;
- X }
- X if (i_ptr->todam > 0)
- X {
- X i_ptr->todam -= randint(2);
- X /* don't send it below zero */
- X if (i_ptr->todam < 0)
- X i_ptr->todam = 0;
- X flag = TRUE;
- X }
- X if (i_ptr->toac > 0)
- X {
- X i_ptr->toac -= randint(2);
- X /* don't send it below zero */
- X if (i_ptr->toac < 0)
- X i_ptr->toac = 0;
- X flag = TRUE;
- X }
- X if (flag)
- X {
- X msg_print("There is a static feeling in the air.");
- X calc_bonuses ();
- X }
- X else
- X notice = FALSE;
- X break;
- X case 22: /*Eat food */
- X if (find_range(TV_FOOD, TV_NEVER, &i, &j))
- X {
- X inven_destroy(i);
- X msg_print ("It got at your rations!");
- X }
- X else
- X notice = FALSE;
- X break;
- X case 23: /*Eat light */
- X i_ptr = &inventory[INVEN_LIGHT];
- X if (i_ptr->p1 > 0)
- X {
- X i_ptr->p1 -= (250 + randint(250));
- X if (i_ptr->p1 < 1) i_ptr->p1 = 1;
- X if (py.flags.blind < 1)
- X msg_print("Your light dims.");
- X else
- X notice = FALSE;
- X }
- X else
- X notice = FALSE;
- X break;
- X case 24: /*Eat charges */
- X i = randint(inven_ctr) - 1;
- X j = r_ptr->level;
- X i_ptr = &inventory[i];
- X if (((i_ptr->tval == TV_STAFF) || (i_ptr->tval == TV_WAND))
- X && (i_ptr->p1 > 0))
- X {
- X m_ptr->hp += j*i_ptr->p1;
- X i_ptr->p1 = 0;
- X if (! known2_p (i_ptr))
- X add_inscribe (i_ptr, ID_EMPTY);
- X msg_print("Energy drains from your pack!");
- X }
- X else
- X notice = FALSE;
- X break;
- X case 99:
- X notice = FALSE;
- X break;
- X default:
- X notice = FALSE;
- X break;
- X }
- X
- X /* Moved here from mon_move, so that monster only confused if it
- X actually hits. A monster that has been repelled has not hit
- X the player, so it should not be confused. */
- X if (py.flags.confuse_monster && adesc != 99)
- X {
- X msg_print("Your hands stop glowing.");
- X py.flags.confuse_monster = FALSE;
- X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
- X (CD_NO_SLEEP & r_ptr->cdefense))
- X (void) sprintf(tmp_str, "%sis unaffected.", cdesc);
- X else
- X {
- X (void) sprintf(tmp_str, "%sappears confused.", cdesc);
- X m_ptr->confused = TRUE;
- X }
- X msg_print(tmp_str);
- X if (visible && !death && randint(4) == 1)
- X c_recall[m_ptr->mptr].r_cdefense |= r_ptr->cdefense &
- X CD_NO_SLEEP;
- X }
- X
- X /* increase number of attacks if notice true, or if visible and had
- X previously noticed the attack (in which case all this does is
- X help player learn damage), note that in the second case do
- X not increase attacks if creature repelled (no damage done) */
- X if ((notice ||
- X (visible && c_recall[m_ptr->mptr].r_attacks[attackn] != 0 &&
- X attype != 99))
- X && c_recall[m_ptr->mptr].r_attacks[attackn] < MAX_UCHAR)
- X c_recall[m_ptr->mptr].r_attacks[attackn]++;
- X if (death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
- X c_recall[m_ptr->mptr].r_deaths++;
- X }
- X else
- X {
- X if ((adesc >= 1 && adesc <= 3) || (adesc == 6))
- X {
- X disturb (1, 0);
- X (void) strcpy(tmp_str, cdesc);
- X msg_print(strcat(tmp_str, "misses you."));
- X }
- X }
- X if (attackn < MAX_MON_NATTACK-1)
- X attackn++;
- X else
- X break;
- X }
- X}
- X
- X
- X/* Make the move if possible, five choices -RAK- */
- Xstatic void make_move(monptr, mm, rcmove)
- Xint monptr;
- Xint *mm;
- Xint32u *rcmove;
- X{
- X int i, newy, newx, do_turn, do_move, stuck_door;
- X int32u movebits;
- X register cave_type *c_ptr;
- X register monster_type *m_ptr;
- X register inven_type *t_ptr;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X i = 0;
- X do_turn = FALSE;
- X do_move = FALSE;
- X m_ptr = &m_list[monptr];
- X movebits = c_list[m_ptr->mptr].cmove;
- X do
- X {
- X /* Get new position */
- X newy = m_ptr->fy;
- X newx = m_ptr->fx;
- X (void) mmove(mm[i], &newy, &newx);
- X c_ptr = &cave[newy][newx];
- X if (c_ptr->fval != BOUNDARY_WALL)
- X {
- X /* Floor is open? */
- X if (c_ptr->fval <= MAX_OPEN_SPACE)
- X do_move = TRUE;
- X /* Creature moves through walls? */
- X#ifdef ATARIST_MWC
- X else if (movebits & (holder = CM_PHASE))
- X#else
- X else if (movebits & CM_PHASE)
- X#endif
- X {
- X do_move = TRUE;
- X#ifdef ATARIST_MWC
- X *rcmove |= holder;
- X#else
- X *rcmove |= CM_PHASE;
- X#endif
- X }
- X /* Creature can open doors? */
- X else if (c_ptr->tptr != 0)
- X {
- X t_ptr = &t_list[c_ptr->tptr];
- X#ifdef ATARIST_MWC
- X if (movebits & (holder = CM_OPEN_DOOR))
- X#else
- X if (movebits & CM_OPEN_DOOR)
- X#endif
- X { /* Creature can open doors. */
- X stuck_door = FALSE;
- X if (t_ptr->tval == TV_CLOSED_DOOR)
- X {
- X do_turn = TRUE;
- X if (t_ptr->p1 == 0) /* Closed doors */
- X do_move = TRUE;
- X else if (t_ptr->p1 > 0) /* Locked doors */
- X {
- X if (randint((m_ptr->hp+1)*(50+t_ptr->p1)) <
- X 40*(m_ptr->hp-10-t_ptr->p1))
- X t_ptr->p1 = 0;
- X }
- X else if (t_ptr->p1 < 0) /* Stuck doors */
- X {
- X if (randint((m_ptr->hp+1)*(50-t_ptr->p1)) <
- X 40*(m_ptr->hp-10+t_ptr->p1))
- X {
- X msg_print("You hear a door burst open!");
- X disturb (1, 0);
- X stuck_door = TRUE;
- X do_move = TRUE;
- X }
- X }
- X }
- X else if (t_ptr->tval == TV_SECRET_DOOR)
- X {
- X do_turn = TRUE;
- X do_move = TRUE;
- X }
- X if (do_move)
- X {
- X invcopy(t_ptr, OBJ_OPEN_DOOR);
- X if (stuck_door) /* 50% chance of breaking door */
- X t_ptr->p1 = 1 - randint(2);
- X c_ptr->fval = CORR_FLOOR;
- X lite_spot(newy, newx);
- X#ifdef ATARIST_MWC
- X *rcmove |= holder;
- X#else
- X *rcmove |= CM_OPEN_DOOR;
- X#endif
- X do_move = FALSE;
- X }
- X }
- X else
- X { /* Creature can not open doors, must bash them */
- X if (t_ptr->tval == TV_CLOSED_DOOR)
- X {
- X do_turn = TRUE;
- X if (randint((m_ptr->hp+1)*(80+abs(t_ptr->p1))) <
- X 40*(m_ptr->hp-20-abs(t_ptr->p1)))
- X {
- X invcopy(t_ptr, OBJ_OPEN_DOOR);
- X /* 50% chance of breaking door */
- X t_ptr->p1 = 1 - randint(2);
- X c_ptr->fval = CORR_FLOOR;
- X lite_spot(newy, newx);
- X msg_print ("You hear a door burst open!");
- X disturb (1, 0);
- X }
- X }
- X }
- X }
- X /* Glyph of warding present? */
- X if (do_move && (c_ptr->tptr != 0) &&
- X (t_list[c_ptr->tptr].tval == TV_VIS_TRAP) &&
- X (t_list[c_ptr->tptr].subval == 99))
- X {
- X if (randint(OBJ_RUNE_PROT) < c_list[m_ptr->mptr].level)
- X {
- X if ((newy==char_row) && (newx==char_col))
- X msg_print("The rune of protection is broken!");
- X (void) delete_object(newy, newx);
- X }
- X else
- X {
- X do_move = FALSE;
- X /* If the creature moves only to attack, */
- X /* don't let it move if the glyph prevents */
- X /* it from attacking */
- X if (movebits & CM_ATTACK_ONLY)
- X do_turn = TRUE;
- X }
- X }
- X /* Creature has attempted to move on player? */
- X if (do_move)
- X if (c_ptr->cptr == 1)
- X {
- X /* if the monster is not lit, must call update_mon, it may
- X be faster than character, and hence could have just
- X moved next to character this same turn */
- X if (!m_ptr->ml)
- X update_mon(monptr);
- X make_attack(monptr);
- X do_move = FALSE;
- X do_turn = TRUE;
- X }
- X /* Creature is attempting to move on other creature? */
- X else if ((c_ptr->cptr > 1) &&
- X ((newy != m_ptr->fy) ||
- X (newx != m_ptr->fx)))
- X {
- X /* Creature eats other creatures? */
- X#ifdef ATARIST_MWC
- X if ((movebits & (holder = CM_EATS_OTHER)) &&
- X#else
- X if ((movebits & CM_EATS_OTHER) &&
- X#endif
- X (c_list[m_ptr->mptr].mexp >=
- X c_list[m_list[c_ptr->cptr].mptr].mexp))
- X {
- X if (m_list[c_ptr->cptr].ml)
- X#ifdef ATARIST_MWC
- X *rcmove |= holder;
- X#else
- X *rcmove |= CM_EATS_OTHER;
- X#endif
- X /* It ate an already processed monster. Handle normally. */
- X if (monptr < c_ptr->cptr)
- X delete_monster((int) c_ptr->cptr);
- X /* If it eats this monster, an already processed monster
- X will take its place, causing all kinds of havoc. Delay
- X the kill a bit. */
- X else
- X fix1_delete_monster((int) c_ptr->cptr);
- X }
- X else
- X do_move = FALSE;
- X }
- X /* Creature has been allowed move. */
- X if (do_move)
- X {
- X /* Pick up or eat an object */
- X#ifdef ATARIST_MWC
- X if (movebits & (holder = CM_PICKS_UP))
- X#else
- X if (movebits & CM_PICKS_UP)
- X#endif
- X {
- X c_ptr = &cave[newy][newx];
- X
- X if ((c_ptr->tptr != 0)
- X && (t_list[c_ptr->tptr].tval <= TV_MAX_OBJECT))
- X {
- X#ifdef ATARIST_MWC
- X *rcmove |= holder;
- X#else
- X *rcmove |= CM_PICKS_UP;
- X#endif
- X (void) delete_object(newy, newx);
- X }
- X }
- X /* Move creature record */
- X move_rec((int)m_ptr->fy, (int)m_ptr->fx, newy, newx);
- X if (m_ptr->ml)
- X {
- X m_ptr->ml = FALSE;
- X lite_spot ((int)m_ptr->fy, (int)m_ptr->fx);
- X }
- X m_ptr->fy = newy;
- X m_ptr->fx = newx;
- X m_ptr->cdis = distance (char_row, char_col, newy, newx);
- X do_turn = TRUE;
- X }
- X }
- X i++;
- X /* Up to 5 attempts at moving, give up. */
- X }
- X while ((!do_turn) && (i < 5));
- X}
- X
- X
- X/* Creatures can cast spells too. (Dragon Breath) -RAK- */
- X/* cast_spell = true if creature changes position */
- X/* took_turn = true if creature casts a spell */
- Xstatic void mon_cast_spell(monptr, took_turn)
- Xint monptr;
- Xint *took_turn;
- X{
- X int32u i;
- X int y, x, chance, thrown_spell, r1;
- X register int k;
- X int spell_choice[30];
- X vtype cdesc, outval, ddesc;
- X register monster_type *m_ptr;
- X register creature_type *r_ptr;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X if (death)
- X return;
- X
- X m_ptr = &m_list[monptr];
- X r_ptr = &c_list[m_ptr->mptr];
- X chance = (int)(r_ptr->spells & CS_FREQ);
- X /* 1 in x chance of casting spell */
- X if (randint(chance) != 1)
- X *took_turn = FALSE;
- X /* Must be within certain range */
- X else if (m_ptr->cdis > MAX_SPELL_DIS)
- X *took_turn = FALSE;
- X /* Must have unobstructed Line-Of-Sight */
- X else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
- X *took_turn = FALSE;
- X else /* Creature is going to cast a spell */
- X {
- X *took_turn = TRUE;
- X /* Check to see if monster should be lit. */
- X update_mon (monptr);
- X /* Describe the attack */
- X if (m_ptr->ml)
- X (void) sprintf(cdesc, "The %s ", r_ptr->name);
- X else
- X (void) strcpy(cdesc, "It ");
- X /* For "DIED_FROM" string */
- X#ifdef ATARIST_MWC
- X holder = CM_WIN;
- X if (holder & r_ptr->cmove)
- X#else
- X if (CM_WIN & r_ptr->cmove)
- X#endif
- X (void) sprintf(ddesc, "The %s", r_ptr->name);
- X else if (is_a_vowel (r_ptr->name[0]))
- X (void) sprintf (ddesc, "an %s", r_ptr->name);
- X else
- X (void) sprintf(ddesc, "a %s", r_ptr->name);
- X /* End DIED_FROM */
- X
- X /* Extract all possible spells into spell_choice */
- X#ifdef ATARIST_MWC
- X holder = ~CS_FREQ;
- X i = (r_ptr->spells & holder);
- X#else
- X i = (r_ptr->spells & ~CS_FREQ);
- X#endif
- X k = 0;
- X while (i != 0)
- X {
- X spell_choice[k] = bit_pos(&i);
- X k++;
- X }
- X /* Choose a spell to cast */
- X thrown_spell = spell_choice[randint(k) - 1];
- X thrown_spell++;
- X /* all except teleport_away() and drain mana spells always disturb */
- X if (thrown_spell > 6 && thrown_spell != 17)
- X disturb (1, 0);
- X /* save some code/data space here, with a small time penalty */
- X if ((thrown_spell < 14 && thrown_spell > 6) || (thrown_spell == 16))
- X {
- X (void) strcat(cdesc, "casts a spell.");
- X msg_print(cdesc);
- X }
- X /* Cast the spell. */
- X switch(thrown_spell)
- X {
- X case 5: /*Teleport Short*/
- X teleport_away(monptr, 5);
- X break;
- X case 6: /*Teleport Long */
- X teleport_away(monptr, MAX_SIGHT);
- X break;
- X case 7: /*Teleport To */
- X teleport_to((int)m_ptr->fy, (int)m_ptr->fx);
- X break;
- X case 8: /*Light Wound */
- X if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else
- X take_hit(damroll(3, 8), ddesc);
- X break;
- X case 9: /*Serious Wound */
- X if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else
- X take_hit(damroll(8, 8), ddesc);
- X break;
- X case 10: /*Hold Person */
- X if (py.flags.free_act)
- X msg_print("You are unaffected.");
- X else if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else if (py.flags.paralysis > 0)
- X py.flags.paralysis += 2;
- X else
- X py.flags.paralysis = randint(5)+4;
- X break;
- X case 11: /*Cause Blindness*/
- X if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else if (py.flags.blind > 0)
- X py.flags.blind += 6;
- X else
- X py.flags.blind += 12 + randint(3);
- X break;
- X case 12: /*Cause Confuse */
- X if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else if (py.flags.confused > 0)
- X py.flags.confused += 2;
- X else
- X py.flags.confused = randint(5) + 3;
- X break;
- X case 13: /*Cause Fear */
- X if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else if (py.flags.afraid > 0)
- X py.flags.afraid += 2;
- X else
- X py.flags.afraid = randint(5) + 3;
- X break;
- X case 14: /*Summon Monster*/
- X (void) strcat(cdesc, "magically summons a monster!");
- X msg_print(cdesc);
- X y = char_row;
- X x = char_col;
- X /* in case compact_monster() is called,it needs monptr */
- X hack_monptr = monptr;
- X (void) summon_monster(&y, &x, FALSE);
- X hack_monptr = -1;
- X update_mon ((int)cave[y][x].cptr);
- X break;
- X case 15: /*Summon Undead*/
- X (void) strcat(cdesc, "magically summons an undead!");
- X msg_print(cdesc);
- X y = char_row;
- X x = char_col;
- X /* in case compact_monster() is called,it needs monptr */
- X hack_monptr = monptr;
- X (void) summon_undead(&y, &x);
- X hack_monptr = -1;
- X update_mon ((int)cave[y][x].cptr);
- X break;
- X case 16: /*Slow Person */
- X if (py.flags.free_act)
- X msg_print("You are unaffected.");
- X else if (player_saves())
- X msg_print("You resist the effects of the spell.");
- X else if (py.flags.slow > 0)
- X py.flags.slow += 2;
- X else
- X py.flags.slow = randint(5) + 3;
- X break;
- X case 17: /*Drain Mana */
- X if (py.misc.cmana > 0)
- X {
- X disturb (1, 0);
- X (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc);
- X msg_print(outval);
- X if (m_ptr->ml)
- X {
- X (void) sprintf(outval, "%sappears healthier.", cdesc);
- X msg_print(outval);
- X }
- X r1 = (randint((int)r_ptr->level) >> 1) + 1;
- X if (r1 > py.misc.cmana)
- X {
- X r1 = py.misc.cmana;
- X py.misc.cmana = 0;
- X py.misc.cmana_frac = 0;
- X }
- X else
- X py.misc.cmana -= r1;
- X prt_cmana();
- X m_ptr->hp += 6*(r1);
- X }
- X break;
- X case 20: /*Breath Light */
- X (void) strcat(cdesc, "breathes lightning.");
- X msg_print(cdesc);
- X breath(GF_LIGHTNING, char_row, char_col, (m_ptr->hp / 4), ddesc,
- X monptr);
- X break;
- X case 21: /*Breath Gas */
- X (void) strcat(cdesc, "breathes gas.");
- X msg_print(cdesc);
- X breath(GF_POISON_GAS, char_row, char_col, (m_ptr->hp / 3), ddesc,
- X monptr);
- X break;
- X case 22: /*Breath Acid */
- X (void) strcat(cdesc, "breathes acid.");
- X msg_print(cdesc);
- X breath(GF_ACID, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
- X break;
- X case 23: /*Breath Frost */
- X (void) strcat(cdesc, "breathes frost.");
- X msg_print(cdesc);
- X breath(GF_FROST, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
- X break;
- X case 24: /*Breath Fire */
- X (void) strcat(cdesc, "breathes fire.");
- X msg_print(cdesc);
- X breath(GF_FIRE, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
- X break;
- X default:
- X (void) strcat (cdesc, "cast unknown spell.");
- X msg_print(cdesc);
- X }
- X /* End of spells */
- X if (m_ptr->ml)
- X {
- X c_recall[m_ptr->mptr].r_spells |= 1L << (thrown_spell-1);
- X if ((c_recall[m_ptr->mptr].r_spells & CS_FREQ) != CS_FREQ)
- X c_recall[m_ptr->mptr].r_spells++;
- X if (death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
- X c_recall[m_ptr->mptr].r_deaths++;
- X }
- X }
- X}
- X
- X
- X/* Places creature adjacent to given location -RAK- */
- X/* Rats and Flys are fun! */
- Xint multiply_monster(y, x, cr_index, monptr)
- Xint y, x, cr_index;
- Xint monptr;
- X{
- X register int i, j, k;
- X register cave_type *c_ptr;
- X int result;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X i = 0;
- X do
- X {
- X j = y - 2 + randint(3);
- X k = x - 2 + randint(3);
- X /* don't create a new creature on top of the old one, that causes
- X invincible/invisible creatures to appear */
- X if (in_bounds(j, k) && (j != y || k != x))
- X {
- X c_ptr = &cave[j][k];
- X if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) &&
- X (c_ptr->cptr != 1))
- X {
- X if (c_ptr->cptr > 1) /* Creature there already? */
- X {
- X /* Some critters are cannibalistic! */
- X#ifdef ATARIST_MWC
- X holder = CM_EATS_OTHER;
- X if ((c_list[cr_index].cmove & holder)
- X#else
- X if ((c_list[cr_index].cmove & CM_EATS_OTHER)
- X#endif
- X /* Check the experience level -CJS- */
- X && c_list[cr_index].mexp >=
- X c_list[m_list[c_ptr->cptr].mptr].mexp)
- X {
- X /* It ate an already processed monster.Handle normally.*/
- X if (monptr < c_ptr->cptr)
- X delete_monster((int) c_ptr->cptr);
- X /* If it eats this monster, an already processed mosnter
- X will take its place, causing all kinds of havoc.
- X Delay the kill a bit. */
- X else
- X fix1_delete_monster((int) c_ptr->cptr);
- X
- X /* in case compact_monster() is called,it needs monptr */
- X hack_monptr = monptr;
- X /* Place_monster() may fail if monster list full. */
- X result = place_monster(j, k, cr_index, FALSE);
- X hack_monptr = -1;
- X if (! result)
- X return FALSE;
- X mon_tot_mult++;
- X return check_mon_lite(j, k);
- X }
- X }
- X else
- X /* All clear, place a monster */
- X {
- X /* in case compact_monster() is called,it needs monptr */
- X hack_monptr = monptr;
- X /* Place_monster() may fail if monster list full. */
- X result = place_monster(j, k, cr_index, FALSE);
- X hack_monptr = -1;
- X if (! result)
- X return FALSE;
- X mon_tot_mult++;
- X return check_mon_lite(j, k);
- X }
- X }
- X }
- X i++;
- X }
- X while (i <= 18);
- X return FALSE;
- X}
- X
- X
- X/* Move the critters about the dungeon -RAK- */
- Xstatic void mon_move(monptr, rcmove)
- Xint monptr;
- Xint32u *rcmove;
- X{
- X register int i, j;
- X int k, move_test, dir;
- X#ifdef M_XENIX
- X /* Avoid 'register' bug. */
- X creature_type *r_ptr;
- X#else
- X register creature_type *r_ptr;
- X#endif
- X register monster_type *m_ptr;
- X int mm[9];
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X int rest_val;
- X
- X m_ptr = &m_list[monptr];
- X r_ptr = &c_list[m_ptr->mptr];
- X /* Does the critter multiply? */
- X /* rest could be negative, to be safe, only use mod with positive values. */
- X rest_val = abs (py.flags.rest);
- X#ifdef ATARIST_MWC
- X holder = CM_MULTIPLY;
- X if ((r_ptr->cmove & holder) && (MAX_MON_MULT >= mon_tot_mult) &&
- X#else
- X if ((r_ptr->cmove & CM_MULTIPLY) && (MAX_MON_MULT >= mon_tot_mult) &&
- X#endif
- X ((rest_val % MON_MULT_ADJ) == 0))
- X {
- X k = 0;
- X for (i = m_ptr->fy-1; i <= m_ptr->fy+1; i++)
- X for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
- X if (in_bounds(i, j) && (cave[i][j].cptr > 1))
- X k++;
- X /* can't call randint with a value of zero, increment counter
- X to allow creature multiplication */
- X if (k == 0)
- X k++;
- X if ((k < 4) && (randint(k*MON_MULT_ADJ) == 1))
- X if (multiply_monster((int)m_ptr->fy, (int)m_ptr->fx,
- X (int)m_ptr->mptr, monptr))
- X#ifdef ATARIST_MWC
- X *rcmove |= holder;
- X#else
- X *rcmove |= CM_MULTIPLY;
- X#endif
- X }
- X move_test = FALSE;
- X
- X /* if in wall, must immediately escape to a clear area */
- X#ifdef ATARIST_MWC
- X holder = CM_PHASE;
- X if (!(r_ptr->cmove & holder) &&
- X#else
- X if (!(r_ptr->cmove & CM_PHASE) &&
- X#endif
- X (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL))
- X {
- X /* If the monster is already dead, don't kill it again!
- X This can happen for monsters moving faster than the player. They
- X will get multiple moves, but should not if they die on the first
- X move. This is only a problem for monsters stuck in rock. */
- X if (m_ptr->hp < 0)
- X return;
- X
- X k = 0;
- X dir = 1;
- X /* note direction of for loops matches direction of keypad from 1 to 9*/
- X /* do not allow attack against the player */
- X /* Must cast fy-1 to signed int, so that a nagative value of i will
- X fail the comparison. */
- X for (i = m_ptr->fy+1; i >= (int)(m_ptr->fy-1); i--)
- X for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
- X {
- X if ((dir != 5) && (cave[i][j].fval <= MAX_OPEN_SPACE)
- X && (cave[i][j].cptr != 1))
- X mm[k++] = dir;
- X dir++;
- X }
- X if (k != 0)
- X {
- X /* put a random direction first */
- X dir = randint (k) - 1;
- X i = mm[0];
- X mm[0] = mm[dir];
- X mm[dir] = i;
- X make_move (monptr, mm, rcmove);
- X /* this can only fail if mm[0] has a rune of protection */
- X }
- X /* if still in a wall, let it dig itself out, but also apply some
- X more damage */
- X if (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL)
- X {
- X /* in case the monster dies, may need to call fix1_delete_monster()
- X instead of delete_monsters() */
- X hack_monptr = monptr;
- X i = mon_take_hit(monptr, damroll (8, 8));
- X hack_monptr = -1;
- X if (i >= 0)
- X {
- X msg_print("You hear a scream muffled by rock!");
- X prt_experience();
- X }
- X else
- X {
- X msg_print ("A creature digs itself out from the rock!");
- X (void) twall ((int)m_ptr->fy, (int)m_ptr->fx, 1, 0);
- X }
- X }
- X return; /* monster movement finished */
- X }
- X /* Creature is confused? Chance it becomes un-confused */
- X else if (m_ptr->confused)
- X {
- X mm[0] = randint(9);
- X mm[1] = randint(9);
- X mm[2] = randint(9);
- X mm[3] = randint(9);
- X mm[4] = randint(9);
- X /* don't move him if he is not supposed to move! */
- X if (!(r_ptr->cmove & CM_ATTACK_ONLY))
- X make_move(monptr, mm, rcmove);
- X if (randint(8) == 1)
- X m_ptr->confused = FALSE;
- X move_test = TRUE;
- X }
- X /* Creature may cast a spell */
- X else if (r_ptr->spells != 0)
- X mon_cast_spell(monptr, &move_test);
- X if (!move_test)
- X {
- X /* 75% random movement */
- X if ((r_ptr->cmove & CM_75_RANDOM) && (randint(100) < 75))
- X {
- X mm[0] = randint(9);
- X mm[1] = randint(9);
- X mm[2] = randint(9);
- X mm[3] = randint(9);
- X mm[4] = randint(9);
- X *rcmove |= CM_75_RANDOM;
- X make_move(monptr, mm, rcmove);
- X }
- X /* 40% random movement */
- X else if ((r_ptr->cmove & CM_40_RANDOM) && (randint(100) < 40))
- X {
- X mm[0] = randint(9);
- X mm[1] = randint(9);
- X mm[2] = randint(9);
- X mm[3] = randint(9);
- X mm[4] = randint(9);
- X *rcmove |= CM_40_RANDOM;
- X make_move(monptr, mm, rcmove);
- X }
- X /* 20% random movement */
- X else if ((r_ptr->cmove & CM_20_RANDOM) && (randint(100) < 20))
- X {
- X mm[0] = randint(9);
- X mm[1] = randint(9);
- X mm[2] = randint(9);
- X mm[3] = randint(9);
- X mm[4] = randint(9);
- X *rcmove |= CM_20_RANDOM;
- X make_move(monptr, mm, rcmove);
- X }
- X /* Normal movement */
- X else if (r_ptr->cmove & CM_MOVE_NORMAL)
- X {
- X if (randint(200) == 1)
- X {
- X mm[0] = randint(9);
- X mm[1] = randint(9);
- X mm[2] = randint(9);
- X mm[3] = randint(9);
- X mm[4] = randint(9);
- X }
- X else
- X get_moves(monptr, mm);
- X *rcmove |= CM_MOVE_NORMAL;
- X make_move(monptr, mm, rcmove);
- X }
- X /* Attack, but don't move */
- X else if (r_ptr->cmove & CM_ATTACK_ONLY)
- X {
- X if (m_ptr->cdis < 2)
- X {
- X get_moves(monptr, mm);
- X make_move(monptr, mm, rcmove);
- X }
- X else
- X /* Learn that the monster does does not move when it should have
- X moved, but didn't. */
- X *rcmove |= CM_ATTACK_ONLY;
- X }
- X else if ((r_ptr->cmove & CM_ONLY_MAGIC) && (m_ptr->cdis < 2))
- X {
- X /* A little hack for Quylthulgs, so that one will eventually notice
- X that they have no physical attacks. */
- X if (c_recall[m_ptr->mptr].r_attacks[0] < MAX_UCHAR)
- X c_recall[m_ptr->mptr].r_attacks[0]++;
- X /* Another little hack for Quylthulgs, so that one can eventually
- X learn their speed. */
- X if (c_recall[m_ptr->mptr].r_attacks[0] > 20)
- X c_recall[m_ptr->mptr].r_cmove |= CM_ONLY_MAGIC;
- X }
- X }
- X}
- X
- X
- X/* Creatures movement and attacking are done from here -RAK- */
- Xvoid creatures(attack)
- Xint attack;
- X{
- X register int i, k;
- X register monster_type *m_ptr;
- X recall_type *r_ptr;
- X int32u notice, rcmove;
- X int wake, ignore;
- X vtype cdesc;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X /* Process the monsters */
- X for (i = mfptr - 1; i >= MIN_MONIX && !death; i--)
- X {
- X m_ptr = &m_list[i];
- X /* Get rid of an eaten/breathed on monster. Note: Be sure not to
- X process this monster. This is necessary because we can't delete
- X monsters while scanning the m_list here. */
- X if (m_ptr->hp < 0)
- X {
- X fix2_delete_monster(i);
- X continue;
- X }
- X
- X m_ptr->cdis = distance(char_row, char_col,
- X (int)m_ptr->fy, (int)m_ptr->fx);
- X if (attack) /* Attack is argument passed to CREATURE*/
- X {
- X k = movement_rate(m_ptr->cspeed);
- X if (k <= 0)
- X update_mon(i);
- X else
- X while (k > 0)
- X {
- X k--;
- X wake = FALSE;
- X ignore = FALSE;
- X rcmove = 0;
- X if (m_ptr->ml || (m_ptr->cdis <= c_list[m_ptr->mptr].aaf)
- X /* Monsters trapped in rock must be given a turn also,
- X so that they will die/dig out immediately. */
- X#ifdef ATARIST_MWC
- X || ((! (c_list[m_ptr->mptr].cmove & (holder = CM_PHASE)))
- X#else
- X || ((! (c_list[m_ptr->mptr].cmove & CM_PHASE))
- X#endif
- X && cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL))
- X {
- X if (m_ptr->csleep > 0)
- X if (py.flags.aggravate)
- X m_ptr->csleep = 0;
- X else if ((py.flags.rest == 0 && py.flags.paralysis < 1)
- X || (randint(50) == 1))
- X {
- X notice = randint(1024);
- X if (notice*notice*notice <= (1L << (29 - py.misc.stl)))
- X {
- X m_ptr->csleep -= (100 / m_ptr->cdis);
- X if (m_ptr->csleep > 0)
- X ignore = TRUE;
- X else
- X {
- X wake = TRUE;
- X /* force it to be exactly zero */
- X m_ptr->csleep = 0;
- X }
- X }
- X }
- X if (m_ptr->stunned != 0)
- X {
- X /* NOTE: Balrog = 100*100 = 10000, it always
- X recovers instantly */
- X if (randint(5000) < c_list[m_ptr->mptr].level
- X * c_list[m_ptr->mptr].level)
- X m_ptr->stunned = 0;
- X else
- X m_ptr->stunned--;
- X if (m_ptr->stunned == 0)
- X {
- X if (!m_ptr->ml)
- X (void) strcpy(cdesc, "It ");
- X else
- X (void) sprintf(cdesc, "The %s ",
- X c_list[m_ptr->mptr].name);
- X msg_print(strcat(cdesc,
- X "recovers and glares at you."));
- X }
- X }
- X if ((m_ptr->csleep == 0) && (m_ptr->stunned == 0))
- X mon_move (i, &rcmove);
- X }
- X
- X update_mon(i);
- X if (m_ptr->ml)
- X {
- X r_ptr = &c_recall[m_ptr->mptr];
- X if (wake)
- X {
- X if (r_ptr->r_wake < MAX_UCHAR)
- X r_ptr->r_wake++;
- X }
- X else if (ignore)
- X {
- X if (r_ptr->r_ignore < MAX_UCHAR)
- X r_ptr->r_ignore++;
- X }
- X r_ptr->r_cmove |= rcmove;
- X }
- X }
- X }
- X else
- X update_mon(i);
- X
- X /* Get rid of an eaten/breathed on monster. This is necessary because
- X we can't delete monsters while scanning the m_list here. This
- X monster may have been killed during mon_move(). */
- X if (m_ptr->hp < 0)
- X {
- X fix2_delete_monster(i);
- X continue;
- X }
- X }
- X /* End processing monsters */
- X}
- END_OF_FILE
- if test 46325 -ne `wc -c <'source/creature.c'`; then
- echo shar: \"'source/creature.c'\" unpacked with wrong size!
- fi
- # end of 'source/creature.c'
- fi
- if test -f 'util/printit/pr_monst.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/printit/pr_monst.c'\"
- else
- echo shar: Extracting \"'util/printit/pr_monst.c'\" \(6250 characters\)
- sed "s/^X//" >'util/printit/pr_monst.c' <<'END_OF_FILE'
- X/* util/printit/pr_monst.c: pretty print monster info
- X
- X Copyright (c) 1990-1992 Carlton Hommel, James E. Wilson
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X
- Xextern creature_type c_list[];
- X
- Xmain()
- X{
- X int i;
- X creature_type *c;
- X
- X printf(" Lvl(Ep) [ HD, AC]\tspd aaf/{sleep}\t\t Name");
- X printf("\tDamage(special) <Defense> {Moves} /* Spells */\n");
- X for (i=0; i<MAX_CREATURES; i++) {
- X c = &c_list[i];
- X call_it(c);
- X }
- X return 0;
- X}
- X
- Xcall_it(c)
- Xcreature_type *c;
- X{
- X /* Line 1 */
- X printf("'%c' ", c->cchar);
- X printf("%2d", c->level);
- X printf("(%4d) ", c->mexp);
- X printf("[%2dd%d, %2d]\t", c->hd[0], c->hd[1], c->ac);
- X
- X printf("%2d ", ((int)c->speed)-10);
- X printf("%2d/", c->aaf);
- X printf("{%d}\t", c->sleep*10);
- X
- X printf("%20.20s\t", c->name);
- X print_damage(c->damage);
- X printf("\t");
- X
- X print_flags_cdefense(c->cdefense);
- X printf(" ");
- X print_flags_cmove(c->cmove);
- X printf(" ");
- X print_flags_spells(c->spells);
- X
- X printf("\n");
- X
- X}
- X
- Xprint_damage(attstr)
- Xint8u attstr[4];
- X{
- X int attype, adesc, adice, asides;
- X int count;
- X char damstr[50];
- X
- X extern struct m_attack_type monster_attacks[];
- X
- X for (count=0; count<4; count++) {
- X if (attstr[count] == 0) continue;
- X attype = monster_attacks[attstr[count]].attack_type;
- X adesc = monster_attacks[attstr[count]].attack_desc;
- X adice = monster_attacks[attstr[count]].attack_dice;
- X asides = monster_attacks[attstr[count]].attack_sides;
- X
- X sprintf(damstr, "%dd%d", adice, asides);
- X switch(attype) {
- X case 1: printf("%s ", damstr); break;
- X case 2: printf("%s(-Str) ", damstr); break;
- X case 3: printf("%s(Conf) ", damstr); break;
- X case 4: printf("%s(Fear) ", damstr); break;
- X case 5: printf("%s(Fire) ", damstr); break;
- X case 6: printf("%s(Acid) ", damstr); break;
- X case 7: printf("%s(Cold) ", damstr); break;
- X case 8: printf("%s(Zap) ", damstr); break;
- X case 9: printf("%s(Acid) ", damstr); break;
- X case 10: printf("%s(Blind) ", damstr); break;
- X case 11: printf("%s(Paral) ", damstr); break;
- X case 12: printf("%s(-Money) ", damstr); break;
- X case 13: printf("%s(-Object) ", damstr);break;
- X case 14: printf("%s(Poison) ", damstr); break;
- X case 15: printf("%s(-Dex) ", damstr); break;
- X case 16: printf("%s(-Con ) ", damstr); break;
- X case 17: printf("%s(-Int ) ", damstr); break;
- X case 18: printf("%s(-Wis) ", damstr); break;
- X case 19: printf("%s(-Exp) ", damstr); break;
- X case 20: printf("%s(Aggr) ", damstr); break;
- X case 21: printf("%s(-Magic) ", damstr); break;
- X case 22: printf("%s(-Food) ", damstr); break;
- X case 23: printf("%s(-Light) ", damstr); break;
- X case 24: printf("%s(-Charges) ", damstr);break;
- X default:
- X case 99: printf("%s(Blank) ", damstr); break;
- X }
- X
- X }
- X}
- X
- Xprint_flags_spells(spells)
- Xunsigned long spells;
- X{
- X int count;
- X unsigned long mask;
- X int chance;
- X
- X if (spells == 0)
- X return;
- X
- X printf("/* ");
- X chance = (int)spells & CS_FREQ;
- X printf("%2.1f%% ", 1.0 / chance * 100.0);
- X for (count=4,mask=0x010; count<32; mask <<= 1, count++) {
- X switch (spells & mask) {
- X case CS_TEL_SHORT: printf("CS_TEL_SHORT ");break;
- X case CS_TEL_LONG: printf("CS_TEL_LONG "); break;
- X case CS_TEL_TO: printf("CS_TEL_TO "); break;
- X case CS_LGHT_WND: printf("CS_LGHT_WND "); break;
- X case CS_SER_WND: printf("CS_SER_WND "); break;
- X case CS_HOLD_PER: printf("CS_HOLD_PER "); break;
- X case CS_BLIND: printf("CS_BLIND "); break;
- X case CS_CONFUSE: printf("CS_CONFUSE "); break;
- X case CS_FEAR: printf("CS_FEAR "); break;
- X case CS_SUMMON_MON: printf("CS_SUMMON_MON ");break;
- X case CS_SUMMON_UND: printf("CS_SUMMON_UND ");break;
- X case CS_SLOW_PER: printf("CS_SLOW_PER "); break;
- X case CS_DRAIN_MANA: printf("CS_DRAIN_MANA ");break;
- X case CS_BR_LIGHT: printf("CS_BR_LIGHT "); break;
- X case CS_BR_GAS: printf("CS_BR_GAS "); break;
- X case CS_BR_ACID: printf("CS_BR_ACID "); break;
- X case CS_BR_FROST: printf("CS_BR_FROST "); break;
- X case CS_BR_FIRE: printf("CS_BR_FIRE "); break;
- X }
- X }
- X printf("*/");
- X}
- X
- Xprint_flags_cmove(cmove)
- Xunsigned long cmove;
- X{
- X int count;
- X unsigned long mask;
- X
- X if (cmove == 0)
- X return;
- X
- X printf("<");
- X for (count=0,mask=0x01; count<32; mask <<= 1, count++) {
- X switch (cmove & mask) {
- X case CM_ATTACK_ONLY: printf("CM_ATTACK_ONLY "); break;
- X case CM_MOVE_NORMAL: /*printf("CM_MOVE_NORMAL ");*/ break;
- X case CM_20_RANDOM: printf("CM_20_RANDOM "); break;
- X case CM_40_RANDOM: printf("CM_40_RANDOM "); break;
- X case CM_75_RANDOM: printf("CM_75_RANDOM "); break;
- X case CM_INVISIBLE: printf("CM_INVISIBLE "); break;
- X case CM_OPEN_DOOR: printf("CM_OPEN_DOOR "); break;
- X case CM_PHASE: printf("CM_PHASE "); break;
- X case CM_EATS_OTHER: printf("CM_EATS_OTHER "); break;
- X case CM_PICKS_UP: printf("CM_PICKS_UP "); break;
- X case CM_MULTIPLY: printf("CM_MULTIPLY "); break;
- X case CM_CARRY_OBJ: printf("CM_CARRY_OTHER "); break;
- X case CM_CARRY_GOLD: printf("CM_CARRY_GOLD "); break;
- X case CM_60_RANDOM: printf("CM_60_RANDOM "); break;
- X case CM_90_RANDOM: printf("CM_90_RANDOM "); break;
- X case CM_1D2_OBJ: printf("CM_1D2_OBJ "); break;
- X case CM_2D2_OBJ: printf("CM_2D2_OBJ "); break;
- X case CM_4D2_OBJ: printf("CM_4D2_OBJ "); break;
- X case CM_WIN: printf("CM_WIN "); break;
- X }
- X }
- X printf(">");
- X}
- X
- Xprint_flags_cdefense(cdefense)
- Xunsigned int cdefense;
- X{
- X int count;
- X unsigned int mask;
- X
- X if (cdefense == 0)
- X return;
- X
- X printf("{");
- X for (count=0,mask=0x01; count<16; mask <<= 1, count++) {
- X switch (cdefense & mask) {
- X case CD_DRAGON: printf("CD_DRAGON "); break;
- X case CD_ANIMAL: printf("CD_ANIMAL "); break;
- X case CD_EVIL: printf("CD_EVIL "); break;
- X case CD_UNDEAD: printf("CD_UNDEAD "); break;
- X case CD_FROST: printf("CD_FROST "); break;
- X case CD_FIRE: printf("CD_FIRE "); break;
- X case CD_POISON: printf("CD_POISON "); break;
- X case CD_ACID: printf("CD_ACID "); break;
- X case CD_LIGHT: printf("CD_LIGHT "); break;
- X case CD_STONE: printf("CD_STONE "); break;
- X case CD_NO_SLEEP: printf("CD_NO_SLEEP "); break;
- X case CD_INFRA: printf("CD_INFRA "); break;
- X case CD_MAX_HP: printf("CD_MAX_HP "); break;
- X }
- X }
- X printf("}");
- X}
- END_OF_FILE
- if test 6250 -ne `wc -c <'util/printit/pr_monst.c'`; then
- echo shar: \"'util/printit/pr_monst.c'\" unpacked with wrong size!
- fi
- # end of 'util/printit/pr_monst.c'
- fi
- echo shar: End of archive 6 \(of 39\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 39 archives.
- echo "Now run "bldfiles.sh" to build split files"
- 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
-