|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 30175 (0x75df) Types: TextFile Names: »mess.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Rog-O-Matic/mess.c«
/* * mess.c: Rog-O-Matic XIV (CMU) Thu Jan 31 15:33:12 1985 - mlm * Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin * * mess.c: This file contains all of the functions which parse the * message line. */ # include <curses.h> # include <ctype.h> # include "types.h" # include "globals.h" /* Matching macros */ # define MATCH(p) smatch(mess,p,result) /* Local data recording statistics */ static int monkilled[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static int totalkilled=0, timeshit=0, timesmissed=0, hits=0, misses=0; static int sumgold=0, sumsqgold=0, numgold=0; static mhit=0, mmiss=0, mtarget= NONE; /* Other local data */ identifying = 0; /* Next message is from identify scroll */ static int justreadid = 0; /* True if just read identify scroll */ static int gushed = 0; /* True ==> water on the head msg recently */ static int echoit; /* True ==> echo this message to the user */ /* Results from star matcher */ static char res1[NAMSIZ], res2[NAMSIZ], res3[NAMSIZ], res4[NAMSIZ]; static char *result[] = { res1, res2, res3, res4 }; /* * terpmes: called when a message from Rogue is on the top line, * this function parses the message and notes the information. * Note that the messages are all lower cased, to help with * compatability bewtween 3.6 and 5.2, since 5.2 capitalizes more * messages than does 3.6. Trailing punctuation is also ignored. * * As of Rogue 5.3, multiple messages are broken into single * messages before being passed to parsemsg. Periods separate * multiple messages. */ terpmes () { char mess[128]; register char *m, *mend, *s = screen[0], *t; /* Set 't' to the tail of the message, skip backward over blank & dot */ for (t=s+79; *t==' ' || *t=='.'; t--) ; /* Find last non-blank */ t++; /* t -> beyond string */ /* * Loop through each message, finding the beginning and end, and * copying it to mess, lower-casing it as we go. Then call parsemsg. */ while (s<t) /* While more chars in msg */ { while (*s==' ' && s<t) s++; /* Skip leading blanks */ for (m = mess; /* Copy text */ s<t && (version < RV53A || *s != '.'); s++) *m++ = isupper (*s) ? tolower (*s) : *s; /* Lower case the char */ s++; /* Skip the period, if any */ *(mend = m) = '\0'; /* Add trailing null */ if (mess != mend) parsemsg (mess, mend); /* Parse it */ } } /* * parsemsg: Parse a single message, and if necessary set variables * or call functions. */ parsemsg (mess, mend) register char *mess, *mend; { int unknown = 0; echoit = 1; /*----------------Take action based on type of message-------------*/ if (MATCH("was wearing *")) ; /* Message indicates we picked up a new item */ else if (mend[-1]==')' && mend[-3]=='(') { inventory (mess, mend); identifying = justreadid = 0; } /* Message describes an old item already in our pack */ else if (mess[1]==')') { echoit = identifying; identifying = justreadid = 0; inventory(mess,mend); } /* A random message, switch of first char to save some time... */ else switch (mess[0]) { case 'a': if (MATCH("as you read the scroll, it vanishes")) echoit=0; else if (MATCH("a cloak of darkness falls around you")) { infer ("blindness"); blinded=1; } else if (MATCH("a teleport trap")) nametrap (TELTRAP,NEAR); else if (MATCH("a trapdoor")) nametrap (TRAPDOR,NEAR); else if (MATCH("an arrow shoots *")) { arrowshot=1; nametrap(ARROW,HERE); } else if (MATCH("an arrow trap")) nametrap (ARROW,NEAR); else if (MATCH("a beartrap")) nametrap (BEARTRP,NEAR); else if (MATCH("a strange white mist *")) nametrap (GASTRAP,HERE); else if (MATCH("a sleeping gas trap")) nametrap (GASTRAP,NEAR); else if (MATCH("a small dart *")) nametrap (DARTRAP,HERE); else if (MATCH("a dart trap")) nametrap (DARTRAP,NEAR); else if (MATCH("a poison dart trap")) nametrap (DARTRAP,NEAR); else if (MATCH("a rust trap")) nametrap (WATERAP,NEAR); else if (MATCH("a gush of water hits you on the head")) gushed++; else if (MATCH("a sting has weakened you")) ; else if (MATCH("a bite has weakened you")) ; else if (MATCH("a ring *")) ; else if (MATCH("a wand *")) ; else if (MATCH("a staff *")) ; else if (MATCH("a scroll *")) ; else if (MATCH("a potion *")) ; else if (MATCH("a +*")) ; else if (MATCH("a -*")) ; else unknown++; break; case 'b': if (MATCH("bolt bounces")) infer ("lightning"); else if (MATCH("bolt hits")) infer ("lightning"); else if (MATCH("bolt misses")) infer ("lightning"); else if (MATCH("bummer, this food tastes awful")) ; else if (MATCH("bummer! you've hit the ground")) floating=0; else if (MATCH("bite has no effect")) ; else unknown++; break; case 'c': if (MATCH("call it*")) echoit=0; /* Handled in getrogue() */ else unknown++; break; case 'd': if (MATCH("defeated the *")) { echoit=0; killed(res1); } else if (MATCH("defeated it")) { echoit=0; killed("it"); } else if (MATCH("defeated *")) { echoit=0; killed(res1); } else if (MATCH("drop what*")) echoit=0; else if (MATCH("dropped *")) ; else unknown++; break; case 'e': if (MATCH("eat what*")) echoit=0; else if (MATCH("everything looks so boring now")) cosmic=0; else unknown++; break; case 'f': if (MATCH("flame *")) ; else if (MATCH("far out! everything is all cosmic again")) blinded=0; else unknown++; break; case 'g': if (MATCH("getting hungry")) echoit=0; else if (MATCH("getting the munchies")) echoit=0; else unknown++; break; case 'h': if (MATCH("hey, this tastes great*")) infer ("restore strength"); else if (MATCH("huh? what? who?")) ; else if (MATCH("heavy! that's a nasty critter!")) ; else unknown++; break; case 'i': if (MATCH("it hit")) { washit ("it"); echoit=0; } else if (MATCH("it misses")) { wasmissed ("it"); echoit=0; } else if (MATCH("it appears confused")) ; else if (MATCH("ice *")) ; else if (MATCH("identify what*")) echoit=0; else if (MATCH("illegal command*")) echoit=0; else if (MATCH("i see no way*")) {unset(STAIRS); findstairs();} else if (MATCH("it appears to be cursed")) curseditem (); else if (MATCH("it make*")) ; else unknown++; break; case 'j': case 'k': unknown++; break; case 'l': if (MATCH("left or*")) echoit=0; else unknown++; break; case 'm': if (MATCH("missile vanishes")) infer ("magic missile"); else if (MATCH("missle vanishes")) infer ("magic missile"); else if (MATCH("my, that was a yummy *")) ; else if (MATCH("moved onto *")) set (STUFF); else unknown++; break; case 'n': if (MATCH("nothing happens")) inven[lastwand].charges = 0; else if (MATCH("no more *")) ; else if (MATCH("nothing appropriate")) ; else if (MATCH("no room")) ; else unknown++; break; case 'o': if (MATCH("oh no! an arrow shot *")) { arrowshot=1; nametrap(ARROW,HERE); } else if (MATCH("oh, now this scroll has a map *")) { infer ("magic mapping"); didreadmap = Level; } else if (MATCH("oh, bummer! everything is dark! help!")) { infer ("blindness"); blinded=1; } else if (MATCH("oh, wow! everything seems so cosmic!")) { infer ("hallucination"); cosmic=1; } else if (MATCH("oh, wow! you're floating in the air!")) { infer ("levitation"); floating=1; } else if (MATCH("oh, wow, that tasted good")) ; else unknown++; break; case 'p': if (MATCH("please spec*")) echoit=0; else if (MATCH("put on what*")) echoit=0; else unknown++; break; case 'q': if (MATCH("quaff what*")) echoit=0; else unknown++; break; case 'r': if (MATCH("range is 'a' to '*'")) { echoit=0; if (*res1-'a'+1 != invcount) { dwait (D_INFORM, "Range check failed..."); usesynch = 0; } } else if (MATCH("read what*")) echoit=0; else unknown++; break; case 's': if (MATCH("she stole *")) usesynch = 0; else if (MATCH("sting has no effect")) ; else unknown++; break; case 't': if (MATCH("throw what*")) echoit=0; else if (MATCH("the * bounces")) ; else if (MATCH("the bolt *")) ; else if (MATCH("the flame *")) ; else if (MATCH("the ice hits")) ; else if (MATCH("the ice misses")) ; else if (MATCH("the ice whizzes by you")) wasmissed ("ice monster"); else if (MATCH("the * hits it")) {echoit=0; mshit ("it");} else if (MATCH("the * misses it")) {echoit=0; msmiss ("it");} else if (MATCH("the * hits the *")) {echoit=0; mshit (res2);} else if (MATCH("the * misses the *")) {echoit=0; msmiss (res2);} else if (MATCH("the * hit")) { washit (res1); gushed=0; echoit=0; } else if (MATCH("the * misses")) { wasmissed (res1); echoit=0; } else if (MATCH("the * appears confused")) ; else if (MATCH("the rust vanishes instantly")) { if (gushed) { gushed = 0; nametrap (WATERAP, HERE); } } else if (MATCH("the room is lit")) { setnewgoal (); infer ("light"); } else if (MATCH("the * has confused you")) confused = 1; else if (MATCH("this scroll is an * scroll")) { if (stlmatch (res1, "identify")) readident (res1); } else if (MATCH("that's not a valid item")) { echoit = justreadid < 1; if (justreadid-- == 0) sendnow (" *"); if (justreadid < -50) dwait (D_FATAL, "Caught in invalid item loop"); } else if (MATCH("the veil of darkness lifts")) blinded=0; else if (MATCH("the scroll turns to dust*")) { deletestuff (atrow, atcol); unset(SCAREM | STUFF); droppedscare--; } else if (MATCH("this potion tastes * dull")) infer ("thirst quenching"); else if (MATCH("this potion tastes pretty")) infer ("thirst quenching"); else if (MATCH("this potion tastes like apricot juice")) { infer ("see invisible"); if (version == RV36A) sendnow ("%c", ESC); } else if (MATCH("this scroll seems to be blank")) infer ("blank paper"); else if (MATCH("the * bounces")) ; else if (MATCH("the * vanishes as it hits the ground")) { darkturns = 0; darkdir = NONE; targetmonster = 0; echoit=0; } else if (MATCH("there is something here*")) { usesynch=0; set(STUFF); } else if (MATCH("the munchies are interfering*")) ; else if (MATCH("the monsters around you freeze")) holdmonsters (); else if (MATCH("the monster freezes")) holdmonsters (); else if (MATCH("that's inedible")) usesynch = 0; else unknown++; break; case 'u': case 'v': unknown++; break; case 'w': if (MATCH("what do you want*")) echoit=0; else if (MATCH("wield what*")) echoit=0; else if (MATCH("wielding a*")) echoit=0; else if (MATCH("wear what*")) echoit=0; else if (MATCH("what monster*")) echoit=0; else if (MATCH("wait, what's going*")) {infer("confusion"); confused=1;} else if (MATCH("wait! that's a *")) ; else if (MATCH("what a*feeling*")) { infer("confusion"); confused=1; } else if (MATCH("what a*piece of paper")) infer ("blank paper"); else if (MATCH("welcome to level *")) ; else if (MATCH("was wearing*")) ; else if (MATCH("what bulging muscles*")) ; else if (MATCH("wearing *")) ; else unknown++; break; case 'x': unknown++; break; case 'y': if (MATCH("you hit*")) { echoit=0; didhit (); } else if (MATCH("you miss*")) { echoit=0; didmiss (); } else if (MATCH("you are starting to feel weak")) echoit=0; else if (MATCH("you are weak from hunger")) {echoit=0; eat();} else if (MATCH("you are being held")) beingheld=30; else if (MATCH("you can move again")) echoit=0; else if (MATCH("you are still stuck *")) nametrap (BEARTRP,HERE); else if (MATCH("you can't move")) echoit=0; else if (MATCH("you can't carry anything else")) { echoit=0; set (STUFF); maxobj=objcount; } else if (MATCH("you can't *")) {echoit=0; curseditem ();} else if (MATCH("you can't")) echoit=0; else if (MATCH("you begin to feel better")) infer ("healing"); else if (MATCH("you begin to feel much better")) infer("extra healing"); else if (MATCH("you begin to sense the presence of monsters")) { infer("monster detection"); } else if (MATCH("you feel a strange sense of loss")) ; else if (MATCH("you feel stronger, now*")) infer ("gain strength"); else if (MATCH("you feel very sick now")) infer ("poison"); else if (MATCH("you feel momentarily sick")) infer ("poison"); else if (MATCH("you suddenly feel much more skillful")) { infer("raise level"); } else if (MATCH("your nose tingles")) infer ("food detection"); else if (MATCH("you start to float in the air")) { infer ("levitation"); floating=1; } else if (MATCH("you're floating off the ground!")) floating=1; else if (MATCH("you float gently to the ground")) floating=0; else if (MATCH("you feel yourself moving much faster")) { infer ("haste self"); hasted = 1; } else if (MATCH("you feel yourself slowing down")) { hasted = 0; doublehasted = 0; } else if (MATCH("you faint from exhaustion")) { if (version < RV52A) doublehasted = 1; else hasted = 0; } else if (MATCH("you feel less confused now")) confused = 0; else if (MATCH("you feel less trip*")) confused = 0; else if (MATCH("your * vanishes as it hits the ground")) { darkturns = 0; darkdir = NONE; echoit=0; } else if (MATCH("your hands begin to glow *")) { infer ("monster confusion"); redhands = 1; } else if (MATCH("your hands stop glowing *")) redhands = 0; else if (MATCH("you feel as if somebody is watching over you") || MATCH("you feel in touch with the universal onenes")) { infer ("remove curse"); cursedarmor = cursedweapon = 0; newarmor = newweapon = 1;} else if (MATCH("your armor weakens")) { inven[currentarmor].phit--; if (gushed) { gushed=0; nametrap (WATERAP,HERE); } } else if (MATCH("your armor is covered by a shimmering * shield")) { infer ("protect armor"); protected++; remember (currentarmor, PROTECTED); } else if (MATCH("your armor glows * for a moment")) { infer ("enchant armor"); inven[currentarmor].phit++; cursedarmor = 0; newarmor = 1; } else if (MATCH("your * glows * for a moment")) { infer ("enchant weapon"); plusweapon (); newweapon = 1; } else if (MATCH("you hear a high pitched humming noise")) { infer ("aggravate monsters"); wakemonster (9); aggravated = 1; } else if (MATCH("you hear maniacal laughter*")) infer ("scare monster"); else if (MATCH("you hear a faint cry*")) infer ("create monster"); else if (MATCH("you fall asleep")) infer ("sleep"); else if (MATCH("you have been granted the boon of genocide")) { infer ("genocide"); echoit=0; rampage (); } else if (MATCH("you have a tingling feeling")) infer ("drain life"); else if (MATCH("you are too weak to use it")) infer ("drain life"); else if (MATCH("you begin to feel greedy")) infer ("gold detection"); else if (MATCH("you feel a pull downward")) infer ("gold detection"); else if (MATCH("you begin to feel a pull downward")) { infer ("gold detection"); } else if (MATCH("you are caught *")) nametrap (BEARTRP,HERE); else if (MATCH("your purse feels lighter")) ; else if (MATCH("you suddenly feel weaker")) ; else if (MATCH("you must identify something")) ; else if (MATCH("you have a * feeling for a moment, then it passes")) ; else if (MATCH("you are transfixed")) ; else if (MATCH("you are frozen")) washit ("ice monster"); else if (MATCH("you faint")) {echoit=0; if (version<RV36B) eat();} else if (MATCH("you freak out")) echoit = 0; else if (MATCH("you fell into a trap!")) ; else if (MATCH("yum*")) echoit=0; else if (MATCH("yuk*")) echoit=0; else if (MATCH("you sense the presence of magic*")) echoit=0; else unknown++; break; case 'z': if (MATCH("zap with what*")) echoit=0; else unknown++; break; default: if (MATCH( "* gold pieces")) { echoit=0; countgold (res1); } else if (MATCH("'*'*: *")) { echoit=0; mapcharacter (*res1, res3); } else if (*mess == '+' || *mess == '-' || ISDIGIT (*mess)) ; else unknown++; break; } /* Log unknown or troublesome messages */ if (morecount > 50) dwait (D_WARNING, "More loop msg '%s'", mess); else if (unknown) dwait (D_WARNING, "Unknown message '%s'", mess); /* Send it to dwait; if dwait doesnt print it (and echo is on) echo it */ if (echoit & !dwait (D_MESSAGE, mess)) saynow (mess); } /* * smatch: Given a data string and a pattern containing one or * more embedded stars (*) (which match any number of characters) * return true if the match succeeds, and set res[i] to the * characters matched by the 'i'th *. */ smatch (dat, pat, res) register char *dat, *pat, **res; { register char *star = 0, *starend, *resp; int nres = 0; while (1) { if (*pat == '*') { star = ++pat; /* Pattern after * */ starend = dat; /* Data after * match */ resp = res[nres++]; /* Result string */ *resp = '\0'; /* Initially null */ } else if (*dat == *pat) /* Characters match */ { if (*pat == '\0') /* Pattern matches */ return (1); pat++; /* Try next position */ dat++; } else { if (*dat == '\0') /* Pattern fails - no more */ return (0); /* data */ if (star == 0) /* Pattern fails - no * to */ return (0); /* adjust */ pat = star; /* Restart pattern after * */ *resp++ = *starend; /* Copy character to result */ *resp = '\0'; /* null terminate */ dat = ++starend; /* Rescan after copied char */ } } } /* * readident: read an identify scroll. */ readident (name) char *name; { int obj; char id = '*'; /* Default is "* for list" */ if (!replaying && version <= RV53A && (nextid < LETTER (0) || nextid > LETTER (invcount))) { dwait (D_FATAL, "Readident: nextid %d, afterid %d, invcount %d.", nextid, afterid, invcount); } infer (name); /* Record what kind of scroll this is */ if (version < RV53A) /* Rogue 3.6, Rogue 5.2 */ { deleteinv (OBJECT (afterid)); /* Assume object gone */ sendnow (" %c", nextid); /* Identify it */ send ("I%c", afterid); /* Generate a message about it */ knowident = identifying = 1; /* Set variables */ } else /* Rogue 5.3 */ { if (streq (name, "identify scroll")) { if ((obj = unknown (scroll)) != NONE || (obj = have (scroll)) != NONE) id = LETTER (obj); } else if (streq (name, "identify potion")) { if ((obj = unknown (potion)) != NONE || (obj = have (potion)) != NONE) id = LETTER (obj); } else if (streq (name, "identify armor")) { if ((obj = unknown (armor)) != NONE || (obj = have (armor)) != NONE) id = LETTER (obj); } else if (streq (name, "identify weapon")) { if ((obj = unknown (hitter)) != NONE || (obj = unknown (thrower)) != NONE || (obj = unknown (missile)) != NONE || (obj = have (hitter)) != NONE || (obj = have (thrower)) != NONE || (obj = have (missile)) != NONE) id = LETTER (obj); } else if (streq (name, "identify ring, wand or staff")) { if ((obj = unknown (ring)) != NONE || (obj = unknown (wand)) != NONE || (obj = have (ring)) != NONE || (obj = have (wand)) != NONE) id = LETTER (obj); } else dwait (D_FATAL, "Unknown identify scroll '%s'", name); waitfor ("not a valid item"); waitfor ("--More--"); sendnow (" %c;", id); /* Pick an object to identify */ usesynch = 0; justreadid=1; /* Must resest inventory */ } newring = newweapon = 1; afterid = nextid = '\0'; } /* * rampage: read a scroll of genocide. */ rampage () { char monc; /* Check the next monster in the list, we may not fear him */ while (monc = *genocide) { /* Do not waste genocide on stalkers if we have the right ring */ if ((streq (monname (monc), "invisible stalker") || streq (monname (monc), "phantom")) && havenamed (ring, "see invisible") != NONE) { genocide++; } /* Do not waste genocide on rusties if we have the right ring */ else if ((streq (monname (monc), "rust monster") || streq (monname (monc), "aquator")) && havenamed (ring, "maintain armor") != NONE) { genocide++; } /* No fancy magic for this monster, use the genocide scroll */ else break; } /* If we found a monster, send his character, else send ESC */ if (monc) { saynow ("About to rampage against %s", monname (monc)); sendnow (" %c;", monc); /* Send the monster */ /* Add to the list of 'gone' monsters */ sprintf (genocided, "%s%c", genocided, monc); genocide++; } else { dwait (D_ERROR, "Out of monsters to genocide!"); sendnow (" %c;", ESC); /* Cancel the command */ } } /* * curseditem: the last object we tried to drop (unwield, etc.) was cursed. * * Note that cursed rings are not a problem since we only put on * Good rings we have identified, so dont bother marking rings. */ curseditem () { usesynch = 0; /* Force a reset inventory */ /* lastdrop is index of last item we tried to use which could be cursed */ if (lastdrop != NONE && lastdrop < invcount) { remember (lastdrop, CURSED); /* Is our armor cursed? */ if (inven[lastdrop].type == armor) { currentarmor = lastdrop; cursedarmor = 1; return; } /* Is it our weapon (may be wielding a hitter or a bogus magic arrow)? */ else if (inven[lastdrop].type==hitter || inven[lastdrop].type==missile) { currentweapon = lastdrop; cursedweapon = 1; return; } } /* Dont know what was cursed, so assume the worst */ cursedarmor=1; cursedweapon=1; } /* * First copy the title of the last scroll into the appropriate slot, * then find the real name of the object by looking through the data * base, and then zap that name into all of the same objects */ infer (roguename) char *roguename; { register int i; if (*lastname && *roguename && !stlmatch (roguename, lastname)) { infername (lastname, roguename); for (i=0; i<MAXINV; i++) if (stlmatch (inven[i].str, lastname)) { strcpy (inven[i].str, roguename); remember (i, KNOWN); } } } /* * Killed: called whenever we defeat a monster. */ killed (monster) register char *monster; { register int m = 0, mh = 0; /* Find out what we really killed */ if (!cosmic && !blinded && targetmonster>0 && streq (monster, "it")) { monster = monname (targetmonster); } if ((mh = getmonhist (monster, 0)) != NONE) { monster = monhist[mh].m_name; m = monsternum (monster); } /* Tell the user what we killed */ dwait (D_BATTLE | D_MONSTER, "Killed '%s'", monster); /* If cheating against Rogue 3.6, check out our arrow */ if (version < RV52A && cheat) { if (usingarrow && hitstokill > 1 && !beingstalked && goodarrow < 20) { saynow ("Oops, bad arrow..."); newweapon = badarrow = 1; remember (currentweapon, WORTHLESS); } else if (usingarrow) goodarrow++; } /* Echo the number arrows we pumped into him */ if (mh >=0 && mhit+mmiss > 0 && mtarget == mh) dwait (D_BATTLE | D_MONSTER, "%d out of %d missiles hit the %s", mhit, mhit+mmiss, monster); /* If we killed it by hacking, add the result to long term memory */ if (hitstokill > 0 && mh != NONE) addstat (&monhist[mh].htokill, hitstokill); /* If we killed it with arrows, add that fact to long term memory */ if (mhit > 0 && mh != NONE) addstat (&monhist[mh].atokill, mhit); /* Stop shooting arrows if we killed the right monster */ if (targetmonster == (m+'A'-1)) { darkturns = 0; darkdir = NONE; targetmonster = 0; } goalr = goalc = NONE; /* Clear old movement goal */ killmonster (m+'A'-1); /* Notify lost monster functions */ monkilled[m]++; totalkilled++; /* Bump kill count */ hitstokill = mhit = mmiss = 0; /* Clear indiviual monster stats */ mtarget = NONE; /* Clear target */ beingheld = cancelled = 0; /* Clear flags */ /* If we killed an invisible, assume no more invisible around */ if (!cosmic && !blinded && (streq (monster, "invisible stalker") || streq (monster, "phantom"))) beingstalked = 0; } /* * washit: Record being hit by a monster. */ washit (monster) char *monster; { register int mh = 0, m = 0; /* Find out what really hit us */ if ((mh = getmonhist (monster, 1)) != NONE) { monster = monhist[mh].m_name; m = monsternum (monster); } dwait (D_MONSTER, "was hit by a '%s'", monster); timeshit++; /* Bump global count */ if (m>0) wakemonster(-m); /* Wake him up */ terpbot (); /* Hit points changed, read bottom */ /* Add data about the event to long term memory */ if (mh != NONE) { addprob (&monhist[mh].theyhit, SUCCESS); addstat (&monhist[mh].damage, lastdamage); analyzeltm (); } } /* * wasmissed: Record being missed by a monster. */ wasmissed (monster) char *monster; { register int mh = 0, m = 0; /* Find out what really missed us */ if ((mh = getmonhist (monster, 1)) != NONE) { monster = monhist[mh].m_name; m = monsternum (monster); } dwait (D_MONSTER, "was missed by a '%s'", monster); timesmissed++; /* Bump global count */ if (m>0) wakemonster(-m); /* Wake him up */ /* Add data to long term memory */ if (mh != NONE) { addprob (&monhist[mh].theyhit, FAILURE); analyzeltm (); } } /* * didhit: Record hitting a monster. */ didhit () { register int m = 0; /* Record our hit */ if (!cosmic) m = lastmonster; hits++; hitstokill++; addprob (&monhist[monindex[m]].wehit, SUCCESS); if (wielding (wand)) { inven[currentweapon].charges--; newweapon++; } } /* * didmiss: Record missing a monster. */ didmiss () { register int m = 0; /* Record our miss */ if (!cosmic) m = lastmonster; misses++; addprob (&monhist[monindex[m]].wehit, FAILURE); if (usingarrow && goodarrow < 20) { newweapon = badarrow = 1; remember (currentweapon, WORTHLESS); } } /* * mshit: Record hitting a monster with a missile. */ mshit (monster) char *monster; { register int mh; /* Arching in a dark room? */ if (!cosmic && !blinded && targetmonster > 0 && streq (monster, "it")) monster = monname (targetmonster); /* Add data about the event to long term memory */ if ((mh = getmonhist (monster, 0)) < 0) return; { addprob (&monhist[monindex[mh]].arrowhit, SUCCESS); if (mh == mtarget) { mhit++; } else { mhit=1; mmiss = 0; mtarget=mh; } } } /* * msmiss: Record missing a monster with a missile. */ msmiss (monster) char *monster; { register int mh; /* Arching in a dark room? */ if (!cosmic && !blinded && targetmonster > 0 && streq (monster, "it")) monster = monname (targetmonster); /* Add data about the event to long term memory */ if ((mh = getmonhist (monster, 0)) < 0) return; { addprob (&monhist[monindex[mh]].arrowhit, FAILURE); if (mh == mtarget) { mmiss++; } else { mmiss=1; mhit=0; mtarget=mh; } } } /* * Countgold: called whenever msg contains a message about the number * of gold pieces we just picked up. This routine keeps * statistics about the amount of gold picked up. */ countgold (amount) register char *amount; { int pot; if ((pot = atoi (amount)) > 0) { sumgold += pot; sumsqgold += pot*pot; numgold ++; } } /* * Summary: print a summary of the game. */ summary (f, sep) FILE *f; char sep; { register int m; char s[1024], *monname (); sprintf (s, "Monsters killed:%c%c", sep, sep); for (m=0; m<=26; m++) if (monkilled[m] > 0) { sprintf (s, "%s\t%d %s%s%c", s, monkilled[m], monname (m+'A'-1), plural (monkilled[m]), sep); } sprintf (s, "%s%cTotal: %d%c%c", s, sep, totalkilled, sep, sep); sprintf (s, "%sHit %d out of %d times, was hit %d out of %d times.%c", s, hits, misses+hits, timeshit, timesmissed+timeshit, sep); if (numgold > 0) sprintf (s, "%sGold %d total, %d pots, %d average.%c", s, sumgold, numgold, (sumgold*10+5) / (numgold*10), sep); if (f == NULL) addstr (s); else fprintf (f, "%s", s); } /* * versiondep: Set version dependent variables. */ versiondep () { if (version >= RV53A) genocide = "DMJGU"; else if (version >= RV52A) genocide = "UDVPX"; else genocide = "UXDPW"; analyzeltm (); } /* * getmonhist: Retrieve the index in the history array of a monster, * taking our status into account. This code is responsible for determining * when we are being stalked by an invisible monster. */ getmonhist (monster, hitormiss) char *monster; int hitormiss; { if (cosmic || blinded) { return (findmonster ("it")); } else { if (streq (monster, "it") && hitormiss) { if (version < RV53A) { if (! seemonster ("invisible stalker")) beingstalked=INVHIT; return (findmonster ("invisible stalker")); } else { if (! seemonster ("phantom")) beingstalked=INVHIT; return (findmonster ("phantom")); } } else { if (version < RV52B && streq (monster, "invisible stalker") && ! seemonster (monster)) beingstalked = INVHIT; return (findmonster (monster)); } } }