games@tekred.TEK.COM (07/29/88)
Submitted by: "James E. Wilson" <wilson@ji.berkeley.edu>
Comp.sources.games: Volume 5, Issue 45
Archive-name: umoria2/Part11
#! /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 11 (of 18)."
# Contents: creature.c save.c
# Wrapped by billr@saab on Wed Jul 13 11:16:29 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'creature.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'creature.c'\"
else
echo shar: Extracting \"'creature.c'\" \(35194 characters\)
sed "s/^X//" >'creature.c' <<'END_OF_FILE'
X#include <stdio.h>
X
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
X#ifdef sun /* correct SUN stupidity in the stdio.h file */
Xchar *sprintf();
X#endif
X
Xextern int search_flag;
Xextern int moria_flag;
X
X/* Updates screen when monsters move about -RAK- */
Xupdate_mon(monptr)
Xint monptr;
X{
X int flag;
X char tmp_str[2];
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X
X m_ptr = &m_list[monptr];
X c_ptr = &cave[m_ptr->fy][m_ptr->fx];
X flag = FALSE;
X if (m_ptr->cdis <= MAX_SIGHT)
X if (py.flags.blind < 1)
X if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx))
X /* Wizard sight... */
X if (wizard2)
X flag = TRUE;
X /* Normal sight... */
X else if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
X {
X r_ptr = &c_list[m_ptr->mptr];
X if ((c_ptr->pl) || (c_ptr->tl))
X {
X if (py.flags.see_inv)
X flag = TRUE;
X else if ((0x10000 & r_ptr->cmove) == 0)
X flag = TRUE;
X }
X /* Infra vision... */
X else if (py.flags.see_infra > 0)
X if (m_ptr->cdis <= py.flags.see_infra)
X if (0x2000 & r_ptr->cdefense)
X flag = TRUE;
X }
X /* Light it up... */
X if (flag)
X {
X if (!m_ptr->ml)
X {
X tmp_str[0] = c_list[m_ptr->mptr].cchar;
X tmp_str[1] = '\0';
X print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx);
X m_ptr->ml = TRUE;
X if (search_flag)
X search_off();
X if (py.flags.rest > 0)
X rest_off();
X flush();
X if (find_flag)
X {
X find_flag = FALSE;
X move_light (char_row, char_col, char_row, char_col);
X }
X }
X }
X /* Turn it off... */
X else if (m_ptr->ml)
X {
X m_ptr->ml = FALSE;
X if ((c_ptr->tl) || (c_ptr->pl))
X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X else
X unlite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X }
X}
X
X
X/* Choose correct directions for monster movement -RAK- */
Xget_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 if (ay > (ax*1.7321))
X move_val += 2;
X else if (ax > (ay*1.7321))
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] = 8;
X mm[4] = 2;
X }
X else
X {
X mm[1] = 7;
X mm[2] = 1;
X mm[3] = 2;
X mm[4] = 8;
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] = 1;
X mm[2] = 3;
X mm[3] = 4;
X mm[4] = 6;
X }
X else
X {
X mm[1] = 3;
X mm[2] = 1;
X mm[3] = 6;
X mm[4] = 4;
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- */
Xmake_attack(monptr)
Xint monptr;
X{
X int xpos, attype, adesc, dam;
X int i, j, l;
X vtype attstr, attx;
X vtype cdesc, ddesc, tmp_str;
X dtype damstr;
X int flag;
X register creature_type *c_ptr;
X monster_type *m_ptr;
X register struct misc *p_ptr;
X register struct flags *f_ptr;
X register treasure_type *i_ptr;
X char *string;
X
X m_ptr = &m_list[monptr];
X c_ptr = &c_list[m_ptr->mptr];
X (void) strcpy(attstr, c_ptr->damage);
X if ((0x10000 & c_ptr->cmove) && (!py.flags.see_inv))
X (void) strcpy(cdesc, "It ");
X else if (py.flags.blind > 0)
X (void) strcpy(cdesc, "It ");
X else if (!m_ptr->ml)
X (void) strcpy(cdesc, "It ");
X else
X (void) sprintf(cdesc, "The %s ", c_ptr->name);
X /* For "DIED_FROM" string */
X if (0x80000000 & c_ptr->cmove)
X (void) sprintf(ddesc, "The %s", c_ptr->name);
X else
X (void) sprintf(ddesc, "& %s", c_ptr->name);
X (void) strcpy(inventory[INVEN_MAX].name, ddesc);
X inventory[INVEN_MAX].number = 1;
X objdes(ddesc, INVEN_MAX, TRUE);
X /* End DIED_FROM */
X
X while (strlen(attstr) > 0)
X {
X string = index(attstr, '|');
X if (string)
X xpos = strlen(attstr) - strlen(string);
X else
X xpos = -1;
X if (xpos >= 0)
X {
X (void) strncpy(attx, attstr, xpos);
X attx[xpos] = '\0';
X (void) strcpy(attstr, &attstr[xpos+1]);
X }
X else
X {
X (void) strcpy(attx, attstr);
X attstr[0] = '\0';
X }
X (void) sscanf(attx, "%d %d %s", &attype, &adesc, damstr);
X flag = FALSE;
X if (py.flags.protevil > 0)
X if (c_ptr->cdefense & 0x0004)
X if ((py.misc.lev + 1) > c_ptr->level)
X {
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)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 2: /*Poison Strength*/
X if (test_hit(-3, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 3: /*Confusion attack*/
X if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 4: /*Fear attack */
X if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 5: /*Fire attack */
X if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 6: /*Acid attack */
X if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 7: /*Cold attack */
X if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 8: /*Lightning attack*/
X if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 9: /*Corrosion attack*/
X if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 10: /*Blindness attack*/
X if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 11: /*Paralysis attack*/
X if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 12: /*Steal Money */
X if (test_hit(5, (int)c_ptr->level, 0, (int)py.misc.lev))
X if (py.misc.au > 0)
X flag = TRUE;
X break;
X case 13: /*Steal Object */
X if (test_hit(2, (int)c_ptr->level, 0, (int)py.misc.lev))
X if (inven_ctr > 0)
X flag = TRUE;
X break;
X case 14: /*Poison */
X if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 15: /*Lose dexterity*/
X if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 16: /*Lose constitution*/
X if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 17: /*Lose intelligence*/
X if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 18: /*Lose wisdom*/
X if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 19: /*Lose experience*/
X if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
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)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 22: /*Eat food */
X if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 23: /*Eat light */
X if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
X flag = TRUE;
X break;
X case 24: /*Eat charges */
X if (test_hit(15, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac))
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 (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 case 6: msg_print(strcat(tmp_str, "kicks you.")); break;
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 case 11: msg_print(strcat(tmp_str, "embraces you.")); break;
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 switch(attype)
X {
X case 1: /*Normal attack */
X dam = damroll(damstr);
X dam -= (int)((((p_ptr->pac+p_ptr->ptoac)/200.0)*dam)+.5);
X take_hit(dam, ddesc);
X prt_chp();
X break;
X case 2: /*Poison Strength*/
X take_hit(damroll(damstr), ddesc);
X if (py.flags.sustain_str)
X msg_print("You feel weaker for a moment, it passes.");
X else if (randint(2) == 1)
X {
X msg_print("You feel weaker.");
X py.stats.cstr = de_statp(py.stats.cstr);
X prt_strength();
X /* adjust misc stats */
X py_bonuses(blank_treasure, 0);
X }
X prt_chp();
X break;
X case 3: /*Confusion attack*/
X f_ptr = &py.flags;
X take_hit(damroll(damstr), 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)c_ptr->level);
X }
X f_ptr->confused += 3;
X }
X prt_chp();
X break;
X case 4: /*Fear attack */
X f_ptr = &py.flags;
X take_hit(damroll(damstr), ddesc);
X if (player_saves(wis_adj()))
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)c_ptr->level);
X }
X else
X f_ptr->afraid += 3;
X prt_chp();
X break;
X case 5: /*Fire attack */
X msg_print("You are enveloped in flames!");
X fire_dam(damroll(damstr), ddesc);
X break;
X case 6: /*Acid attack */
X msg_print("You are covered in acid!");
X acid_dam(damroll(damstr), ddesc);
X break;
X case 7: /*Cold attack */
X msg_print("You are covered with frost!");
X cold_dam(damroll(damstr), ddesc);
X break;
X case 8: /*Lightning attack*/
X msg_print("Lightning strikes you!");
X light_dam(damroll(damstr), 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(damroll(damstr), ddesc);
X prt_chp();
X break;
X case 10: /*Blindness attack*/
X f_ptr = &py.flags;
X take_hit(damroll(damstr), ddesc);
X if (f_ptr->blind < 1)
X {
X f_ptr->blind += 10 + randint((int)c_ptr->level);
X msg_print("Your eyes begin to sting.");
X }
X f_ptr->blind += 5;
X prt_chp();
X break;
X case 11: /*Paralysis attack*/
X f_ptr = &py.flags;
X take_hit(damroll(damstr), ddesc);
X if (player_saves(con_adj()))
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)c_ptr->level) + 3;
X msg_print("You are paralyzed.");
X }
X }
X prt_chp();
X break;
X case 12: /*Steal Money */
X if ((randint(124) < py.stats.cdex) && (py.flags.paralysis < 1))
X msg_print("You quickly protect your money pouch!");
X else
X {
X i = (p_ptr->au/10) + randint(25);
X if (i > p_ptr->au)
X p_ptr->au = 0;
X else
X p_ptr->au -= i;
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 ((randint(124) < py.stats.cdex) && (py.flags.paralysis < 1))
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(damroll(damstr), ddesc);
X prt_chp();
X msg_print("You feel very sick.");
X f_ptr->poisoned += randint((int)c_ptr->level)+5;
X break;
X case 15: /*Lose dexterity */
X f_ptr = &py.flags;
X take_hit(damroll(damstr), ddesc);
X if (f_ptr->sustain_dex)
X msg_print("You feel clumsy for a moment, it passes.");
X else
X {
X msg_print("You feel more clumsy.");
X py.stats.cdex = de_statp(py.stats.cdex);
X prt_dexterity();
X /* adjust misc stats */
X py_bonuses(blank_treasure, 0);
X }
X prt_chp();
X break;
X case 16: /*Lose constitution */
X f_ptr = &py.flags;
X take_hit(damroll(damstr), 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 py.stats.ccon = de_statp(py.stats.ccon);
X prt_constitution();
X }
X prt_chp();
X break;
X case 17: /*Lose intelligence */
X f_ptr = &py.flags;
X take_hit(damroll(damstr), ddesc);
X if (f_ptr->sustain_int)
X {
X msg_print("You feel your memories fading...");
X msg_print("Your memories are suddenly restored!");
X }
X else
X {
X msg_print("You feel your memories fading...");
X py.stats.cint = de_statp(py.stats.cint);
X prt_intelligence();
X }
X prt_chp();
X break;
X case 18: /*Lose wisdom */
X f_ptr = &py.flags;
X take_hit(damroll(damstr), 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 py.stats.cwis = de_statp(py.stats.cwis);
X prt_wisdom();
X }
X prt_chp();
X break;
X case 19: /*Lose experience */
X msg_print("You feel your life draining away!");
X i = damroll(damstr) + (py.misc.exp / 100)*MON_DRAIN_LIFE;
X lose_exp(i);
X break;
X case 20: /*Aggravate monster*/
X (void) aggravate_monster(5);
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 flag = TRUE;
X }
X if (i_ptr->todam > 0)
X {
X i_ptr->todam -= randint(2);
X flag = TRUE;
X }
X if (i_ptr->toac > 0)
X {
X i_ptr->toac -= randint(2);
X flag = TRUE;
X }
X if (flag)
X {
X msg_print("There is a static feeling in the air...");
X py_bonuses(blank_treasure, 1);
X }
X break;
X case 22: /*Eat food */
X if (find_range(80, -1, &i, &j))
X inven_destroy(i);
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 msg_print("Your light dims...");
X }
X break;
X case 24: /*Eat charges */
X i = randint(inven_ctr) - 1;
X l = c_ptr->level;
X i_ptr = &inventory[i];
X if ((i_ptr->tval == 55) || (i_ptr->tval == 60) ||
X (i_ptr->tval == 65))
X if (i_ptr->p1 > 0)
X {
X m_ptr->hp += l*i_ptr->p1;
X i_ptr->p1 = 0;
X msg_print("Energy drains from your pack!");
X }
X break;
X case 99: break;
X default: break;
X }
X }
X else
X switch(adesc)
X {
X case 1: case 2: case 3: case 6:
X (void) strcpy(tmp_str, cdesc);
X msg_print(strcat(tmp_str, "misses you."));
X break;
X default: break;
X }
X }
X}
X
X
X/* Make the move if possible, five choices -RAK- */
Xint make_move(monptr, mm)
Xint monptr;
Xint *mm;
X{
X int i, j, newy, newx;
X unsigned int movebits;
X int flag, tflag;
X int res;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X register treasure_type *t_ptr;
X register creature_type *r_ptr;
X char tmp_str[80];
X vtype m_name;
X
X i = 0;
X flag = FALSE;
X res = FALSE;
X movebits = c_list[m_list[monptr].mptr].cmove;
X do
X {
X /* Get new position */
X newy = m_list[monptr].fy;
X newx = m_list[monptr].fx;
X (void) move(mm[i], &newy, &newx);
X c_ptr = &cave[newy][newx];
X if (c_ptr->fval != 15)
X {
X tflag = FALSE;
X /* Floor is open? */
X if (c_ptr->fopen)
X tflag = TRUE;
X /* Creature moves through walls? */
X else if (movebits & 0x40000)
X tflag = TRUE;
X /* Creature can open doors? */
X else if (c_ptr->tptr != 0)
X {
X t_ptr = &t_list[c_ptr->tptr];
X m_ptr = &m_list[monptr];
X if (movebits & 0x20000)
X { /* Creature can open doors... */
X switch(t_ptr->tval)
X {
X case 105: /* Closed doors... */
X if (t_ptr->p1 == 0) /* Closed doors */
X {
X tflag = TRUE;
X if (los(char_row, char_col, newy, newx))
X {
X t_list[c_ptr->tptr] = door_list[0];
X c_ptr->fopen = TRUE;
X lite_spot(newy, newx);
X tflag = FALSE;
X }
X }
X else if (t_ptr->p1 > 0) /* Locked doors */
X {
X if (randint(100-t_ptr->level) < 5)
X t_ptr->p1 = 0;
X }
X else if (t_ptr->p1 < 0) /* Stuck doors */
X {
X if (randint(m_ptr->hp+1) > (10+abs(t_ptr->p1)))
X t_ptr->p1 = 0;
X }
X break;
X case 109: /* Secret doors... */
X tflag = TRUE;
X if (los(char_row, char_col, newy, newx))
X {
X t_list[c_ptr->tptr] = door_list[0];
X c_ptr->fopen = TRUE;
X lite_spot(newy, newx);
X tflag = FALSE;
X }
X break;
X default: break;
X }
X }
X else
X { /* Creature can not open doors, must bash them */
X switch(t_ptr->tval)
X {
X case 105: /* Closed doors... */
X j = abs(t_ptr->p1) + 20;
X if (randint(m_ptr->hp+1) > j)
X {
X tflag = TRUE;
X if (los(char_row, char_col, newy, newx))
X {
X t_list[c_ptr->tptr] = door_list[0];
X t_list[c_ptr->tptr].p1 = randint(2) - 1;
X c_ptr->fopen = TRUE;
X lite_spot(newy, newx);
X tflag = FALSE;
X }
X }
X break;
X case 109: /* Secret doors... */
X break;
X default:
X break;
X }
X }
X }
X /* Glyph of warding present? */
X if (tflag) /* Scare Monster trap */
X if (c_ptr->tptr != 0)
X if (t_list[c_ptr->tptr].tval == 102)
X if (t_list[c_ptr->tptr].subval == 99)
X {
X if (randint(OBJ_RUNE_PROT) <
X c_list[m_list[monptr].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 tflag = FALSE;
X }
X /* Creature has attempted to move on player? */
X if (tflag)
X if (c_ptr->cptr == 1)
X {
X if (!m_list[monptr].ml)
X update_mon(monptr);
X if (search_flag) search_off();
X if (py.flags.rest > 0) rest_off();
X if (find_flag)
X {
X find_flag = FALSE;
X move_light (char_row, char_col, char_row, char_col);
X }
X flush();
X make_attack(monptr);
X /* Player has read a Confuse Monster? */
X /* Monster gets a saving throw... */
X if (py.flags.confuse_monster)
X {
X m_ptr = &m_list[monptr];
X r_ptr = &c_list[m_ptr->mptr];
X msg_print("Your hands stop glowing.");
X py.flags.confuse_monster = FALSE;
X
X /* Does the player know what he's fighting? */
X if ((0x10000 & r_ptr->cmove) && (!py.flags.see_inv))
X (void) strcpy(m_name, "It");
X else if (py.flags.blind > 0)
X (void) strcpy(m_name, "It");
X else if (!m_ptr->ml)
X (void) strcpy(m_name, "It");
X else
X (void) sprintf(m_name, "The %s", r_ptr->name);
X if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
X (0x1000 & r_ptr->cdefense))
X {
X (void) sprintf(tmp_str, "%s is unaffected.",
X m_name);
X msg_print(tmp_str);
X }
X else
X {
X (void) sprintf(tmp_str, "%s appears confused.",
X m_name);
X msg_print(tmp_str);
X m_ptr->confused = TRUE;
X }
X }
X tflag = FALSE;
X flag = TRUE;
X }
X /* Creature is attempting to move on other creature? */
X else if ((c_ptr->cptr > 1) &&
X ((newy != m_list[monptr].fy) ||
X (newx != m_list[monptr].fx)))
X {
X /* Creature eats other creatures? */
X if (movebits & 0x80000)
X delete_monster((int)c_ptr->cptr);
X else
X tflag = FALSE;
X }
X /* Creature has been allowed move... */
X if (tflag)
X {
X m_ptr = &m_list[monptr];
X /* Pick up or eat an object */
X if (movebits & 0x100000)
X {
X c_ptr = &cave[newy][newx];
X
X if (c_ptr->tptr != 0)
X if (t_list[c_ptr->tptr].tval < 100)
X (void) delete_object(newy, newx);
X }
X /* Move creature record */
X move_rec((int)m_ptr->fy, (int)m_ptr->fx, newy, newx);
X m_ptr->fy = newy;
X m_ptr->fx = newx;
X flag = TRUE;
X res = TRUE;
X }
X }
X i++;
X /* Up to 5 attempts at moving, give up... */
X }
X while ((!flag) && (i < 5));
X return(res);
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 */
Xint mon_cast_spell(monptr, took_turn)
Xint monptr;
Xint *took_turn;
X{
X unsigned int i;
X int y, x;
X register int k;
X int chance, thrown_spell;
X double r1;
X int spell_choice[30];
X vtype cdesc, ddesc, outval;
X int flag;
X register monster_type *m_ptr;
X register creature_type *r_ptr;
X int cast;
X
X m_ptr = &m_list[monptr];
X r_ptr = &c_list[m_ptr->mptr];
X chance = (int)((r_ptr->spells & 0x0000000F));
X /* 1 in x chance of casting spell */
X if (randint(chance) != 1)
X {
X cast = FALSE;
X *took_turn = FALSE;
X }
X /* Must be within certain range */
X else if (m_ptr->cdis > MAX_SPELL_DIS)
X {
X cast = FALSE;
X *took_turn = FALSE;
X }
X /* Must have unobstructed Line-Of-Sight */
X else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
X {
X cast = FALSE;
X *took_turn = FALSE;
X }
X else /* Creature is going to cast a spell */
X {
X *took_turn = TRUE;
X cast = TRUE;
X /* Describe the attack */
X flag = TRUE;
X if (!m_ptr->ml)
X flag = FALSE;
X else if ((0x10000 & c_list[m_ptr->mptr].cmove) &&
X (!py.flags.see_inv))
X flag = FALSE;
X else if (py.flags.blind > 0)
X flag = FALSE;
X if (flag)
X (void) sprintf(cdesc, "The %s ", r_ptr->name);
X else
X (void) strcpy(cdesc, "It ");
X /* For "DIED_FROM" string */
X if (0x80000000 & r_ptr->cmove)
X (void) sprintf(ddesc, "The %s", r_ptr->name);
X else
X (void) sprintf(ddesc, "& %s", r_ptr->name);
X (void) strcpy(inventory[INVEN_MAX].name, ddesc);
X inventory[INVEN_MAX].number = 1;
X objdes(ddesc, INVEN_MAX, TRUE);
X /* End DIED_FROM */
X
X /* Extract all possible spells into spell_choice */
X i = (r_ptr->spells & 0xFFFFFFF0);
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 /* 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 (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X teleport_to((int)m_ptr->fy, (int)m_ptr->fx);
X break;
X case 8: /*Light Wound */
X (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (player_saves(wis_adj()))
X msg_print("You resist the effects of the spell.");
X else
X take_hit(damroll("3d8"), ddesc);
X break;
X case 9: /*Serious Wound */
X (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (player_saves(wis_adj()))
X msg_print("You resist the effects of the spell.");
X else
X take_hit(damroll("8d8"), ddesc);
X break;
X case 10: /*Hold Person */
X (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (py.flags.free_act)
X msg_print("You are unaffected...");
X else if (player_saves(wis_adj()))
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 (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (player_saves(wis_adj()))
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 (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (player_saves(wis_adj()))
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 (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (player_saves(wis_adj()))
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 (void) summon_monster(&y, &x, FALSE);
X check_mon_lite(y, x);
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 (void) summon_undead(&y, &x);
X check_mon_lite(y, x);
X break;
X case 16: /*Slow Person */
X (void) strcat(cdesc, "casts a spell.");
X msg_print(cdesc);
X if (py.flags.free_act)
X msg_print("You are unaffected...");
X else if (player_saves(wis_adj()))
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 (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc);
X msg_print(outval);
X if (flag)
X {
X (void) sprintf(outval, "%sappears healthier...", cdesc);
X msg_print(outval);
X }
X r1 = ( randint((int)r_ptr->level) / 2 ) + 1;
X if (r1 > py.misc.cmana) r1 = py.misc.cmana;
X py.misc.cmana -= r1;
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(1, char_row, char_col, (int)(m_ptr->hp/4.0), ddesc);
X break;
X case 21: /*Breath Gas */
X (void) strcat(cdesc, "breathes gas.");
X msg_print(cdesc);
X breath(2, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc);
X break;
X case 22: /*Breath Acid */
X (void) strcat(cdesc, "breathes acid.");
X msg_print(cdesc);
X breath(3, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc);
X break;
X case 23: /*Breath Frost */
X (void) strcat(cdesc, "breathes frost.");
X msg_print(cdesc);
X breath(4, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc);
X break;
X case 24: /*Breath Fire */
X (void) strcat(cdesc, "breathes fire.");
X msg_print(cdesc);
X breath(5, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc);
X break;
X default:
X msg_print("Creature cast unknown spell.");
X cdesc[0] = '\0';
X }
X /* End of spells */
X }
X return(cast);
X}
X
X
X/* Move the critters about the dungeon -RAK- */
Xint mon_move(monptr)
Xint monptr;
X{
X register int i, j;
X int k;
X int move_test;
X int movem;
X register creature_type *c_ptr;
X register monster_type *m_ptr;
X int mm[5];
X
X /* Main procedure for monster movement (MON_MOVE) -RAK- */
X movem = FALSE;
X c_ptr = &c_list[m_list[monptr].mptr];
X /* Does the critter multiply? */
X if (c_ptr->cmove & 0x00200000)
X if (MAX_MON_MULT >= mon_tot_mult)
X if ((py.flags.rest % MON_MULT_ADJ) == 0)
X {
X m_ptr = &m_list[monptr];
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))
X if (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)
X if (randint(k*MON_MULT_ADJ) == 1)
X multiply_monster((int)m_ptr->fy, (int)m_ptr->fx,
X (int)m_ptr->mptr, FALSE);
X }
X /* Creature is confused? Chance it becomes un-confused */
X move_test = FALSE;
X if (m_list[monptr].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 (!(c_ptr->cmove & 0x00000001))
X movem = make_move(monptr, mm);
X if (randint(8) == 1)
X m_list[monptr].confused = FALSE;
X move_test = TRUE;
X }
X /* Creature may cast a spell */
X else if (c_ptr->spells != 0)
X movem = mon_cast_spell(monptr, &move_test);
X if (!move_test)
X {
X /* 75% random movement */
X if ((randint(100) < 75) &&
X (c_ptr->cmove & 0x00000020))
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 movem = make_move(monptr, mm);
X }
X /* 40% random movement */
X else if ((randint(100) < 40) &&
X (c_ptr->cmove & 0x00000010))
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 movem = make_move(monptr, mm);
X }
X /* 20% random movement */
X else if ((randint(100) < 20) &&
X (c_ptr->cmove & 0x00000008))
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 movem = make_move(monptr, mm);
X }
X /* Normal movement */
X else if (c_ptr->cmove & 0x00000002)
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 movem = make_move(monptr, mm);
X }
X /* Attack, but don't move */
X else if (c_ptr->cmove & 0x00000001)
X if (m_list[monptr].cdis < 2)
X {
X get_moves(monptr, mm);
X movem = make_move(monptr, mm);
X }
X }
X return(movem);
X}
X
X
X/* Creatures movement and attacking are done from here -RAK- */
Xcreatures(attack)
Xint attack;
X{
X register int i, j, k;
X int moldy, moldx;
X register monster_type *m_ptr;
X /* Main procedure for creatures -RAK- */
X
X /* Process the monsters */
X i = muptr;
X while ((i > 0) && (!moria_flag))
X {
X m_ptr = &m_list[i];
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 for (j = 0; j < movement_rate(m_ptr->cspeed); j++)
X {
X if ((m_ptr->cdis <= c_list[m_ptr->mptr].aaf) ||
X (m_ptr->ml))
X {
X if (m_ptr->csleep > 0)
X if (py.flags.aggravate)
X m_ptr->csleep = 0;
X else if (py.flags.rest < 1)
X if (randint(10) > py.misc.stl)
X m_ptr->csleep -= (75.0/m_ptr->cdis);
X if (m_ptr->stunned > 0)
X m_ptr->stunned--;
X if ((m_ptr->csleep <= 0) && (m_ptr->stunned <= 0))
X {
X moldy = m_ptr->fy;
X moldx = m_ptr->fx;
X if (mon_move(i))
X if (m_ptr->ml)
X {
X m_ptr->ml = FALSE;
X if (test_light(moldy, moldx))
X lite_spot(moldy, moldx);
X else
X unlite_spot(moldy, moldx);
X }
X }
X }
X update_mon(i);
X }
X else
X update_mon(i);
X }
X else
X update_mon(i);
X i = m_list[i].nptr;
X }
X /* End processing monsters */
X}
END_OF_FILE
if test 35194 -ne `wc -c <'creature.c'`; then
echo shar: \"'creature.c'\" unpacked with wrong size!
fi
# end of 'creature.c'
fi
if test -f 'save.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'save.c'\"
else
echo shar: Extracting \"'save.c'\" \(15988 characters\)
sed "s/^X//" >'save.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
X#ifdef sun /* correct SUN stupidity in the stdio.h file */
Xchar *sprintf();
X#endif
X
X#ifdef ultrix
Xvoid sleep();
X#endif
X
X#ifdef USG
Xunsigned sleep();
X#endif
X
X#define IREAD 00400
X#define IWRITE 00200
X
X/* This save package was brought to by -JWT-
X and -RAK-
X and has been completely rewritten for UNIX by -JEW- */
X
X/* Wizard command for restoring character -RAK- */
Xrestore_char()
X{
X vtype fnam;
X register int i, j;
X register FILE *f1;
X int error;
X vtype temp;
X double version;
X struct stat buf2;
X char char_tmp;
X char char_tmp_array[3];
X register cave_type *c_ptr;
X
X clear_screen(0, 0);
X
X prt("Enter Filename:", 0, 0);
X if (!get_string(fnam, 0, 16, 60))
X {
X return(FALSE);
X }
X no_controlz();
X
X if (chmod(fnam, (IREAD | IWRITE)) == -1)
X {
X (void) sprintf(temp, "Can not change file mode for %s", fnam);
X prt(temp, 0, 0);
X }
X
X if ((f1 = fopen(fnam, "r")) == NULL)
X {
X (void) sprintf(temp, "Cannot open file %s for reading.", fnam);
X prt(temp, 0, 0);
X return(FALSE);
X }
X
X prt("Restoring Character...", 0, 0);
X put_qio();
X error = 0;
X error |= !fread((char *)&version, sizeof(version), 1, f1);
X error |= !fread((char *)&py, sizeof(py), 1, f1);
X error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
X error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
X error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
X error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
X error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
X error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
X error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
X error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
X error |= !fread((char *)&turn, sizeof(turn), 1, f1);
X error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
X error |= !fread((char *)magic_spell[py.misc.pclass],
X sizeof(spell_type), 31, f1);
X error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
X error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
X error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
X error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
X
X for (i = 0; i < MAX_HEIGHT; i++)
X for (j = 0; j < MAX_WIDTH; j++)
X {
X c_ptr = &cave[i][j];
X error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
X error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
X error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
X c_ptr->fval = char_tmp & 0xF;
X c_ptr->fopen = (char_tmp >> 4) & 0x1;
X c_ptr->fm = (char_tmp >> 5) & 0x1;
X c_ptr->pl = (char_tmp >> 6) & 0x1;
X c_ptr->tl = (char_tmp >> 7) & 0x1;
X }
X
X error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
X error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
X error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
X error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
X error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
X error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);
X
X if (version == 4.83)
X {
X /* insult_cur was a byte in 4.83, but is now a short */
X for (i = 0; i < MAX_STORES; i++)
X {
X error |= !fread((char *)&store[i].store_open,
X sizeof(short), 1, f1);
X error |= !fread((char *)&char_tmp,
X sizeof(char), 1, f1); /* this is different */
X store[i].insult_cur = (short)char_tmp;
X error |= !fread((char *)&store[i].owner,
X sizeof(char), 1, f1);
X error |= !fread((char *)&store[i].store_ctr,
X sizeof(char), 1, f1);
X /* quick compatibility hack for a local vax */
X /* ignore three bytes of fill character */
X error |= !fread((char *)char_tmp_array,
X sizeof(char), 3, f1);
X error |= !fread((char *)store[i].store_inven,
X sizeof(inven_record), STORE_INVEN_MAX, f1);
X }
X }
X else
X {
X error |= !fread((char *)store, sizeof(store), 1, f1);
X }
X
X error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
X
X error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
X error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
X error |= !fread((char *)&randes_seed, sizeof(randes_seed), 1, f1);
X error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
X error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);
X
X if (version >= 4.87)
X {
X error |= !fread((char *)&panic_save, sizeof(panic_save), 1, f1);
X /* clear the panic_save condition, which is used to indicate
X cheating */
X panic_save = 0;
X }
X
X error |= fclose(f1);
X
X controlz();
X
X if (error)
X {
X (void) sprintf(temp, "Error reading in file %s", fnam);
X prt(temp, 0, 0);
X return(FALSE);
X }
X if (unlink(fnam) == -1)
X {
X (void) sprintf(temp, "Cannot delete file %s", fnam);
X prt(temp, 0, 0);
X }
X
X /* reidentify objects */
X /* very inefficient, should write new routine perhaps? */
X for (i = 0; i < MAX_OBJECTS; i++)
X if (object_ident[i] == TRUE)
X identify(object_list[i]);
X
X return(FALSE);
X}
X
X
Xsave_char(exit, no_ask)
Xint exit;
Xint no_ask;
X{
X register int i, j;
X int flag;
X int error;
X vtype fnam, temp;
X double version;
X struct stat buf;
X register FILE *f1;
X char char_tmp;
X register cave_type *c_ptr;
X
X flag = FALSE;
X
X if (!no_ask)
X {
X prt("Enter Filename:", 0, 0);
X if (!get_string(fnam, 0, 16, 60))
X {
X /* only return if exit TRUE, i.e. this is not a panic save */
X if (exit)
X return;
X else
X (void) strcpy(fnam, "MORIACHR.SAV");
X }
X /* if get_string succeeded, but returned zero length */
X else if (strlen(fnam) == 0)
X (void) strcpy(fnam, "MORIACHR.SAV");
X }
X else
X (void) strcpy(fnam, "MORIACHR.SAV");
X
X no_controlz();
X
X /* Open the user's save file -JEW- */
X if ((f1 = fopen(fnam, "w")) == NULL)
X {
X (void) sprintf(temp, "Error creating %s", fnam);
X msg_print(temp);
X return;
X }
X flag = TRUE;
X clear_screen(0, 0);
X prt("Saving character...", 0, 0);
X put_qio();
X version = CUR_VERSION;
X error = 0;
X error |= !fwrite((char *)&version, sizeof(version), 1, f1);
X error |= !fwrite((char *)&py, sizeof(py), 1, f1);
X error |= !fwrite((char *)&char_row, sizeof(char_row), 1, f1);
X error |= !fwrite((char *)&char_col, sizeof(char_col), 1, f1);
X error |= !fwrite((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
X error |= !fwrite((char *)&inven_weight, sizeof(inven_weight), 1, f1);
X error |= !fwrite((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
X error |= !fwrite((char *)&dun_level, sizeof(dun_level), 1, f1);
X error |= !fwrite((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
X error |= !fwrite((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
X error |= !fwrite((char *)&turn, sizeof(turn), 1, f1);
X error |= !fwrite((char *)inventory, sizeof(inventory), 1, f1);
X error |= !fwrite((char *)magic_spell[py.misc.pclass],
X sizeof(spell_type), 31, f1);
X error |= !fwrite((char *)&cur_height, sizeof(cur_height), 1, f1);
X error |= !fwrite((char *)&cur_width, sizeof(cur_width), 1, f1);
X error |= !fwrite((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
X error |= !fwrite((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
X
X for (i = 0; i < MAX_HEIGHT; i++)
X for (j = 0; j < MAX_WIDTH; j++)
X {
X c_ptr = &cave[i][j];
X char_tmp = c_ptr->fval | (c_ptr->fopen << 4) | (c_ptr->fm << 5) |
X (c_ptr->pl << 6) | (c_ptr->tl << 7);
X error |= !fwrite((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
X error |= !fwrite((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
X error |= !fwrite((char *)&char_tmp, sizeof(char_tmp), 1, f1);
X }
X
X error |= !fwrite((char *)t_list, sizeof(t_list), 1, f1);
X error |= !fwrite((char *)&tcptr, sizeof(tcptr), 1, f1);
X error |= !fwrite((char *)object_ident, sizeof(object_ident), 1, f1);
X error |= !fwrite((char *)m_list, sizeof(m_list), 1, f1);
X error |= !fwrite((char *)&mfptr, sizeof(mfptr), 1, f1);
X error |= !fwrite((char *)&muptr, sizeof(muptr), 1, f1);
X error |= !fwrite((char *)store, sizeof(store), 1, f1);
X
X if (stat(fnam, &buf) == -1)
X {
X (void) sprintf(temp, "Can not stat file %s", fnam);
X msg_print(temp);
X return;
X }
X
X error |= !fwrite((char *)&buf, sizeof(buf), 1, f1);
X
X error |= !fwrite((char *)norm_state, sizeof(norm_state), 1, f1);
X error |= !fwrite((char *)randes_state, sizeof(randes_state), 1, f1);
X error |= !fwrite((char *)&randes_seed, sizeof(randes_seed), 1, f1);
X error |= !fwrite((char *)town_state, sizeof(town_state), 1, f1);
X error |= !fwrite((char *)&town_seed, sizeof(town_seed), 1, f1);
X
X /* this indicates 'cheating' if it is a one */
X error |= !fwrite((char *)&panic_save, sizeof(panic_save), 1, f1);
X
X error |= fclose(f1);
X
X character_saved = 1;
X
X if (!wizard1)
X if (chmod(fnam, 0) == -1)
X {
X (void) sprintf(temp, "Can not change file mode for %s", fnam);
X msg_print(temp);
X return;
X }
X
X /* make sure user can't touch save file for 5 seconds */
X (void) sleep(5);
X
X controlz();
X
X if (error)
X {
X (void) sprintf(temp, "Error writing to file %s", fnam);
X prt(temp, 0, 0);
X prt("Game not saved.", 0, 0);
X }
X else if (flag)
X {
X (void) sprintf(temp,"Character saved. [Moria Version %lf]",CUR_VERSION);
X prt(temp, 0, 0);
X if (exit)
X exit_game();
X }
X}
X
X
Xget_char(fnam)
Xchar *fnam;
X{
X register int i, j;
X register FILE *f1;
X int error;
X vtype temp;
X double version;
X#ifdef USG
X struct stat buf, buf2;
X#else
X struct stat lbuf, buf, buf2;
X#endif
X char char_tmp;
X char char_tmp_array[3];
X register cave_type *c_ptr;
X long age;
X
X clear_screen(0, 0);
X
X no_controlz();
X
X#ifdef USG
X /* no symbolic links */
X if (stat(fnam, &buf) == -1)
X#else
X if ((lstat(fnam, &lbuf) == -1) || (stat(fnam, &buf) == -1))
X#endif
X {
X (void) sprintf(temp, "Cannot stat file %s", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X#ifdef USG
X /* no symbolic links */
X#else
X if (lbuf.st_ino != buf.st_ino)
X {
X (void) sprintf(temp, "Cannot restore from symbolic link %s", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X#endif
X
X if (buf.st_nlink != 1)
X {
X (void) sprintf(temp, "Too many links to file %s", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X if (chmod(fnam, (IREAD | IWRITE)) == -1)
X {
X (void) sprintf(temp, "Can not change file mode for %s", fnam);
X prt(temp, 0, 0);
X }
X
X if ((f1 = fopen(fnam, "r")) == NULL)
X {
X (void) sprintf(temp, "Cannot open file %s for reading", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X prt("Restoring Character...", 0, 0);
X put_qio();
X error = 0;
X error |= !fread((char *)&version, sizeof(version), 1, f1);
X error |= !fread((char *)&py, sizeof(py), 1, f1);
X error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
X error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
X error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
X error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
X error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
X error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
X error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
X error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
X error |= !fread((char *)&turn, sizeof(turn), 1, f1);
X error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
X error |= !fread((char *)magic_spell[py.misc.pclass],
X sizeof(spell_type), 31, f1);
X error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
X error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
X error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
X error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
X
X for (i = 0; i < MAX_HEIGHT; i++)
X for (j = 0; j < MAX_WIDTH; j++)
X {
X c_ptr = &cave[i][j];
X error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
X error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
X error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
X c_ptr->fval = char_tmp & 0xF;
X c_ptr->fopen = (char_tmp >> 4) & 0x1;
X c_ptr->fm = (char_tmp >> 5) & 0x1;
X c_ptr->pl = (char_tmp >> 6) & 0x1;
X c_ptr->tl = (char_tmp >> 7) & 0x1;
X }
X
X error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
X error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
X error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
X error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
X error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
X error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);
X
X if (version == 4.83)
X {
X /* insult_cur was a byte in 4.83, but is now a short */
X for (i = 0; i < MAX_STORES; i++)
X {
X error |= !fread((char *)&store[i].store_open,
X sizeof(short), 1, f1);
X error |= !fread((char *)&char_tmp,
X sizeof(char), 1, f1); /* this is different */
X store[i].insult_cur = (short)char_tmp;
X error |= !fread((char *)&store[i].owner,
X sizeof(char), 1, f1);
X error |= !fread((char *)&store[i].store_ctr,
X sizeof(char), 1, f1);
X /* quick compatibility hack for a local vax */
X /* ignore three bytes of fill character */
X error |= !fread((char *)char_tmp_array,
X sizeof(char), 3, f1);
X error |= !fread((char *)store[i].store_inven,
X sizeof(inven_record), STORE_INVEN_MAX, f1);
X }
X }
X else
X {
X error |= !fread((char *)store, sizeof(store), 1, f1);
X }
X
X error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
X
X error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
X error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
X error |= !fread((char *)&randes_seed, sizeof(randes_seed), 1, f1);
X error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
X error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);
X
X if (version >= 4.87)
X {
X error |= !fread((char *)&panic_save, sizeof(panic_save), 1, f1);
X }
X
X error |= fclose(f1);
X
X controlz();
X
X if (buf.st_atime >= buf2.st_atime + 5)
X {
X (void) sprintf(temp, "File %s has been touched, sorry.", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X if (error)
X {
X (void) sprintf(temp, "Error reading in file %s", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X /* rotate store inventory, depending on how old the save file is */
X /* foreach day or fraction thereof old, call store_maint once */
X /* must do this before delete file */
X if (stat (fnam, &buf2) == -1)
X {
X (void) sprintf(temp, "Cannot stat file %s?", fnam);
X prt(temp, 0, 0);
X }
X else
X {
X age = (long)buf2.st_atime - (long)buf.st_atime; /* age in seconds */
X age = (age / 86400) + 1; /* age in days */
X for (i = 0; i < age; i++)
X store_maint();
X }
X
X if (unlink(fnam) == -1)
X {
X (void) sprintf(temp, "Cannot delete file %s", fnam);
X prt(temp, 0, 0);
X exit_game();
X }
X
X if (panic_save == 1)
X {
X (void) sprintf(temp, "This game is from a panic save. Score will not be added to scoreboard.");
X msg_print (temp);
X /* make sure player will see message before change_name is called */
X msg_print (" ");
X }
X
X /* reidentify objects */
X /* very inefficient, should write new routine perhaps? */
X for (i = 0; i < MAX_OBJECTS; i++)
X if (object_ident[i] == TRUE)
X identify(object_list[i]);
X
X /* in case restoring a dead character, this can happen if a signal
X is caught after a characters hit points go below zero, but before
X the game ends */
X if (py.misc.chp <= -1)
X {
X prt("Your character has already died.", 23, 0);
X (void) strcpy(died_from, "Unknown.");
X death = 1;
X }
X
X return(FALSE);
X}
END_OF_FILE
if test 15988 -ne `wc -c <'save.c'`; then
echo shar: \"'save.c'\" unpacked with wrong size!
fi
# end of 'save.c'
fi
echo shar: End of archive 11 \(of 18\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 18 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0