diff --git a/ai.c b/ai.c index ecf1db0..9fcdd5b 100644 --- a/ai.c +++ b/ai.c @@ -108,7 +108,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { if (areallies(player, lf) && cantalk(lf)) { char text[BUFLEN]; if (cansee(lf, victim)) { - real_getlfname(victim, text, B_FALSE, B_FALSE); + real_getlfname(victim, text, NULL, B_NOSHOWALL, B_CURRACE); } else { strcpy(text, "something"); } @@ -777,7 +777,7 @@ int ai_attack_existing_target(lifeform_t *lf) { loseaitargets(lf); if (areallies(lf, player) && cantalk(lf)) { char text[BUFLEN]; - real_getlfname(target, text, B_FALSE, B_FALSE); + real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE); sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text); } } else { @@ -2036,7 +2036,7 @@ void aiturn(lifeform_t *lf) { if (db) { char lfname[BUFLEN]; - real_getlfname(lf, lfname, B_FALSE, B_TRUE); + real_getlfname(lf, lfname, NULL, B_SHOWALL, B_CURRACE); dblog("AIMOVE: %s, facing %s", lfname, getdirnameshort(lf->facing)); } @@ -2586,6 +2586,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if ((ot->id == OT_S_SMITEEVIL) && (getalignment(victim) != AL_EVIL)) { specificcheckok = B_FALSE; } + if (ot->id == OT_S_SPIKEVOLLEY) { + if ((lf->race->id == R_MANTICORE) && lfhasflagval(lf, F_INJURY, IJ_TAILBROKEN, NA, NA, NULL)) { + specificcheckok = B_FALSE; + } + } if (ot->id == OT_A_SPRINT) { if (lfhasflag(lf, F_SPRINTING) || !getstamina(lf) || (getstamina(lf) <= (getmaxstamina(lf)/2))) { specificcheckok = B_FALSE; @@ -2923,6 +2928,12 @@ int lookforobs(lifeform_t *lf) { return B_TRUE; } } + if (cancast(lf, OT_A_SNATCH, NULL) && haslof(lf->cell, c, LOF_NEED, NULL)) { + if (!useability(lf, OT_A_SNATCH, NULL, c)) { + // successful + return B_TRUE; + } + } // start walking towards target cell if (aigoto(lf, c, MR_OB, o, aigetchasetime(lf))) { return B_FALSE; diff --git a/attack.c b/attack.c index 57739da..bafb33a 100644 --- a/attack.c +++ b/attack.c @@ -941,8 +941,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // determine extra damage for flaming etc. // getextradam from USER too if (!willheal) { - getextradamwep(wep, &dam[0], &damtype[0], &ndam); - getextradamlf(lf, &dam[0], &damtype[0], &ndam); + getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE); + getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE); } } else { @@ -1144,7 +1144,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } else { // actually deal the melee damage! char attackername2[BUFLEN]; - real_getlfname(lf, attackername2, B_FALSE, B_TRUE); + real_getlfname(lf, attackername2, NULL, B_SHOWALL, B_REALRACE); if (lf->race->raceclass->id == RC_GOD) { flag_t *gf; gf = lfhasflag(lf, F_GODOF); @@ -1512,13 +1512,12 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { // don't need to check for blessed vs mosnters // determine extra damage - getextradamwep(wep, &dam[0], &damtype[0], &ndam); - getextradamlf(lf, &dam[0], &damtype[0], &ndam); + getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE); + getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE); for (i = 0; i < ndam; i++) { // announce the hit - construct_hit_string(lf, NULL, attackername, obname, NULL, wep, damtype[i], dam[i], maxhp, i, B_FALSE, B_FALSE, B_FALSE, isunarmed, buf); if (strlen(buf)) { @@ -1661,8 +1660,8 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) { // don't need to check for blessed vs mosnters // determine extra damage - getextradamwep(wep, &dam[0], &damtype[0], &ndam); - getextradamlf(lf, &dam[0], &damtype[0], &ndam); + getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE); + getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE); for (i = 0; i < ndam; i++) { @@ -2061,7 +2060,7 @@ enum DAMTYPE getdamtype(object_t *wep) { return dt; } -int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) { +int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax) { flag_t *f; int i; flag_t *retflag[MAXCANDIDATES]; @@ -2085,13 +2084,13 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) { // addition to the first one damwhere = dam; damtypewhere = damtype; - *(damwhere) += roll(f->text); // addition + *(damwhere) += real_roll(f->text, wantmax); // addition } else { // add a new damtype damwhere = (dam + *ndam); damtypewhere = (damtype + *ndam); doinc = B_TRUE; - *(damwhere) = roll(f->text); // set + *(damwhere) = real_roll(f->text, wantmax); // set *(damtypewhere) = f->val[0]; } @@ -2116,7 +2115,7 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) { return *dam; } -int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) { +int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax) { flag_t *f; int i; flag_t *retflag[MAXCANDIDATES]; @@ -2134,36 +2133,61 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) { f = hasflag(wep->flags, F_ENCHANTED); if (f) { if (strlen(f->text)) { - *(dam + *ndam) = roll(f->text); + *(dam + *ndam) = real_roll(f->text, wantmax); } else { - *(dam + *ndam) = roll("1d2"); // default: 1d2 extra damage + *(dam + *ndam) = real_roll("1d2", wantmax); // default: 1d2 extra damage } *(damtype + *ndam) = DT_MAGIC; (*ndam)++; } } - getflags(wep->flags, retflag, &nretflags, F_FROZEN, F_ONFIRE, F_NONE); + getflags(wep->flags, retflag, &nretflags, F_EXTRADAM, F_FROZEN, F_ONFIRE, F_NONE); for (i = 0; i < nretflags; i++) { f = retflag[i]; + + if (f->id == F_EXTRADAM) { + int *damwhere; + int *damtypewhere; + int doinc = B_FALSE; + + if ((f->val[0] == NA) || (f->val[0] == *damtype)) { + // addition to the first one + damwhere = dam; + damtypewhere = damtype; + *(damwhere) += real_roll(f->text, wantmax); // addition + } else { + // add a new damtype + damwhere = (dam + *ndam); + damtypewhere = (damtype + *ndam); + doinc = B_TRUE; + *(damwhere) = real_roll(f->text, wantmax); // set + *(damtypewhere) = f->val[0]; + } + + if (doinc) { + (*ndam)++; + } + } + if (f->id == F_ONFIRE) { if (strlen(f->text)) { - *(dam + *ndam) = roll(f->text); + *(dam + *ndam) = real_roll(f->text, wantmax); } else { - *(dam + *ndam) = rolldie(1,4); + *(dam + *ndam) = real_roll("1d4", wantmax); } *(damtype + *ndam) = DT_FIRE; (*ndam)++; } else if (f->id == F_HOT) { if (strlen(f->text)) { - *(dam + *ndam) = roll(f->text); + *(dam + *ndam) = real_roll(f->text, wantmax); } else { - *(dam + *ndam) = rolldie(1,2); + *(dam + *ndam) = real_roll("1d2", wantmax); } *(damtype + *ndam) = DT_HEAT; (*ndam)++; } else if (f->id == F_FROZEN) { - *(dam + *ndam) = rolldie(1,4); + *(dam + *ndam) = real_roll("1d4", wantmax); *(damtype + *ndam) = DT_COLD; (*ndam)++; } @@ -2543,7 +2567,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { msg("^wA pulse of lethal power blasts %s!", vname); f->known = B_KNOWN; } - real_getlfname(owner, ownername, B_FALSE, B_TRUE); + real_getlfname(owner, ownername, NULL, B_SHOWALL, B_REALRACE); getobname(wep, wepname, 1); snprintf(damstring, BUFLEN, "%s%s %s",ownername, getpossessive(ownername), wepname); losehp(victim, dam*3, DT_DIRECT, owner, damstring); @@ -2570,7 +2594,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { char damstring[BUFLEN]; char victimname[BUFLEN]; getlfname(owner, buf); - real_getlfname(owner, buf2, B_FALSE, B_FALSE); + real_getlfname(owner, buf2, NULL, B_SHOWALL, B_REALRACE); getlfname(victim, victimname); getobname(wep, obname, 1); diff --git a/attack.h b/attack.h index 0be169b..298fbff 100644 --- a/attack.h +++ b/attack.h @@ -16,8 +16,8 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d void getarrange(int arating, int *min, int *max); //object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag); enum DAMTYPE getdamtype(object_t *wep); -int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam); -int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam); +int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax); +int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax); void getdamrange(object_t *o, flag_t *f, int *min, int *max); //void getdamrange(object_t *o, int *min, int *max); //void getdamrangeunarmed(flag_t *f, int *min, int *max); diff --git a/data.c b/data.c index 0c855b0..244f2c8 100644 --- a/data.c +++ b/data.c @@ -271,6 +271,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "lockpick"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rope"); + // initial skills addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); @@ -647,6 +648,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_WHIPS, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); @@ -696,6 +698,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_WHIPS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); // abilities @@ -722,6 +725,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_WHIPS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); @@ -784,6 +788,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); // addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, PR_SKILLED, NA, NULL); // addflag(lastjob->flags, F_CANLEARN, SK_STAVES, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_WHIPS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, PR_EXPERT, NA, NULL); @@ -817,6 +822,8 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_CLUBS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_POLEARMS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_WHIPS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); @@ -929,6 +936,9 @@ void initjobs(void) { // monster jobs addjob(J_GUARD, "Guard", "Guards are paid mercenaries employed to protect a certain area. Accordingly, they are generally outfitetd with high quality armour."); addflag(lastjob->flags, F_NOPLAYER, B_TRUE, NA, NA, NULL); + f = addflag(lastjob->flags, F_STARTOBWEPSK, SK_LONGBLADES, NA, NA, NULL); + addcondition(f, FC_NOCONDITION, 50); + addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "random good armour"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "random good armour"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "random good armour"); @@ -979,14 +989,14 @@ void initobjects(void) { // init poison types - addpoisontype(P_MIGRAINE, "a migraine", "Sick", "", OT_NONE, 0, 0, PS_DISEASE); - addpoisontype(P_COLD, "hypothermia", "Sick", "^bYOU cough#S violently.", OT_NONE, 1, 25, PS_DISEASE); - addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON); - addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON); - addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON); - addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE); - addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON); - addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "cough", B_FALSE, 0, 0, PS_POISON); + addpoisontype(P_MIGRAINE, "a migraine", "Sick", "", OT_NONE, 0, 0, PS_DISEASE,20); + addpoisontype(P_COLD, "hypothermia", "Sick", "^bYOU cough#S violently.", OT_NONE, 1, 25, PS_DISEASE, 30); + addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON,20); + addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30); + addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0); + addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0); + addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0); + addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "cough", B_FALSE, 0, 0, PS_POISON, 0); // generate hidden name text for (n = 0; strlen(colour[n].name); n++) { @@ -1566,7 +1576,7 @@ void initobjects(void) { addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STENCH, B_TRUE, 1, NA, NULL); - addflag(lastot->flags, F_LOCKED, B_TRUE, 30, NA, NULL); // always starts locked + addflag(lastot->flags, F_CANBELOCKED, 50, 0, NA, NULL); addot(OT_GRATINGROOF, "drain in the roof", "An open draining grate set into the roof.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_BLUE, '<', NA, NULL); @@ -2435,7 +2445,7 @@ void initobjects(void) { addflag(lastot->flags, F_GLYPH, C_WHITE, '%', NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "0"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addot(OT_SANDWICHCHEESE, "cheese sandwich", "A tasty cheese sandwich. Filling, and restores all stamina plus some health.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); @@ -4178,18 +4188,20 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_SUCK, "get over here!", "Sucks the target lifeform towards the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_SUCK, "get over here!", "Pulls the target lifeform towards the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_RANGE, 5, 2, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); // l3 addot(OT_S_TWIDDLE, "twiddle", "Swaps places with the target creature.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_INSTANTDISROBE, "instant disrobe", "Transports 1-3 pieces of the target's armour to the air next to them.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -4297,6 +4309,13 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the amount of charges restored."); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addot(OT_S_SPIKEVOLLEY, "spike volley", "Fires a volley of iron spikes, dealing 3 damage plus 1d3 per spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l5 addot(OT_S_DETONATEDELAY, "delayed detonation", "Causes a given area to explode after a short delay.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); @@ -6746,6 +6765,13 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); + addot(OT_WHIPATTACK, "whipattack", "whip object", MT_BONE, 0, OC_WEAPON, SZ_TINY); + addflag(lastot->flags, F_DAM, DT_SLASH, 2, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_BASH, NA, NA, "1d3"); + addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); + addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_ELECTRIC, 2, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); @@ -6821,7 +6847,7 @@ void initobjects(void) { addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_MISSILEDAM, 1, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "1"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); @@ -6832,21 +6858,23 @@ void initobjects(void) { addot(OT_DARTNANO, "nanodart", "A metal dart with a nanofibre point. Capable of piercing most armour.", MT_METAL, 0.5, OC_MISSILE, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_MISSILEDAM, 1, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "2"); addflag(lastot->flags, F_ARMOURPIERCE, 10, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 67, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEALWAYSDIES, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addot(OT_DARTTRANQ, "tranquiliser dart", "A metal dart coated with a strong sleep-inducing serum.", MT_METAL, 0.5, OC_MISSILE, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "0"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 4, NA, NULL); + addflag(lastot->flags, F_MISSILEALWAYSDIES, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HITCONFER, F_ASLEEP, SC_CON, 27, "20-30"); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, ST_ASLEEP, NA, NULL); @@ -6854,7 +6882,7 @@ void initobjects(void) { addot(OT_MANRIKI, "manriki", "A pair of weights on the end of a metal chain, designed to entangle those at whom it is thrown.", MT_METAL, 0.1, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "0"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_TANGLEMISSILE, 26, 21, B_FALSE, NULL); @@ -6862,17 +6890,18 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "It makes sewing easier."); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_MISSILEDAM, 1, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "1"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 25, NA, NULL); + addflag(lastot->flags, F_MISSILEALWAYSDIES, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addot(OT_NET, "throwing net", "A grid of strong cords, weighted at the edges. Made for throwing over a target.", MT_CLOTH, 2, OC_MISSILE, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "0"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 2, NA, NULL); @@ -6884,7 +6913,7 @@ void initobjects(void) { addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 4, OC_MISSILE, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "3"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 90, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 2, NA, ""); @@ -6897,6 +6926,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_CAVE, 85, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "3"); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); @@ -6907,6 +6937,7 @@ void initobjects(void) { addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 80, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "4"); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); @@ -6920,6 +6951,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "4"); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 10, NA, NULL); @@ -6929,6 +6961,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "1"); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); @@ -6936,12 +6969,19 @@ void initobjects(void) { addot(OT_SHURIKEN, "shuriken", "A sharpened star-shaped piece of metal, made for throwing.", MT_METAL, 1, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_MISSILEDAM, 4, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "4"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); + addflag(lastot->flags, F_MISSILEALWAYSDIES, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL); + // special object for spiekvolley spell + addot(OT_SPIKEVOLLEY, "volley of spikes", "A large group of spikes moving at high speed.", MT_METAL, 1, OC_MISSILE, SZ_SMALL); + addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "4d3"); + addflag(lastot->flags, F_MISSILEALWAYSDIES, B_TRUE, NA, NA, NULL); + // MELEE WEAPONS / melee weapons // axes addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); @@ -6983,7 +7023,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURPIERCE, 4, NA, NA, ""); addflag(lastot->flags, F_DAM, DT_CHOP, 7, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); - addflag(lastot->flags, F_MISSILEDAM, 5, NA, NA, NULL); + addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "5"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 35, 55, "5"); @@ -7008,6 +7048,67 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 55, 75, "10"); + // whips + addot(OT_WHIPBULL, "bullwhip", "A long, heavy leather whip.", MT_LEATHER, 5, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_SLASH, 3, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_BASH, B_TRUE, NA, "1d3"); + addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_SNATCH, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_S_SUCK, NA, "range:2;pw:1;"); + addflag(lastot->flags, F_ATTREQ, A_AGI, 40, 60, "5"); + addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); + addot(OT_WHIPMT, "steel-tipped whip", "A leather whip with a sharp metal end.", MT_LEATHER, 6, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_SLASH, 4, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_BASH, B_TRUE, NA, "1d3"); + addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_AGI, 40, 60, "5"); + addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_SNATCH, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_S_SUCK, NA, "range:2;pw:1;"); + + addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_BASH, 7, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_SLASH, B_TRUE, NA, "1d2"); + addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_AGI, 50, 70, "5"); + addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); + addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); + + addot(OT_WHIPBARBED, "barbed whip", "A long leather whip with a spiked metal end.", MT_LEATHER, 6, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_SLASH, 4, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_BASH, B_TRUE, NA, "1d3"); + addflag(lastot->flags, F_EXTRADAM, DT_PIERCE, B_TRUE, NA, "1d3"); + addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_STR, 40, 60, "5"); + addflag(lastot->flags, F_ATTREQ, A_AGI, 40, 60, "5"); + addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_SNATCH, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_S_SUCK, NA, "range:2;pw:1;"); + + addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_BASH, 7, NA, NULL); + addflag(lastot->flags, F_EXTRADAM, DT_SLASH, B_TRUE, NA, "1d4"); + addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_STR, 65, 75, "10"); + addflag(lastot->flags, F_ATTREQ, A_AGI, 50, NA, "5"); + addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); + addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); + // short blades addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); @@ -7588,27 +7689,6 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 50, 60, "10"); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL); - addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); - addflag(lastot->flags, F_RARITY, H_CAVE, 75, NA, NULL); - addflag(lastot->flags, F_DAM, DT_BASH, 8, NA, NULL); - addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); - addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); - addflag(lastot->flags, F_ATTREQ, A_STR, 50, 60, "10"); - addflag(lastot->flags, F_ATTREQ, A_AGI, 50, 70, "5"); - addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); - addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); - addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); - addflag(lastot->flags, F_RARITY, H_CAVE, 75, NA, NULL); - addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL); - addflag(lastot->flags, F_DAM, DT_BASH, 10, NA, NULL); - addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); - addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); - addflag(lastot->flags, F_ATTREQ, A_STR, 70, 80, "10"); - addflag(lastot->flags, F_ATTREQ, A_AGI, 50, NA, "5"); - addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); - addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL); addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 50, NA, NULL); @@ -8413,7 +8493,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL); - addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_HEAVENARM, 6, NA, NA, "force field"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -8437,7 +8517,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL); - addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, 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_STR, AT_GTAVERAGE, NA, NULL); @@ -8466,7 +8546,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_WIS, AT_VLOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL); addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL); - addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, B_TRUE, NULL); addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -8515,7 +8595,7 @@ void initrace(void) { addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); - addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, NULL); + addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, "Your money or your life!"); addflag(lastrace->flags, F_STARTATT, A_STR, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_RANDOM, NA, NULL); @@ -8554,7 +8634,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); - addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, NULL); + addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, "Hand over all your gold!"); 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, 3, NA, NA, NULL); @@ -9162,10 +9242,39 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_EXPERT, 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_CASTCHANCE, 50, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addrace(R_BOGGART, "bogle", 15, 'n', C_BROWN, MT_WOOD, RC_MAGIC, "An evil household fairy made of wood. They delight in sowing disease and misfortune."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 3, 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_CANCAST, OT_S_TWIDDLE, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANCAST, OT_S_INSTANTDISROBE, 3, 3, "pw:1;"); + addflag(lastrace->flags, F_CANCAST, OT_S_BLIGHT, 2, 2, "pw:1;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures"); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL); + addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_AVOIDOBTYPE, OT_SALT, B_TRUE, NA, NULL); + addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, "Give me gold!"); + addrace(R_BUGBEAR, "bugbear", 120, 'G', C_BROWN, MT_FLESH, RC_HUMANOID, "A huge goblinoid creature, similar to a hobgoblin but larger again, with a temperament to match."); setbodytype(lastrace, BT_HUMANOID); setbodypartname(lastrace, BP_HANDS, "paws"); @@ -9235,7 +9344,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "lance"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-20 gold coins"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); - addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 9, NA, NA, NULL); addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -9268,7 +9377,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_PETRIFY, B_TRUE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTIMMUNE, DT_PETRIFY, NA, "50"); // special attack handled in attack.c @@ -9333,7 +9442,6 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "0d6+5"); 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); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_NIGHTVISRANGEMOD, 1, NA, "75"); @@ -9489,7 +9597,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addrace(R_TRICLOPS, "triclops", 160, 'H', C_BROWN, MT_FLESH, RC_HUMANOID, "The three-eyes triclops race are blessed with extraordiny perceptive and are nearly impossible to surprise. They commonly use their third eye to stun enemies, then finish them off with their huge weapons."); @@ -9539,6 +9647,8 @@ void initrace(void) { setbodypartname(lastrace, BP_FEET, "roots"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "tree"); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "stick"); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "leaf"); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -9580,6 +9690,8 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "stick"); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "leaf"); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL); addflag(lastrace->flags, F_TR, 9, NA, NA, NULL); @@ -9619,6 +9731,8 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, 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_BLOODOB, NA, NA, NA, "stick"); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "leaf"); addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL); addflag(lastrace->flags, F_TR, 11, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL); @@ -9768,45 +9882,6 @@ void initrace(void) { addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "50"); - addrace(R_GIANTFIRETITAN, "flame titan", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID, "The ultimate evolutionary form of a flame giant. Flame titans tower over even the largest of regular giants and can generate massive amounts of raging flame at will."); - setbodytype(lastrace, BT_HUMANOID); - addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, 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, 17, NA, NA, NULL); - addflag(lastrace->flags, F_TR, 14, NA, NA, NULL); - 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); - addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 18, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "100-300 gold coins"); - f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword of pyromania"); - addcondition(f, FC_NOCONDITION, 65); - addaltval(f, F_STARTOB, 100, NA, NA, "flaming greatsword"); - addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_WIS, AT_RANDOM, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); - addflag(lastrace->flags, F_NOISETEXT, N_WALK, 3, NA, "^crackling flames."); - addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); - addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_CANCAST, OT_S_BURNINGWAVE, 3, 3, "pw:6;"); - addflag(lastrace->flags, F_RNDSPELLCOUNT, 3, NA, NA, NULL); - addflag(lastrace->flags, F_RNDSPELLSCHOOL, SS_FIRE, 1, 5, "pw:6;"); - addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); - addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); - addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "75"); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "100"); // TODO: storm giant // TODO: storm titan @@ -9880,7 +9955,9 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold coins"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "sling"); - addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_SHORTBLADES, NA, NULL); + f = addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_SHORTBLADES, NA, NULL); + addcondition(f, FC_NOCONDITION, 90); + addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 40, OC_POTION, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL); @@ -10260,7 +10337,9 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTOBWEPSK, 80, SK_LONGBLADES, NA, NULL); + f = addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_LONGBLADES, NA, NULL); + addcondition(f, FC_NOCONDITION, 80); + addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler"); addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins"); @@ -10302,7 +10381,9 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_CLUBS, NA, NULL); + f = addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_CLUBS, NA, NULL); + addcondition(f, FC_NOCONDITION, 80); + addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-75 gold coins"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "large shield"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "scale armour"); @@ -10426,6 +10507,34 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_EXTRALUCK, 1, NA, "25"); + addrace(R_LESHY, "leshy", 35, 'h', C_GREEN, MT_PLANT, RC_HUMANOID, "Human-like figures with leaves (and the occasional fruit) covering their bodies."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "splash of blood"); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "leaf"); + addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_EXTRACORPSE, 100, NA, NA, "10-20 leaves"); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_FAST, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL); + addflag(lastrace->flags, F_STARTOB, 66, NA, NA, "1-3 apples"); + addflag(lastrace->flags, F_STARTOB, 66, NA, NA, "banana"); + addflag(lastrace->flags, F_STARTOB, 66, NA, NA, "passionfruit"); + addflag(lastrace->flags, F_STARTOB, 66, NA, NA, "5-10 berries"); + addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL); + addrace(R_LIZARDMAN, "lizardman", 100, 'z', C_GREEN, MT_LEATHER, RC_HUMANOID, "Lizardmen are as they sound - a cross between a human and a lizard. Their leathery skin helps protect them from pummeling blows, and their tails give them enhanced stability."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_TAIL, NULL); @@ -10499,6 +10608,43 @@ void initrace(void) { addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); + addrace(R_MANTICORE, "manticore", 80, 'm', C_RED, MT_FLESH, RC_MAGIC, "Horrific beasts with the body of a lion, bat-like winds and a human head. The tip of their tail contains a mass of iron spikes."); + setbodytype(lastrace, BT_QUADRAPED); + addbodypart(lastrace, BP_TAIL, NULL); + addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, 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_RARITY, H_DUNGEON, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); + addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CASTCHANCE, 90, NA, NA, NULL); // will nearly always use its spikes first. + addflag(lastrace->flags, F_CANWILL, OT_S_SPIKEVOLLEY, 30, 30, "pw:4;range:4;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_SPIKEVOLLEY, NA, B_APPENDYOU, "aims its tail"); + addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); + addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screams in pain^screams of pain"); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); + addflag(lastrace->flags, F_WANTS, F_EDIBLE, NA, NA, NULL); + addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, NA, NA, NULL); + addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); + addrace(R_MINOTAUR, "minotaur", 130, 'H', C_BROWN, MT_FLESH, RC_HUMANOID, "Legendary creatures with the head of a bull, with a strength and temperament to match."); setbodytype(lastrace, BT_HUMANOID); noarmouron(lastrace, BP_HEAD); @@ -10570,7 +10716,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MINIONS, 50, 1, 5, "orc"); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_WIZARD, SJ_RANDOM, NULL); @@ -10610,7 +10756,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_THROWING, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RESISTMAG, 25, NA, NA, NULL); @@ -10650,7 +10795,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 17, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_WIZARD, SJ_RANDOM, NULL); @@ -10688,7 +10833,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-100 gold coins"); addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); addflag(lastrace->flags, F_MINIONS, 25, 1, 8, "orc"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -10733,7 +10878,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 25, J_WARRIOR, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 25, J_GUARD, NA, NULL); @@ -10776,7 +10921,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 13, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_DEMONOLOGIST, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_SHAMAN, NA, NULL); @@ -10808,7 +10953,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 13, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addrace(R_ORK, "ork", 90, 'o', C_GREEN, MT_FLESH, RC_HUMANOID, "Orcs who have become fascinated with technology tend to become shunned by their peers, and have taken the name 'Orks' for themselves."); setbodytype(lastrace, BT_HUMANOID); @@ -10875,7 +11020,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 16, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 9, NA, NA, NULL); addrace(R_ORCGRAND, "grorc", 120, 'o', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Even more powerful than blood orcs, grand orcs (or 'grorcs') are both extremely rare and extremely powerful."); setbodytype(lastrace, BT_HUMANOID); @@ -10902,7 +11047,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addrace(R_CRYMIDIA, "crymidia", 10, 'e', C_WHITE, MT_ICE, RC_MAGIC, "A floating crystalline form, a crymidia is formed when a mass of crystal becomes sentient."); @@ -10972,7 +11117,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANCAST, OT_S_SMITEEVIL, NA, NA, "pw:8;"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_RESISTMAG, 5, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 25, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); @@ -11012,7 +11157,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_RANGED, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RESISTMAG, 25, NA, NA, NULL); @@ -11074,7 +11218,7 @@ void initrace(void) { addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "small fire"); addflag(lastrace->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 6, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_PYROMANIA, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEBURST, NA, NA, "pw:10;"); @@ -11105,7 +11249,7 @@ void initrace(void) { addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "small fire"); addflag(lastrace->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 2, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_PYROMANIA, NA, NA, "pw:1;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "burns brightly"); @@ -11135,7 +11279,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 16, NA, NULL); addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); @@ -11161,7 +11305,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 12, NA, NULL); addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); @@ -11191,7 +11335,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_AIRFISTS, 5, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 5, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WINDSHIELD, 20, NA, NA, NULL); addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_CHAINLIGHTNING, NA, NA, "pw:2;"); @@ -11225,7 +11369,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_AIRFISTS, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 2, NA, NULL); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WINDSHIELD, 20, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_LIGHTNINGBOLT, NA, NA, "pw:2;"); addflag(lastrace->flags, F_CANCAST, OT_S_SLEETSTORM, 15, 15, "pw:4;"); @@ -11351,14 +11495,14 @@ void initrace(void) { addflag(lastrace->flags, F_NEEDOBFORSPELLS, OT_PANPIPES, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, NA, NA, NULL); - addflag(lastrace->flags, F_CANCAST, OT_S_FEAR, NA, NA, NULL); + addflag(lastrace->flags, F_CANCAST, OT_S_FEAR, 15, 15, "pw:1;"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_MENTAL, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL); addflag(lastrace->flags, F_STARTHIDDENPCT, 60, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addrace(R_SKOOB, "skoob", 40, 'g', C_WHITE, MT_ICE, RC_MAGIC, "Your typical snowman right down to the carrot nose, with just a two key differences: it is alive, and it is homocidal."); @@ -11387,7 +11531,6 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); @@ -11443,7 +11586,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_DRILL, 5, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_DIG, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "pounds its drills into the ground"); @@ -11485,7 +11627,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERARM, B_TRUE, NA, NA, NULL); @@ -11526,7 +11668,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "25"); @@ -11565,7 +11706,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); @@ -11606,7 +11746,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "25"); @@ -11642,7 +11781,6 @@ void initrace(void) { addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_WILD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); @@ -11674,7 +11812,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -11711,7 +11849,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -11744,7 +11882,7 @@ void initrace(void) { addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); @@ -11784,7 +11922,7 @@ void initrace(void) { addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); @@ -11813,7 +11951,6 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "snorts^a snort"); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // fish @@ -11840,7 +11977,6 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addrace(R_FISHFOLK, "fishfolk", 75, 'h', C_BOLDBLUE, MT_FLESH, RC_HUMANOID, "Water-dwelling humanoids capable of breathing normally in both water and air."); setbodytype(lastrace, BT_HUMANOID); @@ -11905,7 +12041,6 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SONICBOLT, 4, 4, "pw:5;dam:2d6;"); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 2, NA, "^gurgling"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "gurgles loudly^a loud gurgle"); - addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100"); @@ -11932,7 +12067,6 @@ void initrace(void) { addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); - addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addrace(R_PIRANHAKING, "king piranha", 1, ';', C_GREEN, MT_FLESH, RC_AQUATIC, "A larger version of a standard piranha. King piranhas can leap through the air."); setbodytype(lastrace, BT_FISH); @@ -11958,7 +12092,6 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addrace(R_EELELEC, "electric eel", 120, ';', C_CYAN, MT_FLESH, RC_AQUATIC, "A sliippery eel charged with electricity."); setbodytype(lastrace, BT_FISH); @@ -11982,7 +12115,6 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 6, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_ELECTRIC, NA, "50"); addrace(R_EELGIANT, "giant eel", 150, ';', C_BLUE, MT_FLESH, RC_AQUATIC, "A very long, slippery eel. They tend to catch and crush their prey."); @@ -12008,13 +12140,65 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, 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;"); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); // plants + addrace(R_BINGEBARK, "bingebark", 30, 'T', C_RED, MT_WOOD, RC_PLANT, "A dry, withered tree with many leafless branches, its dead bark stained by blood."); + addbodypart(lastrace, BP_BODY, "trunk"); + addbodypart(lastrace, BP_HANDS, "branches"); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "stick"); + addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_WHIPATTACK, 6, NA, NULL); + addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANWILL, OT_S_SUCK, NA, NA, "pw:1;range:2;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "extends its branches"); + + addrace(R_BRIARTHRASH, "briar thrash", 30, 'T', C_YELLOW, MT_PLANT, RC_PLANT, "A stringy mass of upright, thorny vines."); + addbodypart(lastrace, BP_BODY, "vines"); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); + addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "thorns"); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_WHIPATTACK, 6, NA, NULL); + addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:1d4;"); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addrace(R_CACTUS, "cactus", 30, 'F', C_BOLDGREEN, MT_PLANT, RC_PLANT, "A wide upright plant coated with sharp spines. Said to sprout delicious fruit."); addbodypart(lastrace, BP_BODY, "stalk"); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); @@ -12028,7 +12212,7 @@ void initrace(void) { addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); @@ -12039,6 +12223,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); @@ -12061,6 +12246,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); @@ -12085,6 +12271,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_EXLOW, NA, NULL); @@ -12116,6 +12303,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -12141,6 +12329,7 @@ void initrace(void) { addbodypart(lastrace, BP_BODY, "stalk"); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); @@ -12168,6 +12357,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); @@ -12216,7 +12406,6 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 2, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); addrace(R_BATMUTATED, "mutated bat", 3, 'B', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Bats exposed to toxic radiation become mutated, and their sonic navigation skills turn deadly."); setbodytype(lastrace, BT_BIRD); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); @@ -12566,7 +12755,6 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "Giant ants are enormous (for an ant, anyway), and keen to take avenge their smaller ancestors who were crushed by small children."); @@ -12597,7 +12785,7 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addrace(R_ANTS, "giant soldier ant", 25, 'a', C_RED, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_ANT; @@ -12629,7 +12817,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_MINIONS, 50, 2, 3, "giant ant"); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addrace(R_ANTLION, "giant antlion", 30, 'a', C_YELLOW, MT_FLESH, RC_ANIMAL, "Antlions are mammoth giant ants with the head of a lion."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_ANT; @@ -12658,7 +12846,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // note: queen and does NOT have baseid ant. this is so that ant nests will only @@ -12689,7 +12877,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -12888,7 +13076,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 2, NA, "growls^growling"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_ADEPT, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 40, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -12917,7 +13105,6 @@ void initrace(void) { addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_FLEEONHPPCT, 80, NA, NA, ""); - addflag(lastrace->flags, F_MORALE, 1, NA, NA, NULL); addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL); addrace(R_FROG, "impaler frog", 10, ';', C_BOLDGREEN, MT_FLESH, RC_ANIMAL, "As their name implies, impaler frogs are dangerous frogs whose tongues end in a very sharp point. They use this to spear their enemies from afar, often while hiding underwater."); @@ -12983,7 +13170,6 @@ void initrace(void) { addflag(lastrace->flags, F_LEVRACE, 4, R_HAWK, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 30, NA, NA, NULL); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -13146,7 +13332,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 8, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "screeches"); - addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 13, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); @@ -13187,7 +13373,6 @@ void initrace(void) { addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "slither"); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addrace(R_MAMMOTH, "mammoth", 6000, 'Q', C_BROWN, MT_LEATHER, RC_ANIMAL, "A massive ancenstor of the elephant, mammoths are covered with fur, slightly larger and more dangerous."); setbodytype(lastrace, BT_QUADRAPED); @@ -13220,7 +13405,6 @@ void initrace(void) { addflag(lastrace->flags, F_VISRANGEMOD, -2, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_SONIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addrace(R_NEWT, "giant newt", 4, ':', C_BROWN, MT_FLESH, RC_ANIMAL, "An abnormally large example of the lizard family."); setbodytype(lastrace, BT_QUADRAPED); @@ -13248,7 +13432,6 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_COLD, B_TRUE, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addrace(R_PORCUPINE, "giant porcupine", 10, 'r', C_GREY, MT_FLESH, RC_ANIMAL, "A large four legged creature covered with sharp spines."); setbodytype(lastrace, BT_QUADRAPED); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -13271,7 +13454,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp spines"); addflag(lastrace->flags, F_CORPSEFLAG, F_SHARP, 1, 4, NULL); - addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL, "An aggressive rodent, approximately the size of a cat."); setbodytype(lastrace, BT_QUADRAPED); @@ -13299,7 +13481,6 @@ void initrace(void) { addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_RATDIRE, "dire rat", 3, 'r', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Dire rats are massive rats, larger than most dogs. Unlike dogs, dire rats are equipped with razor sharp shark-like teeth and their bite is very much worse than their bark."); @@ -13334,6 +13515,7 @@ void initrace(void) { addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); + addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -13359,7 +13541,6 @@ void initrace(void) { addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 1, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian @@ -13388,7 +13569,6 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 8, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "screeches"); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 5, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); @@ -13885,7 +14065,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_FLEEONHPPCT, 75, NA, NA, ""); addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); - addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -13920,7 +14099,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); - addflag(lastrace->flags, F_MORALE, 7, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); @@ -13990,7 +14169,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); - addflag(lastrace->flags, F_MORALE, 11, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_COLDRAY, 10, 10, "pw:2;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "unleashes its icy breath"); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); @@ -14032,7 +14210,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); - addflag(lastrace->flags, F_MORALE, 11, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -14062,7 +14239,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "opens its mouth wide.."); addflag(lastrace->flags, F_NOISETEXT, N_WALK, SV_CAR, NA, "^slithering"); addflag(lastrace->flags, F_FLEEONHPPCT, 20, NA, NA, ""); - addflag(lastrace->flags, F_MORALE, 50, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // end animals @@ -14256,7 +14433,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLOOD, NA, NA, "discharges electricity into the ground"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FEAR, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); @@ -14409,7 +14586,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PYROMANIA, NA, NA, "flaps its wings"); addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); @@ -14558,7 +14735,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_WALLOFICE, NA, NA, "breaths a line of frost along the ground"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_HAILSTORM, NA, NA, "breaths out a blast of hailstones"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); @@ -14587,7 +14764,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "snorts^a snort"); addflag(lastrace->flags, F_DTIMMUNE, DT_EXPLOSIVE, NA, NA, NULL); addflag(lastrace->flags, F_CORPSEFLAG, F_EXPLODEONDEATH, NA, 2, "32d2"); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_STONE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_DETONATEDELAY, 20, 20, "pw:1;range:3;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "vibrates"); @@ -14718,7 +14894,6 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:1d1;"); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); @@ -14775,7 +14950,6 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 3, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "flares its flames^crackling flames"); addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 2, DT_FIRE, NA, NULL); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "10"); addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies."); @@ -14843,7 +15017,48 @@ void initrace(void) { addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CORPSEFLAG, F_STENCH, 1, 3, NULL); + // demons + addrace(R_BALROG, "balrog", 300, '&', C_ORANGE, MT_FLESH, RC_DEMON, "Towering winged humanoids with bright red skin, surrounded by a roaring inferno."); + setbodytype(lastrace, BT_HUMANOID); + addbodypart(lastrace, BP_TAIL, NULL); + addbodypart(lastrace, BP_WINGS, NULL); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_HEAVEN, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, 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, 13, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 13, NA, NA, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 10, 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_STR, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 12, NA, NULL); + addflag(lastrace->flags, F_SEEINDARK, 10, 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_DTVULN, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_CANCAST, OT_S_SUCK, NA, NA, "pw:6;"); + addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEBURST, NA, NA, "pw:10;"); + addflag(lastrace->flags, F_CANCAST, OT_S_FEAR, 30, 30, "pw:6;"); + addflag(lastrace->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, "pw:2;"); + addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONDEMON, 20, 20, "pw:3;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "flares its flames"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_SUCK, NA, B_APPENDYOU, "cracks its flaming whip"); + addflag(lastrace->flags, F_AUTOCREATEOB, 1, NA, NA, "large fire"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming bastard sword"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming barbed whip"); + addflag(lastrace->flags, F_RESISTMAG, 10, NA, NA, NULL); + + addrace(R_DRETCH, "dretch", 30, '&', C_BROWN, MT_FLESH, RC_DEMON, "An ape-like creature with extended forearms ending in clawed hands. They stand about 4 feet tall and weigh 60 pounds."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_TAIL, NULL); @@ -14902,7 +15117,8 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 10, 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_DTVULN, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, NULL); addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_HEATMETAL, 5, 5, "pw:1;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "waves its trident"); @@ -14985,7 +15201,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screech"); - addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); @@ -15234,12 +15450,12 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_LEVITATION, 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_NOISETEXT, N_SONICBOLT, 4, NA, "screams!^an otherworld scream!"); + addflag(lastrace->flags, F_NOISETEXT, N_SONICBOLT, 4, NA, "screams!^an otherworldly scream!"); addflag(lastrace->flags, F_CANWILL, OT_A_SONICBOLT, 3, 3, "pw:4;dam:1d7;"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_EXTRADAM, DT_FIRE, NA, NA, "1d4"); addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); @@ -15579,7 +15795,7 @@ void initrace(void) { //addflag(lastrace->flags, F_CANCAST, OT_S_SMITEEVIL, NA, NA, "pw:8;"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_RESISTMAG, 10, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 25, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); @@ -15682,7 +15898,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addrace(R_WERERAT, "wererat", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Weedy humans with shifty eyes and whiskers, wererats are known for their extreme cunning."); @@ -15722,7 +15938,6 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addrace(R_WEREWOLF, "werewolf", 100, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Shaggy humans with the uncanny ability to shapeshift into a ferocious wolf."); setbodytype(lastrace, BT_HUMANOID); @@ -15759,7 +15974,7 @@ void initrace(void) { addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); // ie. cats will know! addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); // special monsters addrace(R_GASCLOUD, "cloud of gas", 0.1, 'y', C_GREY, MT_GAS, RC_OTHER, "A large cloud of gas which seems to move with a life of its own..."); @@ -15914,6 +16129,7 @@ void initrace(void) { addflag(r->flags, F_MATVULN, MT_SILVER, 200, NA, NULL); addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_GOD) { addflag(r->flags, F_PIETY, 100, NA, NA, NULL); addflag(r->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -15954,7 +16170,7 @@ void initrace(void) { addflag(r->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(r->flags, F_DTVULN, DT_WATER, NA, NA, NULL); addflag(r->flags, F_CORPSETYPE, NA, NA, NA, "unstable power core"); - addflag(r->flags, F_MORALE, 40, NA, NA, NULL); + addflag(r->flags, F_MORALE, 30, NA, NA, NULL); addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); if (!hasflagval(r->flags, F_NOISETEXT, N_WALK, NA, NA, NULL)) { addflag(r->flags, F_NOISETEXT, N_WALK, 2, NA, "^whirring"); @@ -16090,6 +16306,7 @@ void initskills(void) { addskilldesc(SK_FIRSTAID, PR_INEPT, "- Determines how long poison effects will last.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_NOVICE, "+2 hit points per level.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_BEGINNER, "+4 hit points per level.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_BEGINNER, "You now notice the onset of poison.", B_TRUE); addskilldesc(SK_FIRSTAID, PR_ADEPT, "+6 hit points per level.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_ADEPT, "^gYou can now recognise when poison is potentially fatal.^n", B_TRUE); addskilldesc(SK_FIRSTAID, PR_SKILLED, "+8 hit points per level.", B_FALSE); @@ -16217,6 +16434,7 @@ void initskills(void) { addskill(SK_POLEARMS, "Polearms", "Helps you use long bladed weapons like halberds.", 50); addskill(SK_SHORTBLADES, "Short Blades", "Helps you use daggers, gladius', etc.", 50); addskill(SK_STAVES, "Staves", "Helps you use quarterstaffs, staffs, etc.", 50); + addskill(SK_WHIPS, "Whips", "Helps you use whips, flails, etc.", 50); addskill(SK_UNARMED, "Unarmed Combat", "Helps you fight using your bare hands.", 50); free(lastskill->shortname); lastskill->shortname = strdup("Unarmed"); addskilldesc(SK_UNARMED, PR_ADEPT, "^gYour unarmed attacks can now smash wooden objects.^n", B_TRUE); diff --git a/data/hiscores.db b/data/hiscores.db index 4d0a84c..96e30a7 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index b1e36cb..c5b0895 100644 --- a/defs.h +++ b/defs.h @@ -173,6 +173,10 @@ #define B_SHOWALL (-1) #define B_NOSHOWALL (0) +// for real_getlfname +#define B_REALRACE (-1) +#define B_CURRACE (0) + // Limits @@ -620,6 +624,7 @@ enum SKILL { SK_SHORTBLADES, SK_STAVES, SK_UNARMED, + SK_WHIPS, // spell schools SK_SS_ALLOMANCY, SK_SS_MENTAL, @@ -635,7 +640,7 @@ enum SKILL { SK_SS_TRANSLOCATION, SK_SS_WILD, }; -#define MAXSKILLS 52 +#define MAXSKILLS 53 // proficiency levels enum SKILLLEVEL { @@ -993,6 +998,7 @@ enum RACE { R_GODMAGIC, // lumara // monsters R_BEHOLDER, + R_BOGGART, R_BUGBEAR, R_CENTAUR, R_COCKATRICE, @@ -1006,7 +1012,6 @@ enum RACE { R_GIANTHILL, R_GIANTFIRE, R_GIANTFIREFC, - R_GIANTFIRETITAN, R_GNOLL, R_GOBLIN, R_GOBLINR, @@ -1022,9 +1027,11 @@ enum RACE { R_HOBGOBLINWAR, R_KOBOLD, R_LEPRECHAUN, + R_LESHY, R_LAVAX, R_LIZARDMAN, R_MALIK, + R_MANTICORE, R_MINOTAUR, R_NAIAD, R_NIXIE, @@ -1082,6 +1089,8 @@ enum RACE { R_EELELEC, R_EELGIANT, // plants + R_BINGEBARK, + R_BRIARTHRASH, R_CACTUS, R_IVYRAPID, R_FUNGUSDREAM, @@ -1169,6 +1178,7 @@ enum RACE { R_STINKBUG, R_STIRGE, // demons + R_BALROG, R_DRETCH, R_GRIDDLER, R_LURKINGHORROR, @@ -1712,6 +1722,7 @@ enum OBTYPE { OT_S_FLASH, OT_S_NULLIFY, OT_S_REPLENISH, + OT_S_SPIKEVOLLEY, // -- divine powers OT_S_CREATEVAULT, OT_S_GIFT, @@ -2048,6 +2059,7 @@ enum OBTYPE { OT_TENTACLE, OT_TRAMPLE, OT_TONGUE, + OT_WHIPATTACK, OT_ZAPPER, // monster weapons OT_ACIDATTACK, @@ -2072,6 +2084,7 @@ enum OBTYPE { OT_BULLET, OT_RUBBERBULLET, OT_SHURIKEN, + OT_SPIKEVOLLEY, // axes OT_AXE, OT_HANDAXE, @@ -2132,10 +2145,14 @@ enum OBTYPE { OT_WIZARDSTAFF4, OT_WIZARDSTAFF5, OT_WIZARDSTAFF6, - // clubs - OT_CLUB, + // whips + OT_WHIPBARBED, + OT_WHIPBULL, + OT_WHIPMT, OT_FLAIL, OT_FLAILHEAVY, + // clubs + OT_CLUB, OT_GREATCLUB, OT_MACE, OT_MORNINGSTAR, @@ -2656,6 +2673,7 @@ enum FLAG { F_OBATTACKDELAY, // how long weapon takes to attack F_USESSKILL, // weapon needs skill sk_v0 F_MAGICBOOST, // boost power of all spells by v0 + F_WHIP, // this weapon is a whip - use different damtext. F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied // optional: v1 is chance of randomly having it F_ATTREQ, // requires attrib v0 to be at least v1 @@ -2680,7 +2698,8 @@ enum FLAG { // (add this flag multiple times for each damtype, // and remember to include the one listed in its // F_DAM) - F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier) + F_MISSILEDAM, // text = dam if it hits (without speed multiplier) + F_MISSILEALWAYSDIES, // this object will always be destroyed when thrown F_TANGLEMISSILE, // this object will trip anyone it is thrown at // (if it hits), unless they pass a SC_SLIP // check of difficulty v0 @@ -3317,7 +3336,9 @@ enum FLAG { F_DRUNK, // v0 is drunknness - 1-5. F_ENHANCESEARCH, // gives v0 bonus on search checks. F_ENHANCESMELL, // can 'see' scents with v0 range. - F_EXTRADAM, // do 'text' extra damage of damtype v0 when you hit + F_EXTRADAM, // FOR LIFEFORMS OR WEAPONS! + // this lf does 'text' extra damage of damtype v0 + // when they hit // if v1 is TRUE, also deal extra damage based on // the flagpile's F_BONUS flag. F_EXTRAINFO, // knows extra info @@ -3332,6 +3353,14 @@ enum FLAG { // v0 is multiplier. F_FASTMOVE, // modifier for move speed F_FASTACTMOVE, // modifier for action and move speed + F_INCUBATING, // will become poisoned when v1 drops to 0. + // ie obfrom is being used as a timer. + // v0 = poison thpe + // v1 = invubation time left + // v2 = howlong + // obfrom = if you ate a corpse, this records its race + // otherwise, NA. + // text = power^fromwhat .eg'a bad egg' F_POISONED, // has poisoning. v0 = poison type, // v1 = power // v2 = if you ate a corpse, this records its race @@ -3948,6 +3977,7 @@ typedef struct poisontype_s { enum OBTYPE vomitob; int dam; int dampct; + int incubationtime; enum POISONSEVERITY severity; struct poisontype_s *next, *prev; } poisontype_t; diff --git a/god.c b/god.c index 7894451..4dd2c07 100644 --- a/god.c +++ b/god.c @@ -222,7 +222,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { break; case R_GODFIRE: msg("\"Fire will burn away your sins!\""); - dospelleffects(NULL, OT_S_FLAMEPILLAR, 4, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_FLAMEPILLAR, 4, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); break; case R_GODLIFE: msg("\"Your body shall be slow to recover from wounds...\""); @@ -246,7 +246,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { break; case R_GODNATURE: msg("\"You have transgressed against nature!\""); - dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); // note: you will also rot food on touch until god is appeased. // see touch(). break; @@ -279,7 +279,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { } else { // don't have any blessed objects. msg("\"Perhaps you need some time without material wealth...\""); - dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, player->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, player->cell, B_UNCURSED, NULL, B_TRUE, NULL); } break; case R_GODTHIEVES: @@ -317,7 +317,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { case 2: // bad armour msg("\"A fool deserves a fool's armour!\""); // remove all player's armour - dospelleffects(god, OT_S_INSTANTDISROBE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(god, OT_S_INSTANTDISROBE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); // give them cursed armour o = addob(player->pack, "cursed -5 cotton shirt"); if (o) { @@ -361,7 +361,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { break; case R_GODFIRE: msg("\"Burn, infidel!\""); - dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); getradiuscells(player->cell, 1, DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, retcell, &nretcells, 0); for (i = 0; i < nretcells; i++) { if (!retcell[i]->type->solid) { @@ -435,13 +435,13 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) { break; case R_GODNATURE: msg("\"You have violated the cardinal laws of nature!\""); - dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); switch (rnd(1,3)) { case 1: - dospelleffects(NULL, OT_S_CLOUDKILL, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_CLOUDKILL, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); break; case 2: - dospelleffects(NULL, OT_S_HAILSTORM, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_HAILSTORM, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL); break; case 3: msg("\"Destroy him, my pets!\""); @@ -622,7 +622,7 @@ void dooffer(void) { addobsinradius(player->cell, 1, DT_COMPASS, splatterob, B_TRUE, NULL); } if (god->race->id == R_GODFIRE) { - dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL); } } else { nothinghappens(); @@ -789,7 +789,7 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) { lifeform_t *god; char killedname[BUFLEN],godname[BUFLEN]; god = findgod(rid); - real_getlfname(god, godname, B_FALSE, B_FALSE); + real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE); strcpy(killedname, ""); if (!where) { // somewhere next to the player. @@ -1367,7 +1367,7 @@ void godsay(enum RACE rid, int says, char *format, ...) { va_end(args); god = findgod(rid); - real_getlfname(god, godname, B_FALSE, B_FALSE); + real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE); switch (rid) { case R_GODBATTLE: @@ -1608,7 +1608,7 @@ void pleasegod(enum RACE rid, int amt) { lifeform_t *lf; char lfname[BUFLEN]; lf = findgod(rid); - real_getlfname(lf, lfname, B_FALSE, B_FALSE); + real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_REALRACE); modpiety(rid, amt); @@ -1798,11 +1798,11 @@ int prayto(lifeform_t *lf, lifeform_t *god) { break; case 3: // msg("\"I will guide your blade!\""); - dospelleffects(god, OT_S_TRUESTRIKE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_TRUESTRIKE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); break; case 4: // msg("\"Your blows will be as lightning!\""); - dospelleffects(god, OT_S_HASTE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_HASTE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); break; } // end switch }// end while redo @@ -1822,7 +1822,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { for (o = lf->pack->first ; o ; o = o->next) { if (isequipped(o)) { if (isdamaged(o) || (getobbonus(o, B_FALSE) < 0)) { - dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE); + dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE, NULL); i++; } } @@ -1839,7 +1839,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { switch (rnd(1,2)) { case 1: // detect life msg("\"Seek out battle in my name!\""); - dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE, NULL); break; case 2: // bless weapon msg("\"Fight in my name!\""); @@ -1859,7 +1859,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { msg("\"Witness the holy radiance of purity!\""); c = getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND); if (c) { - dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE); + dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE, NULL); } // uncurse ALL equipped obs for (o = lf->pack->first ; o ; o = o->next) { @@ -1870,7 +1870,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { // cure poison if (ispoisoned(lf)) { - dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); } if (isinbattle(lf, B_TRUE)) { @@ -1922,7 +1922,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { // purify your food if (!donesomething) { - if (!dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE)) { + if (!dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL)) { donesomething = B_TRUE; } } @@ -1993,13 +1993,13 @@ int prayto(lifeform_t *lf, lifeform_t *god) { who->hp = 0; } else { //castspell(god, n, who, NULL, who->cell, NULL, NULL); - dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL); break; } } } } - dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); break; case R_GODFIRE: // restore frozen weapons @@ -2016,7 +2016,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (c && cellhaslos(c, player->cell)) { if (c->lf && (c->lf != player)) { dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, - c, B_BLESSED, NULL, B_TRUE); + c, B_BLESSED, NULL, B_TRUE, NULL); } else if (countnoncosmeticobs(c->obpile, B_FALSE, B_FALSE)) { addobfast(c->obpile, OT_FIRESMALL); i++; @@ -2035,7 +2035,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { donesomething = B_TRUE; } if (gethungerlevel(gethungerval(player)) >= H_PECKISH) { - dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL); donesomething = B_TRUE; } if (lf->mp < (getmaxmp(lf)/2)) { @@ -2053,7 +2053,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { } if (isinbattle(lf, B_TRUE)) { if (plev >= PL_INDIFFERENT) { - dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL); donesomething = B_TRUE; } } @@ -2065,7 +2065,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (!isblessed(o)) { blessob(o); } else if (!o->blessknown) { - dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE); + dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL); } } } @@ -2081,7 +2081,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (islowhp(lf)) { // teleport away msg("\"Nothing like a quick getaway!\""); - dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); donesomething = B_TRUE; } else { int redo = B_TRUE; @@ -2120,7 +2120,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (!donesomething) { // teleport away msg("\"Nothing like a quick getaway!\""); - dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); } } else { int redo = B_TRUE; @@ -2154,8 +2154,8 @@ int prayto(lifeform_t *lf, lifeform_t *god) { switch (rnd(1,2)) { case 1: msg("\"Allow me to reveal your surroundings...\""); - dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); - dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); + dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); break; case 2: // identify objects npossob = 0; @@ -2213,7 +2213,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (idnum) { msg("\"One is granted the favour of knowledge!\""); o = toid[rnd(0,idnum-1)]; - dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE); + dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL); } else if (uncursenum) { msg("\"One is granted the favour of redemption!\""); o = touncurse[rnd(0,uncursenum-1)]; @@ -2303,7 +2303,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { // entangle your enemies for (l = lf->cell->map->lf ; l ; l = l->next) { if ((l != lf) && areenemies(l, lf) && cansee(l, player)) { - dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE, NULL); } } break; @@ -2315,7 +2315,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { msg("\"The powers of the sky will smite your foes!\""); for (l = lf->cell->map->lf ; l ; l = l->next) { if ((l != lf) && areenemies(l, lf) && cansee(l, player)) { - dospelleffects(god, OT_S_CALLLIGHTNING, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(god, OT_S_CALLLIGHTNING, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE, NULL); } } break; @@ -2336,7 +2336,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { flag_t *f; // fix any poison potions - dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); if (ispoisoned(lf)) { msg("\"I will cure your poison...\""); @@ -2384,7 +2384,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { } if (nposs) { o = poss[rnd(0,nposs-1)]; - dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE); + dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE, NULL); donesomething = B_TRUE; } } diff --git a/io.c b/io.c index 81ad0af..48c32e1 100644 --- a/io.c +++ b/io.c @@ -1976,6 +1976,11 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { return B_FALSE; } + // dont announce loss of flags yoh didnt know about + if (!f->known) { + return B_FALSE; + } + if (isdead(lf) || isdead(player)) return B_FALSE; getlfname(lf, lfname); @@ -2261,6 +2266,15 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { case F_FRIENDLY: msg("%s no longer looks quite so friendly!", lfname); break; + case F_INCUBATING: + if (isplayer(lf)) { + poisontype_t *pt; + pt = findpoisontype(f->val[0]); + if (pt) { + msg("^%cYour body has fought off %s.", getlfcol(lf, CC_GOOD), pt->name); + } + } + break; case F_POISONED: msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; @@ -2764,7 +2778,7 @@ lifeform_t *askgod(char *prompttext, int onlyprayed) { continue; } - real_getlfname(lf, buf, B_FALSE, B_FALSE); + real_getlfname(lf, buf, NULL, B_NOSHOWALL, B_REALRACE); f = hasflag(lf->flags, F_GODOF); snprintf(godof, BUFLEN, " (%s of %s)", (f->val[0] == B_FEMALE) ? "goddess" : "god", f->text); strcat(buf, godof); @@ -3724,7 +3738,7 @@ void describegod(lifeform_t *god) { assert(god); f = hasflag(god->flags, F_GODOF); - real_getlfname(god, godname, B_FALSE, B_FALSE); + real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE); snprintf(goddesc, BUFLEN, "(%s of %s)", (f->val[0] == B_FEMALE) ? "goddess" : "god", f->text); // title @@ -4759,7 +4773,7 @@ void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) { if (showit) { char lfname[BUFLEN]; - real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE); + real_getlfnamea(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE); msg("\"There is %s living nearby...\"", lfname); more(); ndone++; } @@ -5023,8 +5037,8 @@ void doknowledgelist(void) { if (k->known == B_KNOWN) { mvwprintw(mainwin, y, 0, " %-25s (%s)",ot->name, k->hiddenname); } else { // ie. tried - mvwprintw(mainwin, y, 0, " %-25s (%s%s","???", k->hiddenname, strlen(k->triedon) ? "," : ")"); - if (strlen(k->triedon)) { + mvwprintw(mainwin, y, 0, " %-25s (%s%s","???", k->hiddenname, k->triedon ? "," : ")"); + if (k->triedon) { y++; mvwprintw(mainwin, y, 0, " %-25s tried on %s)"," ", k->triedon); } @@ -5192,7 +5206,7 @@ char *makedesc_god(lifeform_t *god, char *retbuf) { int nretflags,i; f = hasflag(god->flags, F_GODOF); - real_getlfname(god, godname, B_FALSE, B_FALSE); + real_getlfname(god, godname, NULL, B_SHOWALL, B_REALRACE); strcpy(retbuf, ""); @@ -5820,16 +5834,22 @@ char *makedesc_ob(object_t *o, char *retbuf) { sprintf(buf,"@It also inflicts %s extra burning damage.\n", strlen(f->text) ? f->text : "1-2"); strncat(retbuf, buf, HUGEBUFLEN); } - f = hasflag(o->flags, F_FROZEN); - if (f) { - sprintf(buf,"@It also inflicts %s extra cold damage.\n", strlen(f->text) ? f->text : "1-4"); - strncat(retbuf, buf, HUGEBUFLEN); - } f = hasflag(o->flags, F_ENCHANTED); if (f) { sprintf(buf,"@It also inflicts %s extra magical damage if the user has spare mana.\n", strlen(f->text) ? f->text : "1-2"); strncat(retbuf, buf, HUGEBUFLEN); } + getflags(o->flags, retflag, &nretflags, F_EXTRADAM, F_NONE); + for (i = 0 ; i < nretflags; i++) { + f = retflag[i]; + sprintf(buf,"@It also inflicts %s extra %s damage.\n", f->text, getdamname(f->val[0])); + strncat(retbuf, buf, HUGEBUFLEN); + } + f = hasflag(o->flags, F_FROZEN); + if (f) { + sprintf(buf,"@It also inflicts %s extra cold damage.\n", strlen(f->text) ? f->text : "1-4"); + strncat(retbuf, buf, HUGEBUFLEN); + } } else { strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, "\n", HUGEBUFLEN); @@ -11396,10 +11416,14 @@ void showlfstats(lifeform_t *lf, int showall) { int mindam,maxdam; int bonus,speed; int accnum; + int edam[100]; + enum DAMTYPE edt[100]; + int ndam = 0; // weapon if (showall) { char buf2[BUFLEN]; + int n; // calculate damage f = hasflag(w[i]->flags, F_BONUS); if (f && f->known) { @@ -11418,6 +11442,16 @@ void showlfstats(lifeform_t *lf, int showall) { applylfdammod(&mindam, lf, w[i]); applylfdammod(&maxdam, lf, w[i]); + // include extra damage for flaming, f_extradam, etc. + edam[0] = maxdam; // doesn't matter what this is + edt[0] = DT_NONE; // + ndam = 1; + getextradamwep(w[i], edam, edt, &ndam, B_TRUE); + for (n = 1; n < ndam; n++) { + mindam += edam[n]; + maxdam += edam[n]; + } + if (mindam < 0) mindam = 0; if (maxdam < 0) maxdam = 0; @@ -12918,8 +12952,7 @@ void showlfstats(lifeform_t *lf, int showall) { } snprintf(buf, BUFLEN, "%s %s sick with %s%s.", you(lf), is(lf), - pt->name, - knownfatal ? ", potentially fatally" : ""); + pt->name, knownfatal ? ", potentially fatally" : ""); if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) || (getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) { char buf2[BUFLEN]; @@ -12929,6 +12962,14 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, buf); y++; } + + if (f->known && (f->id == F_INCUBATING)) { + poisontype_t *pt; + pt = findpoisontype(f->val[0]); + snprintf(buf, BUFLEN, "%s %s incubating %s.", you(lf), is(lf), pt->name); + mvwprintw(mainwin, y, 0, buf); + y++; + } } f = lfhasflag(lf, F_MUTABLE); @@ -13141,7 +13182,7 @@ void showlfstats(lifeform_t *lf, int showall) { blocked = godblocked(god->race->id); - real_getlfname(god, godname, B_FALSE, B_FALSE); + real_getlfname(god, godname, NULL, B_SHOWALL, B_REALRACE); f = lfhasflag(god, F_GODOF); strcat(godname, " ("); strcat(godname, f->text); diff --git a/lf.c b/lf.c index 2015832..44203de 100644 --- a/lf.c +++ b/lf.c @@ -197,14 +197,18 @@ void awardxpfor(lifeform_t *killed, float pct) { void bleed(lifeform_t *lf, int splatter) { flag_t *f; char obname[BUFLEN]; + flag_t *retflag[MAXCANDIDATES]; + int nretflags; if (lf->cell->type->solid) return; if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) return; if (hasequippedobid(lf->pack, OT_AMU_BLOOD)) return; - f = lfhasflag(lf, F_BLOODOB); - if (f) { + getflags(lf->flags, retflag, &nretflags, F_BLOODOB, F_NONE); + if (nretflags) { + // pick a random one + f = retflag[rnd(0,nretflags-1)]; if (f->text) { strcpy(obname, f->text); } else { @@ -1580,7 +1584,7 @@ int cantalk(lifeform_t *lf) { } // if the lf can't explicitly talk, check its race if (!lfhasflag(lf, F_CANTALK)) { - if (!racecantalk(lf->race->raceclass->id)) { + if (!racecantalk(lf->race->id)) { return B_FALSE; } } @@ -1940,8 +1944,21 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar msg("You start casting %s.", sp->name); } } else { // instant cast + int obfromid = -1; addflag(lf->flags, F_CASTINGSPELL, sid, NA, NA, NULL); - rv = dospelleffects(lf, sid, power, targlf, targob, targcell, spellblessed, seen, B_FALSE); + + + // override obfrom if required + if (willflag && (willflag->obfrom != -1)) { + obfromid = willflag->obfrom; + } else if (castflag && (castflag->obfrom != -1)) { + obfromid = castflag->obfrom; + } + if (obfromid != -1) { + fromob = findobbyid(lf->pack, obfromid); + } + + rv = dospelleffects(lf, sid, power, targlf, targob, targcell, spellblessed, seen, B_FALSE, fromob); f = lfhasflag(lf, F_CASTINGSPELL); if (f) { killflag(f); @@ -2596,6 +2613,10 @@ int demandbribe(lifeform_t *lf) { object_t *gold, *mongold; int satisfied = B_FALSE; int i,heard; + char saybuf[BUFLEN]; + flag_t *demflag; + + demflag = lfhasflag(lf, F_DEMANDSBRIBE); hd = gettr(lf); gold = hasob(player->pack, OT_GOLD); @@ -2608,7 +2629,14 @@ int demandbribe(lifeform_t *lf) { amtwanted = rnd(hd*25, hd*100); getlfname(lf, lfname); - if (say(lf, "Hand over all your gold!", SV_TALK)) { + + if (demflag && strlen(demflag->text)) { + strcpy(saybuf, demflag->text); + } else { + strcpy(saybuf, "Hand over all your gold!"); + } + + if (say(lf, saybuf, SV_TALK)) { heard = B_TRUE; } else { heard = B_FALSE; @@ -2748,7 +2776,7 @@ void die(lifeform_t *lf) { lf->hp = lf->maxhp; statdirty = B_TRUE; // teleport away! - dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); return; } @@ -2809,7 +2837,7 @@ void die(lifeform_t *lf) { lf->hp = 1; killflagsofid(lf->flags, F_DEAD); // convert into a gas cloud! - dospelleffects(NULL, OT_S_GASEOUSFORM, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_GASEOUSFORM, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); // ai will now look for our coffin if (thisisplayer) { msg("^GYou feel the presence of a nearby coffin..."); @@ -2928,7 +2956,7 @@ void die(lifeform_t *lf) { killflagsofid(lf->flags, F_DEAD); statdirty = B_TRUE; // teleport somewhere different. - dospelleffects(god, OT_S_TELEPORT, 3, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_TELEPORT, 3, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE, NULL); return; } break; @@ -3010,15 +3038,17 @@ void die(lifeform_t *lf) { //angergodmaybe(R_GODMERCY, 1, GA_MURDER); } - // minions drop morale, and might flee + // minions who see this one die drop morale, and might flee getminions(lf, minion, &nminions); for (i = 0; i < nminions; i++) { - f = lfhasflag(minion[i], F_MORALE); - if (f) { - f->val[0] -= 10; - // might flee? - if (killer && (f->val[0] <= 0)) { - scare(minion[i], killer, PERMENANT, 10); + if (cansee(minion[i], lf)) { + f = lfhasflag(minion[i], F_MORALE); + if (f) { + f->val[0] -= 2; + // might flee? + if (killer && (f->val[0] <= 0)) { + scare(minion[i], killer, PERMENANT, 10); + } } } } @@ -4201,12 +4231,12 @@ int eat(lifeform_t *lf, object_t *o) { char dambuf[BUFLEN]; snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname)); if (hasflag(corpserace->flags, F_AVIAN)) { - checkdiff = 30; + checkdiff = 20; ptid = P_FOODBAD; timemin = 30; timemax = 50; } else { - checkdiff = 20; + checkdiff = 13; if (onein(3)) { ptid = P_FOOD; } else { @@ -4383,11 +4413,11 @@ int eat(lifeform_t *lf, object_t *o) { // special cases even if not fully eaten if (hasflagval(o->flags, F_CORPSEOF, R_DOGBLINK, NA, NA, NULL)) { // blink! - dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE, NULL); stopeating = B_TRUE; } else if (hasflagval(o->flags, F_CORPSEOF, R_BLASTBUG, NA, NA, NULL)) { - dospelleffects(lf, OT_S_DETONATE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_DETONATE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); stopeating = B_TRUE; } // you can gain F_MUTABLE even if you don't fully eat the corpse. @@ -4512,7 +4542,7 @@ void endlfturn(lifeform_t *lf) { if (ispetof(lf, player)) { if (!canhear(player, lf->cell, 4)) { char realname[BUFLEN]; - real_getlfname(lf, realname, B_FALSE, B_FALSE); + real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE); warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname)); } else if (cantalk(lf)) { sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL); @@ -5550,7 +5580,7 @@ int flee(lifeform_t *lf) { if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; - real_getlfname(lf, lfname, B_FALSE, B_FALSE); + real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_CURRACE); if (isdead(lf)) return B_FALSE; @@ -5582,7 +5612,10 @@ int flee(lifeform_t *lf) { // player let something flee? if (isplayer(thisone)) { pleasegodmaybe(R_GODMERCY, 5); - angergodmaybe(R_GODDEATH, 10, GA_MERCY); + if ((lf->lastdamlf == player->id) || cansee(player, lf)) { + // ie. only if the player + angergodmaybe(R_GODDEATH, 10, GA_MERCY); + } } killflag(f); } else { @@ -7633,7 +7666,8 @@ int getmorale(lifeform_t *lf) { flag_t *f; f = hasflag(lf->flags, F_MORALE); if (f) return f->val[0]; - return 0; + // defaults to threat level + return gettr(lf); } int getnextshortcut(lifeform_t *lf) { @@ -8408,35 +8442,48 @@ char *getpitverb(lifeform_t *lf, int dir, int onpurpose, int climb) { } char *getlfname(lifeform_t *lf, char *buf) { - return real_getlfname(lf, buf, B_TRUE, B_FALSE); + return real_getlfname(lf, buf, player, B_NOSHOWALL, B_CURRACE); } -char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) { +char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace) { char descstring[BUFLEN]; char jobstring[BUFLEN]; char the[6]; char lname[BUFLEN]; - race_t *lfrace; + race_t *lfrace = NULL; flag_t *f; enum LFSIZE size,racesize; int dobehaviour = B_TRUE; enum SKILLLEVEL lorelev; - if (gamemode == GM_GAMESTARTED) { - lorelev = getlorelevel(player, lf->race->raceclass->id); - } else { - lorelev = PR_MASTER; + if (usevis && (gamemode != GM_GAMESTARTED)) { + usevis = NULL; } - if (lfhasflag(lf, F_LYCANTHROPE)) { - // lycanthropes appear as human unless you know better - if (lorelev >= PR_ADEPT) { - lfrace = lf->race; - } else { - lfrace = findrace(R_HUMAN); + if (ispolymorphed(lf) && useorigrace) { + f = lfhasflag(lf, F_ORIGRACE); + if (f) { + lfrace = findrace(f->val[0]); } + } + + if (!lfrace) { + if (lfhasflag(lf, F_LYCANTHROPE)) { + // lycanthropes appear as human unless you know better + if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) { + lfrace = lf->race; + } else { + lfrace = findrace(R_HUMAN); + } + } else { + lfrace = lf->race; + } + } + + if (gamemode == GM_GAMESTARTED) { + lorelev = getlorelevel(player, lfrace->raceclass->id); } else { - lfrace = lf->race; + lorelev = PR_MASTER; } // 'the' or 'your' ? @@ -8466,20 +8513,17 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) { // construct description string strcpy(descstring, ""); - // if you lorelev is high enough, you can tell when the race is larger or smaller than - // they should be. - if (lorelev >= PR_BEGINNER) { - f = hasflag(lfrace->flags, F_SIZE); - if (f) { - racesize = f->val[0]; - } else { - racesize = SZ_HUMAN; // default - } - size = getlfsize(lf); - if (size != racesize) { - strcat(descstring, getsizetext(size)); - strcat(descstring, " "); - } + // are they larger or smaller than they should be? + f = hasflag(lfrace->flags, F_SIZE); + if (f) { + racesize = f->val[0]; + } else { + racesize = SZ_HUMAN; // default + } + size = getlfsize(lf); + if (size != racesize) { + strcat(descstring, getsizetext(size)); + strcat(descstring, " "); } // need a certain amount of race knowledge to recognise ai traits @@ -8519,7 +8563,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) { snprintf(buf, BUFLEN, "you"); } else { //if (isblind(player)) { - if (usevis && !cansee(player, lf) && !showall) { + if (usevis && !cansee(usevis, lf) && !showall) { snprintf(buf, BUFLEN, "something"); } else { if (lf->race->id == R_DANCINGWEAPON) { @@ -8559,31 +8603,43 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) { } char *getlfnamea(lifeform_t *lf, char *buf) { - return real_getlfnamea(lf, buf, B_TRUE, B_FALSE); + return real_getlfnamea(lf, buf, player, B_NOSHOWALL, B_CURRACE); } -char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) { - race_t *lfrace; +char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t * usevis, int showall, int useorigrace) { + race_t *lfrace = NULL; enum SKILLLEVEL lorelev; + flag_t *f; - if (gamemode == GM_GAMESTARTED) { - lorelev = getlorelevel(player, lf->race->raceclass->id); - } else { - lorelev = PR_MASTER; + if (usevis && (gamemode != GM_GAMESTARTED)) { + usevis = NULL; } - switch (lf->race->id) { - case R_WERERAT: - case R_WEREWOLF: - if (lorelev >= PR_ADEPT) { + if (ispolymorphed(lf) && useorigrace) { + f = lfhasflag(lf, F_ORIGRACE); + if (f) { + lfrace = findrace(f->val[0]); + } + } + + if (!lfrace) { + if (lfhasflag(lf, F_LYCANTHROPE)) { + // lycanthropes appear as human unless you know better + if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) { lfrace = lf->race; } else { lfrace = findrace(R_HUMAN); } - break; - default: + } else { lfrace = lf->race; - break; + } + } + + + if (gamemode == GM_GAMESTARTED) { + lorelev = getlorelevel(player, lfrace->raceclass->id); + } else { + lorelev = PR_MASTER; } if (isplayer(lf)) { @@ -8592,7 +8648,7 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) { char buf2[BUFLEN]; char the[6]; - real_getlfname(lf, buf2, usevis, showall); + real_getlfname(lf, buf2, usevis, showall, useorigrace); if (lfhasflag(lf, F_NAME) || lfhasflag(lf, F_UNIQUE)) { strcpy(the, ""); @@ -12729,7 +12785,7 @@ object_t *isstuck(lifeform_t *lf) { } -poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity) { +poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime) { poisontype_t *a; // add to the end of the list @@ -12756,6 +12812,7 @@ poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *da a->dam = dam; a->dampct = dampct; a->severity = severity; + a->incubationtime = incubationtime; return a; } @@ -14057,6 +14114,7 @@ int isweaponskill(enum SKILL skid) { case SK_POLEARMS: case SK_SHORTBLADES: case SK_STAVES: + case SK_WHIPS: //case SK_UNARMED: return B_TRUE; default: @@ -14367,11 +14425,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml int prelowhp = B_FALSE,ko = B_FALSE; int murder = B_FALSE; flag_t *f; + int predead = B_FALSE; if (gamemode < GM_GAMESTARTED) return 0; getlfname(lf, lfname); + if (isdead(lf)) { + predead = B_TRUE; + } + if (isplayer(lf)) { statdirty = B_TRUE; } @@ -14535,13 +14598,15 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml lf->hp -= amt; } - // fill in lastdam... - lf->lastdamtype = damtype; + if (!predead) { + // fill in lastdam... + lf->lastdamtype = damtype; - if (fromlf) { - lf->lastdamlf = fromlf->id; - } else { - lf->lastdamlf = -1; + if (fromlf) { + lf->lastdamlf = fromlf->id; + } else { + lf->lastdamlf = -1; + } } // if they died @@ -14555,71 +14620,73 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp); } - ////////////////////////////////////////// - // Figure out death text for tombstone. - // eg. Killed by something - // Impaled by something. - // etc - ////////////////////////////////////////// + if (!predead) { + ////////////////////////////////////////// + // Figure out death text for tombstone. + // eg. Killed by something + // Impaled by something. + // etc + ////////////////////////////////////////// - // replace 'the' at start of damsrc with 'a' - if (strstr(damsrc, "the ") == damsrc) { - snprintf(buf, BUFLEN, "a %s", (damsrc+4)); - } else { - strcpy(buf, damsrc); - } + // replace 'the' at start of damsrc with 'a' + if (strstr(damsrc, "the ") == damsrc) { + snprintf(buf, BUFLEN, "a %s", (damsrc+4)); + } else { + strcpy(buf, damsrc); + } - // fill in damage amount - snprintf(buf2, BUFLEN, "^%d damage",amt); - strcat(buf, buf2); + // fill in damage amount + snprintf(buf2, BUFLEN, "^%d damage",amt); + strcat(buf, buf2); - // unseen? - if (fromlf && !cansee(lf, fromlf)) { - strcat(buf, "^unseen"); - } + // unseen? + if (fromlf && !cansee(lf, fromlf)) { + strcat(buf, "^unseen"); + } - // "while xxx" - strcpy(buf2, ""); - if ((countcellexits(lf->cell, DT_COMPASS) == 1) && fromlf && (getcelldist(fromlf->cell, lf->cell) == 1)) { - strcat(buf2, "^while cornered"); - } - if (!hasfreeaction(lf)) { - if (strlen(buf2)) strcat(buf2, " and helpless"); - else strcat(buf2, "^while helpless"); - } - if (strlen(buf2)) strcat(buf, buf2); + // "while xxx" + strcpy(buf2, ""); + if ((countcellexits(lf->cell, DT_COMPASS) == 1) && fromlf && (getcelldist(fromlf->cell, lf->cell) == 1)) { + strcat(buf2, "^while cornered"); + } + if (!hasfreeaction(lf)) { + if (strlen(buf2)) strcat(buf2, " and helpless"); + else strcat(buf2, "^while helpless"); + } + if (strlen(buf2)) strcat(buf, buf2); - setlastdam(lf, buf); + setlastdam(lf, buf); - if (fromlf && willeatlf(fromlf, lf)) { - // this string is special - die() checks for this to see whether - // to add "partially eaten" to the corpse. - setkillverb(lf, "Eaten"); - } else { - switch (damtype) { - case DT_ACID: setkillverb(lf, "Dissolved"); break; - case DT_COLD: setkillverb(lf, "Frozen"); break; - case DT_CRUSH: setkillverb(lf, "Crushed"); break; - case DT_ELECTRIC: setkillverb(lf, "Electrocuted"); break; - case DT_FIRE: - case DT_HEAT: - setkillverb(lf, "Incinerated"); break; - case DT_MELT: setkillverb(lf, "Melted"); break; - case DT_PIERCE: setkillverb(lf, "Impaled"); break; - case DT_EXPLOSIVE: setkillverb(lf, "Vaporised"); break; - default: - if (fromlf) { - if (murder) { - setkillverb(lf, "Murdered"); - } else if (amt >= lf->maxhp) { - setkillverb(lf, "Slaughtered"); + if (fromlf && willeatlf(fromlf, lf)) { + // this string is special - die() checks for this to see whether + // to add "partially eaten" to the corpse. + setkillverb(lf, "Eaten"); + } else { + switch (damtype) { + case DT_ACID: setkillverb(lf, "Dissolved"); break; + case DT_COLD: setkillverb(lf, "Frozen"); break; + case DT_CRUSH: setkillverb(lf, "Crushed"); break; + case DT_ELECTRIC: setkillverb(lf, "Electrocuted"); break; + case DT_FIRE: + case DT_HEAT: + setkillverb(lf, "Incinerated"); break; + case DT_MELT: setkillverb(lf, "Melted"); break; + case DT_PIERCE: setkillverb(lf, "Impaled"); break; + case DT_EXPLOSIVE: setkillverb(lf, "Vaporised"); break; + default: + if (fromlf) { + if (murder) { + setkillverb(lf, "Murdered"); + } else if (amt >= lf->maxhp) { + setkillverb(lf, "Slaughtered"); + } else { + setkillverb(lf, "Slain"); + } } else { - setkillverb(lf, "Slain"); + setkillverb(lf, "Killed"); } - } else { - setkillverb(lf, "Killed"); - } - break; + break; + } } } @@ -14695,17 +14762,17 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr char buf2[BUFLEN]; sprintf(buf, "^w%s releases a cloud of purple spores!", lfname); sprintf(buf2, "^wSomething releases a cloud of purple spores!"); - spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE); + spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE, NULL); } else if (lf->race->id == R_FUNGUSRAGE) { char buf2[BUFLEN]; sprintf(buf, "^w%s releases a cloud of red spores!", lfname); sprintf(buf2, "^wSomething releases a cloud of red spores!"); - spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE); + spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE, NULL); } else if ((lf->race->id == R_UNYON) && ((damtype == DT_SLASH) || (damtype == DT_PIERCE))) { char buf2[BUFLEN]; sprintf(buf, "^w%s releases a cloud of fumes!", lfname); sprintf(buf2, "^wSomething releases a cloud of fumes!"); - spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE); + spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL); } @@ -15558,7 +15625,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char distbuf[BUFLEN],distbufbad[BUFLEN]; char dirbuf[BUFLEN]; - real_getlfnamea(noisemaker, lfname, B_FALSE, B_FALSE); + real_getlfnamea(noisemaker, lfname, NULL, B_NOSHOWALL, B_CURRACE); getdisttext(l->cell, c, distbuf, distbufbad, dirbuf); slev = getskill(l, SK_LISTEN); @@ -15971,37 +16038,77 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char } if (!found) { - addtempflag(lf->flags, F_POISONED, ptype, power, srcrace ? srcrace->id : NA, fromwhat, howlong); + // incubation period? + if (pt->incubationtime && isplayer(lf)) { + flag_t *ii; + int multiplier = 0; + int tempmult; + // modify incubation time based on metabolism + sumflags(lf->flags, F_FASTMETAB, &tempmult, NULL, NULL); + multiplier += tempmult; + sumflags(lf->flags, F_SLOWMETAB, &tempmult, NULL, NULL); + multiplier -= tempmult; - // also apply specific poison effect - switch (ptype) { - case P_FOOD: - case P_GAS: - case P_VENOM: - default: - break; - case P_MIGRAINE: - f = addtempflag(lf->flags, F_DTVULN, DT_SONIC, NA, NA, NULL, FROMPOISON); f->obfrom = ptype; - f = addtempflag(lf->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL, FROMPOISON); f->obfrom = ptype; - break; - case P_WEAKNESS: - f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*10), NA, NULL, FROMPOISON); - f->obfrom = ptype; // poison type - break; - case P_ROT: - f = addtempflag(lf->flags, F_ATTRMOD, A_CHA, -(power*10), NA, NULL, FROMPOISON); - f->obfrom = ptype; - f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*5), NA, NULL, FROMPOISON); - f->obfrom = ptype; - f = addtempflag(lf->flags, F_ATTRMOD, A_CON, -(power*10), NA, NULL, FROMPOISON); - f->obfrom = ptype; - f = addtempflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL, FROMPOISON); - f->obfrom = ptype; - break; + if (multiplier > 0) { + howlong /= multiplier; + } else if (multiplier < 0) { + howlong *= abs(multiplier); + } + ii = lfhasflagval(lf, F_INCUBATING, ptype, NA, NA, NULL); + if (ii) { + // will happen faster + ii->val[2] /= 2; + if (ii->val[2] < 1) ii->val[2] = 1; + if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) { + ii->known = B_TRUE; + msg("You feel %s coming on more quickly.", pt->name); + } + } else { + char ftext[BUFLEN]; + sprintf(ftext, "%d^%s", power, fromwhat); + ii = addflag(lf->flags, F_INCUBATING, ptype, power, pt->incubationtime, ftext); + ii->obfrom = srcrace ? srcrace->id : NA; + if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) { + ii->known = B_TRUE; + msg("You feel %s coming on.", pt->name); + } + } + } else { + addtempflag(lf->flags, F_POISONED, ptype, power, srcrace ? srcrace->id : NA, fromwhat, howlong); + poisoneffects(lf, ptype, power); } + } } +int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power) { + flag_t *f; + switch (ptid) { + case P_FOOD: + case P_GAS: + case P_VENOM: + default: return B_TRUE; + case P_MIGRAINE: + f = addtempflag(lf->flags, F_DTVULN, DT_SONIC, NA, NA, NULL, FROMPOISON); f->obfrom = ptid; + f = addtempflag(lf->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL, FROMPOISON); f->obfrom = ptid; + break; + case P_WEAKNESS: + f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*10), NA, NULL, FROMPOISON); + f->obfrom = ptid; // poison type + break; + case P_ROT: + f = addtempflag(lf->flags, F_ATTRMOD, A_CHA, -(power*10), NA, NULL, FROMPOISON); + f->obfrom = ptid; + f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*5), NA, NULL, FROMPOISON); + f->obfrom = ptid; + f = addtempflag(lf->flags, F_ATTRMOD, A_CON, -(power*10), NA, NULL, FROMPOISON); + f->obfrom = ptid; + f = addtempflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL, FROMPOISON); + f->obfrom = ptid; + break; + } + return B_FALSE; +} int poisonthreatenslife(lifeform_t *lf, flag_t *f) { float time,dam,totaldam; @@ -18080,7 +18187,7 @@ int getskillcheckchance(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) { attrib = (getattr(lf, A_IQ) / 10) + lf->level; break; case SC_MORALE: // based on morale, level/hitdice and size. - attrib = getmorale(lf) + gettr(lf); + attrib = getmorale(lf); attrib += getlfsize(lf); break; case SC_SLIP: @@ -18861,7 +18968,7 @@ void startlfturn(lifeform_t *lf) { if (isplayer(lf)) { if (f->val[0] >= 5) { char buf[BUFLEN]; - real_getlfnamea(retcell[i]->lf, buf, B_FALSE, B_FALSE); + real_getlfnamea(retcell[i]->lf, buf, NULL, B_NOSHOWALL, B_CURRACE); warn("^WYour sixth sense warns you of %s %s you!", buf, (reldir == RD_BACKWARDS) ? "behind" : "beside" ); } else if (f->val[0] >= 3) { @@ -19580,7 +19687,7 @@ void startlfturn(lifeform_t *lf) { // effects for/on your own flags getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM, - F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY, + F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INCUBATING, F_INJURY, F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE); for (i = 0; i < nretflags; i++) { f = retflag[i]; @@ -19649,6 +19756,25 @@ void startlfturn(lifeform_t *lf) { } } + if (f->id == F_INCUBATING) { + f->val[1]--; + if (f->val[1] <= 0) { + // parse text to get power & whatfrom + char *p; + char buf[BUFLEN]; + int power; + enum POISONTYPE ptype; + ptype = f->val[0]; + p = readuntil(buf, f->text, '^'); + power = atoi(buf); + readuntil(buf, p, '^'); + addtempflag(lf->flags, F_POISONED, ptype, power, f->obfrom, buf, f->val[2]); + poisoneffects(lf, ptype, power); + killflag(f); + continue; + } + } + // bleeding injuries can stain armour if ((f->id == F_INJURY) && (f->val[2] == DT_SLASH)) { object_t *arm; @@ -20337,7 +20463,7 @@ void timeeffectslf(lifeform_t *lf) { if (amu) { if (!polymorphto(lf, R_AVIAD, 5)) { makeknown(amu->type->id); - dospelleffects(lf, OT_S_FLIGHT, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(lf, OT_S_FLIGHT, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); willfall = B_FALSE; } } @@ -20543,7 +20669,7 @@ int touch(lifeform_t *lf, object_t *o) { // not wearing gloves? if (!getequippedob(lf->pack, BP_HANDS)) { // default power of 4 - dospelleffects(lf, OT_S_FREEZEOB, 4, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE); + dospelleffects(lf, OT_S_FREEZEOB, 4, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL); // we use val[0] here rather than timeleft, because we don't // want to decrement it each turn. @@ -21038,7 +21164,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { for (n = 0; n < nadjallies; n++) { if (seen[n]) { char lname[BUFLEN]; - real_getlfname(adjally[n], lname, B_FALSE, B_FALSE); + real_getlfname(adjally[n], lname, NULL, B_NOSHOWALL, B_CURRACE); msg("%s follows you.", lname); } } @@ -22641,5 +22767,8 @@ int willeatlf(lifeform_t *eater, lifeform_t *eatee) { if ((eatee->material->id == MT_PLANT) && lfhasflag(eater, F_VEGETARIAN)) { return B_TRUE; } + if (eater->race->id == R_BINGEBARK) { + return B_TRUE; + } return B_FALSE; } diff --git a/lf.h b/lf.h index 8eaa805..426110f 100644 --- a/lf.h +++ b/lf.h @@ -3,7 +3,7 @@ void addbodypart(race_t *r, enum BODYPART bp, char *name); lifeform_t *addlf(cell_t *cell, enum RACE rid, int level); lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller); -poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity); +poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime); job_t *addjob(enum JOB id, char *name, char *desc); race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); @@ -217,9 +217,9 @@ char *getmoveverbother(lifeform_t *lf); lifeform_t *getnearbypeaceful(lifeform_t *lf); char *getpitverb(lifeform_t *lf, int dir, int onpurpose, int climb); char *getlfname(lifeform_t *lf, char *buf); -char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall); +char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace); char *getlfnamea(lifeform_t *lf, char *buf); -char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall); +char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace); enum LFSIZE getlfsize(lifeform_t *lf); float getlfweight(lifeform_t *lf, int withobs); object_t *getsecmeleeweapon(lifeform_t *lf); @@ -392,6 +392,7 @@ void outfitlf(lifeform_t *lf); void petify(lifeform_t *lf, lifeform_t *owner); int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int antannounce); void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid); +int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power); int poisoncausesvomit(enum POISONTYPE ptype); int poisonthreatenslife(lifeform_t *lf, flag_t *f); int polymorphto(lifeform_t *lf, enum RACE rid, int howlong); diff --git a/map.c b/map.c index ecb1121..fae2bfa 100644 --- a/map.c +++ b/map.c @@ -7559,7 +7559,7 @@ int remove_deadends(map_t *m, int howmuch) { void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph) { if (targettype == TT_MONSTER) { if (desc) { - real_getlfnamea((lifeform_t *)what, desc, B_FALSE, B_FALSE); + real_getlfnamea((lifeform_t *)what, desc, NULL, B_NOSHOWALL, B_CURRACE); strcat(desc, descappend); } if (glyph) { @@ -7593,7 +7593,8 @@ void setcellknown(cell_t *cell, int forcelev) { o = hassecretdoor(cell->obpile); if (o) { celltype_t *ct; - ct = findcelltype(getcellsolid(cell)); + //ct = findcelltype(getcellsolid(cell)); + ct = findcelltype(getmapsolid(cell->map)); cell->knownglyph = ct->glyph; } else { cell->knownglyph = cell->type->glyph; diff --git a/move.c b/move.c index 39c3bdd..d89aa22 100644 --- a/move.c +++ b/move.c @@ -1596,7 +1596,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) { if (preseenbyplayer && !cansee(player, lf) && !changedlev) { if (isadjacent(lf->cell, precell)) { // ie don't say this if we teleported/jumped if (areenemies(player, lf)) { - real_getlfnamea(lf, lfname, B_FALSE, B_FALSE); + real_getlfnamea(lf, lfname, NULL, B_NOSHOWALL, B_CURRACE); msg("%s %ss out of view.", lfname, getmoveverb(lf)); } } @@ -2755,7 +2755,7 @@ void triggertrap(lifeform_t *lf, object_t *o, object_t *trapob, cell_t *where) { if ((plev >= PL_PLEASED) && pctchance(plev*33)) { godsay(R_GODMERCY, B_TRUE, "We all make mistakes..."); // bamf away - dospelleffects(NULL, OT_S_BLINK, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(NULL, OT_S_BLINK, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); } } @@ -3385,7 +3385,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) { for (n = 0; n < nadjallies; n++) { if (seen[n]) { char lname[BUFLEN]; - real_getlfname(adjally[n], lname, B_FALSE, B_FALSE); + real_getlfname(adjally[n], lname, NULL, B_NOSHOWALL, B_CURRACE); msg("%s follows you.", lname); } } diff --git a/nexus.c b/nexus.c index 7489054..207bbcc 100644 --- a/nexus.c +++ b/nexus.c @@ -797,7 +797,7 @@ void donextturn(map_t *map) { targcell = getcellat(targmap, x, y); } taketime(who, getspellspeed(who)); - dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE); + dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE, NULL); killflagsofid(who->flags, F_CASTINGSPELL); } else { if (isplayer(who)) { @@ -1426,14 +1426,22 @@ int rnd(int min, int max) { } -int roll(char *string) { +int real_roll(char *string, int wantmax) { int ndice,nsides,bonus; int roll; texttodice(string, &ndice,&nsides,&bonus); - roll = rolldie(ndice, nsides) + bonus; + if (wantmax) { + roll = (ndice * nsides) + bonus; + } else { + roll = rolldie(ndice, nsides) + bonus; + } return roll; } +int roll(char *string) { + return real_roll(string, B_FALSE); +} + // get a random number int rolldie(int ndice, int sides) { int i; diff --git a/nexus.h b/nexus.h index 982408f..7217be2 100644 --- a/nexus.h +++ b/nexus.h @@ -33,6 +33,7 @@ int parseplayerfile(FILE *f, lifeform_t *lf); int pctchance(int pct); float pctof(float pct, float num); int rnd(int min, int max); +int real_roll(char *string, int wantmax); int roll(char *string); int rolldie(int ndice, int sides); int rollhitdice(lifeform_t *lf, int wantmax); diff --git a/objects.c b/objects.c index aadc1cd..fb0606d 100644 --- a/objects.c +++ b/objects.c @@ -1577,7 +1577,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum assert(addobfast(o->contents, oid)); } } - } else if (o->type->id == OT_GRIMOIRE) { + } else if ((o->type->id == OT_GRIMOIRE) && (gamemode != GM_LOADING)) { // 1 spell from each school int i; int nschools = -1; @@ -1758,11 +1758,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum regiontype_t *dstrt = NULL; int srcdepth; char buf[BUFLEN]; + regionthing_t *poss[MAXCANDIDATES]; + int nposs = 0; // fill in map destination. if (!wantregionthing) { - regionthing_t *poss[MAXCANDIDATES]; - int nposs = 0; - getbranchlinks(poss, &nposs); if (nposs) { @@ -1770,19 +1769,20 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum } } if (dolinks) { - assert(wantregionthing); - // we now have the destination regionlink thing which the - // map will lead to. + if (wantregionthing) { + // we now have the destination regionlink thing which the + // map will lead to. - // just using this to fill in srcregion - findregionthing(wantregionthing->id, &srcregion); - srcdepth = wantregionthing->depth; - dstrt = findregiontype(wantregionthing->value); + // just using this to fill in srcregion + findregionthing(wantregionthing->id, &srcregion); + srcdepth = wantregionthing->depth; + dstrt = findregiontype(wantregionthing->value); - strcpy(buf, dstrt->name); - makelowercase(buf); + strcpy(buf, dstrt->name); + makelowercase(buf); - addflag(o->flags, F_MAPTO, srcregion->id, srcdepth, wantregionthing->id, buf); + addflag(o->flags, F_MAPTO, srcregion->id, srcdepth, wantregionthing->id, buf); + } } } else if (o->type->id == OT_STATUE) { flag_t *f, *rf; @@ -2681,6 +2681,7 @@ int blessob(object_t *o) { char obname[BUFLEN]; int rv = B_FALSE; lifeform_t *owner; + flag_t *f; if (hasflag(o->flags, F_NOBLESS)) return B_TRUE; @@ -2714,6 +2715,11 @@ int blessob(object_t *o) { msg("%s is bathed in a divine glow!", obname); seen = B_TRUE; } + // remove negative "bonuses". ie. "-3 sword" becomes "sword". + f = hasflag(o->flags, F_BONUS); + if (f && (f->val[0] < 0)) { + killflag(f); + } } else { // game not started yet. owner = o->pile->owner; @@ -3676,7 +3682,7 @@ glyph_t *getglyph(object_t *o) { if (isdoor(o, &isopen)) { if (issecretdoor(o)) { - return &(findcelltype(obloc->map->habitat->solidcelltype)->glyph); + return &(findcelltype(getmapsolid(obloc->map))->glyph); } else { if (isopen) { g = '-'; @@ -5125,7 +5131,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan } if (who) { char lfname[BUFLEN]; - real_getlfnamea(who, lfname, B_FALSE, B_FALSE); + real_getlfnamea(who, lfname, NULL, B_NOSHOWALL, B_REALRACE); snprintf(buf, BUFLEN, "a %s%s scent",adjective,r->name); } else { snprintf(buf, BUFLEN, "%s%s scent",adjective, r->name ); @@ -5573,7 +5579,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan strcat(localbuf, "secret "); } else if (where) { celltype_t *ct; - ct = findcelltype(where->map->habitat->solidcelltype); + ct = findcelltype(getmapsolid(where->map)); // solid cell description strcpy(pluralname, ct->name); } @@ -6539,7 +6545,7 @@ int getthrowdam(object_t *o) { // modify if it has a damage value f = hasflag(o->flags, F_MISSILEDAM); if (f) { - dam = f->val[0]; + dam = roll(f->text); } else { // base damage is = kilograms/5. // ie. 1 kg object does 0 damage @@ -9228,7 +9234,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { default: break; } - dospelleffects(lf, spelltocast, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, spelltocast, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); // special wands } else if (o->type->id == OT_WAND_WONDER) { int power; @@ -9252,67 +9258,67 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } break; case 1: // summon monster - dospelleffects(lf, OT_S_CREATEMONSTER, rnd(1,4), NULL, NULL, NULL, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_CREATEMONSTER, rnd(1,4), NULL, NULL, NULL, B_UNCURSED, &willid, B_FALSE, NULL); break; case 2: // animate dead - dospelleffects(lf, OT_S_ANIMATEDEAD, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_ANIMATEDEAD, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 3: // blindness - dospelleffects(lf, OT_S_BLINDNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_BLINDNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 4: // levitate - dospelleffects(lf, OT_S_LEVITATION, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_LEVITATION, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 5: // dispersal - dospelleffects(lf, OT_S_DISPERSAL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_DISPERSAL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 6: // flash - dospelleffects(lf, OT_S_FLASH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_FLASH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 7: // light - dospelleffects(lf, OT_S_LIGHT, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_LIGHT, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 8: // heal - dospelleffects(lf, OT_S_HEALING, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_HEALING, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 9: // minor heal - dospelleffects(lf, OT_S_HEALINGMIN, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_HEALINGMIN, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 10: // invis - dospelleffects(lf, OT_S_INVISIBILITY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_INVISIBILITY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 11: // haste - dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 12: // pull - dospelleffects(lf, OT_S_SUCK, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_SUCK, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 13: // blast - dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 14: // slow - dospelleffects(lf, OT_S_SLOW, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_SLOW, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 15: // sleep - dospelleffects(lf, OT_S_SLEEP, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_SLEEP, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 16: // gas - dospelleffects(lf, OT_S_CLOUDKILL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_CLOUDKILL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 17: // dark - dospelleffects(lf, OT_S_DARKNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_DARKNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 18: // stone - dospelleffects(lf, OT_S_PETRIFY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_PETRIFY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 19: // fireball - dospelleffects(lf, OT_S_FIREBALL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_FIREBALL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 20: // poly - dospelleffects(lf, OT_S_POLYMORPH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_POLYMORPH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL); break; case 21: // teleport - dospelleffects(lf, OT_S_TELEPORT, power, lf , NULL, lf->cell, B_UNCURSED, &willid, B_FALSE); + dospelleffects(lf, OT_S_TELEPORT, power, lf , NULL, lf->cell, B_UNCURSED, &willid, B_FALSE, NULL); break; case 22: // create banana peel if (where->type->solid) { @@ -9345,7 +9351,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } else if (o->type->id == OT_BUTANETORCH) { int seen = B_FALSE; // if above half charges, big spray - dospelleffects(lf, OT_S_SPARK, 1, NULL, NULL, where, B_UNCURSED, &seen, B_FALSE); + dospelleffects(lf, OT_S_SPARK, 1, NULL, NULL, where, B_UNCURSED, &seen, B_FALSE, o); // announce if (!seen) { noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL); @@ -9398,7 +9404,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { // revert polymorphs if (lfhasflag(c->lf, F_ORIGRACE)) { dospelleffects(NULL, OT_A_POLYREVERT, 1, - c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE); + c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE, NULL); } // fix injuries ("deformities") killflagsofid(c->lf->flags, F_INJURY); @@ -9438,7 +9444,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { if (c->lf) { // restore dospelleffects(NULL, OT_S_RESTORATION, 1, - c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE); + c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE, NULL); } else { object_t *oo, *nextoo; // revive corpses @@ -9446,7 +9452,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { nextoo = oo->next; if (oo->type->id == OT_CORPSE) { dospelleffects(NULL, OT_S_RESSURECTION, 1, - NULL, oo, c, B_BLESSED, NULL, B_TRUE); + NULL, oo, c, B_BLESSED, NULL, B_TRUE, NULL); } } } @@ -9465,7 +9471,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { object_t *oo, *nextoo; // they get an injury - dospelleffects(NULL, OT_S_FLAYFLESH, 1, c->lf, NULL, c, B_BLESSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_FLAYFLESH, 1, c->lf, NULL, c, B_BLESSED, NULL, B_TRUE, NULL); // they attack themself. attackcell(c->lf, c, B_TRUE); @@ -10456,7 +10462,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } break; case OT_POT_CANINETRACKING: - dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_COFFEE: if (isplayer(lf)) { @@ -10550,7 +10556,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } break; case OT_POT_ETHEREALNESS: - dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_EXPERIENCE: // gain xp! @@ -10592,29 +10598,29 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE pleasegodmaybe(R_GODBATTLE, 15); break; case OT_POT_GASEOUSFORM: - dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_GROWTH: i = getlfsize(lf); if (iscursed(o)) { - dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE); + dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL); } else { - dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE); + dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL); } // revert in a little while... addflag(lf->flags, F_SIZETIMER, i, rnd(10,20), NA, NULL); break; case OT_POT_HEALING: - dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_HEALINGMIN: - dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_HEALINGMAJ: - dospelleffects(lf, OT_S_HEALINGMAJ,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_HEALINGMAJ,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_INVIS: - dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen, B_TRUE); + dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_INVULN: if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) { @@ -10669,14 +10675,14 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE case OT_POT_POLYMORPH: if (potblessed == B_BLESSED) { // controlled polymorph - you can chnage back. - dospelleffects(NULL, OT_S_POLYMORPH, 5, lf, NULL, lf->cell, potblessed, NULL, B_TRUE); + dospelleffects(NULL, OT_S_POLYMORPH, 5, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL); } else { // random polymorph - dospelleffects(NULL, OT_S_POLYMORPH, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE); + dospelleffects(NULL, OT_S_POLYMORPH, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL); } break; case OT_POT_RESTORATION: - dospelleffects(NULL, OT_S_RESTORATION, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE); + dospelleffects(NULL, OT_S_RESTORATION, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL); break; case OT_POT_SANCTUARY: // how long for? @@ -10711,16 +10717,16 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } break; case OT_POT_SLEEP: - dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); if (seen) *seen = B_TRUE; break; case OT_POT_SPEED: if (potblessed == B_BLESSED) { - dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE, NULL); } else if (potblessed == B_CURSED) { - dospelleffects(lf, OT_S_SLOW, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_SLOW, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); } else { // uncursed - dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); } if (seen) *seen = B_TRUE; break; @@ -10779,7 +10785,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } else if (potblessed == B_CURSED) { b = B_BLESSED; } - dospelleffects(lf, OT_S_HEALINGMAJ,b ? 5 : 1, lf, NULL, lf->cell, b, seen, B_TRUE); + dospelleffects(lf, OT_S_HEALINGMAJ,b ? 5 : 1, lf, NULL, lf->cell, b, seen, B_TRUE, NULL); modhunger(lf, -HUNGERCONST); } else { if (isplayer(lf)) msg("Yuck, this tastes like blood!"); @@ -11009,7 +11015,7 @@ int readsomething(lifeform_t *lf, object_t *o) { // identify evertthing! for (oo = lf->pack->first ; oo ; oo = oo->next) { if (!isidentified(oo)) { - dospelleffects(lf, OT_S_IDENTIFY, 10, NULL, oo, NULL, o->blessed, &seen, B_FALSE); + dospelleffects(lf, OT_S_IDENTIFY, 10, NULL, oo, NULL, o->blessed, &seen, B_FALSE, NULL); } } } @@ -11027,7 +11033,7 @@ int readsomething(lifeform_t *lf, object_t *o) { power = getobspellpower(o, lf); for (oo = lf->pack->first ; oo ; oo = oo->next) { if (isdamaged(oo)) { - dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE); + dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE, NULL); } } if (seen) { @@ -11297,7 +11303,7 @@ int readsomething(lifeform_t *lf, object_t *o) { // make a piece of armour invulnerable for (oo = lf->pack->first ; oo ; oo = oo->next) { - if (isequipped(oo) && !hasflag(o->flags, F_INVULNERABLE)) { + if (isequipped(oo) && !hasflag(oo->flags, F_INVULNERABLE)) { poss[nposs++] = oo; } } @@ -11305,17 +11311,18 @@ int readsomething(lifeform_t *lf, object_t *o) { if (nposs) { oo = poss[rnd(0,nposs-1)]; addflag(oo->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL); + killflagsofid(oo->flags, F_DAMAGABLE); if (isplayer(lf)) { char ooname[BUFLEN]; getobname(oo, ooname, oo->amt); - msg("Your %s become%s ultra-dense!", obname, (oo->amt == 1) ? "s" : ""); + msg("Your %s become%s ultra-dense!", ooname, (oo->amt == 1) ? "s" : ""); } else if (cansee(player, lf)) { char lfname[BUFLEN]; char ooname[BUFLEN]; getlfname(lf, lfname); getobname(oo, ooname, oo->amt); msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname), - obname, (oo->amt == 1) ? "s" : ""); + ooname, (oo->amt == 1) ? "s" : ""); } ndone++; } @@ -11772,7 +11779,7 @@ void setobcreatedby(object_t *o, lifeform_t *lf) { if (!lf) { return; } - real_getlfnamea(lf, lfname, B_FALSE, B_TRUE); + real_getlfnamea(lf, lfname, NULL, B_SHOWALL, B_REALRACE); addflag(o->flags, F_CREATEDBY, lf->id, NA, NA, lfname); } @@ -12496,7 +12503,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp if (thrower) { getlfname(thrower, throwername); - real_getlfname(thrower, realthrowername, B_FALSE, B_FALSE); + real_getlfname(thrower, realthrowername, NULL, B_NOSHOWALL, B_CURRACE); if (isplayer(thrower)) { strcpy(throwernamea, throwername); @@ -12685,7 +12692,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp radius = o->amt * 2; if (radius > 10) radius = 10; - spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE); + spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL); } else if (o->type->id == OT_ASHSLEEP) { int radius; char buf[BUFLEN]; @@ -12698,7 +12705,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp radius = o->amt * 2; if (radius > 10) radius = 10; - spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE); + spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL); } else if (o->type->id == OT_SALT) { int dist; dist = getcelldist(srcloc, where); @@ -13030,7 +13037,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp adjustdamforblessings(&throwdam, target, o->blessed); //dam = (int)((float)throwdam * multiplier); - dam = throwdam + speed; + dam = throwdam + (speed/2); // firearm adjustments if (firearm) { @@ -13177,6 +13184,9 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp if (thrower && isplayer(thrower)) { angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); } + } else if (hasflag(newob->flags, F_MISSILEALWAYSDIES)) { + killob(newob); + newob = NULL; } else { // object only gets damaged if it hit someone/something if (missiledam) { @@ -13969,7 +13979,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) { if (oid == OT_TRAPWIND) { // can't be dodged - dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPNEEDLEP) { if (lf) { @@ -14009,7 +14019,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) { } addob(c->obpile, "stone"); } else if (oid == OT_TRAPTELEPORT) { - dospelleffects(NULL, OT_S_DISPERSAL, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_DISPERSAL, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); } else if (oid == OT_TRAPPIT) { cell_t *escapeto = NULL; addob(c->obpile, "hole in the ground"); @@ -14086,10 +14096,10 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) { // announcement. } // can't be dodged - dospelleffects(NULL, OT_S_ENERGYBLAST, 1, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_ENERGYBLAST, 1, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPFIRE) { - dospelleffects(NULL, OT_S_FLAMEPILLAR, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_FLAMEPILLAR, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (lf && avoided) { cell_t *escapeto = NULL; escapeto = getrandomadjcell(c, WE_WALKABLE, B_NOEXPAND); @@ -14105,11 +14115,11 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) { if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPLIGHTNING) { // can't be dodged - dospelleffects(NULL, OT_S_CHAINLIGHTNING, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_CHAINLIGHTNING, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPGAS) { // can't be dodged - dospelleffects(NULL, OT_S_CLOUDKILL, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE); + dospelleffects(NULL, OT_S_CLOUDKILL, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPMINE) { // can't be dodged diff --git a/save.c b/save.c index 887cb08..03c1379 100644 --- a/save.c +++ b/save.c @@ -881,7 +881,7 @@ int savebones(map_t *m, room_t *r) { } else { // the lf will appear in the bones file char lfname[BUFLEN]; - real_getlfname(c->lf, lfname, B_FALSE, B_TRUE); + real_getlfname(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE); fprintf(f, "at(%d,%d) lf:%s\n", relx,rely, lfname); } } @@ -1183,6 +1183,8 @@ int saveobtobones(object_t *o, FILE *f, int x, int y) { if (o->material->id == MT_BLOOD) { sprintf(obname, "a blood stain"); + } else if (o->type->id == OT_GRIMOIRE) { + sprintf(obname, "grimoire"); } else { getobnametrue(o, obname, o->amt); } diff --git a/shops.c b/shops.c index c191b78..a3f6496 100644 --- a/shops.c +++ b/shops.c @@ -408,7 +408,7 @@ enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char * ch = getch(); if (possible && (ch == 'y')) { givemoney(player, NULL, cost); - dospelleffects(lf, OT_S_DETECTAURA, 10, lf, NULL, NULL, B_BLESSED, NULL, B_FALSE); + dospelleffects(lf, OT_S_DETECTAURA, 10, lf, NULL, NULL, B_BLESSED, NULL, B_FALSE, NULL); more(); } return SR_BACK; diff --git a/spell.c b/spell.c index aef2801..69380c7 100644 --- a/spell.c +++ b/spell.c @@ -59,10 +59,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef int power = 0,needgrab = B_FALSE, range = 0; char damstr[BUFLEN],racestr[BUFLEN]; objecttype_t *ot; + object_t *fromob = NULL; + char fromobname[BUFLEN]; flag_t *f; + strcpy(fromobname, ""); + if (user && cwflag && (cwflag->obfrom != -1)) { + fromob = findobbyid(user->pack, cwflag->obfrom); + if (fromob) { + real_getobname(fromob, fromobname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL); + } + } + getlfname(user, username); - real_getlfname(user,killername, B_FALSE, B_FALSE); + real_getlfname(user,killername, NULL, B_NOSHOWALL, B_REALRACE); // defaults strcpy(damstr,""); @@ -321,7 +331,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else { if (slev >= PR_EXPERT) { // overwrite name - real_getlfnamea(inway, thismovetext, B_FALSE, B_FALSE); + real_getlfnamea(inway, thismovetext, NULL, B_NOSHOWALL, B_CURRACE); } movetext[0] = strdup(thismovetext); movetextcount[0] = 1; @@ -335,7 +345,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (getnoisedetails(lf, N_WALK, NULL, thismovetext, NULL, &vol)) continue; if (slev >= PR_EXPERT) { // overwrite name - real_getlfnamea(lf, thismovetext, B_FALSE, B_FALSE); + real_getlfnamea(lf, thismovetext, NULL, B_NOSHOWALL, B_CURRACE); } if (canhear(user, lf->cell, vol)) { // already have this text? @@ -1742,8 +1752,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } if (targcell->obpile->first) { - // select object from cell... - o = askobject(targcell->obpile, "Snatch which object", NULL, NULL, '\0', AO_NONE); + if (isplayer(user)) { + // select object from cell... + o = askobject(targcell->obpile, "Snatch which object", NULL, NULL, '\0', AO_NONE); + } else { + object_t *oo; + for (oo = targcell->obpile->first; oo ; oo = oo->next) { + if (aiwants(user, oo, NULL)) { + o = oo; + break; + } + } + } } else { if (isplayer(user)) msg("There is nothing there to snatch!"); return B_TRUE; @@ -1753,8 +1773,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - // setting v0 to spellid just in case pickup() changes flags - addflag(user->flags, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); + // spell doesn't take any time, using an object does. + if (fromob) { + if (cansee(player, user)) { + char obname[BUFLEN]; + getobname(o, obname, 1); + msg("%s%s %s wraps around %s.", username, getpossessive(username), + noprefix(fromobname), obname); + } + } else { + // setting v0 to spellid just in case pickup() changes flags + addflag(user->flags, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); + } pickup(user, o, 1, B_TRUE, B_TRUE); f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); if (f) killflag(f); @@ -3438,7 +3468,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // returns TRUE on error -int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot) { +int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob) { char buf[BUFLEN]; char castername[BUFLEN]; int rv = B_FALSE; @@ -4110,7 +4140,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ dam = rnd(1,power); if (caster) { char cname[BUFLEN]; - real_getlfnamea(caster, cname, B_FALSE, B_FALSE); + real_getlfnamea(caster, cname, NULL, B_SHOWALL, B_REALRACE); sprintf(damstr, "%s%s blight spell.", cname, getpossessive(cname)); } else { strcpy(damstr, "a blight spell."); @@ -4304,7 +4334,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (!isimmuneto(c->lf->flags, DT_FIRE, B_FALSE)) { msg("%s burn%s!",buf,isplayer(c->lf) ? "" : "s"); } - real_getlfname(caster, realcname, B_FALSE, B_TRUE); + real_getlfname(caster, realcname, NULL, B_SHOWALL, B_REALRACE); snprintf(damstring, BUFLEN, "%s%s wave of fire", realcname, getpossessive(realcname)); losehp(c->lf, rolldie(2,10), DT_FIRE, caster, damstring); } @@ -5268,7 +5298,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } - getflags(target->flags, retflag, &nretflags, F_POISONED, F_NONE); + getflags(target->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE); for (i = 0; i < nretflags; i++) { poisontype_t *pt; pt = findpoisontype(retflag[i]->val[0]); @@ -5638,7 +5668,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_DETECTPOISON) { if (isplayer(caster)) { int npoisoned = 0; - int n; + int n,i; + flag_t *retflag[MAXCANDIDATES]; + int nretflags; + getflags(caster->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE); + for (i = 0; i < nretflags ; i++) { + flag_t *f; + poisontype_t *pt; + f = retflag[i]; + pt = findpoisontype(f->val[0]); + msg("You detect %s in your body.", pt->name); + f->known = B_TRUE; + } + for (n = 0; n < caster->nlos; n++) { object_t *o; for (o = caster->los[n]->obpile->first ; o ; o = o->next) { @@ -6902,7 +6944,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (killflagsofid(target->flags, F_PAIN)) { donesomething = B_TRUE; } - getflags(target->flags, retflag, &nretflags, F_POISONED, F_NONE); + getflags(target->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE); for (i = 0; i < nretflags; i++) { poisontype_t *pt; pt = findpoisontype(retflag[i]->val[0]); @@ -7365,7 +7407,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { char dambuf[BUFLEN]; char cname[BUFLEN]; - real_getlfname(caster, cname, B_FALSE, B_TRUE); + real_getlfname(caster, cname, NULL, B_SHOWALL, B_REALRACE); snprintf(dambuf, BUFLEN, "%s%s infinite death spell", cname, getpossessive(cname)); losehp(l, 500, DT_NECROTIC, NULL, dambuf); } @@ -7381,7 +7423,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { char dambuf[BUFLEN]; char cname[BUFLEN]; - real_getlfname(caster, cname, B_FALSE, B_TRUE); + real_getlfname(caster, cname, NULL, B_SHOWALL, B_REALRACE); snprintf(dambuf, BUFLEN, "%s%s infinite death spell", cname, getpossessive(cname)); losehp(caster, 500, DT_NECROTIC, NULL, dambuf); } @@ -7859,13 +7901,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (newsize != SZ_ANY) { resizeobject(targob, newsize); getobname(targob, newobname, 1); + getobname(targob, newobname, 1); if (seen) msg("%s grows into %s!", obname, newobname); } else if (newcelltype != CT_NONE) { cell_t *where; if (seen) { celltype_t *ct; ct = findcelltype(newcelltype); - msg("%s grows into %s %s!", needan(ct->name) ? "an" : "a", ct->name); + msg("%s grows into %s %s!", obname, needan(ct->name) ? "an" : "a", ct->name); } where = getoblocation(targob); killob(targob); @@ -8972,7 +9015,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char distbuf[BUFLEN],dirbuf[BUFLEN]; char lfname[BUFLEN]; - real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE); + real_getlfnamea(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE); getdisttext(caster->cell, c, distbuf, NULL, dirbuf); sprintf(ptext, "%s: %s (%s to the %s, held by %s)", mapname, obname, distbuf, dirbuf, lfname); @@ -9832,6 +9875,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } ndone++; } + } else if (f->id == F_INCUBATING) { + f->val[1] *= 2; } } if (ndone) { @@ -10595,6 +10640,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } // end if corpse + } else if (spellid == OT_S_SPIKEVOLLEY) { + object_t *o; + flag_t *f; + + // create a volley of spikes + o = addobfast(caster->pack, OT_SPIKEVOLLEY); + if (!o) { + fizzle(caster); + } + if (isplayer(caster) || cansee(player, caster)) { + msg("%s fire%s a volley of spikes!",castername,isplayer(caster) ? "" : "s"); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + f = hasflag(o->flags, F_MISSILEDAM); + if (f) { // should always be true + char dambuf[BUFLEN]; + free(f->text); + sprintf(dambuf, "%dd3", power); + f->text = strdup(dambuf); + } + real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY); } else if (spellid == OT_S_STENCH) { int howlong; @@ -10802,9 +10868,33 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (target) { int failed = B_FALSE; - if (spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) { + + if (!fromob && spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) { failed = B_TRUE; - } else { + } else if (fromob && skillcheck(target, SC_DODGE, 12, 0)) { + failed = B_TRUE; + // announce whip failures + if (cansee(player, target)) { + char obname[BUFLEN]; + char tname[BUFLEN]; + real_getobname(fromob, obname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL); + getlfname(target, tname); + msg("%s%s %s misses %s.", castername, getpossessive(castername), noprefix(obname), tname); + } + return B_FALSE; + } + if (!failed) { + // announce whip attacks + if (fromob && cansee(player, target)) { + char obname[BUFLEN]; + char tname[BUFLEN]; + real_getobname(fromob, obname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL); + getlfname(target, tname); + msg("%s%s %s wraps around %s.", castername, getpossessive(castername), noprefix(obname), tname); + } + if (caster) { + fightback(target, caster); + } // they get pulled towards caster failed = pullnextto(target, caster->cell); } @@ -10823,7 +10913,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } } else { - fizzle(caster); + if (!fromob) fizzle(caster); return B_TRUE; } } else if (spellid == OT_S_SUPERHEAT) { @@ -13229,7 +13319,7 @@ int schoolappearsinbooks(enum SPELLSCHOOL ss) { return B_TRUE; } -void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes) { +void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob) { int x,y; objecttype_t *ot; ot = findot(sid); @@ -13252,7 +13342,7 @@ void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE if (getcelldistorth(srcloc, c) <= radius) { // cast the spell if (ot->obclass->id == OC_SPELL) { - dospelleffects(NULL, ot->id, power, c->lf, NULL, c, B_UNCURSED, NULL, frompot); + dospelleffects(NULL, ot->id, power, c->lf, NULL, c, B_UNCURSED, NULL, frompot, fromob); } else if (ot->obclass->id == OC_ABILITY) { abilityeffects(c->lf, ot->id, c, c->lf, NULL); } diff --git a/spell.h b/spell.h index d3d172b..aa2a5c1 100644 --- a/spell.h +++ b/spell.h @@ -3,7 +3,7 @@ #include "defs.h" int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag); -int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot); +int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob); objecttype_t *findspelln(char *buf); enum SPELLSCHOOL findspellschoolbyname(char *buf); void fizzle(lifeform_t *caster); @@ -35,7 +35,7 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat); void pullobto(object_t *o, lifeform_t *lf); int schoolappearsinbooks(enum SPELLSCHOOL ss); -void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes); +void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob); int spellisfromschool(int spellid, enum SPELLSCHOOL school); int spellokformonsters(int spellid); int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce); diff --git a/text.c b/text.c index ceed2ea..3561962 100644 --- a/text.c +++ b/text.c @@ -246,11 +246,11 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam case DT_FIRE: snprintf(retbuf, BUFLEN, "^n%s %s hot.", locvictimname, isplayer(victim) ? "don't feel" : "doesn't look"); break; - case DT_MAGIC: - strcpy(retbuf, ""); - break; + //case DT_MAGIC: + //snprintf(retbuf, BUFLEN, "^n%s shrug%s off the effects.", locvictimname, isplayer(victim) ? "" : "s"); + //break; default: - snprintf(retbuf, BUFLEN, "^n%s shrug%s off the effects.", locvictimname, isplayer(victim) ? "" : "s"); + strcpy(retbuf, ""); break; } } else if (fatal) { // fatal @@ -282,7 +282,8 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam snprintf(retbuf, BUFLEN, "^nMagical energy sears %s!", locvictimname); break; default: - snprintf(retbuf, BUFLEN, "^n%s %s hurt!", locvictimname, is(victim)); + //snprintf(retbuf, BUFLEN, "^n%s %s hurt!", locvictimname, is(victim)); + strcpy(retbuf, ""); break; } } @@ -452,6 +453,18 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam } } } + + // whips deal normal damagetype(s), but have diferent attack + // verbs. + if (hasflagval(wep->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL)) { + if (dam <= 4) { + return "whip"; + } else if (dam <= 8) { + return "thrash"; + } else { + return "flay"; + } + } } if (damtype == DT_ACID) { @@ -1121,8 +1134,8 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d int canbehead = B_TRUE; if (wep) { sk = getobskill(wep->flags); - if (sk && (sk->id == SK_SHORTBLADES)) { - // short blades can't behead/bisect. + if (sk && (sk->id != SK_LONGBLADES) && (sk->id != SK_EXOTICWEPS)) { + // only long blades can behead/bisect. canbehead = B_FALSE; } } @@ -2193,9 +2206,15 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) { char *p,*plusloc; localtext = strdup(text); // number of dice - p = strtok_r(localtext, "d", &dummy); - if (!p) { - return B_TRUE; + if (strchr(localtext, 'c')) { + p = strtok_r(localtext, "d", &dummy); + } else { + // assume it's just a single number + *ndice = 0; + *nsides = 0; + *bonus = atoi(text); + free(localtext); + return B_FALSE; } if (ndice) { *ndice = atoi(p); @@ -2203,6 +2222,7 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) { // sides on each die p = strtok_r(NULL, "d", &dummy); if (!p) { + free(localtext); return B_TRUE; }