- [+] when throwin gn aobject, warn if you have no LOF (just like

spells)
- [+] allow dodge/catch of thrown object when there is no thrower (ie.
      arrow traps)
- [+] simplify monster spellcasting
    - [+] don't use any mp
    - [+] select power based on monster hit dice only
    - [+] monsters should cast spells less often  - use f_castchance,
          default of 15% chance
    - [+] TEST
    - [+] you keep your own mpdice when polymorphing into a mosnter
- [+] fxied: throw a tranq dart, then:
    - [+] The cockatrice loses consciousness.  The cockatrice falls
          asleep.
- [+] bug: can't operate a fridge on the ground cause it's too heavy to
      lift
- [+] monsters generated on dark levels should always have seeindark 3-4
- [+] vending machines not working... fixed.

- [+] in getchoicestr:
    - [+]  if !showall, and if it shows a longdesc, then you hit
          backspace, longdesc should be cleared.
    - [+] show completion in a different colour
- [+] bug: sometimes we seem to have map->room[x], but no cells with
      cell->room->id == thatid!!
    - [+] stop vaults from overlapping.
- [+] taking too long to walk down levels - enforce max number of
      monster free turns
- [+] inept weapon penalty should be slightly higher
- [+] bad feeling check is too easy.
- [+] skeletons should have f_noinjuries
- [+] shouldn't check for slipping on things while swimming
- [+] tweak how traps + perception skill impact search checks 
- [+] bug: sometimes we have no player start position.
    - [+] if the vault creation fails, restart map generation.
- [+] only give study scroll ability at high spellcasting skill
- [+] typo:  ring (1 charges left)
* [+] god effects when you die:
- [+] pea soup should work in the cell in FRONT of you.
- [+] bug: ring of control seems to work when you _weild_ it!!
- [+] non-lethal weapons
    - [+] sword of mercy (at <1hp, ko)
    - [+] tranq dart
- [+] add sleeptypes
    - [+] change all refernces to f_asleep->val[1] (now an enum)
    - [+] change "stirs in its slumber" if unconscious
    - [+] change all 'fallasleep' calls
    - [+] attacking a ko'd enemy with merciful weapon should do nothing.
    - [+] ai shouldn't target ko'd enemies
- [+] ai should stop targetting people once they're dead/ko'd
- [+] bashing damage should sometimes just knock unconscious instead of
      killing?
    - [+] if their hp would be >= -3, and onein(2)
- [+] different body part names? "metal frame" instead of "body"
    - [+]  implement F_BPNAME, v0=enum bodypart, text = name
    - [+] getbodypartname() needs a lf argument.
    - [+] once i add this, also make animals have "front legs" instead
          of "arms", "paws" rather than "hands" etc.
    - [+] fix calls to getbodypartname to pass in lf or null
- [+] cyborg mods:
    - [+] can't wear most armour?
        - [+] need f_noarmouron - we HAVE this bp, but can't put armour
              on it.
    - [+] large rust damage from water
- [+] if you have a bad feeling about an object, mark it as "[bad]"
    - [+] f_knownbad
- [+] killing should anger the god of mercy
This commit is contained in:
Rob Pearce 2011-09-22 02:00:16 +00:00
parent 7f33b6351c
commit 2db53bca61
19 changed files with 1112 additions and 474 deletions

23
ai.c
View File

@ -571,6 +571,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
if (attackok) { if (attackok) {
objecttype_t *st; objecttype_t *st;
flag_t *f;
int spellchance = 0;
// drink boost potions // drink boost potions
if (!useitemwithflag(lf, F_AIBOOSTITEM)) { if (!useitemwithflag(lf, F_AIBOOSTITEM)) {
return B_FALSE; return B_FALSE;
@ -579,7 +581,17 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
// try spells first. // try spells first.
// can we attack with spells (ie. ones which target the victim)? // can we attack with spells (ie. ones which target the victim)?
// if target is adjacent, we will normally just attack rather than try a spell. // if target is adjacent, we will normally just attack rather than try a spell.
// random chance of casting a spell
f = lfhasflag(lf, F_CASTCHANCE);
if (f) spellchance = f->val[0];
else spellchance = 15;
if (pctchance(spellchance)) {
spell = aigetattackspell(lf, target); spell = aigetattackspell(lf, target);
} else {
spell = OT_NONE;
}
st = findot(spell); st = findot(spell);
if ( (spell != OT_NONE) && // found a valid spell/ability to use if ( (spell != OT_NONE) && // found a valid spell/ability to use
((dist != 1) || // there is distance between us and target ((dist != 1) || // there is distance between us and target
@ -1237,6 +1249,12 @@ void aiturn(lifeform_t *lf) {
// do we already have a target we are attacking? // do we already have a target we are attacking?
if (target) { if (target) {
if (db) dblog(".oO { i have a target: lfid %d (%s). }", target->id, target->race->name); if (db) dblog(".oO { i have a target: lfid %d (%s). }", target->id, target->race->name);
// target dead or unconscious?
if (isdead(target) || isunconscious(target)) {
if (db) dblog(".oO { my target is dead/ko'd }", target->id, target->race->name);
loseaitargets(lf);
} else {
// aquatic grabbers will try to drag their prey into the water // aquatic grabbers will try to drag their prey into the water
if (lfhasflagval(lf, F_GRABBING, target->id, NA, NA, NULL) && isaquatic(lf) ) { if (lfhasflagval(lf, F_GRABBING, target->id, NA, NA, NULL) && isaquatic(lf) ) {
if ( hasobwithflag(lf->cell->obpile, F_DEEPWATER) && if ( hasobwithflag(lf->cell->obpile, F_DEEPWATER) &&
@ -1253,6 +1271,7 @@ void aiturn(lifeform_t *lf) {
return; return;
} }
} }
}
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -1375,7 +1394,7 @@ void aiturn(lifeform_t *lf) {
lifeform_t *who; lifeform_t *who;
if (lf->los[n] != lf->cell) { if (lf->los[n] != lf->cell) {
who = lf->los[n]->lf; who = lf->los[n]->lf;
if (who && cansee(lf, who)) { if (who && !isdead(who) && !isunconscious(who) && cansee(lf, who)) {
if (lfhasflagval(lf, F_HATESRACE, who->race->id, NA, NA, NULL) || if (lfhasflagval(lf, F_HATESRACE, who->race->id, NA, NA, NULL) ||
lfhasflagval(lf, F_HATESRACE, who->race->baseid, NA, NA, NULL) ) { lfhasflagval(lf, F_HATESRACE, who->race->baseid, NA, NA, NULL) ) {
if (db) dblog(".oO { found a hated target - lfid %d (%s) ! }",who->id, who->race->name); if (db) dblog(".oO { found a hated target - lfid %d (%s) ! }",who->id, who->race->name);
@ -1391,7 +1410,7 @@ void aiturn(lifeform_t *lf) {
if (lf->los[n] != lf->cell) { if (lf->los[n] != lf->cell) {
lifeform_t *who; lifeform_t *who;
who = lf->los[n]->lf; who = lf->los[n]->lf;
if (who && cansee(lf, who)) { if (who && cansee(lf, who) && !isdead(who) && !isunconscious(who)) {
if (areenemies(lf, who)) { if (areenemies(lf, who)) {
if (db) dblog(".oO { found an enemy target - lfid %d (%s) ! }",who->id, who->race->name); if (db) dblog(".oO { found an enemy target - lfid %d (%s) ! }",who->id, who->race->name);
newtarget = who; newtarget = who;

145
attack.c
View File

@ -172,6 +172,8 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
int attackedfriend = B_FALSE; int attackedfriend = B_FALSE;
int attackedpeaceful = B_FALSE; int attackedpeaceful = B_FALSE;
stoprunning(lf);
// anyone there? if so just attack. // anyone there? if so just attack.
if (c->lf) { if (c->lf) {
if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) { if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) {
@ -462,7 +464,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
// god effects... // god effects...
if (attacktype == AT_LF) { if ((attacktype == AT_LF) && isplayer(lf)) {
if (attackedfriend) { if (attackedfriend) {
angergodmaybe(R_GODMERCY, 100); angergodmaybe(R_GODMERCY, 100);
angergodmaybe(R_GODPURITY, 100); angergodmaybe(R_GODPURITY, 100);
@ -587,6 +589,22 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
} }
if (wep && lfhasflagval(victim, F_ASLEEP, NA, ST_KO, NA, NULL)) {
f = hasflag(wep->flags, F_MERCIFUL);
if (f) {
if (isplayer(lf)) {
msg("^wYour %s refuses to attack %s!", noprefix(wepname), victimname);
if (!f->known) f->known = B_TRUE;
} else if (cansee(player, lf)) {
msg("^w%s%s %s refuses to attack %s!", attackername, getpossessive(attackername),
noprefix(wepname), victimname);
if (!f->known) f->known = B_TRUE;
}
taketime(lf, getattackspeed(lf));
return B_FALSE;
}
}
getflags(lf->flags, retflag, &nretflags, F_NONCORPOREAL, F_NONE); getflags(lf->flags, retflag, &nretflags, F_NONCORPOREAL, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
@ -613,10 +631,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
critpos = getrandomcorebp(victim); critpos = getrandomcorebp(victim);
// replace victicname to include body part // replace victicname to include body part
if ((lf == victim) && !isplayer(lf)) { if ((lf == victim) && !isplayer(lf)) {
snprintf(victimbpname, BUFLEN, "its %s", getbodypartname(critpos)); snprintf(victimbpname, BUFLEN, "its %s", getbodypartname(victim, critpos));
} else { } else {
getlfname(victim, buf); getlfname(victim, buf);
snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), getbodypartname(critpos)); snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), getbodypartname(victim, critpos));
} }
} else { } else {
strcpy(victimbpname, ""); strcpy(victimbpname, "");
@ -751,7 +769,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
dam[0] *= 2; dam[0] *= 2;
} }
// bonus for knowledge about the other lf's race? applied LAST. // bonus for knowledge about the other lf's race? applied LAST.
slev = getlorelevel(lf, victim->race->raceclass->id); slev = getlorelevel(lf, victim->race->raceclass->id);
if (slev == PR_INEPT) { if (slev == PR_INEPT) {
@ -907,7 +924,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
strcpy(extradambuf, ""); strcpy(extradambuf, "");
if (dam[i] == 0) { if (dam[i] == 0) {
if (getlorelevel(lf, victim->race->raceclass->id) >= PR_ADEPT) { if (getlorelevel(lf, victim->race->raceclass->id)) {
//strcpy(extradambuf, " but do no damage"); //strcpy(extradambuf, " but do no damage");
strcpy(extradambuf, " ineffectually"); strcpy(extradambuf, " ineffectually");
} }
@ -1040,7 +1057,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// other effects // other effects
if (!isdead(victim) && !blocked) { if (!isdead(victim) && !blocked) {
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW)) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
wepeffects(wep->flags, victim->cell, damflag, dam[0]); wepeffects(wep->flags, victim->cell, damflag, dam[0]);
} }
if (isunarmed) { if (isunarmed) {
@ -1106,7 +1123,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// confer flags from attacker? // confer flags from attacker?
if (dam[0]) {
wepeffects(lf->flags, victim->cell, damflag, dam[0]); wepeffects(lf->flags, victim->cell, damflag, dam[0]);
}
// special lifeform-based effects // special lifeform-based effects
if ((lf->race->id == R_COCKATRICE) && dam[0]) { if ((lf->race->id == R_COCKATRICE) && dam[0]) {
@ -1135,7 +1154,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
} }
// if victim can still move...
if (hasfreeaction(victim)) {
fightback(victim, lf); fightback(victim, lf);
}
} // end if !isdead(victim) } // end if !isdead(victim)
// retaliation happens even if victim died // retaliation happens even if victim died
@ -1371,7 +1393,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
} // end foreach damtype } // end foreach damtype
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW)) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
wepeffects(wep->flags, obloc, damflag, dam[0]); wepeffects(wep->flags, obloc, damflag, dam[0]);
} }
@ -1393,8 +1415,8 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype) { void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype) {
object_t *o; object_t *o,*armour;
char lfname[BUFLEN],victimname[BUFLEN]; char lfname[BUFLEN],victimname[BUFLEN],obname[BUFLEN];
// replace some dam types // replace some dam types
if (damtype == DT_UNARMED) damtype = DT_BASH; if (damtype == DT_UNARMED) damtype = DT_BASH;
if (damtype == DT_BITE) damtype = DT_SLASH; if (damtype == DT_BITE) damtype = DT_SLASH;
@ -1410,23 +1432,42 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: fall(victim, lf, B_TRUE); break; case 1: fall(victim, lf, B_TRUE); break;
case 2: case 2:
if (lf) {
if (cansee(player, lf) || cansee(player, victim)) { if (cansee(player, lf) || cansee(player, victim)) {
getlfname(lf, lfname); getlfname(lf, lfname);
getlfname(victim, victimname); getlfname(victim, victimname);
setfacing(victim, getrandomdirexcept(DT_COMPASS, victim->facing)); setfacing(victim, getrandomdirexcept(DT_COMPASS, victim->facing));
msg("%s%s blow spins %s around!", lfname, getpossessive(lfname),victimname); msg("%s%s blow spins %s around!", lfname, getpossessive(lfname),victimname);
} }
} else {
if (isplayer(victim) || cansee(player, victim)) {
getlfname(victim, victimname);
setfacing(victim, getrandomdirexcept(DT_COMPASS, victim->facing));
msg("%s is spun around!", victimname);
}
}
break; break;
} }
} }
if (!getarmour(victim, BP_BODY)) injure(victim, BP_BODY, damtype); if ((armour = getarmour(victim, BP_BODY)) != NULL) {
getobname(armour, obname, armour->amt);
if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) {
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
} else {
injure(victim, BP_BODY, damtype);
}
break; break;
case BP_HEAD: case BP_HEAD:
if (pctchance(80)) fall(victim, lf, B_TRUE); if (pctchance(80)) fall(victim, lf, B_TRUE);
stun(victim, 1); stun(victim, 2);
// chance of your helmet falling off // chance of your helmet falling off
o = getarmour(victim, BP_HEAD); o = getarmour(victim, BP_HEAD);
if (o) { if (o) {
if (onein(2)) {
if (isplayer(victim)) { if (isplayer(victim)) {
char buf[BUFLEN]; char buf[BUFLEN];
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
@ -1438,23 +1479,70 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
msg("%s%s %s falls off!", lfname, getpossessive(lfname), noprefix(buf)); msg("%s%s %s falls off!", lfname, getpossessive(lfname), noprefix(buf));
} }
moveob(o, victim->cell->obpile, o->amt); moveob(o, victim->cell->obpile, o->amt);
} else {
if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) {
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
}
} else { } else {
injure(victim, BP_HEAD, damtype); injure(victim, BP_HEAD, damtype);
} }
break; break;
case BP_HANDS: case BP_HANDS:
if (!getarmour(victim, BP_HANDS)) injure(victim, BP_HANDS, damtype); if ((armour = getarmour(victim, BP_HANDS)) != NULL) {
getobname(armour, obname, armour->amt);
if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) {
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
} else {
injure(victim, BP_HANDS, damtype);
}
if (onein(2)) {
// drop your weapon! // drop your weapon!
o = getweapon(victim); o = getweapon(victim);
if (o) drop(o, ALL); if (o) drop(o, ALL);
break; break;
}
case BP_LEGS: case BP_LEGS:
if (pctchance(70)) fall(victim, lf, B_TRUE); if (pctchance(70)) fall(victim, lf, B_TRUE);
if (!getarmour(victim, BP_LEGS)) injure(victim, BP_LEGS, damtype); if ((armour = getarmour(victim, BP_LEGS)) != NULL) {
getobname(armour, obname, armour->amt);
if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) {
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
} else {
injure(victim, BP_LEGS, damtype);
}
break; break;
} }
} else if (damtype == DT_SLASH) { } else if (damtype == DT_SLASH) {
if (!getarmour(victim, hitpos)) injure(victim, hitpos, damtype); if ((armour = getarmour(victim, hitpos)) != NULL) {
getobname(armour, obname, armour->amt);
if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) {
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
} else {
injure(victim, hitpos, damtype);
}
} else if (damtype == DT_EXPLOSIVE) {
if ((armour = getarmour(victim, hitpos)) != NULL) {
int min,max;
max = getobmaxhp(o);
min = max / 2;
limit(&min, 1, NA);
takedamage(armour, rnd(min,max), DT_EXPLOSIVE);
} else {
injure(victim, hitpos, damtype);
}
} }
if (lf) { if (lf) {
@ -1581,16 +1669,18 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
} else if (damtype == DT_BASH) { } else if (damtype == DT_BASH) {
if (pct <= 5) { if (pct <= 5) {
return "whack"; return "whack";
} else if (pct <= 20) { } else if (pct <= 15) {
if (onein(2)) { if (onein(2)) {
return "hit"; return "hit";
} else { } else {
return "bash"; return "bash";
} }
} else if (pct <= 30) { } else if (pct <= 25) {
return "pummel"; return "pummel";
} else { } else if (pct <= 35) {
return "slam"; return "slam";
} else {
return "clobber";
} }
} else if (damtype == DT_BITE) { } else if (damtype == DT_BITE) {
if (lf && (ownersize <= SZ_SMALL)) { if (lf && (ownersize <= SZ_SMALL)) {
@ -1807,6 +1897,10 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
float pct; float pct;
pct = (int)(((float) dam / (float) maxhp) * 100.0); pct = (int)(((float) dam / (float) maxhp) * 100.0);
if (wep && hasflag(wep->flags, F_MERCIFUL)) {
return "knock out";
}
if (victim->race->id == R_DANCINGWEAPON) { if (victim->race->id == R_DANCINGWEAPON) {
return "defeat"; return "defeat";
} }
@ -1876,6 +1970,11 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
// can't "kill" the undead // can't "kill" the undead
return "destroy"; return "destroy";
} }
// never use 'kill' for bashing since you might just knock them out
if (damtype == DT_BASH) {
return "clobber";
}
return "kill"; return "kill";
} }
@ -2324,7 +2423,6 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
f->known = B_TRUE; f->known = B_TRUE;
} else if ((f->id == F_HITCONFER) && victim ) { } else if ((f->id == F_HITCONFER) && victim ) {
// only works if we did damage // only works if we did damage
if (dam) {
enum FLAG fid; enum FLAG fid;
int howlong; int howlong;
flag_t *valflag = NULL; flag_t *valflag = NULL;
@ -2392,15 +2490,11 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
poison(victim, howlong, ptype, ppower, frombuf); poison(victim, howlong, ptype, ppower, frombuf);
} else { } else {
flag_t *conferredflag;
conferredflag = addtempflag(victim->flags, fid, NA, NA, NA, NULL, howlong);
// flag values // flag values
if (valflag) { if (valflag) {
conferredflag->val[0] = valflag->val[0]; addtempflag(victim->flags, fid, valflag->val[0], valflag->val[1], valflag->val[2], valflag->text, howlong);
conferredflag->val[1] = valflag->val[1]; } else {
conferredflag->val[2] = valflag->val[2]; addtempflag(victim->flags, fid, NA, NA, NA, NULL, howlong);
free(conferredflag->text);
conferredflag->text = strdup(valflag->text);
} }
} }
} // end if passedcheck } // end if passedcheck
@ -2413,7 +2507,6 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
addflag(owner->flags, F_USEDPOISON, B_TRUE, NA, NA, NULL); addflag(owner->flags, F_USEDPOISON, B_TRUE, NA, NA, NULL);
} }
} }
}
} // end if (fid == hitconfer) } // end if (fid == hitconfer)
} }

213
data.c
View File

@ -161,6 +161,7 @@ void initjobs(void) {
// stat mods // stat mods
// initial objects // initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "short sword");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing");
@ -178,7 +179,6 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
} }
// abilities // abilities
addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL);
addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL);
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
@ -268,6 +268,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_NATURE, PR_NOVICE, NA, NULL);
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
@ -607,6 +608,7 @@ void initjobs(void) {
f = addflag(lastjob->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 33); f = addflag(lastjob->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 33);
f = addflag(lastjob->flags, F_CANCAST, OT_S_HASTE, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20); f = addflag(lastjob->flags, F_CANCAST, OT_S_HASTE, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20);
f = addflag(lastjob->flags, F_CANCAST, OT_S_HEALING, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20); f = addflag(lastjob->flags, F_CANCAST, OT_S_HEALING, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20);
addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL);
// non-player jobs // non-player jobs
addjob(J_SHOPKEEPER, "Shopkeeper"); addjob(J_SHOPKEEPER, "Shopkeeper");
@ -742,14 +744,16 @@ void initobjects(void) {
// weapons // weapons
addbrand(BR_BALANCE, "of balance", BP_WEAPON); addbrand(BR_BALANCE, "of balance", BP_WEAPON);
addflag_real(lastbrand->flags, F_BALANCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_BALANCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_IMPACT, "of impact", BP_WEAPON); // TODO: make thisonly go ont obashing weapons
addflag_real(lastbrand->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_MERCY, "of mercy", BP_WEAPON);
addflag_real(lastbrand->flags, F_MERCIFUL, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_PYROMANIA, "of pyromania", BP_WEAPON); addbrand(BR_PYROMANIA, "of pyromania", BP_WEAPON);
addflag_real(lastbrand->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_REVENGE, "of revenge", BP_WEAPON); addbrand(BR_REVENGE, "of revenge", BP_WEAPON);
addflag_real(lastbrand->flags, F_REVENGE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_REVENGE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_SHARPNESS, "of sharpness", BP_WEAPON); addbrand(BR_SHARPNESS, "of sharpness", BP_WEAPON);
addflag_real(lastbrand->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_IMPACT, "of impact", BP_WEAPON); // TODO: make thisonly go ont obashing weapons
addflag_real(lastbrand->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
// feet // feet
addbrand(BR_LEVITATION, "of hovering", BP_FEET); addbrand(BR_LEVITATION, "of hovering", BP_FEET);
@ -3077,7 +3081,7 @@ void initobjects(void) {
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
addot(OT_FRIDGE, "refrigerator", "An insulated household appliance, made for storing food.", MT_METAL, 80, OC_TOOLS, SZ_HUMAN); addot(OT_FRIDGE, "refrigerator", "An insulated household appliance, made for storing food.", MT_METAL, 120, OC_TOOLS, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "]"); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "]");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -3542,7 +3546,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "evaporates"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "evaporates");
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of acid"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of acid");
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
@ -3556,7 +3560,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "~"); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "~");
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates"); addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
@ -3570,7 +3574,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates"); addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
@ -4350,7 +4354,7 @@ void initobjects(void) {
addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING, SZ_MINI); addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 2, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 3, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL);
addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING, SZ_MINI); addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
@ -4533,22 +4537,31 @@ void initobjects(void) {
addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE, SZ_SMALL); 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_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, ""); addflag(lastot->flags, F_MISSILEDAM, 1, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL);
addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE, SZ_TINY); 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_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, ""); addflag(lastot->flags, F_MISSILEDAM, 1, NA, NA, "");
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, 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_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 4, NA, NULL);
addflag(lastot->flags, F_HITCONFER, F_ASLEEP, SC_CON, 27, "20-30");
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, ST_ASLEEP, NA, NULL);
addot(OT_NEEDLE, "needle", "A tiny pointed needle.", MT_METAL, 0.02, OC_MISSILE, SZ_TINY); addot(OT_NEEDLE, "needle", "A tiny pointed needle.", MT_METAL, 0.02, OC_MISSILE, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
@ -4618,7 +4631,6 @@ void initobjects(void) {
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM); addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+1"); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+1");
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
@ -5196,6 +5208,9 @@ void initrace(void) {
addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
// other special stuff // other special stuff
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screechs^a screech"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screechs^a screech");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "talons");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right claw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left claw");
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL);
addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL);
@ -5207,25 +5222,39 @@ void initrace(void) {
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL);
addrace(R_CYBORG, "cyborg", 150, 'R', C_GREY, MT_METAL, RC_HUMANOID); addrace(R_CYBORG, "cyborg", 150, 'R', C_GREY, MT_FLESH, RC_HUMANOID);
// stats // stats
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL);
// bonuses // bonuses
addflag(lastrace->flags, F_EXTRAINFO, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EXTRAINFO, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_TECHUSAGE, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_TECHUSAGE, PR_ADEPT, NA, NULL);
// penalties // penalties
addflag(lastrace->flags, F_DTVULN, 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_DTVULN, DT_WATER, NA, NA, "2d6");
addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_BODY, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_RIGHTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_LEFTFINGER, NA, NA, NULL);
// other special stuff // other special stuff
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of oil"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of oil");
addflag(lastrace->flags, F_BODYPARTNAME, BP_EARS, NA, NA, "audio inputs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_EYES, NA, NA, "video inputs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "metal frame");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEGS, NA, NA, "stabilisers");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "robotic hands");
addflag(lastrace->flags, F_BODYPARTNAME, BP_FEET, NA, NA, "lower propulsion units");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right sensor");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left sensor");
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL);
addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL);
@ -5273,8 +5302,6 @@ void initrace(void) {
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins");
@ -5290,6 +5317,10 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL);
// bonuses
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
// human monsters... // human monsters...
addrace(R_BANDITLDR, "bandit leader", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID); addrace(R_BANDITLDR, "bandit leader", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID);
@ -5572,10 +5603,12 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "50d4"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "50d4");
addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed longsword of mercy");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 blessed vials of ambrosia"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 blessed vials of ambrosia");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "2 rings of regeneration"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "2 rings of regeneration");
addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_LONGBLADES, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "raises her hand"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "raises her hand");
// god abilities // god abilities
addflag(lastrace->flags, F_GODOF, B_FEMALE, NA, NA, "Mercy"); addflag(lastrace->flags, F_GODOF, B_FEMALE, NA, NA, "Mercy");
@ -5631,6 +5664,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_EXPERT, 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_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_EYES, NA, NA, "eyestalks");
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_BUGBEAR, "bugbear", 120, 'G', C_BROWN, MT_FLESH, RC_HUMANOID); addrace(R_BUGBEAR, "bugbear", 120, 'G', C_BROWN, MT_FLESH, RC_HUMANOID);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -5654,6 +5689,9 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_MINIONS, 50, 1, 3, "goblin"); addflag(lastrace->flags, F_MINIONS, 50, 1, 3, "goblin");
addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior"); addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC); addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC);
addflag(lastrace->flags, F_STARTATT, A_DEX, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_VHIGH, NA, NULL);
@ -5701,6 +5739,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:1d6;"); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:1d6;");
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;");
addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL);
addrace(R_DARKMANTLE, "darkmantle", 70, 'U', C_BLUE, MT_FLESH, RC_MAGIC); addrace(R_DARKMANTLE, "darkmantle", 70, 'U', C_BLUE, MT_FLESH, RC_MAGIC);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -5748,8 +5787,6 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLSPEED, SP_VERYSLOW, NA, NA, NULL); addflag(lastrace->flags, F_SPELLSPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_MPDICE, 0, 25, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 12, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_DISPERSAL, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_DISPERSAL, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_GRAVBOOST, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_GRAVBOOST, NA, NA, NULL);
addflag(lastrace->flags, F_CASTTYPE, CT_GAZE, NA, NA, NULL); addflag(lastrace->flags, F_CASTTYPE, CT_GAZE, NA, NA, NULL);
@ -5764,6 +5801,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, 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_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_GIANTHILL, "hill giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID); addrace(R_GIANTHILL, "hill giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -5854,8 +5892,6 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL);
addflag(lastrace->flags, F_MPDICE, 0, 9, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 1, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEPILLAR, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEPILLAR, NA, NA, NULL);
@ -5922,6 +5958,9 @@ void initrace(void) {
addflag(lastrace->flags, F_PACKATTACK, 3, NA, 2, NULL); addflag(lastrace->flags, F_PACKATTACK, 3, NA, 2, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); 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_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_GNOLLHM, "gnoll huntmaster", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); addrace(R_GNOLLHM, "gnoll huntmaster", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID);
lastrace->baseid = R_GNOLL; lastrace->baseid = R_GNOLL;
@ -5952,6 +5991,9 @@ void initrace(void) {
addflag(lastrace->flags, F_MINIONS, 75, 1, 2, "gnoll"); addflag(lastrace->flags, F_MINIONS, 75, 1, 2, "gnoll");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, 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_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_GNOLLMR, "gnoll marauder", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); addrace(R_GNOLLMR, "gnoll marauder", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID);
lastrace->baseid = R_GNOLL; lastrace->baseid = R_GNOLL;
@ -5981,6 +6023,9 @@ void initrace(void) {
addflag(lastrace->flags, F_MINIONS, 75, 1, 2, "gnoll"); addflag(lastrace->flags, F_MINIONS, 75, 1, 2, "gnoll");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); 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_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_GOBLIN, "goblin", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); addrace(R_GOBLIN, "goblin", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -6093,14 +6138,13 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_PACKATTACK, 2, DT_SLASH, 3, NULL); addflag(lastrace->flags, F_PACKATTACK, 2, DT_SLASH, 3, NULL);
addflag(lastrace->flags, F_MPDICE, 0, 10, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 3, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_BLINDNESS, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_BLINDNESS, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_PAIN, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_PAIN, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, 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_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MINIONS, 90, 1, 2, "goblin"); addflag(lastrace->flags, F_MINIONS, 90, 1, 2, "goblin");
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID); addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -6109,7 +6153,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_FOREST, 73, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 73, NA, NULL);
addflag(lastrace->flags, F_NUMAPPEAR, 1, 2, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 2, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+3"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3");
addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -6180,7 +6224,7 @@ void initrace(void) {
addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3-1");
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_DEX, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_HIGH, NA, NULL);
@ -6209,8 +6253,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d4");
addflag(lastrace->flags, F_HASATTACK, OT_TAIL, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_TAIL, NA, NA, "1d6");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "club"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "club");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold coins"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold coins");
@ -6268,10 +6312,12 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_EXPERT, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;");
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roar"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roar");
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HEAD, NA, NA, NULL);
addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID); addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID);
@ -6496,8 +6542,6 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_MPDICE, 0, 4, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 4, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures");
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
@ -6511,6 +6555,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_XPMULTIPLY, 2, NA, NA, NULL); addflag(lastrace->flags, F_XPMULTIPLY, 2, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID); addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -6532,8 +6577,6 @@ void initrace(void) {
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "plays its pipes"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "plays its pipes");
addflag(lastrace->flags, F_RESISTMAG, 10, NA, NA, NULL); addflag(lastrace->flags, F_RESISTMAG, 10, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MPDICE, 0, 16, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 8, NA, NA, NULL);
addflag(lastrace->flags, F_NEEDOBFORSPELLS, OT_PANPIPES, NA, NA, NULL); 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_CHARM, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, NA, NA, NULL);
@ -6544,6 +6587,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_HIDE, NA, 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_STARTHIDDENPCT, 60, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_SHADOWCAT, "shadowcat", 5, 'f', C_BLUE, MT_FLESH, RC_MAGIC); addrace(R_SHADOWCAT, "shadowcat", 5, 'f', C_BLUE, MT_FLESH, RC_MAGIC);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -6561,6 +6605,9 @@ void initrace(void) {
addflag(lastrace->flags, F_CANSEETHROUGHMAT, MT_GAS, NA, NA, NULL); addflag(lastrace->flags, F_CANSEETHROUGHMAT, MT_GAS, NA, NA, NULL);
addflag(lastrace->flags, F_AUTOCREATEOB, 1, NA, NA, "cloud of smoke"); addflag(lastrace->flags, F_AUTOCREATEOB, 1, NA, NA, "cloud of smoke");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME); addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pool of slime"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pool of slime");
@ -6571,6 +6618,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL);
@ -6602,8 +6650,6 @@ void initrace(void) {
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_MPDICE, 0, 4, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 1, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3");
@ -6615,6 +6661,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, 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_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC); addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "sheet of ice"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "sheet of ice");
@ -6628,8 +6675,6 @@ void initrace(void) {
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_MPDICE, 4, 2, NA, NULL);
addflag(lastrace->flags, F_MPREGEN, 1, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FROSTBITE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FROSTBITE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FREEZEOB, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FREEZEOB, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_ICICLE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_ICICLE, NA, NA, NULL);
@ -6641,6 +6686,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, 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_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addrace(R_TROLL, "troll", 100, 't', C_GREEN, MT_FLESH, RC_HUMANOID); addrace(R_TROLL, "troll", 100, 't', C_GREEN, MT_FLESH, RC_HUMANOID);
@ -6660,6 +6706,9 @@ void initrace(void) {
addflag(lastrace->flags, F_HUMANOID, 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, 30, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL);
@ -6676,6 +6725,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
// fish // fish
addrace(R_CRAB, "giant crab", 250, ';', C_ORANGE, MT_FLESH, RC_AQUATIC); addrace(R_CRAB, "giant crab", 250, ';', C_ORANGE, MT_FLESH, RC_AQUATIC);
@ -6691,13 +6743,16 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d4");
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "pincers");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addflag(lastrace->flags, F_NOARMOURON, BP_RIGHTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_LEFTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL);
addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC); addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC);
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -6921,6 +6976,9 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, 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:2d4;"); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d4;");
addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub"); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_YELLOW, MT_FLESH, RC_ANIMAL); addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_YELLOW, MT_FLESH, RC_ANIMAL);
lastrace->baseid = R_BEAR; lastrace->baseid = R_BEAR;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -6946,6 +7004,9 @@ void initrace(void) {
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BLEEDABIL, OT_A_RAGE, NA, NA, NULL); addflag(lastrace->flags, F_BLEEDABIL, OT_A_RAGE, NA, NA, NULL);
addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub"); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL);
lastrace->baseid = R_BEAR; lastrace->baseid = R_BEAR;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -6966,6 +7027,9 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, 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_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL);
lastrace->baseid = R_ANT; lastrace->baseid = R_ANT;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -7068,7 +7132,6 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
@ -7076,6 +7139,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_FLEEONHPPCT, 60, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 60, NA, NA, "");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL); addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -7092,7 +7158,6 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL);
@ -7102,6 +7167,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL); addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_NUMAPPEAR, 2, 6, NA, ""); addflag(lastrace->flags, F_NUMAPPEAR, 2, 6, NA, "");
@ -7121,7 +7189,6 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
@ -7131,6 +7198,9 @@ void initrace(void) {
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 24, "10-15"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 24, "10-15");
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL);
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NUMAPPEAR, 1, 4, NA, ""); addflag(lastrace->flags, F_NUMAPPEAR, 1, 4, NA, "");
@ -7147,7 +7217,6 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
@ -7155,6 +7224,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 2, NA, "growls^growling"); 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_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian
lastrace->baseid = R_HAWK; lastrace->baseid = R_HAWK;
@ -7290,6 +7362,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:4;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:4;");
addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;"); addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addrace(R_NEWT, "giant newt", 4, ':', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_NEWT, "giant newt", 4, ':', C_BROWN, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
@ -7300,6 +7373,9 @@ void initrace(void) {
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d2-1");
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2-1");
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_FLEEONDAM, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLEEONDAM, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
@ -7346,6 +7422,9 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 4, NA, 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_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL); addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, "");
addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, "");
@ -7414,6 +7493,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^hissing"); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^hissing");
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, 2, 2, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, 2, 2, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addrace(R_SNAKECOBRABLACK, "black cobra", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL); addrace(R_SNAKECOBRABLACK, "black cobra", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, "");
@ -7532,6 +7612,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:1;range:4;"); addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:1;range:4;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
@ -7539,6 +7620,8 @@ void initrace(void) {
addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web"); addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs"); addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HEAD, NA, NA, "cephalothorax");
addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen");
addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL); addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL);
lastrace->baseid = R_SPIDER; lastrace->baseid = R_SPIDER;
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, "");
@ -7558,6 +7641,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:5;range:2;"); addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:5;range:2;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
@ -7565,6 +7649,8 @@ void initrace(void) {
addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web"); addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "20-30 webs"); addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "20-30 webs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HEAD, NA, NA, "cephalothorax");
addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen");
addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL); addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL);
lastrace->baseid = R_SPIDER; lastrace->baseid = R_SPIDER;
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, "");
@ -7584,6 +7670,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:7;range:3;"); addflag(lastrace->flags, F_CANWILL, OT_S_WEB, 3, 3, "pw:7;range:3;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
@ -7591,6 +7678,8 @@ void initrace(void) {
addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web"); addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "10-20 webs"); addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "10-20 webs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HEAD, NA, NA, "cephalothorax");
addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen");
addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL); addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -7616,6 +7705,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
addflag(lastrace->flags, F_FLEEONHPPCT, 75, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 75, NA, NA, "");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL); addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -7641,6 +7733,9 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "paws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
// insects // insects
addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL); addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL);
@ -7733,6 +7828,9 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:1d4;"); addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:1d4;");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT); addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, "");
@ -7894,12 +7992,27 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d5"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d5");
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOBDT, 50, DT_CHOP, NA, NULL); addflag(lastrace->flags, F_STARTOBDT, 50, DT_CHOP, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 25, DT_CHOP, NA, "buckler"); addflag(lastrace->flags, F_STARTOB, 25, NA, NA, "buckler");
addflag(lastrace->flags, F_DTVULN, DT_BASH, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_EARS, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_WEAPON, NA, NA, "right metacarpals");
addflag(lastrace->flags, F_BODYPARTNAME, BP_SECWEAPON, NA, NA, "left metacarpals");
addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "ribs");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HEAD, NA, NA, "skull");
addflag(lastrace->flags, F_BODYPARTNAME, BP_SHOULDERS, NA, NA, "scapulas");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "carpals");
addflag(lastrace->flags, F_BODYPARTNAME, BP_WAIST, NA, NA, "coccyx");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEGS, NA, NA, "fibulas");
addflag(lastrace->flags, F_BODYPARTNAME, BP_FEET, NA, NA, "tarsals");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right phalange");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left phalange");
addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD); addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -7921,6 +8034,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD); // p for sPirit addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD); // p for sPirit
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -7934,6 +8048,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+2"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+2");
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_XRAYVIS, 3, NA, NA, NULL); addflag(lastrace->flags, F_XRAYVIS, 3, NA, NA, NULL);
@ -7964,6 +8079,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws");
addrace(R_VAMPIRE, "vampire", 75, 'V', C_BLUE, MT_FLESH, RC_UNDEAD); addrace(R_VAMPIRE, "vampire", 75, 'V', C_BLUE, MT_FLESH, RC_UNDEAD);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -7993,11 +8109,11 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4");
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+3");
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_RETAINHPMPONPOLY, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_S_CHARM, 3, 3, "pw:6;"); addflag(lastrace->flags, F_CANWILL, OT_S_CHARM, 3, 3, "pw:6;");
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, 5, 5, "range:3;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, 5, 5, "range:3;");
addflag(lastrace->flags, F_CANWILL, OT_S_STUN, 5, 5, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_STUN, 5, 5, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_POLYMORPH, 3, 3, "pw:1;race:vampire bat;"); addflag(lastrace->flags, F_CANWILL, OT_S_POLYMORPH, 3, 3, "pw:1;race:vampire bat;");
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_DETECTOBS, 10, OT_COFFIN, NA, NULL); addflag(lastrace->flags, F_DETECTOBS, 10, OT_COFFIN, NA, NULL);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pile of ash"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pile of ash");
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "gestures"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "gestures");
@ -8030,6 +8146,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 4, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_ALL, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_ALL, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
@ -8054,6 +8171,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
@ -8079,6 +8197,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
@ -8237,7 +8356,7 @@ void initskills(void) {
addskilldesc(SK_SPEECH, PR_EXPERT, "^gShop item prices are reduced by 25%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_EXPERT, "^gShop item prices are reduced by 25%.^n", B_FALSE);
addskilldesc(SK_SPEECH, PR_MASTER, "^gShop item prices are reduced by 30%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_MASTER, "^gShop item prices are reduced by 30%.^n", B_FALSE);
addskill(SK_SPELLCASTING, "Sorcery", "Increases the power of spells from all schools except Allomancy, Nature and Psionics.", 50); addskill(SK_SPELLCASTING, "Sorcery", "Increases the power of spells from all schools except Allomancy, Nature and Psionics.", 50);
addskilldesc(SK_SPELLCASTING, PR_NOVICE, "^gYou gain the 'study scrolls' ability.^n", B_FALSE); addskilldesc(SK_SPELLCASTING, PR_SKILLED, "^gYou gain the 'study scrolls' ability.^n", B_FALSE);
addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50); addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50);
addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE); addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE);
addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE);

Binary file not shown.

37
defs.h
View File

@ -251,7 +251,7 @@ enum RELATIVEDIR {
#define SAVEDIR "data/save" #define SAVEDIR "data/save"
#define VAULTDIR "vaults" #define VAULTDIR "vaults"
// rank, score, name, job, killer // rank, score, name, job, killer
#define HISCOREFORMAT "%-6s%-7s%-10s%-18s%s" #define HISCOREFORMAT "%-5s%-7s%-10s%-23s%s"
// game strings // game strings
#define MORESTRING "--More--" #define MORESTRING "--More--"
@ -292,8 +292,8 @@ enum RELATIVEDIR {
// Time periods // Time periods
#define TM_DRUNKTIME (10) // how long it takes for alcohol to wear off #define TM_DRUNKTIME (10) // how long it takes for alcohol to wear off
#define TM_WETTIME (10) // how long it takes for things to dry #define TM_WETTIME (10) // how long it takes for things to dry
#define TM_SCENT (15) // how long scents take to fade #define TM_SCENT (30) // how long scents take to fade
#define TM_FOOTPRINT (20) // how long footprints take to fade #define TM_FOOTPRINT (35) // how long footprints take to fade
// object conditions for random objects // object conditions for random objects
#define RO_NONE 0 #define RO_NONE 0
@ -1503,7 +1503,8 @@ enum OBTYPE {
OT_ARROW, OT_ARROW,
OT_BOLT, OT_BOLT,
OT_DART, OT_DART,
OT_NANODART, OT_DARTNANO,
OT_DARTTRANQ,
OT_NEEDLE, OT_NEEDLE,
OT_JAVELIN, OT_JAVELIN,
OT_BULLET, OT_BULLET,
@ -1684,6 +1685,12 @@ enum RANGEATTACK {
RA_WAND, RA_WAND,
}; };
enum SLEEPTYPE {
ST_ASLEEP = 0,
ST_MEDITATING,
ST_KO,
};
enum FLAG { enum FLAG {
F_NONE = 0, // dummy flag F_NONE = 0, // dummy flag
// map flags // map flags
@ -1792,11 +1799,12 @@ enum FLAG {
F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit
F_HITCONFER, // hitting with this gives flagid=v0 F_HITCONFER, // hitting with this gives flagid=v0
// unless you pass a val1 skillcheck, diff val2
// with timeleft = text ("min-max") // with timeleft = text ("min-max")
// unless you pass a val1 skillcheck, diff val2
// MUST ALSO HAVE HITCONFERVALS.
F_HITCONFERVALS,// specifies values for conferred flag. F_HITCONFERVALS,// specifies values for conferred flag.
F_ACTIVATED, // val0 = is this object turned on? F_ACTIVATED, // val0 = is this object turned on?
F_GRENADE, // this obkejct will drain charge when activated, then die F_GRENADE, // this object will drain charge when activated, then die
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage. F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
// val1 = BIG means hit surrounding cells // val1 = BIG means hit surrounding cells
// val2 = ifactivated, only explodes if activated. // val2 = ifactivated, only explodes if activated.
@ -1848,6 +1856,7 @@ enum FLAG {
// v2 = max trap chance // v2 = max trap chance
F_TRAPPED, // this object HAS a trap. F_TRAPPED, // this object HAS a trap.
// v0 is the trap object type // v0 is the trap object type
// v1 - 'curtime' when this trap was last triggered
// v2 = TRUE means we've spotted this. // v2 = TRUE means we've spotted this.
F_TRAP, // this object _IS_ a trap. v0 is sc_disarm/sc_spot difficulty. F_TRAP, // this object _IS_ a trap. v0 is sc_disarm/sc_spot difficulty.
// (NA = impossible) // (NA = impossible)
@ -1945,6 +1954,7 @@ enum FLAG {
// end gun flags // end gun flags
F_FLAMESTRIKE, // causes fires where you hit F_FLAMESTRIKE, // causes fires where you hit
F_BALANCE, // heals target if their maxhp < your maxhp F_BALANCE, // heals target if their maxhp < your maxhp
F_MERCIFUL, // puts to sleep instead of killing.
F_REVENGE, // causes damage based on your hp F_REVENGE, // causes damage based on your hp
F_HELPSREST, // makes you heal mp/hp faster when using 'R' F_HELPSREST, // makes you heal mp/hp faster when using 'R'
// reduces skillcheck difficulty by v0. // reduces skillcheck difficulty by v0.
@ -1983,6 +1993,7 @@ enum FLAG {
// ob identification flags // ob identification flags
F_HASHIDDENNAME, // whether this object class has a hidden name F_HASHIDDENNAME, // whether this object class has a hidden name
F_IDENTIFIED, // whether this object is fully identified F_IDENTIFIED, // whether this object is fully identified
F_KNOWNBAD, // you know this object is somehow bad
// bad flags // bad flags
F_DEEPWATER, // v0 = depth. F_DEEPWATER, // v0 = depth.
F_WALKDAM, // val0 = damtype, text = dam per sec F_WALKDAM, // val0 = damtype, text = dam per sec
@ -2133,6 +2144,8 @@ enum FLAG {
F_LOSLOF, // v0 = whether this spell needs line of sight F_LOSLOF, // v0 = whether this spell needs line of sight
// v1 = whether this spell needs line of fire // v1 = whether this spell needs line of fire
// MONSTER AI FLAGS // MONSTER AI FLAGS
F_CASTCHANCE, // this lf has v0% chance of using spell/abil
// (default is 15%)
F_DEMANDSBRIBE, // lf will demand gold from the player. F_DEMANDSBRIBE, // lf will demand gold from the player.
F_NOSWAP, // other mosnters won't swap with this one. F_NOSWAP, // other mosnters won't swap with this one.
// cleared at start of turn. // cleared at start of turn.
@ -2248,7 +2261,7 @@ enum FLAG {
F_ORIGRACE, // original player race (if you polymorphed) F_ORIGRACE, // original player race (if you polymorphed)
F_ORIGJOB, // original player job (if you polymorphed) F_ORIGJOB, // original player job (if you polymorphed)
F_POLYMORPHED, // lf has been polymorphed F_POLYMORPHED, // lf has been polymorphed
F_RETAINHPMPONPOLY, // don't take on hp/mp of what you polymorph F_RETAINHPONPOLY, // don't take on hp/mp of what you polymorph
// into // into
F_SHORTCUT, // spell keyboard shortcut. F_SHORTCUT, // spell keyboard shortcut.
// v0=slot (0-9) // v0=slot (0-9)
@ -2257,13 +2270,18 @@ enum FLAG {
F_DOESNTMOVE, // this race doesn't move (but can still attack) F_DOESNTMOVE, // this race doesn't move (but can still attack)
F_AQUATIC, // this race can attack normally in water and suffers no F_AQUATIC, // this race can attack normally in water and suffers no
// movement penalties // movement penalties
F_BODYPARTNAME, // for this race, bodypart v0 is called 'text'
F_HUMANOID, // this race can wear armour / use weapons F_HUMANOID, // this race can wear armour / use weapons
F_INSECT, // this race is classed as an insect F_INSECT, // this race is classed as an insect
F_UNDEAD, // this race is classed as undead F_UNDEAD, // this race is classed as undead
F_COLDBLOOD, // this race is coldblooded F_COLDBLOOD, // this race is coldblooded
F_NOARMOURON, // this race can't wear armour on bodypart v0
// obviously doesn't make sense to have both this
// and f_nobodypart for the same body part.
F_NOBODYPART, // this race doesn't have bodypart val0 F_NOBODYPART, // this race doesn't have bodypart val0
// if v0 is true or b_frominjury, you can regrow it // if v0 is true or b_frominjury, you can regrow it
// via a healing potion. // via a healing potion.
F_NOINJURIES, // this race cannot sustain injuries.
F_NOPACK, // this race cannot hold objects F_NOPACK, // this race cannot hold objects
F_NOSPELLS, // this race cannot cast spells F_NOSPELLS, // this race cannot cast spells
F_INDUCEFEAR, // causes fear when you attack it F_INDUCEFEAR, // causes fear when you attack it
@ -2543,7 +2561,8 @@ enum INJURY {
IJ_FINGERMISSING, IJ_FINGERMISSING,
IJ_EYELIDSCRAPED, IJ_EYELIDSCRAPED,
IJ_EYEDESTROYED, IJ_EYEDESTROYED,
// // explosive
IJ_HANDMISSING,
}; };
@ -2639,6 +2658,7 @@ enum ERROR {
E_DRUNK, E_DRUNK,
// //
E_NOBP, E_NOBP,
E_DOESNTFIT,
E_VEGETARIAN, E_VEGETARIAN,
E_PARTVEGETARIAN, E_PARTVEGETARIAN,
E_CARNIVORE, E_CARNIVORE,
@ -3170,6 +3190,7 @@ enum OBMOD {
enum BRAND { enum BRAND {
BR_BALANCE, BR_BALANCE,
BR_MERCY,
BR_NIMBLENESS, BR_NIMBLENESS,
BR_FEEBLENESS, BR_FEEBLENESS,
BR_FLIGHT, BR_FLIGHT,

1
flag.c
View File

@ -420,6 +420,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
case F_ATTRMOD: case F_ATTRMOD:
case F_BLIND: case F_BLIND:
case F_CONFUSED: case F_CONFUSED:
case F_DRUNK:
case F_EATING: case F_EATING:
case F_FASTMOVE: case F_FASTMOVE:
case F_FLYING: case F_FLYING:

20
god.c
View File

@ -386,6 +386,22 @@ enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness) {
return PL_INDIFFERENT; return PL_INDIFFERENT;
} }
// get a random god which player has prayed to
lifeform_t *getrandomprayedgod(void) {
int i,nposs = 0;
lifeform_t *god,*poss[MAXGODS];
for (i = 0; i < ngodlfs; i++) {
god = godlf[i];
if (lfhasflag(god, F_PRAYEDTO)) {
poss[nposs++] = god;
}
}
if (nposs == 0) {
return NULL;
}
return poss[rnd(0,nposs-1)];
}
lifeform_t *godappears(enum RACE rid, cell_t *where) { lifeform_t *godappears(enum RACE rid, cell_t *where) {
lifeform_t *god; lifeform_t *god;
char killedname[BUFLEN],godname[BUFLEN]; char killedname[BUFLEN],godname[BUFLEN];
@ -805,9 +821,13 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
msg("\"Behold, the power of death!\""); msg("\"Behold, the power of death!\"");
for (l = lf->cell->map->lf ; l ; l = l->next) { for (l = lf->cell->map->lf ; l ; l = l->next) {
if ((l != lf) && lfhasflagval(l, F_TARGETLF, lf->id, NA, NA, NULL)) { if ((l != lf) && lfhasflagval(l, F_TARGETLF, lf->id, NA, NA, NULL)) {
if (isundead(l)) {
makepeaceful(l);
} else {
castspell(god, OT_S_PAIN, l, NULL, l->cell); castspell(god, OT_S_PAIN, l, NULL, l->cell);
} }
} }
}
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);
dospelleffects(god, OT_S_DARKNESS, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); dospelleffects(god, OT_S_DARKNESS, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
break; break;

1
god.h
View File

@ -6,6 +6,7 @@ void dooffer(void);
lifeform_t *findgod(enum RACE rid); lifeform_t *findgod(enum RACE rid);
int getpiety(enum RACE rid); int getpiety(enum RACE rid);
enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness); enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness);
lifeform_t *getrandomprayedgod(void);
lifeform_t *godappears(enum RACE rid, cell_t *where); lifeform_t *godappears(enum RACE rid, cell_t *where);
int godgiftmaybe(enum RACE rid); int godgiftmaybe(enum RACE rid);
int godisangry(enum RACE rid); int godisangry(enum RACE rid);

132
io.c
View File

@ -690,8 +690,10 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
f = lfhasflag(c->lf, F_ASLEEP); f = lfhasflag(c->lf, F_ASLEEP);
if (f) { if (f) {
if (strlen(extrainfo)) strcat(extrainfo, ", "); if (strlen(extrainfo)) strcat(extrainfo, ", ");
if (f->val[1] != B_TRUE) { if (f->val[1] == ST_MEDITATING) {
strcat(extrainfo, "meditating"); strcat(extrainfo, "meditating");
} else if (f->val[1] == ST_KO) {
strcat(extrainfo, "unconscious");
} else if (f->val[2] == NA) { } else if (f->val[2] == NA) {
strcat(extrainfo, "sleeping"); strcat(extrainfo, "sleeping");
} else { } else {
@ -1147,7 +1149,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
if (isplayer(lf) && (f->val[2] != NA)) { // ie. resting, not forced asleep if (isplayer(lf) && (f->val[2] != NA)) { // ie. resting, not forced asleep
object_t *restob; object_t *restob;
int meditating = B_FALSE; int meditating = B_FALSE;
if (f->val[1] != NA) meditating = B_TRUE; if (f->val[1] == ST_MEDITATING) meditating = B_TRUE;
restob = getrestob(lf); restob = getrestob(lf);
if (restob) { if (restob) {
char restobname[BUFLEN]; char restobname[BUFLEN];
@ -1157,7 +1159,11 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
msg("You start %s (on the ground)...", meditating ? "meditating" : "resting" ); msg("You start %s (on the ground)...", meditating ? "meditating" : "resting" );
} }
} else { } else {
if (f->val[1] == ST_ASLEEP) {
msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s"); msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s");
} else {
msg("%s lose%s consciousness.",lfname, isplayer(lf) ? "" : "s");
}
} }
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
@ -1740,10 +1746,16 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
} }
break; break;
case F_ASLEEP: case F_ASLEEP:
if (f->val[1] == NA) { switch (f->val[1]) {
case ST_ASLEEP:
msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s"); msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s");
} else { break;
case ST_MEDITATING:
msg("%s stop%s meditating.",lfname, isplayer(lf) ? "" : "s"); msg("%s stop%s meditating.",lfname, isplayer(lf) ? "" : "s");
break;
case ST_KO:
msg("%s regain%s consciousness.",lfname, isplayer(lf) ? "" : "s");
break;
} }
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
@ -2308,10 +2320,13 @@ void announceobflagloss(object_t *o, flag_t *f) {
} }
int confirm_badfeeling(void) { int confirm_badfeeling(object_t *o) {
char ch; char ch;
ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE); ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE);
if (ch == 'y') return B_TRUE; if (ch == 'y') return B_TRUE;
if (o && !hasflag(o->flags, F_KNOWNBAD)) {
addflag(o->flags, F_KNOWNBAD, B_TRUE, NA, NA, NULL);
}
return B_FALSE; return B_FALSE;
} }
@ -2566,11 +2581,11 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
} }
// draw prompt // draw prompt
if (strlen(numstring) > 0) { if (strlen(numstring) > 0) {
mvwprintw(mainwin, 0, 0, "%s (%sesc to quit) [%s]: ",prompt, mvwprintw(mainwin, 0, 0, "%s (%sESC to quit) [%s]: ",prompt,
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : "", (opts & AO_INCLUDENOTHING) ? "- for nothing, " : "",
numstring); numstring);
} else { } else {
mvwprintw(mainwin, 0, 0, "%s (%sesc to quit): ", prompt, mvwprintw(mainwin, 0, 0, "%s (%sESC to quit): ", prompt,
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : ""); (opts & AO_INCLUDENOTHING) ? "- for nothing, " : "");
} }
if (nextpage != -1) { if (nextpage != -1) {
@ -2763,11 +2778,11 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
mvwprintw(mainwin, y, 0, MORESTRING); mvwprintw(mainwin, y, 0, MORESTRING);
} }
if (strlen(numstring) > 0) { if (strlen(numstring) > 0) {
snprintf(pbuf, BUFLEN,"%s (%s','=all, esc to quit) [%s]: ",prompt, snprintf(pbuf, BUFLEN,"%s (%s','=all, ESC to quit) [%s]: ",prompt,
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : "", (opts & AO_INCLUDENOTHING) ? "- for nothing, " : "",
numstring); numstring);
} else { } else {
snprintf(pbuf, BUFLEN,"%s (%sesc to quit): ", prompt, snprintf(pbuf, BUFLEN,"%s (%sESC to quit): ", prompt,
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : ""); (opts & AO_INCLUDENOTHING) ? "- for nothing, " : "");
} }
@ -3799,8 +3814,8 @@ void doeat(obpile_t *op) {
eatob = askobject(op, "Eat what", NULL, AO_EDIBLE); eatob = askobject(op, "Eat what", NULL, AO_EDIBLE);
} }
if (eatob) { if (eatob) {
if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, 26, 0)) { if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling()) { if (!confirm_badfeeling(eatob)) {
msg("Cancelled."); msg("Cancelled.");
return; return;
} }
@ -3918,8 +3933,8 @@ int dowear(obpile_t *op) {
int rv; int rv;
o = askobject(op, "Wear what", NULL, AO_WEARABLE); o = askobject(op, "Wear what", NULL, AO_WEARABLE);
if (o) { if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 26, 0)) { if (isunknownbadobject(o) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling()) { if (!confirm_badfeeling(o)) {
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
} }
@ -3940,8 +3955,8 @@ int doweild(obpile_t *op) {
int rv; int rv;
o = askobject(op, "Weild what", &count, AO_WEILDABLE | AO_INCLUDENOTHING); o = askobject(op, "Weild what", &count, AO_WEILDABLE | AO_INCLUDENOTHING);
if (o) { if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 26, 0)) { if (isunknownbadobject(o) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling()) { if (!confirm_badfeeling(o)) {
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
} }
@ -4433,7 +4448,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
if (isarmour(o)) { if (isarmour(o)) {
f = hasflag(o->flags, F_GOESON); f = hasflag(o->flags, F_GOESON);
if (f) { if (f) {
snprintf(buf, BUFLEN, "It is worn %s your %s, ",getbodypartequipname(f->val[0]), getbodypartname(f->val[0])); snprintf(buf, BUFLEN, "It is worn %s your %s, ",getbodypartequipname(f->val[0]), getbodypartname(NULL, f->val[0]));
} else { } else {
strcpy(buf, ""); strcpy(buf, "");
} }
@ -4480,7 +4495,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
// non armour, but still wearable. // non armour, but still wearable.
f = hasflag(o->flags, F_GOESON); f = hasflag(o->flags, F_GOESON);
if (f) { if (f) {
snprintf(buf, BUFLEN, "It is worn %s your %s.\n",getbodypartequipname(f->val[0]), getbodypartname(f->val[0])); snprintf(buf, BUFLEN, "It is worn %s your %s.\n",getbodypartequipname(f->val[0]), getbodypartname(NULL, f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
} }
@ -5514,7 +5529,8 @@ void dooperate(obpile_t *op) {
// operable objects here? // operable objects here?
for (o = player->cell->obpile->first; o ; o = o->next) { for (o = player->cell->obpile->first; o ; o = o->next) {
if (isoperable(o) && canpickup(player, o, 1)) { //if (isoperable(o) && canpickup(player, o, 1)) {
if (isoperable(o)) {
char obname[BUFLEN],buf[BUFLEN]; char obname[BUFLEN],buf[BUFLEN];
char verb[BUFLEN]; char verb[BUFLEN];
int ch; int ch;
@ -5819,8 +5835,8 @@ void doquaff(obpile_t *op) {
} }
if (liquid) { if (liquid) {
if (canquaff(player, liquid)) { if (canquaff(player, liquid)) {
if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, 26, 0)) { if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling()) { if (!confirm_badfeeling(liquid)) {
msg("Cancelled."); msg("Cancelled.");
return; return;
} }
@ -6139,13 +6155,17 @@ void dothrow(obpile_t *op) {
if (where) { if (where) {
cell_t *newwhere = NULL; cell_t *newwhere = NULL;
if (!haslof(player->cell, where, LOF_WALLSTOP, &newwhere)) { if (!haslof(player->cell, where, LOF_WALLSTOP, &newwhere)) {
if (newwhere) { if (newwhere && (newwhere != player->cell)) {
char ch;
ch = askchar("Your line of fire is blocked - really throw here", "yn", "y", B_TRUE);
if (ch == 'y') {
// update destination cell. // update destination cell.
where = newwhere; where = newwhere;
} else return;
} else { } else {
if (reason == E_NOLOS) { if (reason == E_NOLOS) {
msg("You can't see there!"); msg("You can't see there!");
} else { // ie. E_NOLOF } else { // ie. E_NOLOF and no new cell
msg("You don't have a clear line of fire to there."); msg("You don't have a clear line of fire to there.");
} }
return; return;
@ -6833,17 +6853,28 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
} }
if (strlen(prompt->choice[validchoice].longdesc)) { if (strlen(prompt->choice[validchoice].longdesc)) {
int dummy; int dummy;
wmove(mainwin, 5, 0); if (showall) y++;
wmove(mainwin, y, 0);
textwithcol(mainwin, prompt->choice[validchoice].longdesc); textwithcol(mainwin, prompt->choice[validchoice].longdesc);
getyx(mainwin, descendy, dummy); // remember bottom of description getyx(mainwin, descendy, dummy); // remember bottom of description
} }
} else if ((descendy != -1) && showall) { } else if (descendy != -1) {
if (showall) {
int yy; int yy;
// clear to bottom of screen // clear to bottom of screen
for (yy = y ; yy < lastline; yy++) { for (yy = y ; yy < lastline; yy++) {
wmove(mainwin, yy, 0); wmove(mainwin, yy, 0);
wclrtoeol(mainwin); wclrtoeol(mainwin);
} }
} else {
int yy;
char gamewinbuf[BUFLEN];
// copy text from gamewin
for (yy = y ; yy < lastline; yy++) {
mvwinchstr(gamewin, yy-2, 0, (chtype *)gamewinbuf);
mvwaddchstr(mainwin, yy, 0,(chtype *) gamewinbuf);
}
}
descendy = -1; descendy = -1;
} }
@ -6858,6 +6889,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
// if there's only one match, complete it // if there's only one match, complete it
if (nvalid == 1) { if (nvalid == 1) {
char remainder[BUFLEN];
int cx,cy; int cx,cy;
// remember cursor pos // remember cursor pos
getyx(mainwin, cy, cx); getyx(mainwin, cy, cx);
@ -6868,13 +6900,20 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
prompt->choice[validone].text); prompt->choice[validone].text);
*/ */
// 'validchoice' was calculated earlier
snprintf(promptstr, BUFLEN, "%s [%s%s] %s", /*
snprintf(promptstr, BUFLEN, "%s [%s%s] ",
prompt->q[prompt->whichq], prompt->q[prompt->whichq],
prompt->maycancel ? "ESC," : "", prompt->maycancel ? "ESC," : "",
showall ? "'=next page,?=toggle" : "?=list", showall ? "'=next page,?=toggle" : "?=list");
prompt->choice[validchoice].text); prompt->choice[validchoice].text);
mvwprintw(mainwin, 0, 0, "%s", promptstr); */
// show the remainder of what we have typed.
// ('validchoice' was calculated earlier)
snprintf(remainder, BUFLEN, "^g%s",prompt->choice[validchoice].text + strlen(inpstring));
textwithcol(mainwin, remainder);
// move cursor back
wmove(mainwin, cy, cx);
} }
wrefresh(mainwin); wrefresh(mainwin);
@ -7794,15 +7833,19 @@ void drawstatus(void) {
// paralysed somehow? // paralysed somehow?
if ((f = isresting(player)) != NULL) { if ((f = isresting(player)) != NULL) {
setcol(statwin, C_CYAN); setcol(statwin, C_CYAN);
if (f->val[1] == NA) { if (f->val[1] == ST_ASLEEP) {
wprintw(statwin, " Resting"); wprintw(statwin, " Resting");
} else { } else {
wprintw(statwin, " Meditating"); wprintw(statwin, " Meditating");
} }
unsetcol(statwin, C_CYAN); unsetcol(statwin, C_CYAN);
} else if (lfhasflag(player, F_ASLEEP)) { } else if ((f = lfhasflag(player, F_ASLEEP)) != NULL) {
setcol(statwin, C_MAGENTA); setcol(statwin, C_MAGENTA);
if (f->val[2] == ST_KO) {
wprintw(statwin, " KO");
} else {
wprintw(statwin, " Asleep"); wprintw(statwin, " Asleep");
}
unsetcol(statwin, C_MAGENTA); unsetcol(statwin, C_MAGENTA);
} else if (isprone(player)) { } else if (isprone(player)) {
setcol(statwin, C_YELLOW); setcol(statwin, C_YELLOW);
@ -8131,6 +8174,11 @@ void setobcolour(WINDOW *win, object_t *o, int set) {
return; return;
} }
if (hasflag(o->flags, F_KNOWNBAD)) {
funcptr(win, C_RED);
return;
}
if (o->blessknown) { if (o->blessknown) {
if (iscursed(o)) { if (iscursed(o)) {
funcptr(win, C_RED); funcptr(win, C_RED);
@ -8200,7 +8248,7 @@ void showlfarmour(lifeform_t *lf) {
if (!lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) { if (!lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
object_t *outerob; object_t *outerob;
snprintf(buf, BUFLEN, "%15s:%3s",getbodypartname(bp), " "); snprintf(buf, BUFLEN, "%13s:%1s",getbodypartname(lf, bp), " ");
o = getequippedob(lf->pack, bp); o = getequippedob(lf->pack, bp);
arm[bp] = o; // remember for later arm[bp] = o; // remember for later
outerob = getouterequippedob(lf, bp); outerob = getouterequippedob(lf, bp);
@ -8678,7 +8726,6 @@ void showlfstats(lifeform_t *lf, int showall) {
if (lorelev >= PR_BEGINNER) unsetcol(mainwin, lorecol); if (lorelev >= PR_BEGINNER) unsetcol(mainwin, lorecol);
} }
y2++; y2++;
} // end if o } // end if o
} // end if fid == hasattack } // end if fid == hasattack
} // end for each flag } // end for each flag
@ -8869,7 +8916,16 @@ void showlfstats(lifeform_t *lf, int showall) {
// obvious physical effects here. // obvious physical effects here.
f = lfhasknownflag(lf, F_ASLEEP); f = lfhasknownflag(lf, F_ASLEEP);
if (f) { if (f) {
wrapprint(mainwin, &y, &x, "%s %s %s.", you(lf), is(lf), (f->val[1] == NA) ? "sleeping" : "meditating"); char sleepname[BUFLEN];
switch (f->val[1]) {
case ST_ASLEEP:
strcpy(sleepname, "sleeping"); break;
case ST_MEDITATING:
strcpy(sleepname, "meditating"); break;
case ST_KO:
strcpy(sleepname, "unconscious"); break;
}
wrapprint(mainwin, &y, &x, "%s %s %s.", you(lf), is(lf), sleepname);
} }
f = lfhasknownflag(lf, F_ATTACHEDTO); f = lfhasknownflag(lf, F_ATTACHEDTO);
if (f && (f->known)) { if (f && (f->known)) {
@ -9022,16 +9078,16 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
if (nmissingbp) { if (nmissingbp) {
snprintf(buf, BUFLEN, "%s %s no %s",you(lf), isplayer(lf) ? "have" : "has", getbodypartname(missingbp[0])); snprintf(buf, BUFLEN, "%s %s no %s",you(lf), isplayer(lf) ? "have" : "has", getbodypartname(lf, missingbp[0]));
if (nmissingbp > 1) { if (nmissingbp > 1) {
// construct list of missing body parts // construct list of missing body parts
for (i = 1; i < nmissingbp ; i++) { for (i = 1; i < nmissingbp ; i++) {
if (i == nmissingbp - 1) { // last if (i == nmissingbp - 1) { // last
strcat(buf, " or "); strcat(buf, " or ");
strcat(buf, getbodypartname(missingbp[i])); strcat(buf, getbodypartname(lf, missingbp[i]));
} else { } else {
strcat(buf, ", "); strcat(buf, ", ");
strcat(buf, getbodypartname(missingbp[i])); strcat(buf, getbodypartname(lf, missingbp[i]));
} }
} }
} }
@ -9150,9 +9206,9 @@ void showlfstats(lifeform_t *lf, int showall) {
if (lfhasknownflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT)) { if (lfhasknownflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT)) {
if (f->lifetime != PERMENANT) { if (f->lifetime > 0) {
char buf3[BUFLEN]; char buf3[BUFLEN];
snprintf(buf3, BUFLEN, "[%dt]",f->lifetime); snprintf(buf3, BUFLEN, "[%dturns]",f->lifetime);
strcat(buf2, buf3); strcat(buf2, buf3);
} }
} }

2
io.h
View File

@ -16,7 +16,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f);
int announceflagloss(lifeform_t *lf, flag_t *f); int announceflagloss(lifeform_t *lf, flag_t *f);
int announceobflaggain(object_t *o, flag_t *f); int announceobflaggain(object_t *o, flag_t *f);
void announceobflagloss(object_t *o, flag_t *f); void announceobflagloss(object_t *o, flag_t *f);
int confirm_badfeeling(void); int confirm_badfeeling(object_t *o);
lifeform_t *askgod(char *prompt); lifeform_t *askgod(char *prompt);
object_t *askobject(obpile_t *op, char *title, int *count, long opts); object_t *askobject(obpile_t *op, char *title, int *count, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag); object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag);

372
lf.c
View File

@ -563,7 +563,11 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
return B_FALSE; return B_FALSE;
} }
// how much mp does it take to cast this? // how much mp does it take to cast this?
if (isplayer(lf)) {
cost = getmpcost(lf, oid); cost = getmpcost(lf, oid);
} else {
cost = 0;
}
if (mpcost) *mpcost = cost; if (mpcost) *mpcost = cost;
if (lf->mp >= cost) { if (lf->mp >= cost) {
castable = B_TRUE; castable = B_TRUE;
@ -678,7 +682,8 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
// can't hear when dead. // can't hear when dead.
if (isdead(lf)) return B_FALSE; if (isdead(lf)) return B_FALSE;
// can't hear if you are deaf // can't hear if you are deaf or have no ears
if (!hasbp(lf, BP_EARS)) return B_FALSE;
if (lfhasflag(lf, F_DEAF)) return B_FALSE; if (lfhasflag(lf, F_DEAF)) return B_FALSE;
// can't hear when training // can't hear when training
@ -992,10 +997,16 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
int nretflags; int nretflags;
reason = E_OK; reason = E_OK;
if ((where != BP_NONE) && !hasbp(lf, where)) { if (where != BP_NONE) {
if (!hasbp(lf, where)) {
reason = E_NOBP; reason = E_NOBP;
return B_FALSE; return B_FALSE;
} else if (lfhasflagval(lf, F_NOARMOURON, where, NA, NA, NULL)) {
reason = E_DOESNTFIT;
return B_FALSE;
} }
}
// already equipped? // already equipped?
if (hasflag(o->flags, F_EQUIPPED)) { if (hasflag(o->flags, F_EQUIPPED)) {
@ -1295,13 +1306,14 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
} }
// announce // announce
if (!isplayer(lf) && cansee(player, lf)) { if (!isplayer(lf)) {
if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
char whattosay[BUFLEN]; char whattosay[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
// special case // special case
f = lfhasflag(lf,F_SPELLCASTTEXT); f = lfhasflag(lf, F_SPELLCASTTEXT);
if (f) { if (f) {
if (strlen(f->text)) { if (strlen(f->text)) {
snprintf(whattosay, BUFLEN, "%s %s", lfname, f->text); snprintf(whattosay, BUFLEN, "%s %s", lfname, f->text);
@ -1324,6 +1336,11 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
msg("%s starts casting a spell.", lfname); msg("%s starts casting a spell.", lfname);
} }
} }
} else { // player can't see them
if ((targlf == player) || (targcell = player->cell)) {
msg("Something casts a spell at you.");
}
}
} }
// boost power? // boost power?
@ -1506,7 +1523,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
flag_t *f; flag_t *f;
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
if (!isairborne(lf)) { if (isairborne(lf)) {
return B_FALSE; return B_FALSE;
} }
@ -1926,6 +1943,7 @@ void die(lifeform_t *lf) {
} }
if (isplayer(lf)) { if (isplayer(lf)) {
lifeform_t *god;
// force screen redraw so you see your hp = 0 // force screen redraw so you see your hp = 0
drawscreen(); drawscreen();
@ -1935,9 +1953,39 @@ void die(lifeform_t *lf) {
} else { } else {
msg("^BYou die."); msg("^BYou die.");
} }
more(); more(); drawmsg();
// force msg redraw!
drawmsg(); // god effects...
if (!vaporised) {
god = getrandomprayedgod();
if (god && !godisangry(god->race->id)) {
switch (god->race->id) {
case R_GODDEATH:
godsay(god->race->id, "Come to me, my servant..."); more();
msg("Bony claws rise up and drag your corpse underground."); more(); break;
case R_GODPURITY:
msg("Your spirit ascends to the heavens."); more(); break;
case R_GODTHIEVES:
msg("All your possessions suddenly vanish!"); more();
godsay(god->race->id, "Yoink!"); more();
break;
case R_GODMERCY:
if (onein(10)) {
godsay(god->race->id, "I will grant you a second chance, mortal... use it wisely."); more();
lf->hp = lf->maxhp;
lf->alive = B_TRUE;
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);
return;
}
break;
default:
break;
}
}
}
} else { } else {
if (!hasflag(lf->flags, F_NODEATHANNOUNCE)) { if (!hasflag(lf->flags, F_NODEATHANNOUNCE)) {
if (cansee(player, lf)) { if (cansee(player, lf)) {
@ -1972,6 +2020,9 @@ void die(lifeform_t *lf) {
} else { // ie. neutral } else { // ie. neutral
pleasegodmaybe(R_GODDEATH, 1); pleasegodmaybe(R_GODDEATH, 1);
} }
// mercy god doesn't like killing
angergodmaybe(R_GODMERCY, 1);
} }
} }
@ -2396,6 +2447,8 @@ void do_eyesight_adjust(lifeform_t *lf) {
int i,nlitcells = 0; int i,nlitcells = 0;
int preea; int preea;
if (isblind(lf)) return;
// any lit cells within los? // any lit cells within los?
for (i = 0; i < lf->nlos; i++) { for (i = 0; i < lf->nlos; i++) {
if (lf->los[i]->lit) { if (lf->los[i]->lit) {
@ -2993,7 +3046,7 @@ void enhanceskills(lifeform_t *lf) {
if (lf->skillpoints >= cost) { if (lf->skillpoints >= cost) {
char buf[BUFLEN]; char buf[BUFLEN];
char buf2[HUGEBUFLEN]; char buf2[HUGEBUFLEN];
snprintf(buf, BUFLEN, "%s (%s, cost:%d points)", getskillname(f->val[0]), snprintf(buf, BUFLEN, "%s -> %s (cost:%d points)", getskillname(f->val[0]),
getskilllevelname(f->val[1] + 1), cost); getskilllevelname(f->val[1] + 1), cost);
makedesc_skill(f->val[0], buf2); makedesc_skill(f->val[0], buf2);
addchoice(&prompt, ch++, getskillname(f->val[0]), buf, f, buf2); addchoice(&prompt, ch++, getskillname(f->val[0]), buf, f, buf2);
@ -3303,11 +3356,12 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) {
// if you are going to sleep on purpose, use 'gotosleep'. // if you are going to sleep on purpose, use 'gotosleep'.
// this function is for when it is forced upon you by a spell, etc. // this function is for when it is forced upon you by a spell, etc.
int fallasleep(lifeform_t *lf, int howlong) { int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) {
if (lfhasflag(lf, F_ASLEEP)) { if (lfhasflag(lf, F_ASLEEP)) {
return B_TRUE; return B_TRUE;
} }
if (lfhasflag(lf, F_CAFFEINATED)) {
if ((how == ST_ASLEEP) && lfhasflag(lf, F_CAFFEINATED)) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You feel momentarily tired."); msg("You feel momentarily tired.");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
@ -3323,7 +3377,7 @@ int fallasleep(lifeform_t *lf, int howlong) {
killflagsofid(lf->flags, F_RAGE); killflagsofid(lf->flags, F_RAGE);
killflagsofid(lf->flags, F_TRAINING); killflagsofid(lf->flags, F_TRAINING);
addtempflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL, howlong); addtempflag(lf->flags, F_ASLEEP, B_TRUE, how, NA, NULL, howlong);
return B_FALSE; return B_FALSE;
} }
@ -3331,7 +3385,7 @@ int fallasleep(lifeform_t *lf, int howlong) {
void fightback(lifeform_t *lf, lifeform_t *attacker) { void fightback(lifeform_t *lf, lifeform_t *attacker) {
interrupt(lf); interrupt(lf);
if (lfhasflag(lf, F_FEIGNINGDEATH)) { if (lfhasflag(lf, F_FEIGNINGDEATH) || lfhasflagval(lf, F_ASLEEP, NA, ST_KO, NA, NULL)) {
// don't respond. // don't respond.
return; return;
} }
@ -3345,8 +3399,12 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
} }
if (attacker) { if (attacker) {
flag_t *f;
f = lfhasflag(lf, F_ASLEEP);
if (f && (f->val[1] != ST_KO)) {
// wake up // wake up
killflagsofid(lf->flags, F_ASLEEP); killflagsofid(lf->flags, F_ASLEEP);
}
// monsters might flee, fight back, etc // monsters might flee, fight back, etc
if (!isplayer(lf)) { if (!isplayer(lf)) {
if (isplayer(attacker) && ishirable(lf)) { if (isplayer(attacker) && ishirable(lf)) {
@ -4856,7 +4914,16 @@ int getbodyparthitchance(enum BODYPART bp) {
return 0; // ie rings, ears, weapon return 0; // ie rings, ears, weapon
} }
char *getbodypartname(enum BODYPART bp) { char *getbodypartname(lifeform_t *lf, enum BODYPART bp) {
flag_t *f;
if (lf) {
f = lfhasflagval(lf, F_BODYPARTNAME, bp, NA, NA, NULL);
if (f) {
return f->text;
}
}
switch (bp) { switch (bp) {
case BP_WEAPON: case BP_WEAPON:
return "right hand"; return "right hand";
@ -6912,6 +6979,8 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
modattr(lf, f->val[0], f->val[1]); modattr(lf, f->val[0], f->val[1]);
// these aren't temporary.
lf->baseatt[f->val[0]] = lf->att[f->val[0]];
} }
// inherit all flags except: // inherit all flags except:
@ -7083,14 +7152,19 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
int flagsknown = 0, flagsfound = 0; int flagsknown = 0, flagsfound = 0;
flag_t *f,*newflag; flag_t *f,*newflag;
int held, equipped,activated; int held = B_FALSE, equipped = B_FALSE,activated = B_FALSE;
int lifetimeval; int lifetimeval;
if (o->pile->owner == lf) held = B_TRUE; if (o->pile->owner == lf) held = B_TRUE;
if (held && hasflag(o->flags, F_EQUIPPED)) { if (held) {
f = hasflag(o->flags, F_EQUIPPED);
// make sure it's equipped in the right place - ie. weilded rings don't
// do anything.
if (f && hasflagval(o->flags, F_GOESON, f->val[0], NA, NA, NULL)) {
equipped = B_TRUE; equipped = B_TRUE;
} }
}
if (held && hasflag(o->flags, F_ACTIVATED)) { if (held && hasflag(o->flags, F_ACTIVATED)) {
activated = B_TRUE; activated = B_TRUE;
} }
@ -7212,12 +7286,6 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL); newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
newf->lifetime = FROMSKILL; newf->lifetime = FROMSKILL;
} }
} else if (id == SK_SPELLCASTING) {
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
if (!newf) {
newf = addflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
newf->lifetime = FROMSKILL;
}
} else if (id == SK_THIEVERY) { } else if (id == SK_THIEVERY) {
newf = addflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL); newf = addflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL);
newf->lifetime = FROMSKILL; newf->lifetime = FROMSKILL;
@ -7258,6 +7326,14 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
lf->losdirty = B_TRUE; lf->losdirty = B_TRUE;
if (isplayer(lf)) needredraw = B_TRUE; if (isplayer(lf)) needredraw = B_TRUE;
} }
} else if (id == SK_SPELLCASTING) {
if (f->val[1] == PR_SKILLED) {
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
if (!newf) {
newf = addflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
newf->lifetime = FROMSKILL;
}
}
} else if (id == SK_STEALTH) { } else if (id == SK_STEALTH) {
if (f->val[1] == PR_BEGINNER) { if (f->val[1] == PR_BEGINNER) {
newf = addflag(lf->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL); newf = addflag(lf->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL);
@ -7628,13 +7704,13 @@ int gotosleep(lifeform_t *lf, int onpurpose) {
return B_TRUE; return B_TRUE;
} }
if (onpurpose) taketime(lf, getactspeed(lf)); if (onpurpose) taketime(lf, getactspeed(lf));
addflag(lf->flags, F_ASLEEP, B_TRUE, lfhasflag(lf, F_MEDITATES) ? B_TRUE : NA, onpurpose ? B_TRUE : NA, NULL); addflag(lf->flags, F_ASLEEP, B_TRUE, lfhasflag(lf, F_MEDITATES) ? ST_MEDITATING : ST_ASLEEP, onpurpose ? B_TRUE : NA, NULL);
return B_FALSE; return B_FALSE;
} }
int hasfreeaction(lifeform_t *lf) { int hasfreeaction(lifeform_t *lf) {
if (isdead(lf)) return B_FALSE;
if (isimmobile(lf)) return B_FALSE; if (isimmobile(lf)) return B_FALSE;
if (lfhasflag(lf, F_ASLEEP)) return B_FALSE;
if (lfhasflag(lf, F_CASTINGSPELL)) return B_FALSE; if (lfhasflag(lf, F_CASTINGSPELL)) return B_FALSE;
if (lfhasflag(lf, F_EATING)) return B_FALSE; if (lfhasflag(lf, F_EATING)) return B_FALSE;
return B_TRUE; return B_TRUE;
@ -7671,8 +7747,10 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
enum BODYPART bp2; enum BODYPART bp2;
object_t *wep = NULL; object_t *wep = NULL;
int howlong; int howlong;
if (where == BP_NONE) return B_TRUE; if (where == BP_NONE) return B_TRUE;
if (!hasbp(lf, where)) return B_TRUE; if (!hasbp(lf, where)) return B_TRUE;
if (lfhasflag(lf, F_NOINJURIES)) return B_TRUE;
if (lfhasflagval(lf, F_INJURY, NA, where, NA, NULL)) return B_TRUE; if (lfhasflagval(lf, F_INJURY, NA, where, NA, NULL)) return B_TRUE;
howlong = rnd(30,80); // might be overridden depending on injury howlong = rnd(30,80); // might be overridden depending on injury
@ -7759,7 +7837,7 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
o = getequippedob(lf->pack, bp2); o = getequippedob(lf->pack, bp2);
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL); addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL);
inj = IJ_FINGERMISSING; inj = IJ_FINGERMISSING;
sprintf(buf, "%s is severed^cannot wear rings on this hand", getbodypartname(bp2)); sprintf(buf, "%s is severed^cannot wear rings on this hand", getbodypartname(lf, bp2));
desc = strdup(buf); desc = strdup(buf);
howlong = PERMENANT; howlong = PERMENANT;
if (o) { if (o) {
@ -7811,6 +7889,62 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
} }
default: break; default: break;
} }
} else if (damtype == DT_EXPLOSIVE) {
switch (where) {
case BP_BODY:
switch (rnd(1,2)) {
case 1:
break;
case 2:
break;
}
// massive burns
// collapsed lung
break;
case BP_HANDS:
// lose limb
if (onein(2)) bp2 = BP_WEAPON;
else bp2 = BP_SECWEAPON;
if (hasbp(lf, bp2)) {
object_t *o[2];
char buf[BUFLEN];
int i;
// drop anyting in that hand
o[0] = getequippedob(lf->pack, bp2);
if (bp2 == BP_WEAPON) o[1] = getequippedob(lf->pack, BP_RIGHTFINGER);
else o[1] = getequippedob(lf->pack, BP_LEFTFINGER);
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL);
inj = IJ_HANDMISSING;
sprintf(buf, "%s is destroyed^cannot use this hand", getbodypartname(lf, bp2));
desc = strdup(buf);
howlong = PERMENANT;
for (i = 0; i < 2; i++) {
if (o[i]) {
char obname[BUFLEN];
if (isplayer(lf)) {
getobname(o[i],obname,o[i]->amt);
msg("Your %s drops to the ground.",noprefix(obname));
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getobname(o[i],obname,o[i]->amt);
getlfname(lf,lfname);
msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname));
}
moveob(o[i], lf->cell->obpile, o[i]->amt);
}
}
}
break;
case BP_HEAD:
// ringing ears
// burnt eyes
break;
case BP_LEGS:
// lose limb
break;
default:
break;
}
} }
if (inj == IJ_NONE) { if (inj == IJ_NONE) {
@ -8383,7 +8517,7 @@ int isblind(lifeform_t *lf) {
if (!lf) return B_FALSE; if (!lf) return B_FALSE;
f = lfhasflag(lf, F_ASLEEP); f = lfhasflag(lf, F_ASLEEP);
if (f && (f->val[1] == NA)) { if (f && (f->val[1] != ST_MEDITATING)) {
return B_TRUE; return B_TRUE;
} }
if (lfhasflag(lf, F_BLIND)) { if (lfhasflag(lf, F_BLIND)) {
@ -8741,10 +8875,12 @@ int ispolymorphed(lifeform_t *lf) {
} }
int isprone(lifeform_t *lf) { int isprone(lifeform_t *lf) {
flag_t *f;
if (lfhasflag(lf, F_PRONE)) { if (lfhasflag(lf, F_PRONE)) {
return B_TRUE; return B_TRUE;
} }
if (lfhasflag(lf, F_ASLEEP)) { f = lfhasflag(lf, F_ASLEEP);
if (f && (f->val[1] != ST_MEDITATING)) {
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -9058,10 +9194,13 @@ void addtrail(lifeform_t *lf, int dir) {
object_t *footprint, *scent; object_t *footprint, *scent;
flag_t *fpflag; flag_t *fpflag;
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { // no tracks at all?
// no tracks at all if (lf->cell->type->solid) {
return;
} else if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
return; return;
} }
// footprints first // footprints first
if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) { if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) {
int fpdir; int fpdir;
@ -9601,6 +9740,11 @@ int isswimming(lifeform_t *lf) {
return B_FALSE; return B_FALSE;
} }
int isunconscious(lifeform_t *lf) {
if (lfhasflagval(lf, F_ASLEEP, NA, ST_KO, NA, NULL)) return B_TRUE;
return B_FALSE;
}
int isundead(lifeform_t *lf) { int isundead(lifeform_t *lf) {
if (lf->race->raceclass->id == RC_UNDEAD) { if (lf->race->raceclass->id == RC_UNDEAD) {
return B_TRUE; return B_TRUE;
@ -9866,7 +10010,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
char buf[BUFLEN]; char buf[BUFLEN];
char buf2[BUFLEN]; char buf2[BUFLEN];
char lfname[BUFLEN]; char lfname[BUFLEN];
int prebleed = B_FALSE,postbleed = B_FALSE; int prebleed = B_FALSE,postbleed = B_FALSE,ko = B_FALSE;
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
@ -9954,6 +10098,32 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// stop hiding // stop hiding
killflagsofid(lf->flags, F_HIDING); killflagsofid(lf->flags, F_HIDING);
// merciful weapons
if (fromob) {
f = hasflag(fromob->flags, F_MERCIFUL);
if (f && (amt >= lf->hp)) {
amt = lf->hp - 1; // ie end up at 1hp
ko = B_TRUE;
if (fromob->pile->owner && cansee(player, fromob->pile->owner)) {
f->known = B_TRUE;
}
}
}
// bashing damage sometimes ko's
if (!ko) {
if (damtype == DT_BASH) {
int hpleft;
hpleft = lf->hp - amt;
if ((hpleft >= -5) && (hpleft <= 0)) {
if (onein(2)) {
ko = B_TRUE;
amt = lf->hp - 1; // ie end up at 1hp
}
}
}
}
// large damage? // large damage?
if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) { if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) {
if (useringofmiracles(lf, 1)) { if (useringofmiracles(lf, 1)) {
@ -10057,7 +10227,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// further effects if not dead... // further effects if not dead...
if (!isdead(lf)) { if (!isdead(lf)) {
// fight back if required // fight back if required
if (fromlf && retaliate) { if (fromlf && retaliate && !ko) {
fightback(lf, fromlf); fightback(lf, fromlf);
} }
@ -10073,8 +10243,19 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} }
} }
// you wake up if you were hit! if (ko) {
// you are knocked unconscious for a _long_ time
fallasleep(lf, ST_KO, rnd(50,100));
if (fromlf && isplayer(fromlf)) {
pleasegodmaybe(R_GODMERCY, 5);
}
} else {
// you wake up if you were hit, unless you were unconscious!
f = lfhasflag(lf, F_ASLEEP);
if (f && (f->val[1] != ST_KO)) {
killflagsofid(lf->flags, F_ASLEEP); killflagsofid(lf->flags, F_ASLEEP);
}
}
// automatic onbleed abilities? // automatic onbleed abilities?
if (postbleed && !prebleed) { if (postbleed && !prebleed) {
@ -10582,6 +10763,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
int dist; int dist;
int difficulty; int difficulty;
int lbonus; int lbonus;
flag_t *f;
if (l == noisemaker) continue; if (l == noisemaker) continue;
@ -10601,7 +10783,10 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
// listen bonus is based on sound volume // listen bonus is based on sound volume
lbonus = volume; lbonus = volume;
if (lfhasflag(l, F_ASLEEP)) { f = lfhasflag(l, F_ASLEEP);
if (f) {
// can't hear while unconscious
if (f->val[1] == ST_KO) continue;
lbonus -= 4; lbonus -= 4;
limit(&lbonus, 0, NA); limit(&lbonus, 0, NA);
} }
@ -10639,9 +10824,11 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
//strncpy(textnopunc, text, strlen(text)-1); //strncpy(textnopunc, text, strlen(text)-1);
strcpy(textnopunc, text); strcpy(textnopunc, text);
punc = textnopunc[strlen(textnopunc)-1]; punc = textnopunc[strlen(textnopunc)-1];
if (punc != '\"') { // ie. not someone saying something if (punc == '\"') {
textnopunc[strlen(textnopunc)-1] = '\0'; // ie. someone saying something
punc = '\0'; punc = '\0';
} else {
textnopunc[strlen(textnopunc)-1] = '\0';
} }
dist = getcelldist(l->cell, c); dist = getcelldist(l->cell, c);
@ -10758,7 +10945,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
} }
// still asleep? // still asleep?
if (lfhasflag(l, F_ASLEEP) && cansee(player, l)) { f = lfhasflag(l, F_ASLEEP);
if (f && (f->val[1] != ST_KO) && cansee(player, l)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(l, lfname); getlfname(l, lfname);
msg("%s stir%s in %s slumber...", lfname, msg("%s stir%s in %s slumber...", lfname,
@ -11855,7 +12043,7 @@ void setguntarget(lifeform_t *lf, lifeform_t *targ) {
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
flag_t *f,*nextf; flag_t *f,*nextf;
int i,retainhpmp = B_FALSE; int i,retainhp = B_FALSE;
int nkilled = 0; int nkilled = 0;
race_t *newrace; race_t *newrace;
char buf[BUFLEN]; char buf[BUFLEN];
@ -11868,8 +12056,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
statdirty = B_TRUE; statdirty = B_TRUE;
} }
if (lfhasflag(lf, F_RETAINHPMPONPOLY)) { if (lfhasflag(lf, F_RETAINHPONPOLY)) {
retainhpmp = B_TRUE; retainhp = B_TRUE;
} }
if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) { if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) {
@ -11946,10 +12134,23 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
// set material // set material
lf->material = lf->race->material; lf->material = lf->race->material;
// inherit flags from race // inherit most flags from race
for (f = lf->race->flags->first ; f ; f = f->next) {
switch (f->id) {
case F_RARITY:
case F_MPDICE:
break;
default:
addflag_real(lf->flags, f->id, f->val[0], f->val[1], f->val[2], f->text, FROMRACE, f->known, -1);
break;
}
}
/*
copyflags(lf->flags, lf->race->flags, FROMRACE); copyflags(lf->flags, lf->race->flags, FROMRACE);
// don't want certain race only flags... // don't want certain race only flags...
killflagsofid(lf->flags, F_RARITY); killflagsofid(lf->flags, F_RARITY);
*/
// certain other flags are rnadom // certain other flags are rnadom
getflags(lf->flags, retflag, &nretflags, F_RNDHOSTILE, F_NONE); getflags(lf->flags, retflag, &nretflags, F_RNDHOSTILE, F_NONE);
@ -11969,7 +12170,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
lf->baseatt[i] = lf->att[i]; lf->baseatt[i] = lf->att[i];
} }
if (!retainhpmp) { if (!retainhp) {
// generate hp/maxhp from hit dice // generate hp/maxhp from hit dice
lf->maxhp = 0; lf->maxhp = 0;
for (i = 0; i < lf->level; i++) { for (i = 0; i < lf->level; i++) {
@ -11978,6 +12179,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
lf->hp = lf->maxhp; lf->hp = lf->maxhp;
// don't regenerate mp
/*
// generate mp, if you have it. // generate mp, if you have it.
f = hasflag(lf->flags, F_MPDICE); f = hasflag(lf->flags, F_MPDICE);
if (f) { if (f) {
@ -11990,6 +12193,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
lf->maxmp = 0; lf->maxmp = 0;
} }
lf->mp = lf->maxmp; lf->mp = lf->maxmp;
*/
} }
lf->born = B_TRUE; lf->born = B_TRUE;
@ -12256,7 +12460,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
attrib = (getattr(lf, A_CON)/6) + (getattr(lf, A_WIS)/6) + getmr(lf); attrib = (getattr(lf, A_CON)/6) + (getattr(lf, A_WIS)/6) + getmr(lf);
break; break;
case SC_SEARCH: case SC_SEARCH:
attrib = (getskill(lf, SK_PERCEPTION)*3); attrib = (getskill(lf, SK_PERCEPTION)*2);
break; break;
case SC_STEAL: case SC_STEAL:
attrib = (getskill(lf, SK_THIEVERY)); attrib = (getskill(lf, SK_THIEVERY));
@ -13004,7 +13208,7 @@ void startlfturn(lifeform_t *lf) {
f = hasflag(o->flags, F_SECRET); f = hasflag(o->flags, F_SECRET);
if (f && (f->val[0] != NA)) { if (f && (f->val[0] != NA)) {
if (hasflag(o->flags, F_TRAP)) { if (hasflag(o->flags, F_TRAP)) {
mod += getskill(lf, SK_TRAPS); mod += (getskill(lf, SK_TRAPS)*2);
} }
if (skillcheck(lf, SC_SEARCH, f->val[0], mod)) { if (skillcheck(lf, SC_SEARCH, f->val[0], mod)) {
@ -13236,7 +13440,7 @@ void startlfturn(lifeform_t *lf) {
switch (damtype) { switch (damtype) {
case DT_WATER: case DT_WATER:
if ((bp == BP_FEET) && isplayer(lf) && hasbp(lf, bp) && !donefeetwet) { if ((bp == BP_FEET) && isplayer(lf) && hasbp(lf, bp) && !donefeetwet) {
msg("Your %s get wet.", getbodypartname(bp)); msg("Your %s get wet.", getbodypartname(lf, bp));
donefeetwet = B_TRUE; // don't keep repeating this donefeetwet = B_TRUE; // don't keep repeating this
} }
break; break;
@ -13542,7 +13746,7 @@ void stopresting(lifeform_t *lf) {
if (f) { if (f) {
killflag(f); killflag(f);
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your %s is interrupted!", (f->val[1] == NA) ? "rest" : "meditation"); msg("Your %s is interrupted!", (f->val[1] == ST_MEDITATING) ? "meditation" : "rest");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char buf[BUFLEN]; char buf[BUFLEN];
getlfname(lf, buf); getlfname(lf, buf);
@ -13553,12 +13757,7 @@ void stopresting(lifeform_t *lf) {
} }
void stoprunning(lifeform_t *lf) { void stoprunning(lifeform_t *lf) {
flag_t *f; killflagsofid(lf->flags, F_RUNNING);
f = hasflag(lf->flags, F_RUNNING);
if (f) {
killflag(f);
}
} }
void stopsprinting(lifeform_t *lf) { void stopsprinting(lifeform_t *lf) {
@ -14530,44 +14729,6 @@ int validateraces(void) {
printf("ERROR in race '%s' - F_STARTOB with zero length text.\n", r->name); printf("ERROR in race '%s' - F_STARTOB with zero length text.\n", r->name);
goterror = B_TRUE; goterror = B_TRUE;
} }
} else if ((f->id == F_CANCAST) || (f->id == F_CANWILL)) {
objecttype_t *sp;
enum SPELLSCHOOL school;
sp = findot(f->val[0]);
school = getspellschool(f->val[0]);
if (sp->obclass->id == OC_SPELL) {
if ((f->id == F_CANWILL) ||
hasflagval(r->flags, F_HASSKILL, SK_SPELLCASTING, NA, NA, NULL) ||
hasflagval(r->flags, F_STARTSKILL, SK_SPELLCASTING, NA, NA, NULL) ||
(school == SS_ALLOMANCY) || (school == SS_MENTAL)
) {
int power;
//power = (1 + ff->val[1]) / getspelllevel(f->val[0]);
power = getspellpower(lf, f->val[0]);
if (power <= 0) {
printf("ERROR in race '%s' - %s %s (l%d) but insufficient spell power.\n",
r->name,
(f->id == F_CANWILL) ? "F_CANWILL" : "F_CANCAST",
sp->name,getspelllevel(sp->id));
if (f->id == F_CANWILL) {
printf(" f_canwill text = '%s'\n\n",f->text);
}
goterror = B_TRUE;
}
} else {
objecttype_t *sp;
sp = findot(f->val[0]);
printf("ERROR in race '%s' - F_CANCAST %s (l%d) but no spellcasting skill\n", r->name, sp->name, getspelllevel(sp->id));
goterror = B_TRUE;
}
} else { // ie. ability
if (f->val[0] == OT_A_SWOOP) {
if (!hasflag(r->flags, F_SWOOPRANGE)) {
printf("ERROR in race '%s' - has SWOOP ability but no F_SWOOPRANGE.\n", r->name);
goterror = B_TRUE;
}
}
}
} else if (f->id == F_HITCONFER) { } else if (f->id == F_HITCONFER) {
if (!lfhasflag(lf, F_HITCONFERVALS)) { if (!lfhasflag(lf, F_HITCONFERVALS)) {
printf("ERROR in race '%s' - F_HITCONFER, but no HITCONFERVALS defined.\n", r->name); printf("ERROR in race '%s' - F_HITCONFER, but no HITCONFERVALS defined.\n", r->name);
@ -14666,7 +14827,7 @@ int rest(lifeform_t *lf, int onpurpose) {
// restore full hp // restore full hp
lf->hp = lf->maxhp; lf->hp = lf->maxhp;
// fall asleep for a while // fall asleep for a while
fallasleep(lf, 50); fallasleep(lf, ST_ASLEEP, 50);
// mark screen as dirty // mark screen as dirty
needredraw = B_TRUE; needredraw = B_TRUE;
if (isplayer(lf)) { if (isplayer(lf)) {
@ -14945,9 +15106,9 @@ int wear(lifeform_t *lf, object_t *o) {
if (inway) { if (inway) {
char inwayname[BUFLEN]; char inwayname[BUFLEN];
getobname(inway, inwayname, inway->amt); getobname(inway, inwayname, inway->amt);
snprintf(buf, BUFLEN, "%s (replace %s)", getbodypartname(possbp[i]), inwayname); snprintf(buf, BUFLEN, "%s (replace %s)", getbodypartname(lf, possbp[i]), inwayname);
} else { } else {
snprintf(buf, BUFLEN, "%s", getbodypartname(possbp[i])); snprintf(buf, BUFLEN, "%s", getbodypartname(lf, possbp[i]));
} }
addchoice(&prompt, ch++, buf, NULL, &possbp[i], NULL); addchoice(&prompt, ch++, buf, NULL, &possbp[i], NULL);
} }
@ -14976,6 +15137,9 @@ int wear(lifeform_t *lf, object_t *o) {
case E_ALREADYUSING: case E_ALREADYUSING:
if (isplayer(lf)) msg("You're already wearing that!"); if (isplayer(lf)) msg("You're already wearing that!");
break; break;
case E_DOESNTFIT:
if (isplayer(lf)) msg("The unnatural shape of your %s prevents this from fitting.", getbodypartname(lf, bp));
break;
case E_INJURED: case E_INJURED:
if (isplayer(lf)) msg("Your injuries prevent you from wearing this."); if (isplayer(lf)) msg("Your injuries prevent you from wearing this.");
break; break;
@ -15019,7 +15183,7 @@ int wear(lifeform_t *lf, object_t *o) {
if (isplayer(lf)) msg("You can't wear that!"); if (isplayer(lf)) msg("You can't wear that!");
break; break;
case E_NOBP: case E_NOBP:
if (isplayer(lf)) msg("You have no %s on which to wear that!", getbodypartname(bp)); if (isplayer(lf)) msg("You have no %s on which to wear that!", getbodypartname(lf, bp));
break; break;
case E_LOWCHA: case E_LOWCHA:
msg("You are not attractive enough to wear this."); msg("You are not attractive enough to wear this.");
@ -15086,7 +15250,7 @@ int wear(lifeform_t *lf, object_t *o) {
if ((gamemode == GM_GAMESTARTED) && lf->created) { if ((gamemode == GM_GAMESTARTED) && lf->created) {
if (isplayer(lf)) { if (isplayer(lf)) {
if (showpos) { if (showpos) {
msg("You are now wearing %s (%s your %s).", obname, getbodypartequipname(bp), getbodypartname(bp)); msg("You are now wearing %s (%s your %s).", obname, getbodypartequipname(bp), getbodypartname(lf, bp));
} else { } else {
msg("You are now wearing %s.", obname); msg("You are now wearing %s.", obname);
} }
@ -15112,9 +15276,25 @@ int wear(lifeform_t *lf, object_t *o) {
// warn if it will be cumbersome // warn if it will be cumbersome
if (isplayer(lf)) { if (isplayer(lf)) {
char howmuch[BUFLEN];
f = hasflagval(o->flags, F_EQUIPCONFER, F_SHIELDPENALTY, NA, NA, NULL); f = hasflagval(o->flags, F_EQUIPCONFER, F_SHIELDPENALTY, NA, NA, NULL);
if (f && (getskill(lf, SK_SHIELDS) <= PR_INEPT) ) { if (f) {
msg("^wYou find this shield very cumbersome to use."); int penalty;
penalty = adjustshieldpenalty(lf, f->val[1]);
if (penalty) {
if (penalty >= 40) {
strcpy(howmuch, "incredibly");
} else if (penalty >= 30) {
strcpy(howmuch, "extremely");
} else if (penalty >= 20) {
strcpy(howmuch, "very");
} else if (penalty >= 10) {
strcpy(howmuch, "quite");
} else {
strcpy(howmuch, "slightly ");
}
msg("^wYou find this shield %s cumbersome to use.", howmuch);
}
} }
} }

5
lf.h
View File

@ -75,7 +75,7 @@ void enhanceskills(lifeform_t *lf);
void extinguishlf(lifeform_t *lf); void extinguishlf(lifeform_t *lf);
object_t *eyesshaded(lifeform_t *lf); object_t *eyesshaded(lifeform_t *lf);
int fall(lifeform_t *lf, lifeform_t *fromlf, int announce); int fall(lifeform_t *lf, lifeform_t *fromlf, int announce);
int fallasleep(lifeform_t *lf, int howlong); int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong);
void fightback(lifeform_t *lf, lifeform_t *attacker); void fightback(lifeform_t *lf, lifeform_t *attacker);
job_t *findjob(enum JOB jobid); job_t *findjob(enum JOB jobid);
job_t *findjobbyname(char *name); job_t *findjobbyname(char *name);
@ -120,7 +120,7 @@ object_t *getbestthrowmissile(lifeform_t *lf);
object_t *getbestweapon(lifeform_t *lf); object_t *getbestweapon(lifeform_t *lf);
object_t *getbestfirearm(lifeform_t *lf); object_t *getbestfirearm(lifeform_t *lf);
int getbodyparthitchance(enum BODYPART bp); int getbodyparthitchance(enum BODYPART bp);
char *getbodypartname(enum BODYPART bp); char *getbodypartname(lifeform_t *lf, enum BODYPART bp);
char *getbodypartequipname(enum BODYPART bp); char *getbodypartequipname(enum BODYPART bp);
object_t *getequippedob(obpile_t *op, enum BODYPART bp); object_t *getequippedob(obpile_t *op, enum BODYPART bp);
int getexposedlimbs(lifeform_t *lf); int getexposedlimbs(lifeform_t *lf);
@ -273,6 +273,7 @@ flag_t *isresting(lifeform_t *lf);
object_t *isstuck(lifeform_t *lf); object_t *isstuck(lifeform_t *lf);
int issmellablelf(lifeform_t *lf); int issmellablelf(lifeform_t *lf);
int isswimming(lifeform_t *lf); int isswimming(lifeform_t *lf);
int isunconscious(lifeform_t *lf);
int isundead(lifeform_t *lf); int isundead(lifeform_t *lf);
flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt); flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt);
int isweaponskill(enum SKILL skid); int isweaponskill(enum SKILL skid);

108
map.c
View File

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "attack.h"
#include "defs.h" #include "defs.h"
#include "flag.h" #include "flag.h"
#include "io.h" #include "io.h"
@ -44,6 +45,14 @@ extern long curtime;
cell_t *addcell(map_t *m, int x, int y) { cell_t *addcell(map_t *m, int x, int y) {
cell_t *cell; cell_t *cell;
// already allocated?
cell = m->cell[(y*m->w)+x];
if (cell) {
clearcell(cell);
free(cell);
}
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t)); m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
cell = m->cell[(y*m->w)+x]; cell = m->cell[(y*m->w)+x];
cell->map = m; cell->map = m;
@ -150,6 +159,9 @@ map_t *addmap(void) {
for (i = 0; i < MAXDIR_ORTH; i++) { for (i = 0; i < MAXDIR_ORTH; i++) {
a->nextmap[i] = -1; a->nextmap[i] = -1;
} }
for (i = 0 ; i < MAX_MAPW*MAX_MAPH; i++) {
a->cell[i] = NULL;
}
a->flags = addflagpile(NULL, NULL); a->flags = addflagpile(NULL, NULL);
a->beingcreated = B_TRUE; a->beingcreated = B_TRUE;
a->habitat = findhabitat(H_DUNGEON); // default!!! a->habitat = findhabitat(H_DUNGEON); // default!!!
@ -272,9 +284,13 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int jobok, int
} }
// TODO: base this on the time, and whether monster is nocturnal // TODO: base this on the time, and whether monster is nocturnal
if (pctchance(asleepchance)) { if (pctchance(asleepchance)) {
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_ASLEEP, NA, ST_ASLEEP, NA, NULL);
} }
} }
// monsters who on dark levels can always see in the dark
if (!islit(lf->cell) && !lfhasflag(lf, F_SEEINDARK)) {
addflag(lf->flags, F_SEEINDARK, rnd(3,5), NA, NA, NULL);
}
} }
// appears in groups? // appears in groups?
@ -310,7 +326,10 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int jobok, int
// if master is asleep, minions will also be asleep // if master is asleep, minions will also be asleep
if (lfhasflag(lf, F_ASLEEP)) { if (lfhasflag(lf, F_ASLEEP)) {
addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL); addflag(newlf->flags, F_ASLEEP, NA, ST_ASLEEP, NA, NULL);
}
if (!islit(newlf->cell) && !lfhasflag(newlf, F_SEEINDARK)) {
addflag(newlf->flags, F_SEEINDARK, rnd(3,5), NA, NA, NULL);
} }
// minions never have certain flags. // minions never have certain flags.
@ -350,7 +369,11 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int jobok, int
if (nadded) (*nadded)++; if (nadded) (*nadded)++;
newlf->born = B_FALSE; newlf->born = B_FALSE;
if (lfhasflag(lf, F_ASLEEP)) addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL); if (lfhasflag(lf, F_ASLEEP)) addflag(newlf->flags, F_ASLEEP, NA, ST_ASLEEP, NA, NULL);
if (!islit(newlf->cell) && !lfhasflag(newlf, F_SEEINDARK)) {
addflag(newlf->flags, F_SEEINDARK, rnd(3,5), NA, NA, NULL);
}
newlf->born = B_TRUE; newlf->born = B_TRUE;
} }
} }
@ -762,7 +785,9 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
cell_t *poss[MAXCANDIDATES], *cell[MAXCANDIDATES]; // TODO: should this be maxroomw * maxroomh ? cell_t *poss[MAXCANDIDATES], *cell[MAXCANDIDATES]; // TODO: should this be maxroomw * maxroomh ?
int ncells = 0, npossible = 0; int ncells = 0, npossible = 0;
int doorsadded = 0; int doorsadded = 0;
int db = B_FALSE; int db = B_TRUE;
if (db) dblog("autodoors starting");
// for each side, make list of all possible door locations // for each side, make list of all possible door locations
// then pick one randomly. // then pick one randomly.
@ -788,7 +813,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
makedoor(cell[i], dooropenchance); makedoor(cell[i], dooropenchance);
} else { } else {
setcelltype(cell[i], cell[i]->habitat->emptycelltype); setcelltype(cell[i], cell[i]->habitat->emptycelltype);
addflag(map->flags, F_ROOMEXIT, roomid, cell[i]->x, cell[i]->y, NULL); addflag(map->flags, F_ROOMEXIT, roomid, cell[i]->x, cell[i]->y, "from autodoors, only way out");
} }
} else { } else {
// otherwise mark this as a _potential_ door location. // otherwise mark this as a _potential_ door location.
@ -808,7 +833,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
makedoor(poss[sel], dooropenchance); makedoor(poss[sel], dooropenchance);
} else { } else {
setcelltype(poss[sel], poss[sel]->habitat->emptycelltype); setcelltype(poss[sel], poss[sel]->habitat->emptycelltype);
addflag(map->flags, F_ROOMEXIT, roomid, poss[sel]->x, poss[sel]->y, NULL); addflag(map->flags, F_ROOMEXIT, roomid, poss[sel]->x, poss[sel]->y, "from autodoors, potential location");
} }
doorsadded++; doorsadded++;
@ -856,7 +881,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
doorsadded++; doorsadded++;
} else { } else {
setcelltype(cell[sel], cell[sel]->habitat->emptycelltype); setcelltype(cell[sel], cell[sel]->habitat->emptycelltype);
addflag(map->flags, F_ROOMEXIT, roomid, cell[sel]->x, cell[sel]->y, NULL); addflag(map->flags, F_ROOMEXIT, roomid, cell[sel]->x, cell[sel]->y, "from autodoors, forced at end");
doorsadded++; doorsadded++;
} }
} }
@ -1139,7 +1164,7 @@ int dowaterspread(cell_t *c) {
return B_FALSE; return B_FALSE;
} }
void fix_reachability(map_t *m) { int fix_reachability(map_t *m) {
int i,keepgoing = B_TRUE, nfixed = 0; int i,keepgoing = B_TRUE, nfixed = 0;
int db = B_TRUE; int db = B_TRUE;
cell_t *c = NULL; cell_t *c = NULL;
@ -1152,7 +1177,7 @@ void fix_reachability(map_t *m) {
case H_PIT: case H_PIT:
case H_VILLAGE: case H_VILLAGE:
if (db) dblog("fix_reachability not required for this habitat."); if (db) dblog("fix_reachability not required for this habitat.");
return; return B_FALSE;
default: break; default: break;
} }
@ -1164,7 +1189,7 @@ void fix_reachability(map_t *m) {
} }
} }
// no empty cells in map? // no empty cells in map?
if (!c) return; if (!c) return B_FALSE;
while (keepgoing) { while (keepgoing) {
keepgoing = B_FALSE; keepgoing = B_FALSE;
// mark all cells as non-filled // mark all cells as non-filled
@ -1182,8 +1207,14 @@ void fix_reachability(map_t *m) {
m->cell[i]->x, m->cell[i]->y); m->cell[i]->x, m->cell[i]->y);
linkexit(m->cell[i], B_TRUE, &nadded); linkexit(m->cell[i], B_TRUE, &nadded);
if (nadded) {
if (db) dblog(" fixed unreachable area by adding %d cells.", nadded); if (db) dblog(" fixed unreachable area by adding %d cells.", nadded);
assert(nadded); } else {
// didn't add anything - fail!
if (db) dblog(" fix_reachability failed.");
return B_TRUE;
}
// now run the test again. // now run the test again.
// 'c' will be where the next flood will will happen. // 'c' will be where the next flood will will happen.
@ -1195,6 +1226,7 @@ void fix_reachability(map_t *m) {
} }
} }
if (db) dblog(" fix_reachability complete. fixed %d unreachable areas.", nfixed); if (db) dblog(" fix_reachability complete. fixed %d unreachable areas.", nfixed);
return B_FALSE;
} }
@ -1520,7 +1552,6 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
int includethiscell = B_FALSE; int includethiscell = B_FALSE;
cell = getcellat(map, rx,ry); cell = getcellat(map, rx,ry);
// NEVER create a vault whcih will: // NEVER create a vault whcih will:
// - be on top of the player (normally this can't happen, // - be on top of the player (normally this can't happen,
// but debugging via 'create vault' could do it) // but debugging via 'create vault' could do it)
@ -1531,6 +1562,10 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
if (hasobwithflag(cell->obpile, F_CLIMBABLE)) { if (hasobwithflag(cell->obpile, F_CLIMBABLE)) {
valid = B_FALSE; valid = B_FALSE;
} }
// - overlap the inside of an existing room
if (cellwalkable(NULL, cell, NULL) && isroom(cell)) {
valid = B_FALSE;
}
// is this cell adjacent to an empty cell and not a // is this cell adjacent to an empty cell and not a
// corner (ie. a valid door location) // corner (ie. a valid door location)
@ -2266,7 +2301,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
int i,x,y; int i,x,y;
enum HABITAT habitat; enum HABITAT habitat;
regionthing_t *thing[MAXOUTLINETHINGS]; regionthing_t *thing[MAXOUTLINETHINGS];
int nthings = 0; int nthings = 0,failed;
int db = B_FALSE; int db = B_FALSE;
// determine habitat based on region // determine habitat based on region
@ -2477,7 +2512,9 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
} }
if (db) dblog(" %d things remembered for later.",nthings); if (db) dblog(" %d things remembered for later.",nthings);
failed = B_TRUE;
while (failed) {
failed = B_FALSE;
// build it... // build it...
if (db) dblog(" creating map habitat."); if (db) dblog(" creating map habitat.");
createhabitat(map, depth, parentmap, exitdir, entryob); createhabitat(map, depth, parentmap, exitdir, entryob);
@ -2488,7 +2525,6 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
addhomeobs(lf); addhomeobs(lf);
} }
// add outline things // add outline things
if (db) dblog(" adding remembered region outline things..."); if (db) dblog(" adding remembered region outline things...");
for (i = 0; i < nthings ;i++) { for (i = 0; i < nthings ;i++) {
@ -2509,6 +2545,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
assert(v); assert(v);
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) { if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
dblog("ERROR - couldn't create vault %s on map %s", v->id, map->name); dblog("ERROR - couldn't create vault %s on map %s", v->id, map->name);
failed = B_TRUE;
} }
break; break;
case RT_RNDVAULTWITHFLAG: case RT_RNDVAULTWITHFLAG:
@ -2517,13 +2554,23 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
assert(v); assert(v);
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) { if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
dblog("ERROR - couldn't create rndvaultwithflag %s on map %s", v->id, map->name); dblog("ERROR - couldn't create rndvaultwithflag %s on map %s", v->id, map->name);
failed = B_TRUE;
} }
break; break;
} }
} }
// ensure there are no unreachable areas // ensure there are no unreachable areas
fix_reachability(map); if (!failed) {
if (fix_reachability(map)) {
failed = B_TRUE;
}
}
if (failed) {
dblog("********* got errors - restarting map creation. *********");
}
}
// special cases // special cases
// village - add town walls and clear it out // village - add town walls and clear it out
@ -2798,7 +2845,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
if (calcroompos(map, w, h, xmargin, ymargin, &minx, &miny, B_TRUE)) { if (calcroompos(map, w, h, xmargin, ymargin, &minx, &miny, B_TRUE)) {
// forced calcroompos should never fail since it's // forced calcroompos should never fail since it's
// allowed to overlap other rooms. // allowed to overlap other rooms.
dblog("** couldn't make vault room!\n"); dblog("** couldn't find position for vault %s (roomid %d)!\n", v->id, roomid);
//msg("** ALERT: couldn't make vault room!\n"); //msg("** ALERT: couldn't make vault room!\n");
return B_TRUE; return B_TRUE;
} }
@ -2815,7 +2862,6 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
thisroom = &(map->room[map->nrooms]); thisroom = &(map->room[map->nrooms]);
map->nrooms++; map->nrooms++;
// now make it // now make it
if (db) dblog("making vault %s at pos %d,%d on map %s", v->id, minx, miny, map->name); if (db) dblog("making vault %s at pos %d,%d on map %s", v->id, minx, miny, map->name);
for (y = miny; y <= maxy; y++) { for (y = miny; y <= maxy; y++) {
@ -2894,10 +2940,10 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
while (c) { while (c) {
dist[d]++; dist[d]++;
if ((roomid >= 0) && getroomid(c) == roomid) { // same room if ((roomid >= 0) && getroomid(c) == roomid) { // same room
if (wantfilled && c->type->solid) { //if (wantfilled && c->type->solid) {
if (c->type->solid) {
// EXCEPTION: // EXCEPTION:
// if we are calling this function from fix_reachability, then // if startcell is a cell _inside_ the room as opposed to
// startcell will actually be a cell _inside_ the room as opposed to
// a cell inside the room's walls. // a cell inside the room's walls.
// in this case, we ARE allowed to travel through the room's walls. // in this case, we ARE allowed to travel through the room's walls.
} else { } else {
@ -2985,7 +3031,13 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
startdir = startposs[rnd(0,nstartposs-1)]; startdir = startposs[rnd(0,nstartposs-1)];
} }
if (wantfilled) {
// if startdir is D_NONE here, it means that we've called
// linkexit for a cell internal to a room.
// if we called this function from fix_reachable (ie. wantfilled=true)
// then this is a bad thing.
assert(startdir != D_NONE); assert(startdir != D_NONE);
}
// figure out perpendicular dirs // figure out perpendicular dirs
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W; perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
@ -3256,6 +3308,9 @@ int linkexits(map_t *m, int roomid) {
} }
assert(roomidx != -1); assert(roomidx != -1);
// does this roomid actually exist??
c = getrandomroomcell(m, roomid);
if (!c) return B_FALSE;
if (db) { if (db) {
char buf[BUFLEN]; char buf[BUFLEN];
@ -3620,6 +3675,14 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
mydist = getcelldist(c,cc); mydist = getcelldist(c,cc);
if (cc && (mydist <= (range+1))) { if (cc && (mydist <= (range+1))) {
if (cc->lf && !isdead(cc->lf)) { if (cc->lf && !isdead(cc->lf)) {
int critchance;
// critical hit? 100% chance in middle, 60 at one cell, 20 at two cells
critchance = 100 - (mydist*40);
if (pctchance(critchance)) {
//criticalhit(NULL, cc->lf, getrandomcorebp(cc->lf), DT_EXPLOSION);
criticalhit(NULL, cc->lf, BP_HANDS, DT_EXPLOSIVE);
}
// move away from centre of explosion // move away from centre of explosion
knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 2, NULL, 40-(mydist*10)); knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 2, NULL, 40-(mydist*10));
} }
@ -5051,6 +5114,7 @@ void mapentereffects(map_t *m) {
if (m->lastplayervisit != -1) { if (m->lastplayervisit != -1) {
int nturns; int nturns;
nturns = (curtime - m->lastplayervisit) / TICK_INTERVAL; nturns = (curtime - m->lastplayervisit) / TICK_INTERVAL;
limit(&nturns, NA, 20);
//nturns *= countlfs(m); //nturns *= countlfs(m);
for (i = 0; i < nturns; i++) { for (i = 0; i < nturns; i++) {
donextturn(m); donextturn(m);
@ -5070,7 +5134,7 @@ enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob) {
donesomething = B_FALSE; donesomething = B_FALSE;
if (strstarts(p, "sleeping ")) { if (strstarts(p, "sleeping ")) {
p += strlen("sleeping "); p += strlen("sleeping ");
if (wantflags) addflag(wantflags, F_ASLEEP, NA, NA, NA, NULL); if (wantflags) addflag(wantflags, F_ASLEEP, NA, ST_ASLEEP, NA, NULL);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
} }

3
map.h
View File

@ -17,7 +17,7 @@ int cellhaslos(cell_t *c1, cell_t *dest);
void clearcell(cell_t *c); void clearcell(cell_t *c);
void clearcell_exceptflags(cell_t *c, ...); void clearcell_exceptflags(cell_t *c, ...);
int dowaterspread(cell_t *c); int dowaterspread(cell_t *c);
void fix_reachability(map_t *m); int fix_reachability(map_t *m);
int fix_unreachable_cell(cell_t *badcell); int fix_unreachable_cell(cell_t *badcell);
void floodfill(cell_t *startcell); void floodfill(cell_t *startcell);
cell_t *getcellat(map_t *map, int x, int y); cell_t *getcellat(map_t *map, int x, int y);
@ -51,6 +51,7 @@ void createheaven(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob); void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob);
void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIONTYPE newregiontype, region_t *parent); void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIONTYPE newregiontype, region_t *parent);
void createregionthing(map_t *map, regionthing_t *rt);
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls); int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety); int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety);
int dirtox(int dt, int dir); int dirtox(int dt, int dir);

9
move.c
View File

@ -348,6 +348,8 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
enum RELATIVEDIR getrelativedir(lifeform_t *lf, int dir) { enum RELATIVEDIR getrelativedir(lifeform_t *lf, int dir) {
int tempdir; int tempdir;
if (lfhasflag(lf, F_AWARENESS)) return RD_FORWARDS;
// facing N, dir N == forwards // facing N, dir N == forwards
if (lf->facing == dir) return RD_FORWARDS; if (lf->facing == dir) return RD_FORWARDS;
@ -905,7 +907,10 @@ int moveeffects(lifeform_t *lf) {
int didmsg = B_FALSE; int didmsg = B_FALSE;
if (lfhasflagval(lf, F_INJURY, IJ_HAMSTRUNG, NA, NA, NULL)) { if (lfhasflagval(lf, F_INJURY, IJ_HAMSTRUNG, NA, NA, NULL)) {
if (!skillcheck(lf, SC_FALL, 20, 0)) fall(lf, NULL, B_TRUE); if (!skillcheck(lf, SC_FALL, 20, 0)) {
fall(lf, NULL, B_TRUE);
if (isplayer(lf)) didmsg = B_TRUE;
}
} }
if (isbleeding(lf)) { if (isbleeding(lf)) {
@ -1432,7 +1437,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
} }
// slip on blood in new cell? // slip on blood in new cell?
if (!isairborne(lf)) { if (!isairborne(lf) && !isswimming(lf)) {
int slip; int slip;
object_t *o,*nexto; object_t *o,*nexto;
object_t *slipob; object_t *slipob;

View File

@ -3071,7 +3071,7 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder) {
switch (slev) { switch (slev) {
case PR_INEPT: case PR_INEPT:
acc -= 30; acc -= 35;
break; break;
case PR_NOVICE: case PR_NOVICE:
acc -= 10; acc -= 10;
@ -3641,6 +3641,7 @@ int getobattackdelay(object_t *o) {
return delay; return delay;
} }
float getobhppct(object_t *o) { float getobhppct(object_t *o) {
float pct; float pct;
flag_t *f; flag_t *f;
@ -3653,6 +3654,16 @@ float getobhppct(object_t *o) {
return pct; return pct;
} }
// returns '1' if object has no F_OBHP
int getobmaxhp(object_t *o) {
flag_t *f;
f = hasflag(o->flags, F_OBHP);
if (f) {
return f->val[1];
}
return 1;
}
int getletidx(char let) { int getletidx(char let) {
int i; int i;
for (i = 0; i < MAXPILEOBS; i++) { for (i = 0; i < MAXPILEOBS; i++) {
@ -3941,7 +3952,7 @@ char *getobequipinfo(object_t *o, char *buf) {
strcat(buf, " ("); strcat(buf, " (");
strcat(buf, getbodypartequipname(f->val[0])); strcat(buf, getbodypartequipname(f->val[0]));
strcat(buf, " "); strcat(buf, " ");
strcat(buf, getbodypartname(f->val[0])); strcat(buf, getbodypartname(o->pile->owner, f->val[0]));
strcat(buf, ")"); strcat(buf, ")");
} }
} }
@ -3971,7 +3982,7 @@ char *getobextrainfo(object_t *o, char *buf) {
} }
} else { } else {
if (f->val[0] > 0) { if (f->val[0] > 0) {
snprintf(chargestr, BUFLEN, " (%d charges left)",f->val[0]); snprintf(chargestr, BUFLEN, " (%d charge%s left)",f->val[0], (f->val[0] == 1) ? "" : "s");
} else { } else {
snprintf(chargestr, BUFLEN, " (empty)"); snprintf(chargestr, BUFLEN, " (empty)");
} }
@ -4082,10 +4093,10 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
} }
if (who) { if (who) {
char lfname[BUFLEN]; char lfname[BUFLEN];
real_getlfname(who, lfname, B_FALSE); real_getlfnamea(who, lfname, B_FALSE);
snprintf(buf, BUFLEN, "%s%s %sscent",lfname,getpossessive(lfname), adjective); snprintf(buf, BUFLEN, "%s%s%s %sscent",adjective,lfname,getpossessive(lfname));
} else { } else {
snprintf(buf, BUFLEN, "%s %sscent",r->name, adjective); snprintf(buf, BUFLEN, "%s%s scent",adjective, r->name );
} }
strcat(basename, buf); strcat(basename, buf);
@ -4530,6 +4541,10 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
} }
} }
if (hasflag(o->flags, F_KNOWNBAD)) {
strcat(localbuf, " [bad]");
}
if (getskill(player, SK_COOKING) >= PR_BEGINNER) { if (getskill(player, SK_COOKING) >= PR_BEGINNER) {
if (isbadfood(o)) { if (isbadfood(o)) {
strcat(localbuf, " [badfood]"); strcat(localbuf, " [badfood]");
@ -6029,11 +6044,13 @@ void killob(object_t *o) {
object_t *nextone, *lastone; object_t *nextone, *lastone;
// debugging // debugging
/*
if (o->type->id == OT_STAIRSUP) { if (o->type->id == OT_STAIRSUP) {
msg("warning: removing an up staircase!"); msg("warning: removing an up staircase!");
dblog("warning: removing an up staircase!"); dblog("warning: removing an up staircase!");
assert(1 == 0); assert(1 == 0);
} }
*/
// remove flags conferred by this object // remove flags conferred by this object
if (o->pile->owner) { if (o->pile->owner) {
@ -6588,11 +6605,14 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
// triggered a trap? // triggered a trap?
for (oo = dst->where->obpile->first ; oo ; oo = nextoo ) { for (oo = dst->where->obpile->first ; oo ; oo = nextoo ) {
nextoo = oo->next; nextoo = oo->next;
if ((oo != o) && hasflag(oo->flags, F_TRAP)) { if (oo != o) {
f = hasflag(oo->flags, F_TRAP);
if (f && (f->val[1] != curtime)) {
triggertrap(NULL, o, oo, dst->where); triggertrap(NULL, o, oo, dst->where);
} }
} }
} }
}
//o = newobeffects(o); //o = newobeffects(o);
@ -10384,8 +10404,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
// saving throws // saving throws
if (youhit && !willcatch && !isprone(target)) { if (youhit && !willcatch && !isprone(target)) {
// can the victim see the thrower? // can the victim see where the object came from?
if (thrower && cansee(target, thrower)) { if (haslos(target, srcloc)) {
int catchmod,dodgemod; int catchmod,dodgemod;
enum LFSIZE sz; enum LFSIZE sz;
sz = getobsize(o); sz = getobsize(o);
@ -10413,7 +10433,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
!isimmobile(target) && !isimmobile(target) &&
skillcheck(target, SC_DEX, 15*speed, catchmod)) { skillcheck(target, SC_DEX, 15*speed, catchmod)) {
willcatch = B_TRUE; willcatch = B_TRUE;
} else if (!lfhasflag(target, F_CASTINGSPELL) && skillcheck(target, SC_DODGE, 10*speed, dodgemod)) { } else if (!lfhasflag(target, F_CASTINGSPELL) && skillcheck(target, SC_DODGE, 7*speed, dodgemod)) {
// then check if we dodge it... // then check if we dodge it...
youhit = B_FALSE; youhit = B_FALSE;
} }
@ -11016,9 +11036,9 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
lf = c->lf; lf = c->lf;
if (lf) getlfname(lf, lfname); if (lf) getlfname(lf, lfname);
temp = findot(oid); temp = findot(oid);
// saving throw? // saving throw?
if (temp && lf) { if (temp && lf) {
flag_t *f; flag_t *f;
@ -11041,6 +11061,13 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
} }
} }
} }
// for actual trap objects (ie. not not doors etc), remember when we last
// triggered this trap. this is to avoid infinite loops with arrow traps!
if (trapob) {
flag_t *f;
f = hasflag(trapob->flags, F_TRAP);
if (f) f->val[1] = curtime;
}
if (oid == OT_TRAPWIND) { if (oid == OT_TRAPWIND) {
// can't be dodged // can't be dodged
@ -11546,6 +11573,8 @@ int getcritchance(lifeform_t *lf, object_t *o, lifeform_t *victim) {
int chance = 0; int chance = 0;
if (!o) return 0; if (!o) return 0;
if (hasflag(o->flags, F_MERCIFUL)) return 0;
f = hasflag(o->flags, F_CRITCHANCE); f = hasflag(o->flags, F_CRITCHANCE);
if (f) { if (f) {
chance += f->val[0]; chance += f->val[0];

View File

@ -94,6 +94,7 @@ char *genhiddenname(enum OBCLASS id);
char *gethiddenname(object_t *o); char *gethiddenname(object_t *o);
int getobattackdelay(object_t *o); int getobattackdelay(object_t *o);
float getobhppct(object_t *o); float getobhppct(object_t *o);
int getobmaxhp(object_t *o);
int getletindex(char let); int getletindex(char let);
int getmaterialvalue(enum MATERIAL mat ); int getmaterialvalue(enum MATERIAL mat );
int getmaxthrowrange(lifeform_t *lf, object_t *o); int getmaxthrowrange(lifeform_t *lf, object_t *o);

47
spell.c
View File

@ -3278,10 +3278,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// announce // announce
getobname(o, obname, 1); getobname(o, obname, 1);
if (isplayer(target)) { if (isplayer(target)) {
msg("%s forms %s your %s!", obname, getbodypartequipname(bp[i]), getbodypartname(bp[i])); msg("%s forms %s your %s!", obname, getbodypartequipname(bp[i]), getbodypartname(target, bp[i]));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]), msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]),
castername, getpossessive(castername), getbodypartname(bp[i])); castername, getpossessive(castername), getbodypartname(target, bp[i]));
} }
wear(target, o); wear(target, o);
// set its values // set its values
@ -4636,13 +4636,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
if ((retflag[i]->id == F_NOBODYPART) && (retflag[i]->val[1] == B_FROMINJURY)) { if ((retflag[i]->id == F_NOBODYPART) && (retflag[i]->val[1] == B_FROMINJURY)) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Your %s grows back!", getbodypartname(retflag[0]->val[0])); msg("Your %s grows back!", getbodypartname(target, retflag[0]->val[0]));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char targname[BUFLEN]; char targname[BUFLEN];
getlfname(target, targname); getlfname(target, targname);
msg("%s%s %s grows back!", targname, getpossessive(targname), msg("%s%s %s grows back!", targname, getpossessive(targname),
getbodypartname(retflag[0]->val[0])); getbodypartname(target, retflag[0]->val[0]));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
killflag(retflag[i]); killflag(retflag[i]);
@ -4978,11 +4978,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if ((f->val[0] == BP_RIGHTFINGER) || (f->val[0] == BP_LEFTFINGER)) { } else if ((f->val[0] == BP_RIGHTFINGER) || (f->val[0] == BP_LEFTFINGER)) {
if (isplayer(caster)) { if (isplayer(caster)) {
getobname(o, buf, 1); getobname(o, buf, 1);
msg("Your %s slides off your %s!", buf, getbodypartname(f->val[0])); msg("Your %s slides off your %s!", buf, getbodypartname(caster, f->val[0]));
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
getobname(o, buf, 1); getobname(o, buf, 1);
msg("%s%s %s slides off its %s!", castername, msg("%s%s %s slides off its %s!", castername,
getpossessive(castername), buf, getbodypartname(f->val[0])); getpossessive(castername), buf, getbodypartname(caster, f->val[0]));
} }
moveob(o, caster->cell->obpile, o->amt); moveob(o, caster->cell->obpile, o->amt);
} else { } else {
@ -6172,7 +6172,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *o; object_t *o;
lifeform_t *l; lifeform_t *l;
targcell = caster->cell; targcell = getcellindir(caster->cell, caster->facing);
if (!targcell || targcell->type->solid) {
fizzle(caster);
return B_TRUE;
}
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -6194,6 +6198,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} }
// hack - make all monsters who can see you stop targetting you. // hack - make all monsters who can see you stop targetting you.
// otherwise they will just try to go to your last known location.
for (l = caster->cell->map->lf ; l ; l = l->next) { for (l = caster->cell->map->lf ; l ; l = l->next) {
flag_t *f; flag_t *f;
if ((l != caster) && (gethitdice(l) <= gethitdice(caster)) ) { if ((l != caster) && (gethitdice(l) <= gethitdice(caster)) ) {
@ -6367,7 +6372,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// - can't turn into monsters which aren't randomly generated. // - can't turn into monsters which aren't randomly generated.
// - can't turn into unique monsters // - can't turn into unique monsters
// - can't turn into undead monsters // - can't turn into undead monsters
if (r && !canpolymorphto(r->id)) r = NULL; if (r && !canpolymorphto(r->id) && !hasjob(caster, J_GOD)) {
if (isplayer(caster)) msg("As you think of a %s, magic energy dampens around you.", r->name);
r = NULL;
}
} else { // random } else { // random
if (isplayer(target) && lfhasflag(target, F_CONTROL)) { if (isplayer(target) && lfhasflag(target, F_CONTROL)) {
askstring("What will you become", '?', buf, BUFLEN, NULL); askstring("What will you become", '?', buf, BUFLEN, NULL);
@ -6774,7 +6782,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE; return B_FALSE;
} }
howlong = getspellduration(5,10,blessed) + (power/2); howlong = getspellduration(5,10,blessed) + (power/2);
fallasleep(target, howlong); fallasleep(target, ST_ASLEEP, howlong);
if (isplayer(target) || haslos(player, target->cell)) { if (isplayer(target) || haslos(player, target->cell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -6990,7 +6998,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE;
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
if (targcell->lf && cansee(player, targcell->lf)) {
char lfname[BUFLEN];
getlfname(targcell->lf, lfname);
msg("A small spark of flame singes %s.", lfname);
} else {
msg("A small spark of flame appears."); msg("A small spark of flame appears.");
}
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7293,8 +7307,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int nallies = 0; int nallies = 0;
// target is always the caster // target is always the caster
target = caster; if (!target) target = caster;
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
if (isplayer(target)) { if (isplayer(target)) {
@ -8672,6 +8685,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
//////////////////////////////////// ////////////////////////////////////
// HOW POWERFUL IS THIS SPELL? // HOW POWERFUL IS THIS SPELL?
//////////////////////////////////// ////////////////////////////////////
if (isplayer(lf)) {
if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) { if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) {
// always okay // always okay
usesorcery = B_FALSE; usesorcery = B_FALSE;
@ -8702,6 +8716,10 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
// +/- 1 for iq // +/- 1 for iq
power += (getstatmod(lf, A_IQ) / 50); power += (getstatmod(lf, A_IQ) / 50);
} }
} else {
// for monsters, just based on hitdice:
power = gethitdice(lf);
}
limit(&power, 0, getspellmaxpower(spellid)); limit(&power, 0, getspellmaxpower(spellid));
return power; return power;
@ -9019,6 +9037,13 @@ int spellisfromschool(int spellid, enum SPELLSCHOOL school) {
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) { int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) {
char text[BUFLEN],buf[BUFLEN]; char text[BUFLEN],buf[BUFLEN];
// cannot resist spells from gods when they are on their home plane
if (caster && (caster->race->raceclass->id == RC_GOD)) {
if (caster->cell && (caster->cell->map->region->rtype->id == RG_HEAVEN)) {
return B_FALSE;
}
}
if (announce) { if (announce) {
getlfname(target, buf); getlfname(target, buf);
if (spellisfromschool(spellid, SS_MENTAL)) { if (spellisfromschool(spellid, SS_MENTAL)) {

2
text.c
View File

@ -424,6 +424,8 @@ char *gettimetextfuzzy(char *retbuf, int wantpm) {
pm = B_TRUE; pm = B_TRUE;
} }
if (hours == 0) hours = 12;
if (mins == 0) { if (mins == 0) {
snprintf(retbuf, BUFLEN, "exactly %d o'clock", hours); snprintf(retbuf, BUFLEN, "exactly %d o'clock", hours);
} else if (mins <= 15) { } else if (mins <= 15) {