diff --git a/ai.c b/ai.c index 3f668ad..2a100c4 100644 --- a/ai.c +++ b/ai.c @@ -1183,7 +1183,7 @@ void aiturn(lifeform_t *lf) { } // do we have better armour? - for (bp = BP_RIGHTHAND ; bp < MAXBODYPARTS; bp++) { + for (bp = BP_RIGHTFINGER ; bp < MAXBODYPARTS; bp++) { object_t *curarm; curarm = getarmour(lf, bp); // do we have a better one? diff --git a/attack.c b/attack.c index bbb43c9..ed60dd1 100644 --- a/attack.c +++ b/attack.c @@ -425,7 +425,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } if (lfhasflagval(lf, F_INJURY, NA, BP_HANDS, DT_SLASH, NULL)) { - bleed(lf); + bleed(lf, B_FALSE); losehp(lf, 1, DT_DIRECT, NULL, "blood loss"); } @@ -762,6 +762,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) //dblog("reduced by armour to dam[%d] = %d",i,dam[i]); } + // if damage has dropped to zero, it's not a critical hit anymore. + if (dam[i] <= 0) { + critical = B_FALSE; + critpos = BP_NONE; + } + if (lfhasflag(lf, F_QUIVERINGPALM)) { // make sure damage isn't fatal if (dam[i] >= victim->hp) { @@ -898,7 +904,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } else if (lfhasflag(lf, F_QUIVERINGPALM)) { // victim explodes! - losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL); + losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL, B_FALSE); } else { char attackername2[BUFLEN]; real_getlfname(lf, attackername2, B_FALSE); @@ -923,7 +929,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } else { strcpy(buf, attackername2); } - losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL); + losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL, B_FALSE); // victim's armour loses hp if (reduceamt && !critical) { @@ -968,7 +974,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) char lfname[BUFLEN]; dam = rolldie(f->val[0], f->val[1]) + f->val[2]; real_getlfname(lf, lfname, B_FALSE); - losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL); + losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL, B_FALSE); if (isplayer(victim) || cansee(player, victim)) { msg("^%c%s bites %s!", isplayer(victim) ? 'b' : 'n', lfname, victimname); } @@ -994,7 +1000,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (nmatched >= f->val[2]) { char damstring[BUFLEN]; snprintf(damstring, BUFLEN, "%s pack", lfname); - losehp(victim, f->val[0], f->val[1], lf, damstring); + losehp_real(victim, f->val[0], f->val[1], lf, damstring, B_TRUE, NULL, B_FALSE); if (isplayer(victim) || cansee(player, victim)) { msg("%c%s pack attacks %s!", isplayer(victim) ? 'b' : 'c', lfname, victimname); } @@ -1004,7 +1010,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // critical hit effects if (critical && damtypecausescriteffects(damtype[0])) { criticalhit(lf, victim, critpos, damtype[0]); - } // confer flags from attacker? @@ -1036,6 +1041,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } } + + fightback(victim, lf); } // retaliation happens even if victim died @@ -1053,7 +1060,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) attackername); } snprintf(damstring, BUFLEN, "%s%s %s", victimname, getpossessive(victimname), noprefix(f->text)); - losehp(lf, rdam, f->val[2], victim, damstring); + losehp_real(lf, rdam, f->val[2], victim, damstring, B_TRUE, NULL, B_TRUE); } } @@ -1104,7 +1111,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } - fightback(victim, lf); } // practice? @@ -1345,14 +1351,14 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum // chance of your helmet falling off o = getarmour(victim, BP_HEAD); if (o) { - if (isplayer(lf)) { + if (isplayer(victim)) { char buf[BUFLEN]; getobname(o, buf, o->amt); msg("Your %s falls off!", noprefix(buf)); - } else if (cansee(player, lf)) { + } else if (cansee(player, victim)) { char buf[BUFLEN], lfname[BUFLEN]; getobname(o, buf, o->amt); - getlfname(lf, lfname); + getlfname(victim, lfname); msg("%s%s %s falls off!", lfname, getpossessive(lfname), noprefix(buf)); } moveob(o, victim->cell->obpile, o->amt); @@ -1375,8 +1381,10 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum if (!getarmour(victim, hitpos)) injure(victim, hitpos, damtype); } - if (lfhasflag(lf, F_CRITKNOCKDOWN) && !isprone(victim)) { - fall(victim, lf, B_TRUE); + if (lf) { + if (lfhasflag(lf, F_CRITKNOCKDOWN) && !isprone(victim)) { + fall(victim, lf, B_TRUE); + } } } @@ -2033,7 +2041,6 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) int acc,ev; int gothit = B_FALSE; enum SKILLLEVEL lorelev = PR_INEPT; - int myroll; flag_t *f; // remember lore about victim... @@ -2088,37 +2095,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) acc -= ev; - // modify if we can't see the victim - if (!cansee(lf, victim)) { - acc -= 50; - } - + if (!cansee(lf, victim)) acc -= 50; // metal weapon versus magnetic shield? - if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) { - acc -= 45; - } - + if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) acc -= 45; // victim immobile or asleep? - if (isimmobile(victim) || lfhasflag(victim, F_EATING)) { - acc += 50; - } - + if (isimmobile(victim) || lfhasflag(victim, F_EATING)) acc += 50; // modify for lore level - if (lorelev != PR_INEPT) { - lorelev += (lorelev*10); - } + if (lorelev != PR_INEPT) lorelev += (lorelev*10); limit(&acc, 0, 100); //if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc); - - myroll = rnd(1,100); - - // modify for lore - if (myroll <= acc) { - gothit = B_TRUE; - } + if (pctchance(acc)) gothit = B_TRUE; } return gothit; diff --git a/defs.h b/defs.h index 60ee75f..a89d21a 100644 --- a/defs.h +++ b/defs.h @@ -49,6 +49,7 @@ #define B_NODOORS (0) #define B_DONTKILL (-1) #define B_APPENDYOU (-1) +#define B_SPLATTER (-1) //#define B_TEMP (-1) //#define B_PERM (-2) @@ -256,6 +257,14 @@ #define AUTO (-7654) #define HEAVYWEPKG (5) +// how quickly the game clock increments +// 1 = roughly 30 secs per turn +#define TIMECONST (3) +// hunger constant - this is how many turns +// it will take to go from 'normal' to 'peckish' etc +// ... try to make this roughly 4 hours (check TIMECONST. +#define HUNGERCONST 500 + // Time periods #define TM_DRUNKTIME (10) // how long it takes for alcohol to wear off #define TM_WETTIME (10) // how long it takes for things to dry @@ -520,9 +529,6 @@ enum MSGCHARCOL { CC_VGOOD, }; -// hunger constant - this is how many turns -// it will take to go from 'normal' to 'hungry' etc -#define HUNGERCONST 200 enum MODTYPE { M_PCT, @@ -747,7 +753,6 @@ enum RACE { R_HOBGOBLINWAR, R_KOBOLD, R_LIZARDMAN, - R_LURKINGHORROR, R_MINOTAUR, R_OGRE, R_OGRESAVAGE, @@ -817,6 +822,10 @@ enum RACE { R_GIANTFLY, R_GIANTBLOWFLY, R_STIRGE, + // demons + R_DRETCH, + R_LURKINGHORROR, + R_QUASIT, // undead R_GHAST, R_GHOST, @@ -960,6 +969,7 @@ enum OBTYPE { OT_CLOVER, // corpses OT_CORPSE, + OT_FINGER, OT_HEAD, // potions OT_POT_ACID, @@ -1073,6 +1083,7 @@ enum OBTYPE { OT_S_CHILL, OT_S_COLDBURST, OT_S_COLDRAY, + OT_S_CRYSTALARM, OT_S_CRYSTALSHIELD, OT_S_FREEZEOB, OT_S_FROSTBITE, @@ -1080,6 +1091,8 @@ enum OBTYPE { OT_S_ICEEDGE, OT_S_ICICLE, OT_S_SLIDE, + OT_S_SHARDSHOT, + OT_S_SNAPFREEZE, OT_S_SNOWBALL, OT_S_WALLOFICE, // -- gravity @@ -1152,6 +1165,7 @@ enum OBTYPE { OT_S_SUMMONANIMALSSM, OT_S_SUMMONANIMALSMD, OT_S_SUMMONANIMALSLG, + OT_S_SUMMONDEMON, OT_S_THORNS, OT_S_WARPWOOD, OT_S_WATERJET, @@ -1373,6 +1387,8 @@ enum OBTYPE { OT_GOLDCROWN, OT_HELMBONE, OT_HELMFOOTBALL, + // armour - ears + OT_EARPLUGS, // armour - eyes OT_SUNGLASSES, OT_EYEPATCH, @@ -1485,7 +1501,13 @@ enum OBTYPE { // special weapons OT_ENERGYBLADE, OT_HANDOFGOD, + OT_ICEARMOUR, + OT_ICEBOOTS, + OT_ICEGLOVES, + OT_ICEHELMET, OT_ICESHIELD, + // special obs + OT_PLAYERSTART, }; @@ -1495,6 +1517,7 @@ enum OBTYPE { enum BODYPART { BP_WEAPON = 0, BP_SECWEAPON, + BP_EARS, BP_EYES, BP_HEAD, BP_SHOULDERS, @@ -1503,10 +1526,10 @@ enum BODYPART { BP_WAIST, BP_LEGS, BP_FEET, - BP_RIGHTHAND, - BP_LEFTHAND, + BP_RIGHTFINGER, + BP_LEFTFINGER, }; -#define MAXBODYPARTS (12) +#define MAXBODYPARTS (13) // depth on a human @@ -1607,6 +1630,7 @@ enum FLAG { F_DEAD, // object will be removed F_ONEPERCELL, // only one of these objects can exist per cell F_CREATEDBY, // object was made by lf id v0, text=real lfname + F_CREATEDBYSPELL, // object was made by spell id v0 F_ENCHANTABLE, // object can get +1/-1 ect F_GODGIFT, // this was a gift form god with race v0. F_NOSHATTER, // object will not shatter, even if it's material should. @@ -2118,7 +2142,7 @@ enum FLAG { F_NUMAPPEAR, // when randomly appearing, can have > 1. val[0] = min, val[1] = max F_MINIONS, // val0 % chance of appearing with v1-v2 lf of type text - F_HITDICE, // val0: # d4 to roll for maxhp per level. val1: +xx + F_HITDICE, // text = xdy+z to roll for maxhp per level. F_MPDICE, // val0: # d4 to roll for maxmp per level. val1: +xx F_JOB, // val0 = player's class/job F_GODOF, // text = what this lf is the god of. use capitals. @@ -2363,6 +2387,7 @@ enum FLAG { F_VAULTGOESIN, // this vault randomly appears in habitat type v0. // can be repeated multiple times // if a vault doesnt have this flag, it can go anywhere + F_VAULTISPLAYERSTART, // player can start in this vault F_VAULTISSHOP, // this vault is a shop, so add f_shopitem to objects // here. F_VAULTISSHRINE, // this vault is a godstone shrine @@ -2403,9 +2428,15 @@ enum HUNGER { // injuries enum INJURY { IJ_NONE, + IJ_ANKLESWOLLEN, + IJ_ARTERYPIERCE, IJ_BLACKEYE, IJ_CHESTBLEED, + IJ_EYELIDSCRAPED, + IJ_EYEDESTROYED, IJ_FINGERBROKEN, + IJ_FINGERMISSING, + IJ_HAMSTRUNG, IJ_HANDBLEED, IJ_LEGBLEED, IJ_LEGBROKEN, @@ -2651,6 +2682,7 @@ typedef struct room_s { int id; int x1,y1,x2,y2; struct vault_s *vault; + int exitslinked; // don't need to save this. } room_t; typedef struct map_s { diff --git a/flag.c b/flag.c index 0098882..fd107a5 100644 --- a/flag.c +++ b/flag.c @@ -921,7 +921,10 @@ void timeeffectsflag(flag_t *f, int howlong) { if (multiplier > 0) { howlong *= multiplier; } + } else if ((f->id == F_INJURY) && hasflag(f->pile, F_ASLEEP)) { + howlong *= 3; } + f->lifetime -= howlong; diff --git a/god.c b/god.c index d3d9a64..f5077cb 100644 --- a/god.c +++ b/god.c @@ -175,7 +175,7 @@ void angergod(enum RACE rid, int amt) { case 2: // summon undead msg("\"Destroy him, my pets!\""); - summonlfs(god, player->cell, RC_UNDEAD, SZ_ANY, AL_EVIL, 3, PERMENANT); + summonlfs(god, player->cell, RC_UNDEAD, SZ_ANY, AL_EVIL, 3, PERMENANT, B_FALSE); break; } break; @@ -227,7 +227,7 @@ void angergod(enum RACE rid, int amt) { case 2: // summon holy creautes msg("\"Destroy him, my pets!\""); - summonlfs(god, player->cell, RC_ANY, SZ_ANY, AL_GOOD, 3, PERMENANT); + summonlfs(god, player->cell, RC_ANY, SZ_ANY, AL_GOOD, 3, PERMENANT, B_FALSE); break; } break; diff --git a/io.c b/io.c index 56702a8..44b4d02 100644 --- a/io.c +++ b/io.c @@ -1240,6 +1240,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; } break; + case F_DEAF: + if (isplayer(lf)) { + msg("^WYou cannot hear anything!"); + } + donesomething = B_TRUE; + break; case F_DTIMMUNE: if (isplayer(lf)) { // don't know if monsters get it msg("^gYou feel immune to %s!", getdamnamenoun(f->val[0])); @@ -1780,6 +1786,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; } break; + case F_DEAF: + if (isplayer(lf)) { + msg("Your hearing returns."); + } + donesomething = B_TRUE; + break; case F_DTIMMUNE: if (isplayer(lf)) { // don't know if monsters lose it msg("You are no longer immune to %s.", getdamnamenoun(f->val[0])); @@ -3426,7 +3438,6 @@ void describeob(object_t *o) { } - // skip line y++; @@ -3615,7 +3626,7 @@ void describeob(object_t *o) { mvwprintw(mainwin, y, 0, "%s modifies your %s.", buf, getattrname(f->val[1])); y++; break; case F_BLIND: - mvwprintw(mainwin, y, 0, "%s prevents you from seeing.", buf); y++; + mvwprintw(mainwin, y, 0, "%s prevents you from seeing anything.", buf); y++; break; case F_BREATHWATER: mvwprintw(mainwin, y, 0, "%s allows you to breath normally while underwater.", buf); y++; @@ -3623,6 +3634,9 @@ void describeob(object_t *o) { case F_CONTROL: mvwprintw(mainwin, y, 0, "%s lets you control teleportation and polymorphic effects.", buf); y++; break; + case F_DEAF: + mvwprintw(mainwin, y, 0, "%s prevents you from hearing anything.", buf); y++; + break; case F_DETECTLIFE: mvwprintw(mainwin, y, 0, "%s will detect nearby lifeforms.", buf); y++; break; @@ -4611,7 +4625,7 @@ void doeat(obpile_t *op) { // edible objects here? for (o = player->cell->obpile->first; o ; o = o->next) { - if (caneat(player, o)) { + if (caneat(player, o) && canpickup(player, o, 1)) { getobname(o, obname, o->amt); snprintf(buf, BUFLEN, "There %s %s here. Eat %s", (o->amt == 1) ? "is" : "are", @@ -5211,7 +5225,7 @@ void dooperate(obpile_t *op) { // operable objects here? for (o = player->cell->obpile->first; o ; o = o->next) { - if (isoperable(o)) { + if (isoperable(o) && canpickup(player, o, 1)) { char obname[BUFLEN],buf[BUFLEN]; char verb[BUFLEN]; int ch; @@ -5503,7 +5517,7 @@ void doquaff(obpile_t *op) { // quaffable objects here? for (o = player->cell->obpile->first; o ; o = o->next) { - if (isdrinkable(o) && canquaff(player, o)) { + if (isdrinkable(o) && canquaff(player, o) && canpickup(player, o, 1)) { char obname[BUFLEN]; char buf[BUFLEN]; char ch; @@ -7865,7 +7879,7 @@ void showlfstats(lifeform_t *lf, int showall) { char buf[BUFLEN],buf2[BUFLEN]; job_t *j; flag_t *f; - char *ftext= "%12s: "; + char *ftext= "%13s: "; long xpneeded; object_t *o; object_t *w[2]; @@ -7881,7 +7895,7 @@ void showlfstats(lifeform_t *lf, int showall) { obpile_t *op = NULL; char ch; char mode = '@'; - char prompt[BUFLEN]; + char promptstr[BUFLEN]; char cmdchars[BUFLEN]; int done = B_FALSE; enum SKILLLEVEL lorelev; @@ -7912,12 +7926,12 @@ void showlfstats(lifeform_t *lf, int showall) { } if (showall) { - snprintf(prompt, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects ^WG^nods %s^W?^n=help ^WESC^n=quit^h]", + snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects ^WG^nods %s^W?^n=help ^WESC^n=quit^h]", isplayer(lf) ? "" : "^WI^ntems " ); snprintf(cmdchars, BUFLEN, "@asmeg%s",isplayer(lf) ? "" : "i"); } else { - snprintf(prompt, BUFLEN, "%s", "[ESC=quit]"); - snprintf(cmdchars, BUFLEN, "%s", "@"); + snprintf(promptstr, BUFLEN, "^h[^W@^n=stats %s ESC=quit]", isplayer(lf) ? "" : "^WI^ntems "); + snprintf(cmdchars, BUFLEN, "@i"); } while (!done) { @@ -8393,7 +8407,7 @@ void showlfstats(lifeform_t *lf, int showall) { rating = comparelfs(player, lf); setcol(mainwin, lorecol); if (rating >= 4) { - snprintf(buf, BUFLEN, "It is not a threat."); + snprintf(buf, BUFLEN, "It should pose no threat to you."); } else if (rating >= 3) { snprintf(buf, BUFLEN, "You could defeat it very easily."); } else if (rating >= 2) { @@ -8549,12 +8563,12 @@ void showlfstats(lifeform_t *lf, int showall) { nmissingbp = 0; for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) { if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) { - if (bp == BP_RIGHTHAND) { + if (bp == BP_RIGHTFINGER) { if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) { missingbp[nmissingbp] = bp; nmissingbp++; } - } else if (bp == BP_LEFTHAND) { + } else if (bp == BP_LEFTFINGER) { if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL) && !lfhasflagval(lf, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL) ) { @@ -8762,7 +8776,7 @@ void showlfstats(lifeform_t *lf, int showall) { snprintf(buf, BUFLEN, "%s%s", ot->desc, eb2); wprintw(mainwin, buf); - if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) { + if (downline(&y, h, "ABILITIES", NULL, promptstr, cmdchars, &ch)) { break; } } @@ -8817,7 +8831,7 @@ void showlfstats(lifeform_t *lf, int showall) { (known[n]->lifetime == FROMSPELL) ? "[spell]" : ""); unsetcol(mainwin, getskilllevelcolour(known[n]->val[1])); } - if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) { + if (downline(&y, h, "SKILLS", skilltitle, promptstr, cmdchars, &ch)) { break; } } @@ -8898,7 +8912,7 @@ void showlfstats(lifeform_t *lf, int showall) { if (castable) unsetcol(mainwin, C_GREEN); else unsetcol(mainwin, C_RED); anyfound = B_TRUE; - if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) { + if (downline(&y, h, "MAGIC", subheading, promptstr, cmdchars, &ch)) { exitnow = B_TRUE; break; } @@ -8944,7 +8958,7 @@ void showlfstats(lifeform_t *lf, int showall) { isplayer(lf) ? "have" : "has"); y++; } - mvwprintw(mainwin, y, 0, " - %s", sp->name); + mvwprintw(mainwin, y, 0, " - %s %s (consuming %d MP)", sp->name, roman(f->val[2]), f->val[1]); y++; nfound++; } @@ -9052,6 +9066,11 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s can control teleportation and polymorphic effects.", you(lf)); y++; } + f = lfhasknownflag(lf, F_DEAF); + if (f) { + mvwprintw(mainwin, y, 0, "%s %s deaf.", you(lf), is(lf)); + y++; + } f = lfhasknownflag(lf, F_DETECTAURAS); if (f) { mvwprintw(mainwin, y, 0, "%s automatically detect blessings or curses.", you(lf)); @@ -9410,27 +9429,39 @@ void showlfstats(lifeform_t *lf, int showall) { } else if (mode == 'i') { object_t *o; cls(); - centre(mainwin, C_WHITE, 0, "INVENTORY"); + if (lf == player) { // mindscanning it + centre(mainwin, C_WHITE, 0, "INVENTORY"); + } else { // not mindscanning + centre(mainwin, C_WHITE, 0, "INVENTORY (equipped items only)"); + } + y = 2; - if (lfhasflag(lf, F_NOPACK)) { + if ((lf == player) && lfhasflag(lf, F_NOPACK)) { mvwprintw(mainwin, y, 0, "It cannot carry anything."); } else if (countobs(lf->pack, B_FALSE)) { char invtitle[BUFLEN]; - float packweight,maxweight,pct; - packweight = getobpileweight(lf->pack); - maxweight = getmaxcarryweight(lf); - pct = (packweight / maxweight) * 100; - snprintf(invtitle, BUFLEN, "It is carrying: (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct); + if (lf == player) { + float packweight,maxweight,pct; + packweight = getobpileweight(lf->pack); + maxweight = getmaxcarryweight(lf); + pct = (packweight / maxweight) * 100; + snprintf(invtitle, BUFLEN, "It is carrying: (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct); + } else { + snprintf(invtitle, BUFLEN, "It is using:"); + } mvwprintw(mainwin, y, 0, "%s", invtitle); y += 2; for (o = lf->pack->first ; o ; o = o->next) { - getobname(o, buf,o->amt); - getobextrainfo(o, buf2); - - mvwprintw(mainwin, y, 0, "%s%s", buf,buf2); - - if (o->next && downline(&y, h, "INVENTORY", NULL, prompt, cmdchars, &ch)) { - break; + if ((lf == player) || isequipped(o)) { + getobname(o, buf,o->amt); + getobequipinfo(o, buf2); strcat(buf, buf2); + getobextrainfo(o, buf2); strcat(buf, buf2); + + mvwprintw(mainwin, y, 0, "%s", buf); + + if (o->next && downline(&y, h, "INVENTORY", NULL, promptstr, cmdchars, &ch)) { + break; + } } } } else { @@ -9515,7 +9546,7 @@ void showlfstats(lifeform_t *lf, int showall) { } // wait for key - centre(mainwin, C_WHITE, h-1, prompt); + centre(mainwin, C_WHITE, h-1, promptstr); if (ch == '\0') { ch = getch(); } @@ -9534,7 +9565,7 @@ void showlfstats(lifeform_t *lf, int showall) { if (showall) mode = ch; break; case 'i': - if (showall && !isplayer(lf)) mode = ch; + if (!isplayer(lf)) mode = ch; break; case '?': if (mode == 'g') { // help on gods diff --git a/lf.c b/lf.c index 9a2950b..48b9d8f 100644 --- a/lf.c +++ b/lf.c @@ -168,17 +168,12 @@ void awardxpfor(lifeform_t *killed, float pct) { } } -void bleed(lifeform_t *lf) { +void bleed(lifeform_t *lf, int splatter) { flag_t *f; char obname[BUFLEN]; - if (lf->cell->type->solid) { - return; - } - - if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { - return; - } + if (lf->cell->type->solid) return; + if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) return; f = lfhasflag(lf, F_BLOODOB); if (f) { @@ -193,6 +188,7 @@ void bleed(lifeform_t *lf) { if (strlen(obname) > 0) { addob(lf->cell->obpile, obname); + if (splatter) addobsinradius(lf->cell, 1, DT_COMPASS, obname, B_TRUE); } } @@ -293,8 +289,9 @@ int calcxp(lifeform_t *lf) { // -- hitdice f = lfhasflag(lf, F_HITDICE); if (f) { - maxhdroll = f->val[0] * 4; - if (f->val[1] != NA) maxhdroll += f->val[1]; + int ndice,nsides,bonus; + texttodice(f->text, &ndice,&nsides,&bonus); + maxhdroll = ndice * nsides + bonus; } else { maxhdroll = 4; } @@ -973,6 +970,11 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) { reason = E_IMPOSSIBLE; return B_FALSE; } + // too heavy? + if ((where == BP_FEET) && lfhasflagval(lf, F_INJURY, IJ_ANKLESWOLLEN, NA, NA, NULL)) { + reason = E_INJURED; + return B_FALSE; + } if (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE)) { reason = E_NOTKNOWN; @@ -2677,6 +2679,7 @@ int eat(lifeform_t *lf, object_t *o) { } } else if (o->type->id == OT_CARROT) { killtransitoryflags(lf->flags, F_BLIND); + addtempflag(lf->flags, F_SEEINDARK, 3, NA, NA, NULL, rnd(20,40)); } } // end if fullyeaten @@ -3188,6 +3191,7 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { char lfname[BUFLEN]; if (isdead(lf)) return B_TRUE; + if (isprone(lf)) return B_TRUE; if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) { return B_TRUE; } @@ -3626,8 +3630,6 @@ int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) { return B_TRUE; } else if (isresistantto(freezee->flags, DT_COLD)) { char buf[BUFLEN]; - // note: damage value here will be halved due to resistance - // so this really means rnd( 5,10) if (isplayer(freezee)) { msg("^bYou feel freezing cold!"); } @@ -3638,7 +3640,8 @@ int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) { } else { strcpy(buf, "being frozen"); } - losehp(freezee, rnd(5,10), DT_COLD, freezer, buf); + // note: damage value here will be halved due to resistance + losehp(freezee, rnd(howlong,howlong*2), DT_COLD, freezer, buf); return B_TRUE; } @@ -3695,7 +3698,6 @@ void gainlevel(lifeform_t *lf) { lf->newlevel++; - // stat gain (str etc) every 3 levels if ((lf->newlevel % 3) == 0) { flag_t *f; @@ -4543,7 +4545,7 @@ int getbodyparthitchance(enum BODYPART bp) { case BP_BODY: return 6; default: break; } - return 0; // ie rings, weapon + return 0; // ie rings, ears, weapon } char *getbodypartname(enum BODYPART bp) { @@ -4552,12 +4554,14 @@ char *getbodypartname(enum BODYPART bp) { return "right hand"; case BP_SECWEAPON: return "left hand"; - case BP_RIGHTHAND: + case BP_RIGHTFINGER: return "right finger"; - case BP_LEFTHAND: + case BP_LEFTFINGER: return "left finger"; case BP_HANDS: return "hands"; + case BP_EARS: + return "ears"; case BP_EYES: return "eyes"; case BP_HEAD: @@ -4580,9 +4584,10 @@ char *getbodypartequipname(enum BODYPART bp) { switch (bp) { case BP_WEAPON: case BP_SECWEAPON: + case BP_EARS: return "in"; // ie. 'in right hand' - case BP_RIGHTHAND: - case BP_LEFTHAND: + case BP_RIGHTFINGER: + case BP_LEFTFINGER: case BP_HANDS: case BP_HEAD: case BP_BODY: @@ -4875,7 +4880,9 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { } else if (f->id == F_ARMOURPENALTY) { acc -= adjustarmourpenalty(lf, f->val[0]); } else if (f->id == F_INJURY) { - if (f->val[0] == IJ_FINGERBROKEN) { + if (f->val[0] == IJ_EYELIDSCRAPED) { + acc -= 20; + } else if (f->val[0] == IJ_FINGERBROKEN) { acc -= 10; } else if (f->val[0] == IJ_SHOULDERDISLOCATED) { acc -= 20; @@ -5095,8 +5102,8 @@ char *getlfconditionname(enum LFCONDITION cond) { object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp) { object_t *o; switch (bp) { - case BP_RIGHTHAND: - case BP_LEFTHAND: + case BP_RIGHTFINGER: + case BP_LEFTFINGER: o = getequippedob(lf->pack, BP_HANDS); if (o) return o; else return getequippedob(lf->pack, bp); @@ -5358,8 +5365,14 @@ int getvisrange(lifeform_t *lf) { range = MAXVISRANGE; } - if (lfhasflagval(lf, F_INJURY, IJ_BLACKEYE, NA, NA, NULL)) { - range /= 2; + getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE); + for (i = 0; i < nretflags; i++) { + switch (retflag[i]->val[0]) { + case IJ_BLACKEYE: + case IJ_EYEDESTROYED: + range /= 2; + break; + } } // can't see as far if you're on the ground @@ -5424,10 +5437,12 @@ int getmovespeed(lifeform_t *lf) { } else if ((f->id == F_FASTMOVE) || (f->id == F_FASTACTMOVE)) { speed -= f->val[0]; } else if (f->id == F_INJURY) { - if (f->val[0] == IJ_LEGBRUISE) { - speed += 5; - } else if (f->val[0] == IJ_LEGBROKEN) { - speed += 10; + switch (f->val[0]) { + case IJ_LEGBROKEN: + case IJ_HAMSTRUNG: + speed += 10; break; + case IJ_LEGBRUISE: + speed += 5; break; } } else if (f->id == F_SPRINTING) { if (f->val[0]) { @@ -7294,24 +7309,14 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { char lfname[BUFLEN]; char *desc = NULL; enum INJURY inj = IJ_NONE; + enum BODYPART bp2; object_t *wep = NULL; + int howlong; if (where == BP_NONE) return B_TRUE; if (!hasbp(lf, where)) return B_TRUE; if (lfhasflagval(lf, F_INJURY, NA, where, NA, NULL)) return B_TRUE; - // special cases for head... - if (where == BP_HEAD) { - if (damtype == DT_SLASH) { - if (isplayer(lf)) { - msg("^BYour brain is ruptured!"); - } else if (cansee(player, lf)) { - getlfname(lf, lfname); - msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); - } - if (lf->hp > 0) lf->hp = 0; - return B_FALSE; - } - } + howlong = rnd(30,80); // might be overridden depending on injury if (damtype == DT_BASH) { switch (where) { @@ -7335,24 +7340,100 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { inj = IJ_LEGBROKEN; desc = strdup("leg is broken^movement speed greatly lowered"); break; } else { - inj = IJ_LEGBRUISE; - desc = strdup("leg is bruised^movement speed lowered"); break; + switch (rnd(1,2)) { + case 1: + inj = IJ_LEGBRUISE; + desc = strdup("leg is bruised^movement speed lowered"); break; + case 2: + inj = IJ_ANKLESWOLLEN; + desc = strdup("ankle is swollen^cannot wear/remove boots"); break; + } } default: break; } } else if (damtype == DT_SLASH) { switch (where) { - case BP_BODY: inj = IJ_CHESTBLEED; desc = strdup("chest is bleeding^damage from enemies is increased"); break; + case BP_BODY: + if (pctchance(10)) { + if (isplayer(lf)) { + msg("^BYour heart is pierced!"); + } else if (cansee(player, lf)) { + getlfname(lf, lfname); + msg("^%c%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); + } + if (lf->hp > 0) lf->hp = 0; + } else { + inj = IJ_CHESTBLEED; desc = strdup("chest is bleeding^damage from enemies is increased"); break; + } + break; case BP_HANDS: - switch (rnd(1,2)) { + switch (rnd(1,4)) { case 1: inj = IJ_HANDBLEED; desc = strdup("hand is bleeding^attacking will cause damage"); break; case 2: inj = IJ_TENDONCUT; desc = strdup("right flexor tendon is cut^cannot weild weapons"); break; + case 3: + inj = IJ_ARTERYPIERCE; desc = strdup("radial artery is pierced^1d8 damage per turn"); break; + case 4: // severed finger + if (onein(2)) bp2 = BP_RIGHTFINGER; + else bp2 = BP_LEFTFINGER; + if (hasbp(lf, bp2)) { + object_t *o; + char buf[BUFLEN]; + addob(lf->cell->obpile, "severed finger"); + o = getequippedob(lf->pack, bp2); + addflag(lf->flags, F_NOBODYPART, bp2, NA, NA, NULL); + inj = IJ_FINGERMISSING; + sprintf(buf, "%s is severed^cannot wear rings on this hand", getbodypartname(bp2)); + desc = strdup(buf); + howlong = PERMENANT; + if (o) { + char obname[BUFLEN]; + if (isplayer(lf)) { + getobname(o,obname,o->amt); + msg("Your %s drops to the ground.",noprefix(obname)); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getobname(o,obname,o->amt); + getlfname(lf,lfname); + msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname)); + } + moveob(o, lf->cell->obpile, o->amt); + } + break; + } + break; } break; - case BP_HEAD: break; // special case handled above - case BP_LEGS: inj = IJ_LEGBLEED; desc = strdup("leg is bleeding^movement will cause damage"); break; + case BP_HEAD: + if (pctchance(10)) { + if (isplayer(lf)) { + msg("^BYour brain is ruptured!"); + } else if (cansee(player, lf)) { + getlfname(lf, lfname); + msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); + } + if (lf->hp > 0) lf->hp = 0; + } else { + switch (rnd(1,2)) { + case 1: + inj = IJ_EYELIDSCRAPED; desc = strdup("eyelid is scraped^accuracy penalty"); break; + case 2: + inj = IJ_EYEDESTROYED; desc = strdup("right eye is destroyed^permenant vision loss"); + howlong = PERMENANT; + break; + + } + } + break; + case BP_LEGS: + switch (rnd(1,2)) { + case 1: + inj = IJ_LEGBLEED; desc = strdup("leg is bleeding^movement will cause damage"); break; + case 2: + inj = IJ_HAMSTRUNG; desc = strdup("left hamstring is torn^lower move speed, chance of falling"); + break; + } default: break; } } @@ -7361,20 +7442,25 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { if (desc) free(desc); return B_TRUE; } else { - addtempflag(lf->flags, F_INJURY, inj, where, damtype, desc,rnd(5,30)); + addtempflag(lf->flags, F_INJURY, inj, where, damtype, desc, howlong); } if (desc) free(desc); // special effects from taking injuries + if (damtype == DT_SLASH) bleed(lf, B_SPLATTER); + switch (inj) { - case IJ_TENDONCUT: - wep = getweapon(lf); - if (wep) drop(wep, wep->amt); + case IJ_HAMSTRUNG: + fall(lf, NULL, B_TRUE); break; case IJ_SHOULDERDISLOCATED: wep = getweapon(lf); if (wep && isheavyweapon(wep)) drop(wep, wep->amt); break; + case IJ_TENDONCUT: + wep = getweapon(lf); + if (wep) drop(wep, wep->amt); + break; default: break; } @@ -8368,7 +8454,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, NA, NA, NULL); // abilities addflag(lastjob->flags, F_STABILITY, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastjob->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastjob->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastjob->flags, F_EXTRALUCK, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young hawk"); @@ -8469,7 +8555,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); // abilities - addflag(lastjob->flags, F_HITDICE, 1, 4, NA, NULL); + addflag(lastjob->flags, F_HITDICE, NA, NA, NA, "1d4+4"); addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 3, OT_A_HEAVYBLOW, 3, NULL); addflag(lastjob->flags, F_LEVABIL, 4, OT_A_WARCRY, 4, NULL); @@ -8520,7 +8606,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_LORE_DEMONS, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL); // abilities - addflag(lastjob->flags, F_HITDICE, 1, 1, NA, NULL); // low hp + addflag(lastjob->flags, F_HITDICE, NA, NA, NA, "1d4+1"); // low hp addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); // wizard heals slowly, but regenerates mp addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); @@ -8570,7 +8656,7 @@ void initrace(void) { addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+2"); //addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); //addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d4"); @@ -8582,7 +8668,6 @@ void initrace(void) { addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL); // stay in our maze addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd"); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "gas mask"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour"); @@ -8604,7 +8689,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); @@ -8630,7 +8715,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); @@ -8653,7 +8738,7 @@ void initrace(void) { addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); @@ -8676,7 +8761,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_VILLAGE, 80, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 70, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-2 gold coins"); @@ -8690,7 +8775,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins"); addflag(lastrace->flags, F_STARTOB, 100, OC_POTION, NA, "1-5 potions of rum"); @@ -8710,7 +8795,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-2 stones"); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); @@ -8729,7 +8814,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_VILLAGE, 80, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+4"); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); @@ -8757,7 +8842,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, NA, NA, "16"); addflag(lastrace->flags, F_STARTASLEEPPCT, 0, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "50d4"); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed +3 flaming longsword"); @@ -8804,7 +8889,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, NA, NA, "6"); addflag(lastrace->flags, F_STARTASLEEPPCT, 0, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "30d4"); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+5 dagger of sharpness"); @@ -8846,7 +8931,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, NA, NA, "6"); addflag(lastrace->flags, F_STARTASLEEPPCT, 0, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "30d4"); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d6"); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHPARALYZE2, NA, NA, "1d6"); @@ -8891,7 +8976,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, NA, NA, "17"); addflag(lastrace->flags, F_STARTASLEEPPCT, 0, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "50d4"); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 blessed vials of ambrosia"); @@ -8925,7 +9010,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 12, 4, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "12d4+4"); addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); @@ -8954,7 +9039,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 4, 5, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+5"); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -8978,7 +9063,7 @@ void initrace(void) { addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "splash of cockatrice blood"); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 7, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "7d4+0"); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL); @@ -8999,7 +9084,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, -2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); @@ -9014,7 +9099,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:1d6;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); @@ -9028,7 +9113,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "9d4"); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); @@ -9057,7 +9142,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_EVASION, 20, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); @@ -9085,7 +9170,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 55, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 19, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "19d4"); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9116,7 +9201,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 21, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "21d4"); addflag(lastrace->flags, F_ARMOURRATING, 13, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9149,7 +9234,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 48, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 17, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "17d4"); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9184,7 +9269,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 40, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_ENORMOUS, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 49, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "49d4"); addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -30, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9220,7 +9305,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 72, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 8, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "8d4"); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9244,7 +9329,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 68, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 68, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4"); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 0, NA, NA, NULL); @@ -9274,7 +9359,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 65, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "10d4"); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 0, NA, NA, NULL); @@ -9301,7 +9386,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9331,7 +9416,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 5, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+5"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9359,7 +9444,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 70, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 7, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+7"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9390,7 +9475,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 63, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, 6, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+6"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9419,7 +9504,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 73, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 2, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9450,7 +9535,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 60, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 2, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9484,7 +9569,7 @@ void initrace(void) { addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9510,7 +9595,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9534,7 +9619,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 72, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); @@ -9552,32 +9637,6 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_S_POISONBOLT, 5, 5, "pw:5;"); addflag(lastrace->flags, F_HASSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); - addrace(R_LURKINGHORROR, "lurking horror", 100, 'U', C_MAGENTA, MT_FLESH, RC_DEMON); - addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); - addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 0, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); - addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); - addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); - addrace(R_MINOTAUR, "minotaur", 130, 'H', C_BROWN, MT_FLESH, RC_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); @@ -9586,7 +9645,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 62, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_GNOLL, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 6, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+3"); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -9615,7 +9674,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 66, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 7, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "7d4+0"); addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9645,7 +9704,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 45, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 55, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 13, 8, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "13d4+8"); addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9675,7 +9734,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 45, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 50, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 35, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "35d4+0"); addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9704,7 +9763,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9734,7 +9793,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9764,7 +9823,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 81, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 81, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); @@ -9796,7 +9855,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 6, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4"); addflag(lastrace->flags, F_HASATTACK, OT_HOOF, NA, NA, "1d8"); addflag(lastrace->flags, F_HASATTACK, OT_HOOF, NA, NA, "1d8"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); @@ -9820,7 +9879,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9847,7 +9906,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4"); @@ -9879,7 +9938,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_EVASION, 40, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); @@ -9895,14 +9954,14 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+0"); addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); @@ -9925,7 +9984,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9950,7 +10009,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9975,7 +10034,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 70, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+0"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); @@ -9991,7 +10050,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -10008,7 +10067,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL); // very high armour - addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+4"); addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYSLOW, NA, NA, ""); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); @@ -10020,15 +10079,15 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, -2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, ""); @@ -10038,8 +10097,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addrace(R_PIRANHAKING, "king piranha", 1, ';', C_GREEN, MT_FLESH, RC_AQUATIC); @@ -10047,7 +10106,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, ""); @@ -10057,8 +10116,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); @@ -10067,7 +10126,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 73, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+0"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); @@ -10077,8 +10136,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, NA, NA, "1d6"); addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); addrace(R_EELGIANT, "giant eel", 150, ';', C_BLUE, MT_FLESH, RC_AQUATIC); @@ -10086,7 +10145,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 68, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+0"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); @@ -10096,8 +10155,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;"); @@ -10112,7 +10171,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 4, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); @@ -10123,8 +10182,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addrace(R_DREAMFUNGUS, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_METAL, RC_PLANT); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, ""); @@ -10136,7 +10195,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); @@ -10147,8 +10206,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); @@ -10159,7 +10218,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -10172,8 +10231,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); // end plants @@ -10187,7 +10246,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 0, 2, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); @@ -10208,7 +10267,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 4, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); @@ -10228,7 +10287,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 73, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_STARTASLEEPPCT, 80, NA, NA, NULL); // hibernating - addflag(lastrace->flags, F_HITDICE, 3, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -10251,7 +10310,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 62, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_STARTASLEEPPCT, 80, NA, NA, NULL); // hibernating - addflag(lastrace->flags, F_HITDICE, 5, 5, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+5"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -10275,7 +10334,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 73, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -10296,7 +10355,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -10317,7 +10376,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 65, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+4"); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -10341,7 +10400,7 @@ void initrace(void) { addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 6, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+0"); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -10362,7 +10421,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_VILLAGE, 100, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 0, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); @@ -10381,7 +10440,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 82, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, 2, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -10405,7 +10464,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 77, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 77, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 3, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -10431,7 +10490,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 60, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d10"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d10"); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); @@ -10459,7 +10518,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 83, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 83, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "2d4"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); @@ -10486,7 +10545,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, 4, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); @@ -10514,7 +10573,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 4, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); @@ -10543,7 +10602,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, 4, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3+3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+3"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); @@ -10568,7 +10627,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 10, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "10d4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+5"); addflag(lastrace->flags, F_EXTRADAM, DT_COLD, NA, NA, "1d6"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); @@ -10594,7 +10653,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 81, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 84, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10614,7 +10673,7 @@ void initrace(void) { addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 1, 0, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -10634,7 +10693,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -10652,7 +10711,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, ""); - addflag(lastrace->flags, F_HITDICE, 0, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); @@ -10673,7 +10732,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 20, "5-10"); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); @@ -10697,7 +10756,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10719,7 +10778,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10742,7 +10801,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10767,7 +10826,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10794,7 +10853,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 4, 3, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "0d1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10820,7 +10879,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+1"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10842,7 +10901,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 1, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10866,7 +10925,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, 1, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 26, "10-20"); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 3, NA, NULL); // strong! @@ -10892,7 +10951,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, 1, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); addflag(lastrace->flags, F_HITCONFER, F_PAIN, SC_POISON, 26, "5-15"); addflag(lastrace->flags, F_HITCONFERVALS, DT_POISON, NA, NA, "1d2"); @@ -10918,7 +10977,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 97, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 2, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -10942,7 +11001,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 90, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, 3, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d5"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d5"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); @@ -10969,7 +11028,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+1"); addflag(lastrace->flags, F_EVASION, 60, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -10992,7 +11051,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, 0, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -11015,7 +11074,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+1"); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -11037,7 +11096,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 90, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+1"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -11061,7 +11120,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, "10-15"); addflag(lastrace->flags, F_HITCONFERVALS, P_WEAKNESS, 3, NA, NULL); @@ -11084,7 +11143,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 97, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, 0, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_EVASION, 60, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, NA, NA, "1d2-1"); addflag(lastrace->flags, F_CANWILL, OT_S_FLASH, 15, 15, "pw:4;"); @@ -11100,6 +11159,85 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FLY, 2, NA, "^buzzing"); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); + // demons + addrace(R_DRETCH, "dretch", 30, '&', C_BROWN, MT_FLESH, RC_DEMON); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d8+4"); + addflag(lastrace->flags, F_ARMOURRATING, 16, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+1"); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); + addflag(lastrace->flags, F_SEEINDARK, 10, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_ACID, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_DETECTLIFE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_S_FEAR, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_CANWILL, OT_S_CLOUDKILL, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_CANWILL, OT_S_SUMMONDEMON, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "narrows its eyes"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "roars^an other-wordly roar"); + + addrace(R_LURKINGHORROR, "lurking horror", 100, 'U', C_MAGENTA, MT_FLESH, RC_DEMON); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+0"); + addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); + addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); + + addrace(R_QUASIT, "quasit", 4, '&', C_BROWN, MT_FLESH, RC_DEMON); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d8"); + addflag(lastrace->flags, F_ARMOURRATING, 18, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+1"); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); + addflag(lastrace->flags, F_SEEINDARK, 10, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_ACID, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_DETECTLIFE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_S_FEAR, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_CANWILL, OT_S_CLOUDKILL, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_CANWILL, OT_S_SUMMONDEMON, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "narrows its eyes"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "roars^an other-wordly roar"); + // undead addrace(R_ZOMBIE, "zombie", 50, 'Z', C_BLUE, MT_FLESH, RC_UNDEAD); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); @@ -11111,7 +11249,7 @@ void initrace(void) { addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, 4, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+4"); addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); @@ -11131,7 +11269,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -11151,7 +11289,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 55, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 4, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6"); @@ -11172,7 +11310,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 4, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL); @@ -11193,7 +11331,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 3, 2, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+2"); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, ""); @@ -11226,7 +11364,7 @@ void initrace(void) { addflag(lastrace->flags, F_AVOIDOBTYPE, OT_GARLIC, B_TRUE, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 8, 3, NA, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "8d4+3"); addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "coffin"); @@ -11258,12 +11396,12 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, 1, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+1"); addflag(lastrace->flags, F_EVASION, 300, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_BODY, NA, NA, NULL); @@ -11281,13 +11419,13 @@ void initrace(void) { addrace(R_DANCINGWEAPON, "dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 2, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); addflag(lastrace->flags, F_EVASION, 50, NA, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_BODY, NA, NA, NULL); @@ -11305,14 +11443,14 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 1, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_FOLLOWRANGE, 1, 1, NA, NULL); // stay right next to master addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_BODY, NA, NA, NULL); @@ -11654,7 +11792,7 @@ int isingunrange(lifeform_t *lf, cell_t *where) { int isgod(lifeform_t *lf) { if (lf->race->raceclass->id == RC_GOD) return B_TRUE; - if (hasjob(lf, J_GOD)) return B_TRUE; + //if (hasjob(lf, J_GOD)) return B_TRUE; return B_FALSE; } @@ -12879,10 +13017,10 @@ void loseconcentration(lifeform_t *lf) { // lose hp, and adjust damage based on resistances int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc) { - return losehp_real(lf, amt, damtype, fromlf, damsrc, B_TRUE, NULL); + return losehp_real(lf, amt, damtype, fromlf, damsrc, B_TRUE, NULL, B_TRUE); } -int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob) { +int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate) { char buf[BUFLEN]; char buf2[BUFLEN]; char lfname[BUFLEN]; @@ -12961,7 +13099,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml // occasionally drop blood if (damtypecausesbleed(damtype) && onein(3)) { - bleed(lf); + bleed(lf, B_FALSE); } if (hasflag(lf->flags, F_DEBUG)) { @@ -13055,7 +13193,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml // further effects if not dead... if (!isdead(lf)) { // fight back if required - if (fromlf) { + if (fromlf && retaliate) { fightback(lf, fromlf); } @@ -13564,6 +13702,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha int lbonus; if (l == noisemaker) continue; + // ie. if this lf is in the process of swapping places if (!l->cell) continue; @@ -13595,11 +13734,20 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha if (noisemaker && cansee(l, noisemaker)) { if (seetext) { char lfname[BUFLEN]; + char realseetext[BUFLEN]; + char *quotepos; getlfname(noisemaker, lfname); - msg("%s %s.", lfname, seetext); + // adjust it if you're deaf + strcpy(realseetext, seetext); + quotepos = strchr(realseetext, '\"'); + if (lfhasflag(l, F_DEAF) && quotepos) { + *quotepos = '\0'; + strcat(realseetext, "something"); + } + msg("%s %s.", lfname, realseetext); rv = B_TRUE; } - } else if (text && ((nt == NC_SPEECH) || !lfhasflag(l, F_DONELISTEN))) { + } else if (text && !lfhasflag(l, F_DEAF) && ((nt == NC_SPEECH) || !lfhasflag(l, F_DONELISTEN))) { char textnopunc[BUFLEN]; char punc; int dist; @@ -13612,6 +13760,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha dist = getcelldist(l->cell, c); + // adjust text if you are deaf. + // listen skill gives you more info about monsters if (noisemaker) { enum SKILLLEVEL slev; @@ -13994,46 +14144,6 @@ void practice(lifeform_t *lf, enum SKILL skid, int amt) { } } -/* -void precalclos_old(lifeform_t *lf) { - int x,y; - cell_t *c; - cell_t **los; - int maxvisrange; - int nlos = 0; - int i; - - los = malloc( sizeof(cell_t *) * (MAX_MAPW * MAX_MAPH)); - - // free existing structures - if (lf->los) { - free(lf->los); lf->los = NULL; - } - - nlos = 0; - maxvisrange = getvisrange(lf); - for (y = lf->cell->y - maxvisrange; y <= lf->cell->y + maxvisrange ; y++) { - for (x = lf->cell->x - maxvisrange; x <= lf->cell->x + maxvisrange ; x++) { - c = getcellat(lf->cell->map, x, y); - // - //if (c && (c != lf->cell) && haslos(lf, c)) { - if (c && haslos(lf, c)) { - los[nlos] = c; - nlos++; - } - } - } - - // now fill in lifeform structure - lf->los = malloc(sizeof(cell_t *) * nlos); - for (i = 0; i < nlos; i++) { - lf->los[i] = los[i]; - } - lf->nlos = nlos; - free(los); -} -*/ - void precalclos_new(lifeform_t *lf) { cell_t *c; int startxray,rangemod; @@ -15122,7 +15232,7 @@ void initskills(void) { addskilldesc(SK_FIRSTAID, PR_INEPT, "- Determines how fast you heal when resting. ", B_FALSE); addskilldesc(SK_FIRSTAID, PR_INEPT, "- Determines how long poison effects will last.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_ADEPT, "^gYou can now recognise when poison is potentially fatal.", B_TRUE); - addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.", 100); + addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.", 200); addskilldesc(SK_LISTEN, PR_BEGINNER, "^gYou now gauge the distance of sounds.", B_TRUE); addskilldesc(SK_LISTEN, PR_ADEPT, "^gYou can now determine the direction sounds are coming from.", B_TRUE); addskilldesc(SK_LISTEN, PR_EXPERT, "^gYou can now identify monsters based on sound.", B_TRUE); @@ -15550,7 +15660,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r break; case SC_LISTEN: // if you are asleep, listen check doesn't help. - if (lfhasflag(lf, F_ASLEEP)) { + if (lfhasflag(lf, F_ASLEEP) || lfhasflag(lf, F_DEAF)) { attrib = 0; } else { attrib = getskill(lf, SK_LISTEN); @@ -16163,9 +16273,8 @@ int takeoff(lifeform_t *lf, object_t *o) { // lose flags loseobflags(lf, o, F_EQUIPCONFER); - if (o->type->id == OT_ICESHIELD) { - stopspell(lf, OT_S_CRYSTALSHIELD); - } + f = hasflag(o->flags, F_CREATEDBYSPELL); + if (f) stopspell(lf, f->val[0]); if (obproduceslight(o)) { calclight((getoblocation(o))->map); @@ -16295,14 +16404,12 @@ void timeeffectslf(lifeform_t *lf) { for (o = lf->pack->first ; o ; o = nexto) { nexto = o->next; - if ((o->type->id == OT_ENERGYBLADE) && !hasactivespell(lf, OT_S_SUMMONWEAPON)) { - killob(o); + f = hasflag(o->flags, F_CREATEDBYSPELL); + if (f && !hasactivespell(lf, f->val[0])) { + killob(o); continue; - } - if ((o->type->id == OT_ICESHIELD) && !hasactivespell(lf, OT_S_CRYSTALSHIELD)) { - killob(o); - continue; - } + } + timeeffectsob(o); } @@ -16499,6 +16606,11 @@ void turneffectslf(lifeform_t *lf) { } } + if (lfhasflagval(lf, F_INJURY, IJ_ARTERYPIERCE, NA, NA, NULL)) { + bleed(lf, B_SPLATTER); + losehp(lf, rnd(1,8), DT_DIRECT, NULL, "blood loss"); + } + // get more hungry modhunger(lf, 1); @@ -16538,10 +16650,13 @@ void turneffectslf(lifeform_t *lf) { } } - if (hasactivespell(lf, OT_S_SUMMONWEAPON) && !hasob(lf->pack, OT_ENERGYBLADE)) { + if (hasactivespell(lf, OT_S_SUMMONWEAPON) && !hasobwithflagval(lf->pack, F_CREATEDBYSPELL, OT_S_SUMMONWEAPON, NA, NA, NULL)) { stopspell(lf, OT_S_SUMMONWEAPON); } - if (hasactivespell(lf, OT_S_CRYSTALSHIELD) && !hasob(lf->pack, OT_ICESHIELD)) { + if (hasactivespell(lf, OT_S_CRYSTALARM) && !hasobwithflagval(lf->pack, F_CREATEDBYSPELL, OT_S_CRYSTALARM, NA, NA, NULL)) { + stopspell(lf, OT_S_CRYSTALARM); + } + if (hasactivespell(lf, OT_S_CRYSTALSHIELD) && !hasobwithflagval(lf->pack, F_CREATEDBYSPELL, OT_S_CRYSTALSHIELD, NA, NA, NULL)) { stopspell(lf, OT_S_CRYSTALSHIELD); } @@ -18116,9 +18231,10 @@ int wear(lifeform_t *lf, object_t *o) { if ((gamemode == GM_GAMESTARTED) && lf->created) { switch (reason) { case E_ALREADYUSING: - if (isplayer(lf)) { - msg("You're already wearing that!"); - } + if (isplayer(lf)) msg("You're already wearing that!"); + break; + case E_INJURED: + if (isplayer(lf)) msg("Your injuries prevent you from wearing this."); break; case E_WEARINGSOMETHINGELSE: f = hasflag(o->flags, F_GOESON); diff --git a/lf.h b/lf.h index 78309b6..9718c5e 100644 --- a/lf.h +++ b/lf.h @@ -21,7 +21,7 @@ void autotarget(lifeform_t *lf); void autoweild(lifeform_t *lf); int appearsrandomly(enum RACE rid); void awardxpfor(lifeform_t *killed, float pct); -void bleed(lifeform_t *lf); +void bleed(lifeform_t *lf, int splatter); void breakgrabs(lifeform_t *lf, int fromme, int tome); long calcscore(lifeform_t *lf); int calcxp(lifeform_t *lf); @@ -272,7 +272,7 @@ int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo); int loadfirearmfast(lifeform_t *lf); void loseconcentration(lifeform_t *lf); int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc); -int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob); +int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate); void losemp(lifeform_t *lf, int amt); void makefriendly(lifeform_t *lf, int howlong); int makenauseated(lifeform_t *lf, int amt, int howlong); diff --git a/map.c b/map.c index cfcf835..eb9fb4f 100644 --- a/map.c +++ b/map.c @@ -1038,7 +1038,19 @@ void fix_reachability(map_t *m) { int i,keepgoing = B_TRUE, nfixed = 0; int db = B_TRUE; cell_t *c = NULL; + if (db) dblog("fix_reachability starting."); + + switch (m->habitat->id) { + case H_FOREST: + case H_HEAVEN: + case H_PIT: + case H_VILLAGE: + if (db) dblog("fix_reachability not required for this habitat."); + return; + default: break; + } + // find first non-empty cell for (i = 0; i < m->w * m->h; i++) { if (!m->cell[i]->type->solid) { @@ -1065,8 +1077,8 @@ void fix_reachability(map_t *m) { m->cell[i]->x, m->cell[i]->y); linkexit(m->cell[i], B_TRUE, &nadded); - if (db) dblog(" fixed unreachable area by added %d cells.", nadded); - + if (db) dblog(" fixed unreachable area by adding %d cells.", nadded); + assert(nadded); // now run the test again. // 'c' will be where the next flood will will happen. @@ -1821,14 +1833,16 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_ } } - // link up room exits - for (i = 0; i < map->nrooms; i++) { - linkexits(map, map->room[i].id); - } - // now clear up dead ends again. remove_deadends(map, sparseness); + // link up room exits + for (i = 0; i < map->nrooms; i++) { + if (!map->room[i].exitslinked) { + linkexits(map, map->room[i].id); + } + } + // add staircases. // first dungeon level has 1 up stairs, 3 down. // subsequent levels always have 3 up and down stairs @@ -1868,6 +1882,8 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_ linkstairs(o, NULL); } } + // make sure we have at least one up stairs + assert(findobinmap(map, OT_STAIRSUP)); // DOWN STAIRS if (map->depth < map->region->rtype->maxdepth) { @@ -1980,9 +1996,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_ clearcell(c); setcelltype(c,solidcell); } - - // ensure there are no unreachable areas - fix_reachability(map); } void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) { @@ -1995,9 +2008,8 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t char buf[BUFLEN]; //object_t *o; - // what kind of cells will 'empty' ones be? + // fill entire maze with emptiness emptycell = map->habitat->emptycelltype; - // fill entire maze with walls for (y = 0; y < map->h; y++) { for (x = 0; x < map->w; x++) { c = addcell(map, x, y); @@ -2005,55 +2017,84 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t } } - // determine density - density = rnd(40,70); - // add a plant to density percent of cells - ntrees = (int)(((float)density/100.0) * (float)(map->w*map->h)); - for (i = 0; i < ntrees; i++) { - c = getrandomcell(map); - while (c->lf) { - c = getrandomcell(map); - } - switch (rnd(0,1)) { - default: case 0: strcpy(buf, "tree"); break; - case 1: strcpy(buf, "shrub"); break; - } - addob(c->obpile, buf); - } - - // clearings - for (i = 0; i < nclearings; i++) { - int w; - c = getrandomcell(map); - w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS); - for (y = c->y - w; y <= c->y + w; y++) { - for (x = c->x - w; x <= c->x + w; x++) { - cell_t *newc; - int dist = 999; - newc = getcellat(map, x, y); - - - if (newc) { - dist = getcelldistorth(newc, c); - if (dist <= w) { - int dirtchance; - // kill all obs here - while (newc->obpile->first) killob(newc->obpile->first); - - // change it into dirt. - // ie. at centre (dist=0) dirt chance is 100% - // ie. at max distance, dirt chance is 30% - dirtchance = 100 - (((float)dist / (float)w) * 70); - if (rnd(1,100) <= dirtchance) { - setcelltype(newc, CT_DIRT); + + switch (rnd(1,2)) { + case 1: // forest type 1: add trees in x% of cells, then add some clearings + // determine density + density = rnd(40,70); + // add a plant to density percent of cells + ntrees = (int)(((float)density/100.0) * (float)(map->w*map->h)); + for (i = 0; i < ntrees; i++) { + c = getrandomcell(map); + while (c->lf) c = getrandomcell(map); + switch (rnd(0,1)) { + default: case 0: strcpy(buf, "tree"); break; + case 1: strcpy(buf, "shrub"); break; + } + addob(c->obpile, buf); + } + // clearings + for (i = 0; i < nclearings; i++) { + int w; + c = getrandomcell(map); + w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS); + for (y = c->y - w; y <= c->y + w; y++) { + for (x = c->x - w; x <= c->x + w; x++) { + cell_t *newc; + int dist = 999; + newc = getcellat(map, x, y); + if (newc) { + dist = getcelldistorth(newc, c); + if (dist <= w) { + int dirtchance; + // kill all obs here + while (newc->obpile->first) killob(newc->obpile->first); + + // change it into dirt. + // ie. at centre (dist=0) dirt chance is 100% + // ie. at max distance, dirt chance is 30% + dirtchance = 100 - (((float)dist / (float)w) * 70); + if (rnd(1,100) <= dirtchance) { + setcelltype(newc, CT_DIRT); + } + } } } } } - } - } + break; + case 2: // add clusters of trees + nclearings = rnd(5,10); + for (i = 0; i < nclearings; i++) { + int w; + c = getrandomcell(map); + while (c->lf) c = getrandomcell(map); - // add monsters + w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS); + for (y = c->y - w; y <= c->y + w; y++) { + for (x = c->x - w; x <= c->x + w; x++) { + cell_t *newc; + int dist = 999; + newc = getcellat(map, x, y); + if (newc) { + dist = getcelldistorth(newc, c); + if (dist <= w) { + int treechance; + treechance = 100 - (((float)dist / (float)w) * 70); + if (rnd(1,100) <= treechance) { + switch (rnd(0,1)) { + default: case 0: strcpy(buf, "tree"); break; + case 1: strcpy(buf, "shrub"); break; + } + addob(c->obpile, buf); + } + } + } + } + } + } + break; + } } @@ -2391,6 +2432,9 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex } } + // ensure there are no unreachable areas + fix_reachability(map); + // special cases // village - add town walls and clear it out if (db) dblog(" finalising village creation..."); @@ -2677,6 +2721,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r map->room[map->nrooms].x2 = maxx; map->room[map->nrooms].y2 = maxy; map->room[map->nrooms].vault = v; + map->room[map->nrooms].exitslinked = B_FALSE; thisroom = &(map->room[map->nrooms]); map->nrooms++; @@ -2718,6 +2763,9 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r autodoors(map, roomid, minx, miny, maxx, maxy, f->val[0], B_NODOORS); } + // link up exits from this vault + linkexits(map, roomid); + return B_FALSE; } @@ -2726,11 +2774,11 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r // if 'wantfilled' is set, only link to "filled" cells. // return TRUE on failure. int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { - int db = B_FALSE; + int db = B_TRUE; int d, roomid; int poss2[MAXCANDIDATES],nposs2; - int dist[MAXDIR_ORTH]; - int hitsedge[MAXDIR_ORTH]; + int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH]; + cell_t *directendcell[MAXDIR_ORTH]; int mindist = 999,maxdist = -1; cell_t *c; @@ -2739,6 +2787,10 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { if (db) dblog(" calling linkexit() for cell at %d,%d", startcell->x, startcell->y); roomid = getroomid(startcell); + for (d = D_N; d <= D_W; d++) { + hitsedge[d] = B_TRUE; + directendcell[d] = NULL; + } // link it. starting from the door, count the number of cells in // each direction until we hit an empty (walkable) cell which isn't a room. @@ -2747,6 +2799,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { for (d = D_N; d <= D_W; d++) { dist[d] = 0; hitsedge[d] = B_TRUE; + sameroom[d] = B_FALSE; c = getcellindir(startcell, d); while (c) { dist[d]++; @@ -2760,6 +2813,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { } else { // mark dir as invalid dist[d] = 999; + sameroom[d] = B_TRUE; if (db) dblog(" going %s hits same room. invalid.", getdirname(d)); break; } @@ -2767,6 +2821,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { if (!wantfilled || c->filled) { // walkable and not in this vault. finished. hitsedge[d] = B_FALSE; + directendcell[d] = c; if (db) dblog(" can make %s path (hits empty cell at dist %d)", getdirname(d), dist[d]); break; } @@ -2785,7 +2840,8 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { if (!wantfilled || c->filled) { // finished. hitsedge[d] = B_FALSE; - if (db) dblog(" can make %s path (hits adjacent empty cell at dist %d)", getdirname(d), dist[d]); + directendcell[d] = c; + if (db) dblog(" can make %s path (hits adjacent empty cell at dist %d)", getdirname(d), dist[d]); break; } } @@ -2796,32 +2852,47 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { c = getcellindir(c, d); // getting the same cell! } if (dist[d] != 999) { - if (!hitsedge[d]) { - if (dist[d] < mindist) mindist = dist[d]; - } + if (dist[d] < mindist) mindist = dist[d]; if (dist[d] > maxdist) maxdist = dist[d]; } } if (mindist == 999) { cell_t *turncell = NULL,*endcell = NULL; + cell_t *perpcell[MAX_MAPW*MAX_MAPH]; + cell_t *perpturncell1[MAX_MAPW*MAX_MAPH]; + int perpturndir1[MAX_MAPW*MAX_MAPH]; + int nperpcells = 0; int perpdir[2]; int startdir = D_NONE; int turndir = D_NONE; int startdist = 0; + int maxdist2 = -1; + int startposs[MAXDIR_ORTH]; + int nstartposs = 0; // no good directions. if (db) dblog(" No directions lead to valid cells. Trying turns."); // starting at the LONGEST distance, traverse up each dir, // branching off looking for rooms. - // find longest distance + // find longest distance that doesn't go through same room for (d = D_N; d <= D_W; d++) { - if (dist[d] == maxdist) { - startdir = d; - break; + if (!sameroom[d] && (dist[d] > maxdist2)) { + maxdist2 = dist[d]; } } + // pick one randomly + for (d = D_N; d <= D_W; d++) { + if (dist[d] == maxdist2) { + startposs[nstartposs++] = d; + } + } + if (nstartposs) { + startdir = startposs[rnd(0,nstartposs-1)]; + } + assert(startdir != D_NONE); + // figure out perpendicular dirs perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W; perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N; @@ -2839,6 +2910,12 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { for (n = 0; n <= 1; n++) { int turndist = 0; c2 = getcellindir(c, perpdir[n]); + + perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns + perpturncell1[nperpcells] = c; + perpturndir1[nperpcells] = perpdir[n]; + nperpcells++; + while (c2) { int gotsolution = B_FALSE; turndist++; @@ -2875,7 +2952,6 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { } } } - if (gotsolution) { if (db) dblog(" Solution found: Walk %d %s, then %d %s.", startdist, getdirname(startdir), @@ -2915,17 +2991,126 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { c = getcellindir(c, turndir); } } else { - // give up?? - if (db) dblog(" Cannot find a way to link up."); + // We need to make 3 turns. + // for each perpcell[], look in startdir + diropposite(startdir) + int dir3[2],i,n; + cell_t *turncell2 = NULL; + int turndir2; + dir3[0] = startdir; + dir3[1] = diropposite(startdir); + for (i = 0; i < nperpcells; i++) { + for (n = 0; n < 1; n++) { + cell_t *c2; + int turndist = 0; + c2 = getcellindir(perpcell[i], dir3[n]); + while (c2) { + int gotsolution = B_FALSE; + turndist++; + if ((roomid >= 0) && (getroomid(c2) == roomid)) { + if (wantfilled && c2->type->solid) { + // see EXCEPTION above. + } else { + // hits same room, not ok. + break; + } + } else if (cellwalkable(NULL, c2, NULL)) { + if (!wantfilled || c2->filled) { + if (db) dblog(" Got to an empty cell here."); + gotsolution = B_TRUE; + } + } else if (turndist > 1) { + // check l/r too + int perpdir2[2],nn; + cell_t *pcell = NULL; + perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W; + perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N; + for (nn = 0; nn <= 1; nn++) { + pcell = getcellindir(c2, perpdir2[nn]); + if (pcell) { + if ( ((roomid == -1) || (getroomid(pcell) != roomid)) && + cellwalkable(NULL, pcell, NULL)) { + if (!wantfilled || pcell->filled) { + // finished. + if (db) dblog(" Got to an empty cell next to us."); + gotsolution = B_TRUE; + break; + } + } + } + } + } + if (gotsolution) { + if (db) dblog(" Solution found: Walk %d %s, then %d %s.", + startdist, getdirname(startdir), + turndist, getdirname(perpdir[n])); + + turncell = perpturncell1[i]; + turndir = perpturndir1[i]; + turncell2 = perpcell[i]; + turndir2 = dir3[n]; + + endcell = c2; + break; + } + // check next cell + c2 = getcellindir(c2, perpdir[n]); + } // end while c2 + if (turncell2) break; + } // end for n=1-2 + if (turncell2) break; + } // end foreach perpcell + + // TODO: if we find a solution, fill in turncell2 and make path. + if (turncell2) { + if (db) dblog(" 2turn Solution found: Walk %s, then %s, then %s.", + getdirname(startdir), getdirname(turndir), getdirname(turndir2)); + + // make a path up to the turn point. + if (db) dblog(" Making path from vault to first corner, initdir=%s", getdirname(startdir)); + c = getcellindir(startcell, startdir); + while (c != turncell) { + setcelltype(c, c->habitat->emptycelltype); + if (ncellsadded) (*ncellsadded)++; + c = getcellindir(c, startdir); + } + // clear the corner cell + setcelltype(c, c->habitat->emptycelltype); + // now turn and clear up to the next turn + if (db) dblog(" Making path from 1st corner to 2nd corner, turndir=%s", getdirname(turndir)); + c = getcellindir(c, turndir); + while (c != turncell2) { + setcelltype(c, c->habitat->emptycelltype); + if (ncellsadded) (*ncellsadded)++; + c = getcellindir(c, turndir); + } + + // now turn and clear up to the next room/empty cell + if (db) dblog(" Making path from 2nd corner to rest of map, turndir=%s", getdirname(turndir2)); + c = getcellindir(c, turndir2); + while (c != endcell) { + setcelltype(c, c->habitat->emptycelltype); + if (ncellsadded) (*ncellsadded)++; + c = getcellindir(c, turndir2); + } + } else { + if (db) dblog(" Cannot find a way to link up."); + } return B_TRUE; } - } else { + } else { // we found a way to go without needing to turn. int whichway,sel; - // now pick the shortest one which doesn't hits the edge + int mindist2 = 999; + // now pick the shortest one which doesn't hit the edge // get list of all the minimums and randomly tie-break nposs2 = 0; for (d = D_N; d <= D_W; d++) { - if (dist[d] == mindist) { + if (!hitsedge[d] && (dist[d] < mindist2)) { + mindist2 = dist[d]; + } + } + + for (d = D_N; d <= D_W; d++) { + if (dist[d] == mindist2) { poss2[nposs2++] = d; } } @@ -2933,9 +3118,10 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) { whichway = poss2[sel]; // now create a path - if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), mindist); + if (db) dblog(" Linking directly %s (distance %d).", getdirname(whichway), mindist); c = getcellindir(startcell, whichway); - while (c && !cellwalkable(NULL, c, NULL)) { + //while (c && !cellwalkable(NULL, c, NULL)) { + while (c && c != directendcell[whichway]) { setcelltype(c, c->habitat->emptycelltype); if (ncellsadded) (*ncellsadded)++; c = getcellindir(c, whichway); @@ -2949,9 +3135,10 @@ int linkexits(map_t *m, int roomid) { int x,y,i; cell_t *poss[MAXCANDIDATES],*c; int nposs = 0; - int db = B_FALSE; + int db = B_TRUE; int nadded = 0; int minx = -1, miny = -1, maxx = -1, maxy = -1; + int roomidx = -1; // figure out room coords for (i = 0; i < m->nrooms; i++) { @@ -2960,10 +3147,11 @@ int linkexits(map_t *m, int roomid) { miny = m->room[i].y1; maxx = m->room[i].x2; maxy = m->room[i].y2; + roomidx = i; break; } } - assert(minx != -1); + assert(roomidx != -1); if (db) { @@ -2984,8 +3172,10 @@ int linkexits(map_t *m, int roomid) { if (!c) continue; if (hasobwithflag(c->obpile, F_DOOR)) { - if (db) dblog("found door at %d,%d",x,y); - poss[nposs++] = c; + if ((x == minx) || (x == maxx) || (y == miny) || (y == maxy) ) { + if (db) dblog("found wall door at %d,%d",x,y); + poss[nposs++] = c; + } } else if (hasflagval(m->flags, F_ROOMEXIT, roomid, x, y, NULL)) { if (db) dblog("found roomexit at %d,%d",x,y); poss[nposs++] = c; @@ -3016,6 +3206,8 @@ int linkexits(map_t *m, int roomid) { } } // end for each door + m->room[roomidx].exitslinked = B_TRUE; + if (db) dblog("linkexits complete (%d added).", nadded); return nadded; } @@ -3116,6 +3308,7 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x map->room[map->nrooms].x2 = maxx; map->room[map->nrooms].y2 = maxy; map->room[map->nrooms].vault = NULL; + map->room[map->nrooms].exitslinked = B_FALSE; thisroom = &(map->room[map->nrooms]); map->nrooms++; @@ -4184,6 +4377,7 @@ void initmap(void) { } //vx = 0; vy = -1; addregionoutline(RG_FIRSTDUNGEON); + addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL); addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair"); addregionthing(lastregionoutline, 10, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISSHRINE, NULL); // godstone on last floor } @@ -4904,6 +5098,9 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) { losehp(target, rnd(1,100), DT_SLASH, fromlf, damstring); // BIG damage } + // change cell type + setcelltype(c, c->habitat->emptycelltype); + // place shards if (c->type->material->id == MT_GLASS) { int numshards; diff --git a/move.c b/move.c index f3404a1..42fe517 100644 --- a/move.c +++ b/move.c @@ -28,9 +28,6 @@ extern void (*precalclos)(lifeform_t *); extern enum ERROR reason; extern void *rdata; -extern flag_t *retflag[]; -extern int nretflags; - extern long curtime; extern WINDOW *gamewin, *msgwin; @@ -739,6 +736,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc i = howfar; // don't fall mightfall = B_FALSE; + if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf), DT_BASH); break; case E_SWIMMING: case E_LFINWAY: @@ -874,21 +872,25 @@ int moveclear(lifeform_t *lf, int dir, enum ERROR *error) { } +// effects which happen after player moves. // IMPORTANT: don't modify lf's flagpile during this code! // particularly don't remove flags... - // returns TRUE if we displayed a message int moveeffects(lifeform_t *lf) { flag_t *f; int didmsg = B_FALSE; + if (lfhasflagval(lf, F_INJURY, IJ_HAMSTRUNG, NA, NA, NULL)) { + if (!skillcheck(lf, SC_FALL, 20, 0)) fall(lf, NULL, B_TRUE); + } + if (isbleeding(lf)) { if (lfhasflagval(lf, F_INJURY, NA, BP_LEGS, DT_SLASH, NULL)) { - bleed(lf); + bleed(lf, B_FALSE); losehp(lf, 1, DT_DIRECT, NULL, "blood loss"); } else { if (rnd(1,2) == 1) { - bleed(lf); + bleed(lf, B_FALSE); } } } @@ -1455,6 +1457,30 @@ int movetowards(lifeform_t *lf, cell_t *dst, int dirtype) { return rv; } +int move_will_hurt(lifeform_t *lf) { + flag_t *retflag[MAXCANDIDATES]; + int nretflags,i; + + if (lfhasflag(lf, F_PAIN)) { + return B_TRUE; + } + getflags(lf->flags, retflag, &nretflags, F_INJURY, F_PAIN, F_NONE); + for (i = 0; i < nretflags; i++) { + flag_t *f; + f = retflag[i]; + if (f->id == F_PAIN) return B_TRUE; + if (f->id == F_INJURY) { + switch (f->val[0]) { + case IJ_LEGBLEED: + return B_TRUE; + default: + break; + } + } + } + return B_FALSE; +} + int opendoorat(lifeform_t *lf, cell_t *c) { object_t *o; int rv; @@ -2649,7 +2675,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) { // for at least average iq things... if (iq >= AT_AVERAGE) { // don't move if in pain - if (lfhasflag(lf, F_PAIN)) { + if (move_will_hurt(lf)) { if (error) *error = E_WONT; return B_FALSE; } diff --git a/move.h b/move.h index fb4bddc..da47675 100644 --- a/move.h +++ b/move.h @@ -19,6 +19,7 @@ int moveeffects(lifeform_t *lf); int movelf(lifeform_t *lf, cell_t *newcell); int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg); int movetowards(lifeform_t *lf, cell_t *dst, int dirtype); +int move_will_hurt(lifeform_t *lf); int opendoorat(lifeform_t *lf, cell_t *c); int opendoor(lifeform_t *lf, object_t *o); int pullnextto(lifeform_t *lf, cell_t *c); diff --git a/nexus.c b/nexus.c index 3526a51..1bf34b3 100644 --- a/nexus.c +++ b/nexus.c @@ -151,11 +151,10 @@ int main(int argc, char **argv) { // if no player (ie. didn't load a game), add them if (!player) { - char *user; - char pname[BUFLEN]; - char buf[BUFLEN]; + char *user,pname[BUFLEN],buf[BUFLEN]; job_t *j = NULL; char ch; + object_t *o; cell_t *where; int dir; flag_t *f; @@ -222,13 +221,20 @@ int main(int argc, char **argv) { killlf(where->lf); } - // add player nearby - where = real_getrandomadjcell(where, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL); + // add player in the starting position + //where = real_getrandomadjcell(where, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL); + where = findobinmap(dmap, OT_PLAYERSTART); + if (!where) { + dblog("fatal error: couldn't find player start position!"); + msg("fatal error: couldn't find player start position!"); + more(); + exit(1); + } real_addlf(where, R_HUMAN, 1, C_PLAYER); // this will assign 'player' - - // add abilities which the player always has addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL); + o = hasob(where->obpile, OT_PLAYERSTART); + killob(o); user = getenv("USER"); if (user) { @@ -1199,50 +1205,32 @@ int rolldie(int ndice, int sides) { int rollhitdice(lifeform_t *lf) { flag_t *f; - int ndice, plus; - int roll = 0; - int i; + int ndice, nsides = 4, plus = 0; + int myroll = 0; float mod; int db = B_FALSE; f = hasflag(lf->flags, F_HITDICE); if (f) { - ndice = f->val[0]; - if (f->val[1] == NA) plus = 0; - else plus = f->val[1]; + myroll = roll(f->text); } else { ndice = 1; + nsides = 4; plus = 0; + myroll = roll("1d4"); } - if (db) dblog("rollhitdice() for %s - rolling %dd4 + %d",lf->race->name,ndice,plus); mod = 100 + getstatmod(lf, A_CON); if (db) dblog("rollhitdice() - mod is +%0.0f%%",mod); - if (ndice == 0) { - int thisroll; - // just the bonus - thisroll = plus; - - if (thisroll < 1) thisroll = 1; - - roll += thisroll; - } else { - for (i = 0; i < ndice; i++) { - int thisroll; - thisroll = rolldie(1, 4) + plus; - if (thisroll < 1) thisroll = 1; - if (db) dblog("rollhitdice() ---- die %d/%d == %d",i+1,ndice,thisroll); - - roll += thisroll; - } - } - if (db) dblog("TOTAL: %d",roll); + + if (db) dblog("TOTAL: %d",myroll); + // modify for fitness/con - roll = pctof(mod, roll); - limit(&roll, 1, NA); - if (db) dblog(" -> modified to: %d",roll); - return roll; + myroll = pctof(mod, myroll); + limit(&myroll, 1, NA); + if (db) dblog(" -> modified to: %d",myroll); + return myroll; } int rollmpdice(lifeform_t *lf) { @@ -1533,7 +1521,7 @@ void timeeffectsworld(map_t *map, int updategametime) { if (updategametime) { // inc game time - curtime += firstlftime; + curtime += (firstlftime*(TIMECONST)); // don't let it get higher than 23:59 while (curtime >= DAYSECS) { curtime -= DAYSECS; diff --git a/objects.c b/objects.c index df5abc2..09cd902 100644 --- a/objects.c +++ b/objects.c @@ -455,6 +455,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes nadded = 0; nretobs = 0; + if (where->where) { + assert(!where->where->type->solid); + } + if (where->owner && hasflag(where->owner->flags, F_NOPACK)) { if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name); nretobs = 0; @@ -468,7 +472,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes dblog("DB: called addobject() for forceoid %s, canstack = %d",ot->name, canstack); } } else { - char *p2; + char *bonusstart,*p2; + int bonussign = 1; localname = strdup(name); if (db) { @@ -532,36 +537,34 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes } bonus = 0; + // handle for bonuses. eg. "+1" - p2 = strchr(p, '+'); - if (p2) { - char *p3; + bonusstart = strchr(p, '+'); + if (!bonusstart) { + bonussign = -1; + bonusstart = strchr(p, '-'); + } + if (bonusstart) { + char *p3,*bonusend; char numbuf[BUFLENSMALL]; + p3 = numbuf; - p++; - while (isdigit(*p2)) { - *p3 = *p2; - p2++; + bonusend = bonusstart+1; // go past the + or - + while (isdigit(*bonusend)) { // grab the full number + *p3 = *bonusend; + bonusend++; p3++; } *p3 = '\0'; - bonus += atoi(numbuf); - } - // check for penalties. eg. "-1" - p2 = strchr(p, '-'); - if (p2) { - char *p3; - char numbuf[BUFLENSMALL]; - p3 = numbuf; - p2++; - while (isdigit(*p2)) { - *p3 = *p2; - p2++; - p3++; + bonus += (atoi(numbuf) * bonussign); + // strip off the "+xxx" / "-xxx", as long as xxx was a number. + // might not be the case if it was part of the object name + // eg. "waist-deep water" + if (bonus) { + while (*bonusend == ' ') bonusend++; // go past spaces + strcpy(bonusstart, bonusend); } - *p3 = '\0'; - bonus -= atoi(numbuf); - } + } // handle prefixes. strip them off as we go. donesomething = B_TRUE; @@ -1269,7 +1272,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes rf = hasflag(corpserace->flags, F_HITDICE); if (rf) { int maxhp; - maxhp = (rf->val[0] * 4) + rf->val[1]; + maxhp = roll(rf->text); f->val[0] = maxhp; f->val[1] = maxhp; } @@ -4576,7 +4579,9 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan strcpy(triedbuf, ""); if (hasflag(o->flags, F_BEINGUSED)) { - strcat(triedbuf, " [currently being read]"); + if (strlen(triedbuf)) strcat(triedbuf, ", "); + else strcpy(triedbuf, " ["); + strcat(triedbuf, "currently being read"); } if (istried(o)) { @@ -5734,9 +5739,8 @@ void initobjects(void) { addmaterial(MT_METAL, "metal", 13); addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL); addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); - addflag(lastmaterial->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL); - addflag(lastmaterial->flags, F_DTIMMUNE, DT_BITE, NA, NA, NULL); - addflag(lastmaterial->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL); + addflag(lastmaterial->flags, F_DTRESIST, DT_BITE, NA, NA, NULL); + addflag(lastmaterial->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL); addflag(lastmaterial->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL); addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL); addmaterial(MT_GLASS, "glass", 13); @@ -5784,8 +5788,8 @@ void initobjects(void) { addoc(OC_RING, "Rings", "A circular band, worn on the finger.", '=', C_GREY); addocnoun(lastobjectclass, "ring"); addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastobjectclass->flags, F_GOESON, BP_LEFTHAND, NA, NA, NULL); + addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTFINGER, NA, NA, NULL); + addflag(lastobjectclass->flags, F_GOESON, BP_LEFTFINGER, NA, NA, NULL); addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY); addocnoun(lastobjectclass, "weapon"); addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -6041,7 +6045,7 @@ void initobjects(void) { addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE); - addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "&"); + addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "^"); addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -6101,7 +6105,7 @@ void initobjects(void) { addot(OT_TRAPSUMMON, "summoning trap", "A magical trap which causes a monster to appear.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); - addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "^"); + addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "^"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "."); @@ -6400,12 +6404,14 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); // corpses addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY); - addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_SMALL); - addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD, SZ_SMALL); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); - addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL); + addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // potions (sorted by rarity) @@ -6589,8 +6595,8 @@ void initobjects(void) { addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, 4, NA, NULL); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); - addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL); @@ -6681,7 +6687,7 @@ void initobjects(void) { addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); - addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -6837,7 +6843,7 @@ void initobjects(void) { addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity, dealing 1-^bpower^n damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); - addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); @@ -6854,6 +6860,7 @@ void initobjects(void) { addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); addot(OT_S_SHATTER, "shatter", "Instantly shatters all glass in the target location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); @@ -6880,8 +6887,9 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // l5 - addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 2d6 damage, the next deals 2d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 3d6 damage, the next deals 3d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power."); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); @@ -6933,14 +6941,14 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); - addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd4 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre."); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim" addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); /////////////////// - // elemental - ice + // elemental - cold /////////////////// // l1 addot(OT_S_CHILL, "chill", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -6981,7 +6989,7 @@ void initobjects(void) { addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); // l3 - addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 2-10 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 3d6 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how difficult the ray is to dodge."); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); @@ -7020,6 +7028,27 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); + addot(OT_S_CRYSTALARM, "crystalline armour", "Summons ice crystal armour to protect you from damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 1-3: one piece of armour is created."); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 4-6: two pieces of armour are created."); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 7-9: three pieces of armour are created."); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 10: four pieces of armour are created."); + addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); + addot(OT_S_SHARDSHOT, "shard shot", "Fires a scattered burst of small, fast moving ice shards. The shot will pass through multiple creatures, but damage is reduced with range.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is determined by its power."); + addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_WALLSTOP, NA, NULL); + addot(OT_S_SNAPFREEZE, "snap freeze", "Instantly freezes the target creature. Cold-resistant creatures will take minor damage instead.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); /////////////////// // nature /////////////////// @@ -7076,6 +7105,7 @@ void initobjects(void) { addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); @@ -7166,6 +7196,7 @@ void initobjects(void) { addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); @@ -7187,7 +7218,7 @@ void initobjects(void) { addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l6 - addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how many bolts will appear."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); @@ -7196,6 +7227,7 @@ void initobjects(void) { addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); @@ -7486,6 +7518,12 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); + // l5 + addot(OT_S_SUMMONDEMON, "summon demon", "Summons a random demonic entity.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its chances of success, and how long the demon will remain."); + addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); /////////////////// // translocation /////////////////// @@ -7551,7 +7589,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addot(OT_S_ALARM, "alarm", "Creates a passive alarm which goes off when an enemy is nearby.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); @@ -7559,7 +7597,7 @@ void initobjects(void) { addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); // l3 - addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster, causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster, causing 2d6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the radius of the blast."); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); @@ -7815,7 +7853,7 @@ void initobjects(void) { addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit"); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL); addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); @@ -7837,7 +7875,7 @@ void initobjects(void) { addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 100, 200, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 200, 400, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); @@ -7849,7 +7887,7 @@ void initobjects(void) { addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 200, 300, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 300, 500, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); @@ -7875,7 +7913,7 @@ void initobjects(void) { addflag(lastot->flags, F_HELPSCLIMB, 3, NA, NA, NULL); addot(OT_SACK, "sack", "A small cloth sack.", MT_CLOTH, 0.5, OC_TOOLS, SZ_SMALL); - addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "("); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -7982,7 +8020,7 @@ void initobjects(void) { addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit"); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 100, 200, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_FIRE, NA, NA, "1d4"); @@ -8174,7 +8212,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addot(OT_CHEST, "chest", "A small wooden treasure chest.", MT_METAL, 40, OC_FURNITURE, SZ_MEDIUM); - addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "("); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -9007,6 +9045,14 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL); + // armour - ears + addot(OT_EARPLUGS, "set of earplugs", "A pair of cloth plugs designed to give the wearer a peaceful night's sleep. ", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_GOESON, BP_EARS, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_DEAF, NA, NA, NULL); + addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + // armour - eyes addot(OT_SUNGLASSES, "pair of sunglasses", "Tinted eyewear to protect against sunlight.", MT_GLASS, 0.01, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); @@ -9796,6 +9842,26 @@ void initobjects(void) { addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); // will be replaced when summoned addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned + + addot(OT_ICEARMOUR, "ice crystal armour", "Summoned body armour made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_HUMAN); + addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned + addot(OT_ICEBOOTS, "pair of ice crystal boots", "Summoned boots made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned + addot(OT_ICEGLOVES, "pair of ice crystal gauntlets", "Summoned gauntlets made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned + addot(OT_ICEHELMET, "ice crystal helmet", "A summoned helmet made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned + + // special obs + addot(OT_PLAYERSTART, "playerstart", "starting pos for player", MT_NOTHING, 0, OC_MISC, SZ_MINI); } // returns the 'armourrating' flag @@ -13217,9 +13283,10 @@ int readsomething(lifeform_t *lf, object_t *o) { // let player select ANY object (even if it won't // work). if (needsob && isplayer(lf) && !isknown(o)) { - f = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL); + flag_t *f2; + f2 = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL); targob = askobject(lf->pack, "Target which object", NULL, AO_NONE); - killflag(f); + killflag(f2); } dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE); @@ -14101,7 +14168,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno // now use the REAL name real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_TRUE); - losehp_real(owner, howmuch , damtype, NULL, obname, B_TRUE, o); + losehp_real(owner, howmuch , damtype, NULL, obname, B_TRUE, o, B_FALSE); if (isdead(owner)) { return howmuch; } @@ -15929,11 +15996,6 @@ int getcritchance(lifeform_t *lf, object_t *o) { } } - if (isplayer(lf)) { - // oooooo - chance = 100; - } - return chance; } diff --git a/spell.c b/spell.c index ecb3300..cb784fc 100644 --- a/spell.c +++ b/spell.c @@ -794,8 +794,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } howlong = 10; addtempflag(user->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); - needredraw = B_TRUE; - statdirty = B_TRUE; + if (isplayer(user)) { + needredraw = B_TRUE; + statdirty = B_TRUE; + drawscreen(); + } } else if (abilid == OT_A_REPAIR) { enum SKILLLEVEL slev; object_t *o; @@ -1983,7 +1986,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char castername[BUFLEN]; int rv = B_FALSE; objecttype_t *sp; - flag_t *casttype; + flag_t *casttype = NULL; sp = findot(spellid); @@ -2042,18 +2045,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ power += powerinc; } } - } - // special: spit attacks need an animation - casttype = lfhasflag(caster, F_CASTTYPE); - if (casttype && (casttype->val[0] == CT_EYESPIT)) { - enum COLOUR col; - if (casttype->val[1] == NA) { - col = C_GREEN; - } else { - col = casttype->val[1]; + // special: spit attacks need an animation + casttype = lfhasflag(caster, F_CASTTYPE); + if (casttype && (casttype->val[0] == CT_EYESPIT)) { + enum COLOUR col; + if (casttype->val[1] == NA) { + col = C_GREEN; + } else { + col = casttype->val[1]; + } + anim(caster->cell, targcell, '}', col); } - anim(caster->cell, targcell, '}', col); } // switch based on spell effects... @@ -2337,49 +2340,44 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); } } else if (spellid == OT_S_BLINK) { - if (!caster->nlos) { - // can't see anywhere - fizzle(caster); - } else { - if (lfhasflag(caster, F_CONTROL) && (power < 6)) { - power = 6; + if (lfhasflag(caster, F_CONTROL) && (power < 6)) { + power = 6; + } + if (power >= 6) { + // controlled + // must be within line of sight. + if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; + if (!targcell || !cellwalkable(caster, targcell, NULL)) { + fizzle(caster); + return B_TRUE; } - if (power >= 6) { - // controlled - // must be within line of sight. - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - if (!targcell || !cellwalkable(caster, targcell, NULL)) { - fizzle(caster); - return B_TRUE; - } - } else { - cell_t *poss[MAXCANDIDATES]; - int nposs = 0,x,y; - // pick a random location - // only needs to be in line-of-FIRE, not neccesarily sight. - for (y = 0 ; y <= caster->cell->map->h; y++) { - for (x = 0 ; x <= caster->cell->map->w; x++) { - cell_t *c; - c = getcellat(caster->cell->map, x, y); - if (c && haslof(caster->cell, c, LOF_WALLSTOP, NULL)) { - if (cellwalkable(caster, targcell, NULL) && - !celldangerous(caster, targcell, B_FALSE, NULL)) { - poss[nposs++] = c; - } + } else { + cell_t *poss[MAXCANDIDATES]; + int nposs = 0,x,y; + // pick a random location + // only needs to be in line-of-FIRE, not neccesarily sight. + for (y = 0 ; y <= caster->cell->map->h; y++) { + for (x = 0 ; x <= caster->cell->map->w; x++) { + cell_t *c; + c = getcellat(caster->cell->map, x, y); + if (c && haslof(caster->cell, c, LOF_WALLSTOP, NULL)) { + if (cellwalkable(caster, c, NULL) && + !celldangerous(caster, c, B_FALSE, NULL)) { + poss[nposs++] = c; } - if (nposs >= MAXCANDIDATES) break; } if (nposs >= MAXCANDIDATES) break; } - - if (!nposs) { - fizzle(caster); - return B_TRUE; - } - targcell = poss[rnd(0,nposs-1)]; + if (nposs >= MAXCANDIDATES) break; } - teleportto(caster, targcell, B_TRUE); + + if (!nposs) { + fizzle(caster); + return B_TRUE; + } + targcell = poss[rnd(0,nposs-1)]; } + teleportto(caster, targcell, B_TRUE); } else if (spellid == OT_S_LOWERMETAB) { flag_t *f; // ie. 2 - 4 @@ -2669,7 +2667,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int stillseen = B_FALSE; // everyone takes damage, and mark cells as hit for (i = 0; i < narccells; i++) { - losehp(arccell[i]->lf, rolldie(2,nsides), DT_ELECTRIC, caster, "an electricity bolt"); + losehp(arccell[i]->lf, rolldie(3,nsides), DT_ELECTRIC, caster, "an electricity bolt"); hitcell[nhitcells++] = arccell[i]; if (haslos(player, arccell[i])) { @@ -2731,8 +2729,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_FALSE; } - radius = power/3; - if (radius < 1) radius = 1; + radius = (power/4)+1; addobburst(targcell, radius, DT_COMPASS, "cloud of poison gas", caster, LOF_WALLSTOP); @@ -2988,7 +2985,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (cansee(player, target)) { msg("A ray of coldness ray hits %s.",lfname); } - losehp(target, rnd(2,5), DT_COLD, caster, "a blast of coldness"); + losehp(target, roll("3d6"), DT_COLD, caster, "a blast of coldness"); // ray stops here. break; } @@ -3130,6 +3127,63 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } + } else if (spellid == OT_S_CRYSTALARM) { + object_t *o; + enum BODYPART bp[4]; + int nbp, donesomething = B_FALSE,i; + targcell = caster->cell; + target = caster; + nbp = (power/3)+1; + bp[0] = BP_BODY; + bp[1] = BP_HEAD; + bp[2] = BP_HANDS; + bp[3] = BP_FEET; + for (i = 0; (i < 4) && (i < nbp); i++) { + if (hasbp(target, bp[i]) && !getequippedob(target->pack, bp[i])) { + switch (bp[i]) { + case BP_BODY: default: + o = addob(target->pack, "ice crystal armour"); break; + case BP_HEAD: + o = addob(target->pack, "ice crystal helmet"); break; + case BP_HANDS: + o = addob(target->pack, "ice crystal gauntlets"); break; + case BP_FEET: + o = addob(target->pack, "ice crystal boots"); break; + } + if (o) { + if (canwear(target, o, BP_NONE)) { + char obname[BUFLEN]; + flag_t *f; + // announce + getobname(o, obname, 1); + if (isplayer(target)) { + msg("%s forms %s your %s!", obname, getbodypartequipname(bp[i]), getbodypartname(bp[i])); + } else if (cansee(player, target)) { + msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]), + castername, getpossessive(castername), getbodypartname(bp[i])); + } + wear(target, o); + // set its values + f = hasflag(o->flags, F_OBHP); + if (f) { + f->val[0] = power*5; + f->val[1] = power*5; + } + addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL); + donesomething = B_TRUE; + } else { + killob(o); + } + } + } + } + + if (!donesomething) { + fizzle(caster); + stopspell(caster, spellid); + return B_FALSE; + } + } else if (spellid == OT_S_CRYSTALSHIELD) { object_t *o; targcell = caster->cell; @@ -3167,6 +3221,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f->val[0] = power*5; f->val[1] = power*5; } + addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL); } else { killob(o); fizzle(caster); @@ -3654,7 +3709,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ getlfname(c->lf, lfname); msg("A blast of energy hits %s.",lfname); } - losehp(c->lf, rnd(2,6), DT_MAGIC, caster, "an energy blast"); + losehp(c->lf, roll("2d6"), DT_MAGIC, caster, "an energy blast"); } } } @@ -3876,7 +3931,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ setobcreatedby(o, caster); } if (c->lf) { - losehp(c->lf, rolldie(power,4), DT_FIRE, caster, "a fireball"); + losehp(c->lf, rolldie(power,3), DT_FIRE, caster, "a fireball"); } } } @@ -3891,7 +3946,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (c->lf) { int ndice; ndice = power / 2; if (ndice < 1) ndice = 1; - losehp(c->lf, rolldie(ndice,4), DT_FIRE, caster, "a fireball"); + losehp(c->lf, rolldie(ndice,3), DT_FIRE, caster, "a fireball"); } } } @@ -4115,8 +4170,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ o = targob; } else { // rings? - o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTHAND, NA, NA, NULL); - if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTHAND, NA, NA, NULL); + o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTFINGER, NA, NA, NULL); + if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTFINGER, NA, NA, NULL); // gloves? if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_HANDS, NA, NA, NULL); // weapon? @@ -4737,7 +4792,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = isequipped(o); if (f) { if ((f->val[0] == BP_WEAPON) || (f->val[0] == BP_SECWEAPON)) { - } else if ((f->val[0] == BP_RIGHTHAND) || (f->val[0] == BP_LEFTHAND)) { + } else if ((f->val[0] == BP_RIGHTFINGER) || (f->val[0] == BP_LEFTFINGER)) { if (isplayer(caster)) { getobname(o, buf, 1); msg("Your %s slides off your %s!", buf, getbodypartname(f->val[0])); @@ -5027,7 +5082,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } else { int howlong = 7; - howlong = getspellduration(3,5,blessed) + (power/2); + howlong = getspellduration(3,5,blessed) + (power/4); addtempflag(target->flags, F_PAIN, DT_MAGIC, NA, NA, "1d3", howlong); } } else { @@ -5083,7 +5138,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("A glob of venom hits %s.",lfname); } if (!isimmuneto(target->flags, DT_POISON)) { - poison(target, power*3, P_VENOM, power, "a glob of venom"); + poison(target, power*3, P_VENOM, (power/4)+1, "a glob of venom"); } } } else { @@ -6449,6 +6504,34 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(caster->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL, FROMSPELL); f->obfrom = spellid; + } else if (spellid == OT_S_SHARDSHOT) { + cell_t *retcell[MAXRETCELLS]; + int nretcells; + int i; + int nhits = power; + if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; + + // create a line of fire towards the target cell + calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcells); + animcells(caster->cell, &retcell[1], nretcells-1, B_FALSE, '*', '\0', C_WHITE); + if (cansee(player, caster)) { + msg("%s fire%s a burst of ice shards!",castername, isplayer(caster) ? "" : "s"); + } + + // don't hit the caster cell on fire! + for (i = 1; (i < nretcells) && (nhits > 0); i++) { + cell_t *c; + c = retcell[i]; + if (c->lf) { + // hit with ice + losehp(c->lf, rolldie(nhits, 6), DT_COLD, caster, "a burst of ice shards"); + nhits--; + } + if (haslos(player, c)) { + needredraw = B_TRUE; + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + } } else if (spellid == OT_S_SHATTER) { char buf[BUFLEN]; if (!validatespellcell(caster, &targcell,TT_NONE, spellid, power, frompot)) return B_TRUE; @@ -6573,6 +6656,28 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // use direct damage rather than holy, because otherwise it might be increased // due to vulnerabilities losehp(target, rnd(1,power*2), DT_DIRECT, caster, "a smiting"); + } else if (spellid == OT_S_SNAPFREEZE) { + if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; + target = haslf(targcell); + if (target) { + if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { + if (isplayer(caster) || cansee(player, target)) { + char tname[BUFLEN]; + getlfname(target, tname); + msg("%s resists.",tname); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + // they get angry! + if (!isplayer(target) && cansee(target, caster)) { + fightback(target, caster); + } + } else { + if (seenbyplayer && (isplayer(caster) || cansee(player, target))) *seenbyplayer = B_TRUE; + freezelf(target, caster, rnd(20,40)); + } + } else { + fizzle(caster); + } } else if (spellid == OT_S_SNOWBALL) { int failed = B_FALSE; // ask for a target cell @@ -6790,12 +6895,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (strstr(r->name, " snake")) { flag_t *f; f = hasflag(r->flags, F_HITDICE); - // ie. 1hd needs power 2 - // ie. 2hd needs power 4 - // ie. 3hd needs power 6 - // ie. 4hd needs power 8 - if (f && (power >= (f->val[0] * 2))) { - raceposs[nraceposs++] = r; + if (f) { + int ndice,nsides,bonus,maxroll; + texttodice(f->text, &ndice,&nsides,&bonus); + maxroll = ndice * nsides + bonus; + // ie. 1hd needs power 2 + // ie. 2hd needs power 4 + // ie. 3hd needs power 6 + // ie. 4hd needs power 8 + if (power >= (maxroll/4)) { + raceposs[nraceposs++] = r; + } } } } @@ -7302,30 +7412,62 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ swapplaces(caster, target, B_FALSE); } else if ((spellid == OT_S_SUMMONANIMALSSM) || (spellid == OT_S_SUMMONANIMALSMD) || - (spellid == OT_S_SUMMONANIMALSLG)) { - int lifetime, nwant,ngot; + (spellid == OT_S_SUMMONANIMALSLG) || + (spellid == OT_S_SUMMONDEMON)) { + int lifetime, nwant,ngot,successrate; enum LFSIZE wantsize; enum RACECLASS wantrc; + int friendly; lifetime = (power * 9) + rnd(1,power*2); - nwant = rnd(2,3); + + switch (spellid) { + case OT_S_SUMMONDEMON: + wantrc = RC_DEMON; + wantsize = SZ_ANY; + nwant = 1; + successrate = power*10; + if (caster->race->raceclass->id == RC_DEMON) { + friendly = B_TRUE; + } else if (onein(4)) { + friendly = B_FALSE; + } else { + friendly = B_TRUE; + } + break; case OT_S_SUMMONANIMALSSM: wantrc = RC_ANIMAL; wantsize = SZ_SMALL; + nwant = rnd(2,3); + successrate = 100; + friendly = B_TRUE; break; case OT_S_SUMMONANIMALSMD: wantrc = RC_ANIMAL; wantsize = SZ_MEDIUM; + nwant = rnd(2,3); + successrate = 100; + friendly = B_TRUE; break; case OT_S_SUMMONANIMALSLG: wantrc = RC_ANIMAL; wantsize = SZ_LARGE; + nwant = rnd(2,3); + successrate = 100; + friendly = B_TRUE; break; default: wantsize = SZ_ANY; + successrate = 100; break; } - ngot = summonlfs(caster, caster->cell, wantrc, wantsize, AL_NONE, nwant, lifetime); + + if (!pctchance(successrate)) { + fizzle(caster); + return B_TRUE; + } + + ngot = summonlfs(caster, caster->cell, wantrc, wantsize, AL_NONE, nwant, lifetime, friendly); if (!ngot) { fizzle(caster); return B_TRUE; @@ -7334,7 +7476,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ raceclass_t *rc; rc = findraceclass(wantrc); if (seenbyplayer) *seenbyplayer = B_TRUE; - msg("%s appear around %s!", makeplural(rc->name), castername); + if (ngot == 1) { + msg("%s %s appears near %s!", needan(rc->name) ? "An" : "A", rc->name, castername); + } else { + msg("%s appear around %s!", makeplural(rc->name), castername); + } } } } else if (spellid == OT_S_SUMMONWEAPON) { @@ -7365,6 +7511,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ snprintf(buf, BUFLEN, "2d%d",power); changeflagtext(f, buf); } + addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL); } else { killob(o); fizzle(caster); @@ -7977,12 +8124,11 @@ void fizzle(lifeform_t *caster) { } else { nothinghappens(); } - /* } else if (cansee(player, caster)) { + char buf[BUFLEN]; getlfname(caster, buf); capitalise(buf); msg("%s's spell fizzles.", buf); - */ } } @@ -8383,12 +8529,13 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) { // If we can _will_ this to occur then we might have a set // range if (lf) { + int newrange; flag_t *f; f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL); if (f && strlen(f->text)) { - texttospellopts(f->text, NULL, NULL, NULL, &range); - if (range > 0) { - return range; + texttospellopts(f->text, NULL, NULL, NULL, &newrange); + if (newrange > 0) { + return newrange; } } } @@ -8419,6 +8566,9 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) { case OT_S_CHAINLIGHTNING: range = (power*3); break; + case OT_S_SHARDSHOT: + range = power; + break; default: break; } @@ -8587,6 +8737,10 @@ void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYP void stopspell(lifeform_t *caster, enum OBTYPE spellid) { flag_t *f,*nextf; object_t *o, *nexto; + objecttype_t *sp; + + sp = findot(spellid); + if (!sp) return; for (f = caster->flags->first ; f ; f = nextf) { nextf = f->next; @@ -8596,28 +8750,22 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) { killflag(f); } } + + if (isplayer(caster)) { + msg("Your %s spell disappates.",sp->name); + } + // remove any other specific effects based on spell type. for (o = caster->pack->first; o ; o = nexto) { nexto = o->next; - if ((o->type->id == OT_ENERGYBLADE) && (spellid == OT_S_SUMMONWEAPON)) { + if (hasflagval(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL)) { if (cansee(player, caster)) { char obname[BUFLEN]; char lfname[BUFLEN]; getobname(o, obname, 1); getlfname(caster, lfname); msg("%s%s %s vanishes.", lfname, getpossessive(lfname), - obname); - } - killob(o); - } - if ((o->type->id == OT_ICESHIELD) && (spellid == OT_S_CRYSTALSHIELD)) { - if (cansee(player, caster)) { - char obname[BUFLEN]; - char lfname[BUFLEN]; - getobname(o, obname, 1); - getlfname(caster, lfname); - msg("%s%s %s vanishes.", lfname, getpossessive(lfname), - obname); + noprefix(obname)); } killob(o); } @@ -8642,7 +8790,7 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) { // returns # created -int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime) { +int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly) { lifeform_t *newlf; race_t *r = NULL; enum RACE poss[MAXCANDIDATES]; @@ -8699,10 +8847,12 @@ int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFS addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL); // summoned addflag(newlf->flags, F_SUMMONEDBY, caster->id, lifetime, NA, NULL); - addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL); - if (areallies(player, caster)) { - makefriendly(newlf, PERMENANT); - } + if (friendly) { + addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL); + if (areallies(player, caster)) { + makefriendly(newlf, PERMENANT); + } + } ncreated++; } } diff --git a/spell.h b/spell.h index bbe6f86..272b095 100644 --- a/spell.h +++ b/spell.h @@ -27,7 +27,7 @@ void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYP void stopspell(lifeform_t *caster, enum OBTYPE spellid); void stopallspells(lifeform_t *lf); void stopallspellsexcept(lifeform_t *lf, ...); -int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime); +int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly); lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target); cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, enum OBTYPE spellid, int power, int frompot); //lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf); diff --git a/vaults/playerstart1.vlt b/vaults/playerstart1.vlt new file mode 100644 index 0000000..4b8eb3d --- /dev/null +++ b/vaults/playerstart1.vlt @@ -0,0 +1,29 @@ +@id:playerstart_1 +@map +########## +#...c..|,# +#...-/-### ++......|,# +#.-/-..### +#...c..|,# +########## +@end +@legend +#:cell:rock wall +|:ob:iron gate +,:ob:1-4 bones:50 ++:ob:wooden door ++:exit +/:ob:wooden table +-:ob:wooden footstool +@end +@flags +goesin:dungeon +playerstart +norandom +atoneof(8,1)(8,3)(8,5) ob:playerstart +scatter(1,1,-2,-2) ob:wooden footstool:0-3 +scatter(1,1,-2,-2) ob:random food:0-2 +mayrotate +@end + diff --git a/vaults/playerstart2.vlt b/vaults/playerstart2.vlt new file mode 100644 index 0000000..f66c192 --- /dev/null +++ b/vaults/playerstart2.vlt @@ -0,0 +1,25 @@ +@id:playerstart_2 +@map +###x### +#.|.|.# +###.### +#.|.|.# +###.### +#.|.|.# +###.### +#.|.|.# +###x### +@end +@legend +#:cell:rock wall +|:ob:iron gate +x:exit +@end +@flags +goesin:dungeon +playerstart +norandom +atoneof(1,1)(1,3)(1,5)(1,7)(5,1)(5,3)(5,5)(5,7) ob:playerstart +mayrotate +@end + diff --git a/vaults/playerstart3.vlt b/vaults/playerstart3.vlt new file mode 100644 index 0000000..1bd33cf --- /dev/null +++ b/vaults/playerstart3.vlt @@ -0,0 +1,26 @@ +@id:playerstart_3 +@map +######### +#.......# +#.IIIII.# +#.II.I..# +#.I.p.,.# +#.II.II.# +#.IIIII.# +#.......# +######### +@end +@legend +#:cell:rock wall +I:cell:glass wall +,:ob:4-8 pieces of broken glass +p:ob:playerstart +@end +@flags +goesin:dungeon +autodoors:50 +playerstart +norandom +mayrotate +@end + diff --git a/vaults/playerstart4.vlt b/vaults/playerstart4.vlt new file mode 100644 index 0000000..a9bf7c1 --- /dev/null +++ b/vaults/playerstart4.vlt @@ -0,0 +1,25 @@ +@id:playerstart_4 +@map +####### +#wwwww# +#ww.ww# +#w.p._x +#ww.ww# +#wwwww# +####### +@end +@legend +#:cell:rock wall +w:cell:low rock floor +w:ob:very deep water +_:cell:wood floor +p:ob:playerstart +x:exit +@end +@flags +goesin:dungeon +playerstart +norandom +mayrotate +@end +