home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume14
/
umoria4
/
part18
< prev
next >
Wrap
Internet Message Format
|
1992-08-31
|
58KB
Path: uunet!zephyr.ens.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v14i050: umoria4 - single player dungeon simulation (ver. 5.5), Part18/39
Message-ID: <3408@master.CNA.TEK.COM>
Date: 20 Aug 92 18:05:51 GMT
Sender: news@master.CNA.TEK.COM
Lines: 1980
Approved: billr@saab.CNA.TEK.COM
Submitted-by: grabiner@math.harvard.edu (David Grabiner)
Posting-number: Volume 14, Issue 50
Archive-name: umoria4/Part18
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 18 (of 39)."
# Contents: source/player.c source/spells.c.1 util/mc/st.h
# Wrapped by billr@saab on Thu Aug 20 09:11:30 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'source/player.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'source/player.c'\"
else
echo shar: Extracting \"'source/player.c'\" \(19531 characters\)
sed "s/^X//" >'source/player.c' <<'END_OF_FILE'
X/* source/player.c: player specific variable definitions
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#include "config.h"
X#include "constant.h"
X#include "types.h"
X
X/* Player record for most player related info */
Xplayer_type py;
X/* player location in dungeon */
Xint16 char_row;
Xint16 char_col;
X/* calculated base hp values for player at each level, store them so that
X drain life + restore life does not affect hit points */
Xint16u player_hp[MAX_PLAYER_LEVEL];
X
X/* Class titles for different levels */
X#ifdef MACGAME
Xchar *(*player_title)[MAX_PLAYER_LEVEL];
X#else
Xchar *player_title[MAX_CLASS][MAX_PLAYER_LEVEL] = {
X /* Warrior */
X{"Rookie","Private","Soldier","Mercenary","Veteran(1st)","Veteran(2nd)",
X"Veteran(3rd)","Warrior(1st)","Warrior(2nd)","Warrior(3rd)","Warrior(4th)",
X"Swordsman-1","Swordsman-2","Swordsman-3","Hero","Swashbuckler","Myrmidon",
X"Champion-1","Champion-2","Champion-3","Superhero","Knight","Superior Knt",
X"Gallant Knt","Knt Errant","Guardian Knt","Baron","Duke","Lord (1st)",
X"Lord (2nd)","Lord (3rd)","Lord (4th)","Lord (5th)","Lord (6th)","Lord (7th)",
X"Lord (8th)","Lord (9th)","Lord Gallant","Lord Keeper","Lord Noble"},
X /* Mage */
X{"Novice","Apprentice","Trickster-1","Trickster-2","Trickster-3","Cabalist-1",
X"Cabalist-2","Cabalist-3","Visionist","Phantasmist","Shadowist","Spellbinder",
X"Illusionist","Evoker (1st)","Evoker (2nd)","Evoker (3rd)","Evoker (4th)",
X"Conjurer","Theurgist","Thaumaturge","Magician","Enchanter","Warlock",
X"Sorcerer","Necromancer","Mage (1st)","Mage (2nd)","Mage (3rd)","Mage (4th)",
X"Mage (5th)","Wizard (1st)","Wizard (2nd)","Wizard (3rd)","Wizard (4th)",
X"Wizard (5th)","Wizard (6th)","Wizard (7th)","Wizard (8th)","Wizard (9th)",
X"Wizard Lord"},
X /* Priests */
X{"Believer","Acolyte(1st)","Acolyte(2nd)","Acolyte(3rd)","Adept (1st)",
X"Adept (2nd)","Adept (3rd)","Priest (1st)","Priest (2nd)","Priest (3rd)",
X"Priest (4th)","Priest (5th)","Priest (6th)","Priest (7th)","Priest (8th)",
X"Priest (9th)","Curate (1st)","Curate (2nd)","Curate (3rd)","Curate (4th)",
X"Curate (5th)","Curate (6th)","Curate (7th)","Curate (8th)","Curate (9th)",
X"Canon (1st)","Canon (2nd)","Canon (3rd)","Canon (4th)","Canon (5th)",
X"Low Lama","Lama-1","Lama-2","Lama-3","High Lama","Great Lama","Patriarch",
X"High Priest","Great Priest","Noble Priest"},
X /* Rogues */
X{"Vagabond","Footpad","Cutpurse","Robber","Burglar","Filcher","Sharper",
X"Magsman","Common Rogue","Rogue (1st)","Rogue (2nd)","Rogue (3rd)",
X"Rogue (4th)","Rogue (5th)","Rogue (6th)","Rogue (7th)","Rogue (8th)",
X"Rogue (9th)","Master Rogue","Expert Rogue","Senior Rogue","Chief Rogue",
X"Prime Rogue","Low Thief","Thief (1st)","Thief (2nd)","Thief (3rd)",
X"Thief (4th)","Thief (5th)","Thief (6th)","Thief (7th)","Thief (8th)",
X"Thief (9th)","High Thief","Master Thief","Executioner","Low Assassin",
X"Assassin","High Assassin","Guildsmaster"},
X /* Rangers */
X{"Runner (1st)","Runner (2nd)","Runner (3rd)","Strider (1st)","Strider (2nd)",
X"Strider (3rd)","Scout (1st)","Scout (2nd)","Scout (3rd)","Scout (4th)",
X"Scout (5th)","Courser (1st)","Courser (2nd)","Courser (3rd)","Courser (4th)",
X"Courser (5th)","Tracker (1st)","Tracker (2nd)","Tracker (3rd)",
X"Tracker (4th)","Tracker (5th)","Tracker (6th)","Tracker (7th)",
X"Tracker (8th)","Tracker (9th)","Guide (1st)","Guide (2nd)","Guide (3rd)",
X"Guide (4th)","Guide (5th)","Guide (6th)","Guide (7th)","Guide (8th)",
X"Guide (9th)","Pathfinder-1","Pathfinder-2","Pathfinder-3","Ranger",
X"High Ranger","Ranger Lord"},
X /* Paladins */
X{"Gallant","Keeper (1st)","Keeper (2nd)","Keeper (3rd)","Keeper (4th)",
X"Keeper (5th)","Keeper (6th)","Keeper (7th)","Keeper (8th)","Keeper (9th)",
X"Protector-1","Protector-2","Protector-3","Protector-4","Protector-5",
X"Protector-6","Protector-7","Protector-8","Defender-1","Defender-2",
X"Defender-3","Defender-4","Defender-5","Defender-6","Defender-7","Defender-8",
X"Warder (1st)","Warder (2nd)","Warder (3rd)","Warder (4th)","Warder (5th)",
X"Warder (6th)","Warder (7th)","Warder (8th)","Warder (9th)","Guardian",
X"Chevalier","Justiciar","Paladin","High Lord"}
X};
X#endif
X
X/* Base experience levels, may be adjusted up for race and/or class*/
Xint32u player_exp[MAX_PLAYER_LEVEL] = {
X 10, 25, 45, 70, 100, 140, 200, 280,
X 380, 500, 650, 850, 1100, 1400, 1800, 2300,
X 2900, 3600, 4400, 5400, 6800, 8400, 10200, 12500,
X 17500, 25000, 35000L, 50000L, 75000L, 100000L, 150000L, 200000L,
X 300000L, 400000L, 500000L, 750000L, 1500000L, 2500000L, 5000000L, 10000000L
X};
X
X/*Race STR,INT,WIS,DEX,CON,CHR,
X Ages, heights, and weights (male then female)
X Racial Bases for: dis,srh,stl,fos,bth,bthb,bsav,hitdie,
X infra, exp base, choice-classes */
X#ifdef MACGAME
Xrace_type *race;
X#else
Xrace_type race[MAX_RACES] = {
X {"Human", 0, 0, 0, 0, 0, 0,
X 14, 6, 72, 6,180, 25, 66, 4,150, 20,
X 0, 0, 0, 0, 0, 0, 0, 10, 0, 100, 0x3F,
X },
X {"Half-Elf", -1, 1, 0, 1, -1, 1,
X 24, 16, 66, 6,130, 15, 62, 6,100, 10,
X 2, 6, 1, -1, -1, 5, 3, 9, 2, 110, 0x3F,
X },
X {"Elf", -1, 2, 1, 1, -2, 1,
X 75, 75, 60, 4,100, 6, 54, 4, 80, 6,
X 5, 8, 1, -2, -5, 15, 6, 8, 3, 120, 0x1F,
X },
X {"Halfling", -2, 2, 1, 3, 1, 1,
X 21, 12, 36, 3, 60, 3, 33, 3, 50, 3,
X 15, 12, 4, -5,-10, 20, 18, 6, 4, 110, 0x0B,
X },
X {"Gnome", -1, 2, 0, 2, 1, -2,
X 50, 40, 42, 3, 90, 6, 39, 3, 75, 3,
X 10, 6, 3, -3, -8, 12, 12, 7, 4, 125, 0x0F,
X },
X {"Dwarf", 2, -3, 1, -2, 2, -3,
X 35, 15, 48, 3,150, 10, 46, 3,120, 10,
X 2, 7, -1, 0, 15, 0, 9, 9, 5, 120, 0x05,
X },
X {"Half-Orc", 2, -1, 0, 0, 1, -4,
X 11, 4, 66, 1,150, 5, 62, 1,120, 5,
X -3, 0, -1, 3, 12, -5, -3, 10, 3, 110, 0x0D,
X },
X {"Half-Troll",4, -4, -2, -4, 3, -6,
X 20, 10, 96, 10,255, 50, 84, 8,225, 40,
X -5, -1, -2, 5, 20,-10, -8, 12, 3, 120, 0x05,
X }
X };
X#endif
X
X/* Background information */
X#ifdef MACGAME
Xbackground_type *background;
X#else
Xbackground_type background[MAX_BACKGROUND] = {
X{"You are the illegitimate and unacknowledged child ", 10, 1, 2, 25},
X{"You are the illegitimate but acknowledged child ", 20, 1, 2, 35},
X{"You are one of several children ", 95, 1, 2, 45},
X{"You are the first child ", 100, 1, 2, 50},
X{"of a Serf. ", 40, 2, 3, 65},
X{"of a Yeoman. ", 65, 2, 3, 80},
X{"of a Townsman. ", 80, 2, 3, 90},
X{"of a Guildsman. ", 90, 2, 3,105},
X{"of a Landed Knight. ", 96, 2, 3,120},
X{"of a Titled Noble. ", 99, 2, 3,130},
X{"of a Royal Blood Line. ", 100, 2, 3,140},
X{"You are the black sheep of the family. ", 20, 3,50, 20},
X{"You are a credit to the family. ", 80, 3,50, 55},
X{"You are a well liked child. ", 100, 3,50, 60},
X{"Your mother was a Green-Elf. ", 40, 4, 1, 50},
X{"Your father was a Green-Elf. ", 75, 4, 1, 55},
X{"Your mother was a Grey-Elf. ", 90, 4, 1, 55},
X{"Your father was a Grey-Elf. ", 95, 4, 1, 60},
X{"Your mother was a High-Elf. ", 98, 4, 1, 65},
X{"Your father was a High-Elf. ", 100, 4, 1, 70},
X{"You are one of several children ", 60, 7, 8, 50},
X{"You are the only child ", 100, 7, 8, 55},
X{"of a Green-Elf ", 75, 8, 9, 50},
X{"of a Grey-Elf ", 95, 8, 9, 55},
X{"of a High-Elf ", 100, 8, 9, 60},
X{"Ranger. ", 40, 9,54, 80},
X{"Archer. ", 70, 9,54, 90},
X{"Warrior. ", 87, 9,54,110},
X{"Mage. ", 95, 9,54,125},
X{"Prince. ", 99, 9,54,140},
X{"King. ", 100, 9,54,145},
X{"You are one of several children of a Halfling ", 85,10,11, 45},
X{"You are the only child of a Halfling ", 100,10,11, 55},
X{"Bum. ", 20,11, 3, 55},
X{"Tavern Owner. ", 30,11, 3, 80},
X{"Miller. ", 40,11, 3, 90},
X{"Home Owner. ", 50,11, 3,100},
X{"Burglar. ", 80,11, 3,110},
X{"Warrior. ", 95,11, 3,115},
X{"Mage. ", 99,11, 3,125},
X{"Clan Elder. ", 100,11, 3,140},
X{"You are one of several children of a Gnome ", 85,13,14, 45},
X{"You are the only child of a Gnome ", 100,13,14, 55},
X{"Beggar. ", 20,14, 3, 55},
X{"Braggart. ", 50,14, 3, 70},
X{"Prankster. ", 75,14, 3, 85},
X{"Warrior. ", 95,14, 3,100},
X{"Mage. ", 100,14, 3,125},
X{"You are one of two children of a Dwarven ", 25,16,17, 40},
X{"You are the only child of a Dwarven ", 100,16,17, 50},
X{"Thief. ", 10,17,18, 60},
X{"Prison Guard. ", 25,17,18, 75},
X{"Miner. ", 75,17,18, 90},
X{"Warrior. ", 90,17,18,110},
X{"Priest. ", 99,17,18,130},
X{"King. ", 100,17,18,150},
X{"You are the black sheep of the family. ", 15,18,57, 10},
X{"You are a credit to the family. ", 85,18,57, 50},
X{"You are a well liked child. ", 100,18,57, 55},
X{"Your mother was an Orc, but it is unacknowledged. ", 25,19,20, 25},
X{"Your father was an Orc, but it is unacknowledged. ", 100,19,20, 25},
X{"You are the adopted child ", 100,20, 2, 50},
X{"Your mother was a Cave-Troll ", 30,22,23, 20},
X{"Your father was a Cave-Troll ", 60,22,23, 25},
X{"Your mother was a Hill-Troll ", 75,22,23, 30},
X{"Your father was a Hill-Troll ", 90,22,23, 35},
X{"Your mother was a Water-Troll ", 95,22,23, 40},
X{"Your father was a Water-Troll ", 100,22,23, 45},
X{"Cook. ", 5,23,62, 60},
X{"Warrior. ", 95,23,62, 55},
X{"Shaman. ", 99,23,62, 65},
X{"Clan Chief. ", 100,23,62, 80},
X{"You have dark brown eyes, ", 20,50,51, 50},
X{"You have brown eyes, ", 60,50,51, 50},
X{"You have hazel eyes, ", 70,50,51, 50},
X{"You have green eyes, ", 80,50,51, 50},
X{"You have blue eyes, ", 90,50,51, 50},
X{"You have blue-gray eyes, ", 100,50,51, 50},
X{"straight ", 70,51,52, 50},
X{"wavy ", 90,51,52, 50},
X{"curly ", 100,51,52, 50},
X{"black hair, ", 30,52,53, 50},
X{"brown hair, ", 70,52,53, 50},
X{"auburn hair, ", 80,52,53, 50},
X{"red hair, ", 90,52,53, 50},
X{"blond hair, ", 100,52,53, 50},
X{"and a very dark complexion.", 10,53, 0, 50},
X{"and a dark complexion.", 30,53, 0, 50},
X{"and an average complexion.", 80,53, 0, 50},
X{"and a fair complexion.", 90,53, 0, 50},
X{"and a very fair complexion.", 100,53, 0, 50},
X{"You have light grey eyes, ", 85,54,55, 50},
X{"You have light blue eyes, ", 95,54,55, 50},
X{"You have light green eyes, ", 100,54,55, 50},
X{"straight ", 75,55,56, 50},
X{"wavy ", 100,55,56, 50},
X{"black hair, and a fair complexion.", 75,56, 0, 50},
X{"brown hair, and a fair complexion.", 85,56, 0, 50},
X{"blond hair, and a fair complexion.", 95,56, 0, 50},
X{"silver hair, and a fair complexion.", 100,56, 0, 50},
X{"You have dark brown eyes, ", 99,57,58, 50},
X{"You have glowing red eyes, ", 100,57,58, 60},
X{"straight ", 90,58,59, 50},
X{"wavy ", 100,58,59, 50},
X{"black hair, ", 75,59,60, 50},
X{"brown hair, ", 100,59,60, 50},
X{"a one foot beard, ", 25,60,61, 50},
X{"a two foot beard, ", 60,60,61, 51},
X{"a three foot beard, ", 90,60,61, 53},
X{"a four foot beard, ", 100,60,61, 55},
X{"and a dark complexion.", 100,61, 0, 50},
X{"You have slime green eyes, ", 60,62,63, 50},
X{"You have puke yellow eyes, ", 85,62,63, 50},
X{"You have blue-bloodshot eyes, ", 99,62,63, 50},
X{"You have glowing red eyes, ", 100,62,63, 55},
X{"dirty ", 33,63,64, 50},
X{"mangy ", 66,63,64, 50},
X{"oily ", 100,63,64, 50},
X{"sea-weed green hair, ", 33,64,65, 50},
X{"bright red hair, ", 66,64,65, 50},
X{"dark purple hair, ", 100,64,65, 50},
X{"and green ", 25,65,66, 50},
X{"and blue ", 50,65,66, 50},
X{"and white ", 75,65,66, 50},
X{"and black ", 100,65,66, 50},
X{"ulcerous skin.", 33,66, 0, 50},
X{"scabby skin.", 66,66, 0, 50},
X{"leprous skin.", 100,66, 0, 50}
X};
X#endif
X
X/* Classes. */
Xclass_type class[MAX_CLASS] = {
X/* HP Dis Src Stl Fos bth btb sve S I W D Co Ch Spell Exp spl */
X{"Warrior",9, 25, 14, 1, 38, 70, 55, 18, 5,-2,-2, 2, 2,-1, NONE, 0, 0},
X{"Mage", 0, 30, 16, 2, 20, 34, 20, 36,-5, 3, 0, 1,-2, 1, MAGE, 30, 1},
X{"Priest", 2, 25, 16, 2, 32, 48, 35, 30,-3,-3, 3,-1, 0, 2, PRIEST, 20, 1},
X{"Rogue", 6, 45, 32, 5, 16, 60, 66, 30, 2, 1,-2, 3, 1,-1, MAGE, 0, 5},
X{"Ranger", 4, 30, 24, 3, 24, 56, 72, 30, 2, 2, 0, 1, 1, 1, MAGE, 40, 3},
X{"Paladin",6, 20, 12, 1, 38, 68, 40, 24, 3,-3, 1, 0, 2, 2, PRIEST, 35, 1}
X};
X
X/* making it 16 bits wastes a little space, but saves much signed/unsigned
X headaches in its use */
X/* CLA_MISC_HIT is identical to CLA_SAVE, which takes advantage of
X the fact that the save values are independent of the class */
Xint16 class_level_adj[MAX_CLASS][MAX_LEV_ADJ] = {
X/* bth bthb device disarm save/misc hit */
X/* Warrior */ { 4, 4, 2, 2, 3 },
X/* Mage */ { 2, 2, 4, 3, 3 },
X/* Priest */ { 2, 2, 4, 3, 3 },
X/* Rogue */ { 3, 4, 3, 4, 3 },
X/* Ranger */ { 3, 4, 3, 3, 3 },
X/* Paladin */ { 3, 3, 3, 2, 3 }
X};
X
Xint32u spell_learned = 0; /* bit mask of spells learned */
Xint32u spell_worked = 0; /* bit mask of spells tried and worked */
Xint32u spell_forgotten = 0; /* bit mask of spells learned but forgotten */
Xint8u spell_order[32]; /* order spells learned/remembered/forgotten */
X
X/* Warriors don't have spells, so there is no entry for them. Note that
X this means you must always subtract one from the py.misc.pclass before
X indexing into magic_spell[]. */
X#ifdef MACGAME
Xspell_type (*magic_spell)[31];
X#else
Xspell_type magic_spell[MAX_CLASS-1][31] = {
X { /* Mage */
X { 1, 1, 22, 1},
X { 1, 1, 23, 1},
X { 1, 2, 24, 1},
X { 1, 2, 26, 1},
X { 3, 3, 25, 2},
X { 3, 3, 25, 1},
X { 3, 3, 27, 2},
X { 3, 4, 30, 1},
X { 5, 4, 30, 6},
X { 5, 5, 30, 8},
X { 5, 5, 30, 5},
X { 5, 5, 35, 6},
X { 7, 6, 35, 9},
X { 7, 6, 50, 10},
X { 7, 6, 40, 12},
X { 9, 7, 44, 19},
X { 9, 7, 45, 19},
X { 9, 7, 75, 22},
X { 9, 7, 45, 19},
X { 11, 7, 45, 25},
X { 11, 7, 99, 19},
X { 13, 7, 50, 22},
X { 15, 9, 50, 25},
X { 17, 9, 50, 31},
X { 19, 12, 55, 38},
X { 21, 12, 90, 44},
X { 23, 12, 60, 50},
X { 25, 12, 65, 63},
X { 29, 18, 65, 88},
X { 33, 21, 80, 125},
X { 37, 25, 95, 200}
X },
X { /* Priest */
X { 1, 1, 10, 1},
X { 1, 2, 15, 1},
X { 1, 2, 20, 1},
X { 1, 2, 25, 1},
X { 3, 2, 25, 1},
X { 3, 3, 27, 2},
X { 3, 3, 27, 2},
X { 3, 3, 28, 3},
X { 5, 4, 29, 4},
X { 5, 4, 30, 5},
X { 5, 4, 32, 5},
X { 5, 5, 34, 5},
X { 7, 5, 36, 6},
X { 7, 5, 38, 7},
X { 7, 6, 38, 9},
X { 7, 7, 38, 9},
X { 9, 6, 38, 10},
X { 9, 7, 38, 10},
X { 9, 7, 40, 10},
X { 11, 8, 42, 10},
X { 11, 8, 42, 12},
X { 11, 9, 55, 15},
X { 13, 10, 45, 15},
X { 13, 11, 45, 16},
X { 15, 12, 50, 20},
X { 15, 14, 50, 22},
X { 17, 14, 55, 32},
X { 21, 16, 60, 38},
X { 25, 20, 70, 75},
X { 33, 24, 90, 125},
X { 39, 32, 99, 200}
X },
X { /* Rogue */
X { 99, 99, 0, 0},
X { 5, 1, 50, 1},
X { 7, 2, 55, 1},
X { 9, 3, 60, 2},
X { 11, 4, 65, 2},
X { 13, 5, 70, 3},
X { 99, 99, 0, 0},
X { 15, 6, 75, 3},
X { 99, 99, 0, 0},
X { 17, 7, 80, 4},
X { 19, 8, 85, 5},
X { 21, 9, 90, 6},
X { 99, 99, 0, 0},
X { 23, 10, 95, 7},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 25, 12, 95, 9},
X { 27, 15, 99, 11},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 29, 18, 99, 19},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X { 99, 99, 0, 0},
X },
X { /* Ranger */
X { 3, 1, 30, 1},
X { 3, 2, 35, 2},
X { 3, 2, 35, 2},
X { 5, 3, 35, 2},
X { 5, 3, 40, 2},
X { 5, 4, 45, 3},
X { 7, 5, 40, 6},
X { 7, 6, 40, 5},
X { 9, 7, 40, 7},
X { 9, 8, 45, 8},
X { 11, 8, 40, 10},
X { 11, 9, 45, 10},
X { 13, 10, 45, 12},
X { 13, 11, 55, 13},
X { 15, 12, 50, 15},
X { 15, 13, 50, 15},
X { 17, 17, 55, 15},
X { 17, 17, 90, 17},
X { 21, 17, 55, 17},
X { 21, 19, 60, 18},
X { 23, 25, 95, 20},
X { 23, 20, 60, 20},
X { 25, 20, 60, 20},
X { 25, 21, 65, 20},
X { 27, 21, 65, 22},
X { 29, 23, 95, 23},
X { 31, 25, 70, 25},
X { 33, 25, 75, 38},
X { 35, 25, 80, 50},
X { 37, 30, 95, 100},
X { 99, 99, 0, 0}
X },
X { /* Paladin */
X { 1, 1, 30, 1},
X { 2, 2, 35, 2},
X { 3, 3, 35, 3},
X { 5, 3, 35, 5},
X { 5, 4, 35, 5},
X { 7, 5, 40, 6},
X { 7, 5, 40, 6},
X { 9, 7, 40, 7},
X { 9, 7, 40, 8},
X { 9, 8, 40, 8},
X { 11, 9, 40, 10},
X { 11, 10, 45, 10},
X { 11, 10, 45, 10},
X { 13, 10, 45, 12},
X { 13, 11, 45, 13},
X { 15, 13, 45, 15},
X { 15, 15, 50, 15},
X { 17, 15, 50, 17},
X { 17, 15, 50, 18},
X { 19, 15, 50, 19},
X { 19, 15, 50, 19},
X { 21, 17, 50, 20},
X { 23, 17, 50, 20},
X { 25, 20, 50, 20},
X { 27, 21, 50, 22},
X { 29, 22, 50, 24},
X { 31, 24, 60, 25},
X { 33, 28, 60, 31},
X { 35, 32, 70, 38},
X { 37, 36, 90, 50},
X { 39, 38, 95, 100}
X }
X };
X#endif
X
Xchar *spell_names[62] = {
X /* Mage Spells */
X "Magic Missile", "Detect Monsters", "Phase Door", "Light Area",
X "Cure Light Wounds", "Find Hidden Traps/Doors", "Stinking Cloud",
X "Confusion", "Lightning Bolt", "Trap/Door Destruction", "Sleep I",
X "Cure Poison", "Teleport Self", "Remove Curse", "Frost Bolt",
X "Turn Stone to Mud", "Create Food", "Recharge Item I", "Sleep II",
X "Polymorph Other", "Identify", "Sleep III", "Fire Bolt", "Slow Monster",
X "Frost Ball", "Recharge Item II", "Teleport Other", "Haste Self",
X "Fire Ball", "Word of Destruction", "Genocide",
X /* Priest Spells, start at index 31 */
X "Detect Evil", "Cure Light Wounds", "Bless", "Remove Fear", "Call Light",
X "Find Traps", "Detect Doors/Stairs", "Slow Poison", "Blind Creature",
X "Portal", "Cure Medium Wounds", "Chant", "Sanctuary", "Create Food",
X "Remove Curse", "Resist Heat and Cold", "Neutralize Poison",
X "Orb of Draining", "Cure Serious Wounds", "Sense Invisible",
X "Protection from Evil", "Earthquake", "Sense Surroundings",
X "Cure Critical Wounds", "Turn Undead", "Prayer", "Dispel Undead",
X "Heal", "Dispel Evil", "Glyph of Warding", "Holy Word"
X};
X
X/* Each type of character starts out with a few provisions. */
X/* Note that the entries refer to elements of the object_list[] array*/
X/* 344 = Food Ration, 365 = Wooden Torch, 123 = Cloak, 318 = Beginners-Majik,
X 103 = Soft Leather Armor, 30 = Stiletto, 322 = Beginners Handbook */
X
Xint16u player_init[MAX_CLASS][5] = {
X { 344, 365, 123, 30, 103}, /* Warrior */
X { 344, 365, 123, 30, 318}, /* Mage */
X { 344, 365, 123, 30, 322}, /* Priest */
X { 344, 365, 123, 30, 318}, /* Rogue */
X { 344, 365, 123, 30, 318}, /* Ranger */
X { 344, 365, 123, 30, 322} /* Paladin */
X};
END_OF_FILE
if test 19531 -ne `wc -c <'source/player.c'`; then
echo shar: \"'source/player.c'\" unpacked with wrong size!
fi
# end of 'source/player.c'
fi
if test -f 'source/spells.c.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'source/spells.c.1'\"
else
echo shar: Extracting \"'source/spells.c.1'\" \(31713 characters\)
sed "s/^X//" >'source/spells.c.1' <<'END_OF_FILE'
X/* source/spells.c: player/creature spells, breaths, wands, scrolls, etc. code
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#endif
X#else
X#include <strings.h>
X#endif
X
X#if defined(LINT_ARGS)
Xstatic void replace_spot(int, int, int);
X#else
Xstatic void replace_spot();
X#endif
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
Xvoid 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)
X (void) strcpy (m_name, "It");
X else
X (void) sprintf (m_name, "The %s", r_ptr->name);
X}
X
Xvoid lower_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)
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, 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 (CD_NO_SLEEP & r_ptr->cdefense))
X {
X if (m_ptr->ml && (r_ptr->cdefense & CD_NO_SLEEP))
X c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
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, 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) && (t_list[c_ptr->tptr].tval == TV_GOLD) &&
X !test_light(i, j))
X {
X c_ptr->fm = TRUE;
X lite_spot(i, j);
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, 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) && (t_list[c_ptr->tptr].tval < TV_MAX_OBJECT)
X && !test_light(i, j))
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 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 inven_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 == TV_INVIS_TRAP)
X {
X c_ptr->fm = TRUE;
X change_trap(i, j);
X detect = TRUE;
X }
X else if (t_list[c_ptr->tptr].tval == TV_CHEST)
X {
X t_ptr = &t_list[c_ptr->tptr];
X known2(t_ptr);
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, 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 == TV_SECRET_DOOR)
X {
X c_ptr->fm = TRUE;
X change_trap(i, j);
X detect = TRUE;
X }
X /* Staircases */
X else if (((t_list[c_ptr->tptr].tval == TV_UP_STAIR) ||
X (t_list[c_ptr->tptr].tval == TV_DOWN_STAIR)) &&
X !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, flag;
X register monster_type *m_ptr;
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X flag = FALSE;
X for (i = mfptr - 1; i >= MIN_MONIX; i--)
X {
X m_ptr = &m_list[i];
X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx) &&
X#ifdef ATARIST_MWC
X ((holder = CM_INVISIBLE) & c_list[m_ptr->mptr].cmove))
X#else
X (CM_INVISIBLE & c_list[m_ptr->mptr].cmove))
X#endif
X {
X m_ptr->ml = TRUE;
X /* works correctly even if hallucinating */
X print((char)c_list[m_ptr->mptr].cchar, (int)m_ptr->fy,
X (int)m_ptr->fx);
X flag = TRUE;
X }
X }
X if (flag)
X {
X msg_print("You sense the presence of invisible creatures!");
X msg_print(CNIL);
X /* must unlight every monster just lighted */
X creatures(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 plus immediate area. */
Xint light_area(y, x)
Xregister int y, x;
X{
X register int i, j, light;
X
X if (py.flags.blind < 1)
X msg_print("You are surrounded by a white light.");
X light = TRUE;
X if (cave[y][x].lr && (dun_level > 0))
X light_room(y, x);
X /* Must always light immediate area, because one might be standing on
X the edge of a room, or next to a destroyed area, etc. */
X for (i = y-1; i <= y+1; i++)
X for (j = x-1; j <= x+1; j++)
X {
X cave[i][j].pl = TRUE;
X lite_spot(i, j);
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;
X int tmp1, tmp2, unlight;
X int start_row, start_col, end_row, end_col;
X register cave_type *c_ptr;
X
X unlight = FALSE;
X if (cave[y][x].lr && (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 for (j = start_col; j <= end_col; j++)
X {
X c_ptr = &cave[i][j];
X if (c_ptr->lr && c_ptr->fval <= MAX_CAVE_FLOOR)
X {
X c_ptr->pl = FALSE;
X c_ptr->fval = DARK_FLOOR;
X lite_spot (i, j);
X if (!test_light(i, j))
X unlight = TRUE;
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 {
X c_ptr = &cave[i][j];
X if ((c_ptr->fval == CORR_FLOOR) && c_ptr->pl)
X {
X /* pl could have been set by star-lite wand, etc */
X c_ptr->pl = FALSE;
X unlight = TRUE;
X }
X }
X
X if (unlight && py.flags.blind <= 0)
X msg_print("Darkness surrounds you.");
X
X return(unlight);
X}
X
X
X/* Map the current area plus some -RAK- */
Xvoid map_area()
X{
X register cave_type *c_ptr;
X register int i7, i8, n, m;
X int i, j, k, l;
X
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) && (cave[m][n].fval <= MAX_CAVE_FLOOR))
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 >= MIN_CAVE_WALL)
X c_ptr->pl = TRUE;
X else if ((c_ptr->tptr != 0) &&
X (t_list[c_ptr->tptr].tval >= TV_MIN_VISIBLE) &&
X (t_list[c_ptr->tptr].tval <= TV_MAX_VISIBLE))
X c_ptr->fm = TRUE;
X }
X prt_map();
X}
X
X
X/* Identify an object -RAK- */
Xint ident_spell()
X{
X int item_val;
X bigvtype out_val, tmp_str;
X register int ident;
X register inven_type *i_ptr;
X
X ident = FALSE;
X if (get_item(&item_val, "Item you wish identified?", 0, INVEN_ARRAY_SIZE,
X CNIL, CNIL))
X {
X ident = TRUE;
X identify(&item_val);
X i_ptr = &inventory[item_val];
X known2(i_ptr);
X objdes(tmp_str, i_ptr, TRUE);
X if (item_val >= INVEN_WIELD)
X {
X calc_bonuses();
X (void) sprintf (out_val, "%s: %s", describe_use(item_val), tmp_str);
X }
X else
X (void) sprintf(out_val, "%c %s", item_val+97, tmp_str);
X msg_print(out_val);
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, aggravate;
X register monster_type *m_ptr;
X
X aggravate = FALSE;
X for (i = mfptr - 1; i >= MIN_MONIX; i--)
X {
X m_ptr = &m_list[i];
X m_ptr->csleep = 0;
X if ((m_ptr->cdis <= dis_affect) && (m_ptr->cspeed < 2))
X {
X m_ptr->cspeed++;
X aggravate = TRUE;
X }
X }
X if (aggravate)
X msg_print ("You hear a sudden stirring in the distance!");
X return(aggravate);
X}
X
X
X/* Surround the fool with traps (chuckle) -RAK- */
Xint trap_creation()
X{
X register int i, j, 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 /* Don't put a trap under the player, since this can lead to
X strange situations, e.g. falling through a trap door while
X trying to rest, setting off a falling rock trap and ending
X up under the rock. */
X if (i == char_row && j == char_col)
X continue;
X c_ptr = &cave[i][j];
X if (c_ptr->fval <= MAX_CAVE_FLOOR)
X {
X if (c_ptr->tptr != 0)
X (void) delete_object(i, j);
X place_trap(i, j, randint(MAX_TRAP)-1);
X /* don't let player gain exp from the newly created traps */
X t_list[c_ptr->tptr].p1 = 0;
X /* open pits are immediately visible, so call lite_spot */
X lite_spot(i, j);
X }
X }
X return(trap);
X}
X
X
X/* Surround the player with doors. -RAK- */
Xint door_creation()
X{
X register int i, j, door;
X int k;
X register cave_type *c_ptr;
X
X door = FALSE;
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 (c_ptr->fval <= MAX_CAVE_FLOOR)
X {
X door = TRUE;
X if (c_ptr->tptr != 0)
X (void) delete_object(i, j);
X k = popt();
X c_ptr->fval = BLOCKED_FLOOR;
X c_ptr->tptr = k;
X invcopy(&t_list[k], OBJ_CLOSED_DOOR);
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, 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 >= TV_INVIS_TRAP) &&
X (t_list[c_ptr->tptr].tval <= TV_CLOSED_DOOR) &&
X (t_list[c_ptr->tptr].tval != TV_RUBBLE)) ||
X (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR))
X {
X if (delete_object(i, j))
X destroy = TRUE;
X }
X else if (t_list[c_ptr->tptr].tval == TV_CHEST)
X {
X /* destroy traps on chest and unlock */
X t_list[c_ptr->tptr].flags &= ~(CH_TRAPPED|CH_LOCKED);
X t_list[c_ptr->tptr].name2 = SN_UNLOCKED;
X msg_print ("You have disarmed the chest.");
X known2(&t_list[c_ptr->tptr]);
X destroy = TRUE;
X }
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, detect;
X register monster_type *m_ptr;
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X detect = FALSE;
X for (i = mfptr - 1; i >= MIN_MONIX; i--)
X {
X m_ptr = &m_list[i];
X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx) &&
X#ifdef ATARIST_MWC
X (((holder = CM_INVISIBLE) & c_list[m_ptr->mptr].cmove) == 0))
X#else
X ((CM_INVISIBLE & c_list[m_ptr->mptr].cmove) == 0))
X#endif
X {
X m_ptr->ml = TRUE;
X /* works correctly even if hallucinating */
X print((char)c_list[m_ptr->mptr].cchar, (int)m_ptr->fy,
X (int)m_ptr->fx);
X detect = TRUE;
X }
X }
X if (detect)
X {
X msg_print("You sense the presence of monsters!");
X msg_print(CNIL);
X /* must unlight every monster just lighted */
X creatures(FALSE);
X }
X return(detect);
X}
X
X
X/* Leave a line of light in given dir, blue light can sometimes */
X/* hurt creatures. -RAK- */
Xvoid light_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 int dist, flag;
X vtype out_val, m_name;
X
X dist = -1;
X flag = FALSE;
X do
X {
X /* put mmove at end because want to light up current spot */
X dist++;
X c_ptr = &cave[y][x];
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else
X {
X if (!c_ptr->pl && !c_ptr->tl)
X {
X /* set pl so that lite_spot will work */
X c_ptr->pl = TRUE;
X if (c_ptr->fval == LIGHT_FLOOR)
X {
X if (panel_contains(y, x))
X light_room(y, x);
X }
X else
X lite_spot(y, x);
X }
X /* set pl in case tl was true above */
X c_ptr->pl = TRUE;
X if (c_ptr->cptr > 1)
X {
X m_ptr = &m_list[c_ptr->cptr];
X r_ptr = &c_list[m_ptr->mptr];
X /* light up and draw monster */
X update_mon ((int)c_ptr->cptr);
X monster_name (m_name, m_ptr, r_ptr);
X if (CD_LIGHT & r_ptr->cdefense)
X {
X if (m_ptr->ml)
X c_recall[m_ptr->mptr].r_cdefense |= CD_LIGHT;
X i = mon_take_hit((int)c_ptr->cptr, damroll(2, 8));
X if (i >= 0)
X {
X (void) sprintf(out_val,
X "%s shrivels away in the light!", m_name);
X msg_print(out_val);
X prt_experience();
X }
X else
X {
X (void) sprintf(out_val, "%s cringes from the light!",
X m_name);
X msg_print (out_val);
X }
X }
X }
X }
X (void) mmove(dir, &y, &x);
X }
X while (!flag);
X}
X
X
X/* Light line in all directions -RAK- */
Xvoid starlite(y, x)
Xregister int y, x;
X{
X register int i;
X
X if (py.flags.blind < 1)
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}
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 inven_type *t_ptr;
X register int disarm, dist;
X
X disarm = FALSE;
X dist = -1;
X do
X {
X /* put mmove at end, in case standing on a trap */
X dist++;
X c_ptr = &cave[y][x];
X /* note, must continue upto and including the first non open space,
X because secret doors have fval greater than MAX_OPEN_SPACE */
X if (c_ptr->tptr != 0)
X {
X t_ptr = &t_list[c_ptr->tptr];
X if ((t_ptr->tval == TV_INVIS_TRAP) || (t_ptr->tval == TV_VIS_TRAP))
X {
X if (delete_object(y, x))
X disarm = TRUE;
X }
X else if (t_ptr->tval == TV_CLOSED_DOOR)
X t_ptr->p1 = 0; /* Locked or jammed doors become merely closed. */
X else if (t_ptr->tval == TV_SECRET_DOOR)
X {
X c_ptr->fm = TRUE;
X change_trap(y, x);
X disarm = TRUE;
X }
X else if ((t_ptr->tval == TV_CHEST) && (t_ptr->flags != 0))
X {
X msg_print("Click!");
X t_ptr->flags &= ~(CH_TRAPPED|CH_LOCKED);
X disarm = TRUE;
X t_ptr->name2 = SN_UNLOCKED;
X known2(t_ptr);
X }
X }
X (void) mmove(dir, &y, &x);
X }
X while ((dist <= OBJ_BOLT_RANGE) && c_ptr->fval <= MAX_OPEN_SPACE);
X return(disarm);
X}
X
X
X/* Return flags for given type area affect -RAK- */
Xvoid get_flags(typ, weapon_type, harm_type, destroy)
Xint typ;
Xint32u *weapon_type; int *harm_type;
Xint (**destroy)();
X{
X switch(typ)
X {
X case GF_MAGIC_MISSILE:
X *weapon_type = 0;
X *harm_type = 0;
X *destroy = set_null;
X break;
X case GF_LIGHTNING:
X *weapon_type = CS_BR_LIGHT;
X *harm_type = CD_LIGHT;
X *destroy = set_lightning_destroy;
X break;
X case GF_POISON_GAS:
X *weapon_type = CS_BR_GAS;
X *harm_type = CD_POISON;
X *destroy = set_null;
X break;
X case GF_ACID:
X *weapon_type = CS_BR_ACID;
X *harm_type = CD_ACID;
X *destroy = set_acid_destroy;
X break;
X case GF_FROST:
X *weapon_type = CS_BR_FROST;
X *harm_type = CD_FROST;
X *destroy = set_frost_destroy;
X break;
X case GF_FIRE:
X *weapon_type = CS_BR_FIRE;
X *harm_type = CD_FIRE;
X *destroy = set_fire_destroy;
X break;
X case GF_HOLY_ORB:
X *weapon_type = 0;
X *harm_type = CD_EVIL;
X *destroy = set_null;
X break;
X default:
X msg_print("ERROR in get_flags()\n");
X }
X}
X
X
X/* Shoot a bolt in a given direction -RAK- */
Xvoid fire_bolt(typ, dir, y, x, dam, bolt_typ)
Xint typ, dir, y, x, dam;
Xchar *bolt_typ;
X{
X int i, oldy, oldx, dist, flag;
X int32u weapon_type; int harm_type;
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, m_name;
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) mmove(dir, &y, &x);
X dist++;
X c_ptr = &cave[y][x];
X lite_spot(oldy, oldx);
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else
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
X /* light up monster and draw monster, temporarily set
X pl so that update_mon() will work */
X i = c_ptr->pl;
X c_ptr->pl = TRUE;
X update_mon ((int)c_ptr->cptr);
X c_ptr->pl = i;
X /* draw monster and clear previous bolt */
X put_qio();
X
X lower_monster_name(m_name, m_ptr, r_ptr);
X (void) sprintf(out_val, "The %s strikes %s.", bolt_typ, m_name);
X msg_print(out_val);
X if (harm_type & r_ptr->cdefense)
X {
X dam = dam*2;
X if (m_ptr->ml)
X c_recall[m_ptr->mptr].r_cdefense |= harm_type;
X }
X else if (weapon_type & r_ptr->spells)
X {
X dam = dam / 4;
X if (m_ptr->ml)
X c_recall[m_ptr->mptr].r_spells |= weapon_type;
X }
X monster_name(m_name, m_ptr, r_ptr);
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 prt_experience();
X }
X else if (dam > 0)
X {
X (void) sprintf (out_val, "%s screams in agony.", m_name);
X msg_print (out_val);
X }
X }
X else if (panel_contains(y, x) && (py.flags.blind < 1))
X {
X print('*', y, x);
X /* show the bolt */
X put_qio();
X }
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- */
Xvoid fire_ball(typ, dir, y, x, dam_hp, descrip)
Xint typ, dir, y, x, dam_hp;
Xchar *descrip;
X{
X register int i, j;
X int dam, max_dis, thit, tkill, k, tmp;
X int oldy, oldx, dist, flag, harm_type;
X int32u weapon_type;
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
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) mmove(dir, &y, &x);
X dist++;
X lite_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->fval >= MIN_CLOSED_SPACE) || (c_ptr->cptr > 1))
X {
X flag = TRUE;
X if (c_ptr->fval >= MIN_CLOSED_SPACE)
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) && (distance(y, x, i, j) <= max_dis)
X && los(y, x, i, j))
X {
X c_ptr = &cave[i][j];
X if ((c_ptr->tptr != 0) &&
X (*destroy)(&t_list[c_ptr->tptr]))
X (void) delete_object(i, j);
X if (c_ptr->fval <= MAX_OPEN_SPACE)
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
X /* lite up creature if visible, temp
X set pl so that update_mon works */
X tmp = c_ptr->pl;
X c_ptr->pl = TRUE;
X update_mon((int)c_ptr->cptr);
X
X thit++;
X dam = dam_hp;
X if (harm_type & r_ptr->cdefense)
X {
X dam = dam*2;
X if (m_ptr->ml)
X c_recall[m_ptr->mptr].r_cdefense |=harm_type;
X }
X else if (weapon_type & r_ptr->spells)
X {
X dam = dam / 4;
X if (m_ptr->ml)
X c_recall[m_ptr->mptr].r_spells |=weapon_type;
X }
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 c_ptr->pl = tmp;
X }
X else if (panel_contains(i, j) &&(py.flags.blind < 1))
X print('*', i, j);
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) && panel_contains(i, j) &&
X (distance(y, x, i, j) <= max_dis))
X lite_spot(i, j);
X
X /* End explosion. */
X if (thit == 1)
X {
X (void) sprintf(out_val,
X "The %s envelops a creature!",
X descrip);
X msg_print(out_val);
X }
X else if (thit > 1)
X {
X (void) sprintf(out_val,
X "The %s envelops 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 if (tkill >= 0)
X prt_experience();
X /* End ball hitting. */
X }
X else if (panel_contains(y, x) && (py.flags.blind < 1))
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- */
Xvoid breath(typ, y, x, dam_hp, ddesc, monptr)
Xint typ, y, x, dam_hp;
Xchar *ddesc;
Xint monptr;
X{
X register int i, j;
X int dam, max_dis, harm_type;
X int32u weapon_type;
X int32u tmp, treas;
X int (*destroy)();
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 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) && (distance(y, x, i, j) <= max_dis)
X && los(y, x, i, j))
X {
X c_ptr = &cave[i][j];
X if ((c_ptr->tptr != 0) &&
X (*destroy)(&t_list[c_ptr->tptr]))
X (void) delete_object(i, j);
X if (c_ptr->fval <= MAX_OPEN_SPACE)
X {
X /* must test status bit, not py.flags.blind here, flag could have
X been set by a previous monster, but the breath should still
X be visible until the blindness takes effect */
X if (panel_contains(i, j) && !(py.flags.status & PY_BLIND))
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);
X dam = (dam/(distance(i, j, y, x)+1));
X /* can not call mon_take_hit here, since player does not
X get experience for kill */
X m_ptr->hp = m_ptr->hp - dam;
X m_ptr->csleep = 0;
X if (m_ptr->hp < 0)
X {
X treas = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
X r_ptr->cmove);
X if (m_ptr->ml)
X {
X#ifdef ATARIST_MWC
X holder = CM_TREASURE;
X tmp = (c_recall[m_ptr->mptr].r_cmove & holder)
X >> CM_TR_SHIFT;
X if (tmp > ((treas & holder) >> CM_TR_SHIFT))
X treas = (treas & ~holder)|(tmp << CM_TR_SHIFT);
X c_recall[m_ptr->mptr].r_cmove = treas |
X (c_recall[m_ptr->mptr].r_cmove & ~holder);
X#else
X tmp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE)
X >> CM_TR_SHIFT;
X if (tmp > ((treas & CM_TREASURE) >> CM_TR_SHIFT))
X treas = (treas & ~CM_TREASURE)|(tmp<<CM_TR_SHIFT);
X c_recall[m_ptr->mptr].r_cmove = treas |
X (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE);
X#endif
X }
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 monster
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 }
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 GF_LIGHTNING: light_dam(dam, ddesc); break;
X case GF_POISON_GAS: poison_gas(dam, ddesc); break;
X case GF_ACID: acid_dam(dam, ddesc); break;
X case GF_FROST: cold_dam(dam, ddesc); break;
X case GF_FIRE: 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) && panel_contains(i, j) &&
X (distance(y, x, i, j) <= max_dis))
X lite_spot(i, j);
X}
X
X
X/* Recharge a wand, staff, or rod. Sometimes the item breaks. -RAK-*/
Xint recharge(num)
Xregister int num;
X{
X int i, j, item_val;
X register int res;
X register inven_type *i_ptr;
X
X res = FALSE;
X if (!find_range(TV_STAFF, TV_WAND, &i, &j))
X msg_print("You have nothing to recharge.");
X else if (get_item(&item_val, "Recharge which item?", i, j, CNIL, CNIL))
X {
X i_ptr = &inventory[item_val];
X res = TRUE;
X /* recharge I = recharge(20) = 1/6 failure for empty 10th level wand */
X /* recharge II = recharge(60) = 1/10 failure for empty 10th level wand*/
X /* make it harder to recharge high level, and highly charged wands, note
X that i can be negative, so check its value before trying to call
X randint(). */
X i = num + 50 - (int)i_ptr->level - i_ptr->p1;
X if (i < 19)
X i = 1; /* Automatic failure. */
X else
X i = randint (i/10);
X
X if (i == 1)
X {
X msg_print("There is a bright flash of light.");
X inven_destroy(item_val);
X }
X else
X {
X num = (num/(i_ptr->level+2)) + 1;
X i_ptr->p1 += 2 + randint(num);
X if (known2_p(i_ptr))
X clear_known2(i_ptr);
X clear_empty(i_ptr);
X }
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, dist, monster;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X vtype out_val, m_name;
X
X monster = FALSE;
X flag = FALSE;
X dist = 0;
X do
X {
X (void) mmove(dir, &y, &x);
X dist++;
X c_ptr = &cave[y][x];
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else 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.", m_name);
X msg_print(out_val);
X prt_experience();
X }
X else if (dam > 0)
X {
X (void) sprintf(out_val, "%s screams in agony.", m_name);
X msg_print(out_val);
X }
X }
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, dist, drain;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X vtype out_val, m_name;
X
X drain = FALSE;
X flag = FALSE;
X dist = 0;
X do
X {
X (void) mmove(dir, &y, &x);
X dist++;
X c_ptr = &cave[y][x];
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else 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 & CD_UNDEAD) == 0)
X {
X drain = TRUE;
X monster_name (m_name, m_ptr, r_ptr);
X i = mon_take_hit((int)c_ptr->cptr, 75);
X if (i >= 0)
X {
X (void) sprintf(out_val, "%s dies in a fit of agony.",m_name);
X msg_print(out_val);
X prt_experience();
X }
X else
X {
X (void) sprintf(out_val, "%s screams in agony.", m_name);
X msg_print(out_val);
X }
X }
X else
X c_recall[m_ptr->mptr].r_cdefense |= CD_UNDEAD;
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 flag, dist, speed;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X vtype out_val, m_name;
X
X speed = FALSE;
X flag = FALSE;
X dist = 0;
X do
X {
X (void) mmove(dir, &y, &x);
X dist++;
X c_ptr = &cave[y][x];
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else 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 m_ptr->csleep = 0;
X (void) sprintf(out_val, "%s is unaffected.", m_name);
X msg_print(out_val);
X }
X }
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, dist, confuse;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X vtype out_val, m_name;
X
X confuse = FALSE;
X flag = FALSE;
X dist = 0;
X do
X {
X (void) mmove(dir, &y, &x);
X dist++;
X c_ptr = &cave[y][x];
X if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
X flag = TRUE;
X else 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 (CD_NO_SLEEP & r_ptr->cdefense))
X {
X if (m_ptr->ml && (r_ptr->cdefense & CD_NO_SLEEP))
X c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
X /* Monsters which resisted the attack should wake up.
X Monsters with inane resistence ignore the attack. */
X if (! (CD_NO_SLEEP & r_ptr->cdefense))
X m_ptr->csleep = 0;
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 }
END_OF_FILE
if test 31713 -ne `wc -c <'source/spells.c.1'`; then
echo shar: \"'source/spells.c.1'\" unpacked with wrong size!
fi
# end of 'source/spells.c.1'
fi
if test -f 'util/mc/st.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'util/mc/st.h'\"
else
echo shar: Extracting \"'util/mc/st.h'\" \(2080 characters\)
sed "s/^X//" >'util/mc/st.h' <<'END_OF_FILE'
X/* util/mc/st.h: definitions for the symbol table module
X *
X * Copyright (c) 1989 by Joseph Hall.
X * All rights reserved except as stated below.
X *
X * Jim Wilson and any other holders of copyright on substantial portions
X * of Moria are granted rights to use, modify, and distribute this program
X * as they see fit, so long as the terms of its use, modification and/or
X * distribution are no less restrictive than those applying to Moria,
X * version 5.0 or later, itself, and so long as this use is related to
X * the further development of Moria.
X *
X * Anyone having any other use in mind for this code should contact the
X * author at 4116 Brewster Dr., Raleigh NC 27606 (jnh@ecemwl.ncsu.edu).
X */
X
X#ifndef _ST_H_
X#define _ST_H_
X
X#ifndef TRUE
X#define TRUE 1
X#endif
X
X#ifndef FALSE
X#define FALSE 0
X#endif
X
X/*
X * Needs generic_t
X */
X
X#include "generic.h"
X
X/*
X * maximum length of symbol strings
X */
X
X#define ST_MAX_SYM_LEN 32
X
X/*
X * Struct for individual entries
X */
X
Xtypedef struct st_EntryStruct {
X
X char name[ST_MAX_SYM_LEN]; /* symbol string */
X int type; /* symbol type */
X struct st_EntryStruct *next_P; /* next entry in chain */
X generic_t gval; /* symbol value */
X
X} st_Entry_t, *st_Entry_Pt;
X
X/*
X * Struct for table header
X */
X
Xtypedef struct {
X
X char name[ST_MAX_SYM_LEN];
X /* table name */
X int size, /* size of table to be allocated */
X entryCt; /* # of entries in table currently */
X st_Entry_Pt *tab_A; /* vector of ptrs to entries */
X
X} st_Table_t, *st_Table_Pt;
X
X#define ST_SYM_FOUND 0
X#define ST_OK 0
X#define ST_SYM_NOT_FOUND 1
X#define ST_NULL_TABLE 2
X
X#define ST_MAX_INPUT_LEN 256
X
X/*
X * functions defined in st_symtab.c
X */
X
Xextern st_Table_Pt St_NewTable();
Xextern void St_DelTable();
Xextern int St_GetSym();
Xextern int St_DefSym();
Xextern int St_ReplSym();
Xextern int St_DelSym();
Xextern st_Table_Pt St_GetTable();
Xextern void St_DumpTable();
Xextern char **St_ListTable();
Xextern char **St_SListTable();
Xextern int St_TableSize();
X
X#endif /* _ST_H_ */
X
END_OF_FILE
if test 2080 -ne `wc -c <'util/mc/st.h'`; then
echo shar: \"'util/mc/st.h'\" unpacked with wrong size!
fi
# end of 'util/mc/st.h'
fi
echo shar: End of archive 18 \(of 39\).
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 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