- [+] fix bug with help not working

- [+] fix bug with redrawing when you open a door.
- [+] fix bug where pleasing gods during killflag() causes crash.
- [+] creatures >= 2 sizes bigger than you should block los
- [+] explosion trap should kill doors
- [+] redo getflags to take more args
- [+] genericise isprisoner code
* [+] jimbo's lair needs a portal back to dlev1
* [+] linkexits still not working properly.  fixed i think!
- [+] rename some spells
- [+] make max spell level be 6 (to match up with pr_master)
- [+] modify mp per level by sk_sorcery/2
- [+] bug: reading a blessed scroll of manding does nothing!
- [+] improved crit effects
    - [+] bash
    - [+] slash
    - [+] fire dam cauterises slash wounds
    - [+] cold dam fixes brusing
- [+] add crit chance to weapons. (default of xxx)
- [+] stirges shouldn't be able to latch on if you have no exposed body
      parts
This commit is contained in:
Rob Pearce 2011-08-24 08:15:09 +00:00
parent 9a3c2c69ba
commit f071b379ca
22 changed files with 1424 additions and 674 deletions

28
ai.c
View File

@ -18,9 +18,6 @@
extern lifeform_t *player; extern lifeform_t *player;
extern enum ERROR reason; extern enum ERROR reason;
extern flag_t *retflag[];
extern int nretflags;
int wantdb = B_TRUE; int wantdb = B_TRUE;
void addignorecell(lifeform_t *lf, cell_t *c) { void addignorecell(lifeform_t *lf, cell_t *c) {
@ -112,6 +109,8 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
} }
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) { enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
flag_t *retflag[MAXCANDIDATES];
int nretflags;
flag_t *f; flag_t *f;
enum OBTYPE poss[MAXPILEOBS]; enum OBTYPE poss[MAXPILEOBS];
int nposs = 0; int nposs = 0;
@ -129,7 +128,8 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
if (castok) { if (castok) {
int i; int i;
getflags(lf->flags, F_CANCAST, F_CANWILL, F_NONE);
getflags(lf->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (aispellok(lf, f->val[0], victim, F_AICASTTOATTACK)) { if (aispellok(lf, f->val[0], victim, F_AICASTTOATTACK)) {
@ -160,6 +160,8 @@ enum OBTYPE aigetfleespell(lifeform_t *lf) {
int nposs = 0,i; int nposs = 0,i;
int db = B_FALSE; int db = B_FALSE;
lifeform_t *fleefrom; lifeform_t *fleefrom;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (lfhasflag(lf, F_DEBUG)) { if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE; db = B_TRUE;
@ -170,8 +172,7 @@ enum OBTYPE aigetfleespell(lifeform_t *lf) {
fleefrom = findlf(lf->cell->map, f->val[0]); fleefrom = findlf(lf->cell->map, f->val[0]);
} }
getflags(lf->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE);
getflags(lf->flags, F_CANCAST, F_CANWILL, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (aispellok(lf, f->val[0], fleefrom, F_AICASTTOFLEE)) { if (aispellok(lf, f->val[0], fleefrom, F_AICASTTOFLEE)) {
@ -921,6 +922,8 @@ void aiturn(lifeform_t *lf) {
lifeform_t *master = NULL; lifeform_t *master = NULL;
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
int n,i; int n,i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
/* /*
@ -981,7 +984,7 @@ void aiturn(lifeform_t *lf) {
// use items, talk,etc // use items, talk,etc
/////////////////////////////////////////////// ///////////////////////////////////////////////
if ((lf->race->id == R_PRISONER) && master && isplayer(master) && cansee(lf, master)) { if (lfhasflag(lf, F_ISPRISONER) && master && isplayer(master) && cansee(lf, master)) {
if (isoutdoors(lf->cell->map) && pctchance(20)) { if (isoutdoors(lf->cell->map) && pctchance(20)) {
object_t *o; object_t *o;
say(lf, "Thanks for getting me out!", SV_TALK); say(lf, "Thanks for getting me out!", SV_TALK);
@ -992,7 +995,9 @@ void aiturn(lifeform_t *lf) {
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
msgnocap("%c - %s", o->letter, obname); msgnocap("%c - %s", o->letter, obname);
} }
// no longer an ally
killflagsofid(lf->flags, F_PETOF); killflagsofid(lf->flags, F_PETOF);
killflagsofid(lf->flags, F_ISPRISONER);
} }
} }
@ -1035,7 +1040,7 @@ void aiturn(lifeform_t *lf) {
flag_t *poss[MAXCANDIDATES]; flag_t *poss[MAXCANDIDATES];
int nposs = 0,i; int nposs = 0,i;
getflags(lf->flags, F_RANDOMTALK, F_NONE); getflags(lf->flags, retflag, &nretflags, F_RANDOMTALK, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
poss[nposs++] = retflag[i]; poss[nposs++] = retflag[i];
} }
@ -1672,6 +1677,9 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }
if ((ot->id == OT_S_FREEZEOB) && lfhasflag(lf, F_FREEZINGTOUCH)) {
specificcheckok = B_FALSE;
}
if ((ot->id == OT_S_HASTE) && (lfhasflag(victim, F_FASTACT) || lfhasflag(victim, F_FASTACTMOVE)) ) { if ((ot->id == OT_S_HASTE) && (lfhasflag(victim, F_FASTACT) || lfhasflag(victim, F_FASTACTMOVE)) ) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
@ -2036,10 +2044,12 @@ int lookforobs(lifeform_t *lf) {
void makewantedoblist(lifeform_t *lf, int *noids, enum OBTYPE *oid, int *oidcovet,int *nwantflags, enum FLAG *wantflag, int *wantflagcovet) { void makewantedoblist(lifeform_t *lf, int *noids, enum OBTYPE *oid, int *oidcovet,int *nwantflags, enum FLAG *wantflag, int *wantflagcovet) {
int i; int i;
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
// construct a list of objects which we want // construct a list of objects which we want
*noids = 0; *noids = 0;
getflags(lf->flags, F_WANTS, F_WANTSOBFLAG, F_NONE); getflags(lf->flags, retflag, &nretflags, F_WANTS, F_WANTSOBFLAG, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_WANTS) { if (f->id == F_WANTS) {

183
attack.c
View File

@ -17,17 +17,12 @@
extern lifeform_t *player; extern lifeform_t *player;
extern flag_t *retflag[];
extern int nretflags;
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) { int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
object_t *armour = NULL; object_t *armour = NULL;
int damtaken = 0; int damtaken = 0;
// first of all, only apply some of the damage // first of all, only apply some of the damage
dam /= 2; dam /= 2;
// figure out what bit of armour was hit
if (dam == 0) { if (dam == 0) {
return 0; return 0;
} }
@ -41,6 +36,7 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
} }
} }
// figure out what bit of armour was hit
if (!armour) { if (!armour) {
// pick a random piece of armour // pick a random piece of armour
armour = getrandomarmour(lf); armour = getrandomarmour(lf);
@ -167,6 +163,8 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
int lastweaponidx = -1; int lastweaponidx = -1;
flag_t *sf; flag_t *sf;
int saysorry = B_FALSE; int saysorry = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
// anyone there? if so just attack. // anyone there? if so just attack.
if (c->lf) { if (c->lf) {
@ -282,7 +280,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
// then use all our innate attacks.. // then use all our innate attacks..
getflags(lf->flags, F_HASATTACK, F_NONE); getflags(lf->flags, retflag, &nretflags, F_HASATTACK, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_HASATTACK) { if (f->id == F_HASATTACK) {
@ -421,6 +419,11 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
sayphrase(lf, SP_SORRY, -1, NA, NULL); sayphrase(lf, SP_SORRY, -1, NA, NULL);
} }
if (lfhasflagval(lf, F_INJURY, BP_HANDS, DT_SLASH, NA, NULL)) {
bleed(lf);
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
}
return B_FALSE; return B_FALSE;
} }
@ -447,9 +450,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int willheal = B_FALSE; int willheal = B_FALSE;
int isunarmed = B_FALSE; int isunarmed = B_FALSE;
skill_t *wepsk = NULL; skill_t *wepsk = NULL;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int aidb = B_FALSE; int aidb = B_FALSE;
flag_t *f; flag_t *f;
enum BODYPART critpos = BP_NONE;
if (wep) { if (wep) {
wepsk = getobskill(wep); wepsk = getobskill(wep);
@ -502,7 +507,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
getflags(lf->flags, 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++) {
f = retflag[i]; f = retflag[i];
// ie. you have been made noncorporeal // ie. you have been made noncorporeal
@ -522,6 +527,27 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
hit = rolltohit(lf, victim, wep, &critical); hit = rolltohit(lf, victim, wep, &critical);
if (critical) {
critpos = getrandomcorebp(victim);
// replace victicname to include body part
if ((lf == victim) && !isplayer(lf)) {
sprintf(victimname, "it's %s", getbodypartname(critpos));
} else {
getlfname(victim, buf);
sprintf(victimname, "%s%s %s", buf, getpossessive(buf), getbodypartname(critpos));
}
}
if (lf == victim) {
if (isplayer(lf)) {
strcpy(victimname, "yourself");
} else {
strcpy(victimname, "itself");
}
} else {
getlfname(victim, victimname);
}
// weapon passing through ghosts etc? // weapon passing through ghosts etc?
if (hit) { if (hit) {
if (lfhasflag(victim, F_NONCORPOREAL) && if (lfhasflag(victim, F_NONCORPOREAL) &&
@ -884,7 +910,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL); losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL);
// victim's armour loses hp // victim's armour loses hp
if (reduceamt) { if (reduceamt && !critical) {
applyarmourdamage(victim, wep, dam[i], damtype[i]); applyarmourdamage(victim, wep, dam[i], damtype[i]);
// train armour // train armour
practice(victim, SK_ARMOUR, 1); practice(victim, SK_ARMOUR, 1);
@ -960,10 +986,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// critical hit effects // critical hit effects
if (critical) { if (critical && damtypecausescriteffects(damtype[0])) {
if (lfhasflag(lf, F_CRITKNOCKDOWN)) { criticalhit(lf, victim, critpos, damtype[0]);
fall(victim, lf, B_TRUE);
}
} }
// confer flags from attacker? // confer flags from attacker?
@ -988,15 +1013,17 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
} }
} else if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) { } else if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) {
// automatically latch on if (getexposedlimbs(victim)) {
if (!lfhasflag(victim, F_NONCORPOREAL) && !hasflag(lf->flags, F_ATTACHEDTO)) { // automatically latch on
addflag(lf->flags, F_ATTACHEDTO, victim->id, NA, NA, NULL); if (!lfhasflag(victim, F_NONCORPOREAL) && !hasflag(lf->flags, F_ATTACHEDTO)) {
addflag(lf->flags, F_ATTACHEDTO, victim->id, NA, NA, NULL);
}
} }
} }
} }
// retaliation happens even if victim died // retaliation happens even if victim died
getflags(victim->flags, F_RETALIATE, F_NONE); getflags(victim->flags, retflag, &nretflags, F_RETALIATE, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_RETALIATE) { if (f->id == F_RETALIATE) {
@ -1280,6 +1307,64 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
return B_FALSE; return B_FALSE;
} }
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype) {
object_t *o;
// replace some dam types
if (damtype == DT_UNARMED) damtype = DT_BASH;
if (damtype == DT_BITE) damtype = DT_SLASH;
if (damtype == DT_PIERCE) damtype = DT_SLASH;
if (damtype == DT_CHOP) damtype = DT_SLASH;
if (damtype == DT_BASH) {
switch (hitpos) {
default:
case BP_BODY:
if (pctchance(40)) fall(victim, lf, B_TRUE);
if (!getarmour(victim, BP_BODY)) injure(victim, BP_BODY, damtype);
break;
case BP_HEAD:
if (pctchance(80)) fall(victim, lf, B_TRUE);
stun(victim, 2);
// chance of your helmet falling off
o = getarmour(victim, BP_HEAD);
if (o) {
if (isplayer(lf)) {
char buf[BUFLEN];
getobname(o, buf, o->amt);
msg("Your %s falls off!", noprefix(buf));
} else if (cansee(player, lf)) {
char buf[BUFLEN], lfname[BUFLEN];
getobname(o, buf, o->amt);
getlfname(lf, lfname);
msg("%s%s %s falls off!", lfname, getpossessive(lfname), noprefix(buf));
}
moveob(o, victim->cell->obpile, o->amt);
} else {
injure(victim, BP_HEAD, damtype);
}
break;
case BP_HANDS:
if (!getarmour(victim, BP_HANDS)) injure(victim, BP_HANDS, damtype);
// drop your weapon!
o = getweapon(victim);
if (o) drop(o, ALL);
break;
case BP_LEGS:
if (pctchance(70)) fall(victim, lf, B_TRUE);
if (!getarmour(victim, BP_LEGS)) injure(victim, BP_LEGS, damtype);
break;
}
} else if (damtype == DT_SLASH) {
if (!getarmour(victim, hitpos)) injure(victim, hitpos, damtype);
}
if (lfhasflag(lf, F_CRITKNOCKDOWN) && !isprone(victim)) {
fall(victim, lf, B_TRUE);
}
}
int damtypecausesbleed(enum DAMTYPE dt) { int damtypecausesbleed(enum DAMTYPE dt) {
switch (dt) { switch (dt) {
case DT_PIERCE: case DT_PIERCE:
@ -1298,6 +1383,21 @@ int damtypecausesbleed(enum DAMTYPE dt) {
return B_FALSE; return B_FALSE;
} }
int damtypecausescriteffects(enum DAMTYPE dt) {
switch (dt) {
case DT_BASH: case DT_UNARMED:
case DT_SLASH: case DT_PIERCE: case DT_BITE: case DT_CHOP:
/*
case DT_EXPLOSIVE:
case DT_FALL:
*/
return B_TRUE;
default:
break;
}
return B_FALSE;
}
// returns the amount of damage the armour blocked... // returns the amount of damage the armour blocked...
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) { int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
int reduceamt = 0; int reduceamt = 0;
@ -1344,6 +1444,8 @@ void getarrange(int arating, int *min, int *max) {
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp) { char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp) {
float pct; float pct;
enum LFSIZE ownersize = SZ_HUMAN; enum LFSIZE ownersize = SZ_HUMAN;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (lf) { if (lf) {
ownersize = getlfsize(lf); ownersize = getlfsize(lf);
@ -1354,7 +1456,7 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
if (wep) { if (wep) {
int i; int i;
flag_t *f; flag_t *f;
getflags(wep->flags, F_ATTACKVERB, F_NONE); getflags(wep->flags, retflag, &nretflags, F_ATTACKVERB, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if ((f->val[0] == NA) && (f->val[1] == NA)) { if ((f->val[0] == NA) && (f->val[1] == NA)) {
@ -1532,9 +1634,11 @@ enum DAMTYPE getdamtype(object_t *wep) {
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) { int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) {
flag_t *f; flag_t *f;
int i; int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
// special case - EXTRADAM goes onto INITIAL dam[] if the same type, rather than // special case - EXTRADAM goes onto INITIAL dam[] if the same type, rather than
// adding a new one. // adding a new one.
getflags(lf->flags, F_EXTRADAM, F_NONE); getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_EXTRADAM) { if (f->id == F_EXTRADAM) {
@ -1578,7 +1682,9 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) {
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) { int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
flag_t *f; flag_t *f;
int i; int i;
getflags(wep->flags, F_FROZEN, F_ONFIRE, F_NONE); flag_t *retflag[MAXCANDIDATES];
int nretflags;
getflags(wep->flags, retflag, &nretflags, F_FROZEN, F_ONFIRE, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_ONFIRE) { if (f->id == F_ONFIRE) {
@ -1613,7 +1719,9 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
if (wep) { if (wep) {
flag_t *f; flag_t *f;
int i; int i;
getflags(wep->flags, F_KILLVERB, F_NONE); flag_t *retflag[MAXCANDIDATES];
int nretflags;
getflags(wep->flags, retflag, &nretflags, F_KILLVERB, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_KILLVERB) { if (f->id == F_KILLVERB) {
@ -1740,6 +1848,11 @@ int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
} }
} }
if (lfhasflagval(victim, F_INJURY, BP_BODY, DT_SLASH, NA, NULL)) {
// extra damage
dam += rnd(1,2);
}
return dam; return dam;
} }
@ -1902,12 +2015,15 @@ void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, en
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) { int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) {
int acc,ev; int acc,ev;
int gothit = B_FALSE; int gothit = B_FALSE;
enum SKILLLEVEL slev; enum SKILLLEVEL lorelev = PR_INEPT;
int myroll; int myroll;
flag_t *f; flag_t *f;
// remember lore about victim...
lorelev = getlorelevel(lf, victim->race->raceclass->id);
// base 5% critical chance - check this first.
// critical chance - check this first.
if (critical) { if (critical) {
int critroll; int critroll;
critroll = rnd(1,100); critroll = rnd(1,100);
@ -1915,13 +2031,13 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
// default // default
*critical = 0; *critical = 0;
// modify for lore // modify for lore level
if (slev != PR_INEPT) { if (lorelev != PR_INEPT) {
myroll += (slev*5); // ie. up to 30% bonus critroll -= (lorelev*5); // ie. up to 30% bonus
} }
limit(&critroll, 1, 100);
if (critroll >= 95) *critical = 1; if (critroll <= getcritchance(lf, wep)) *critical = 1;
} }
f = lfhasflag(lf, F_TRUESTRIKE); f = lfhasflag(lf, F_TRUESTRIKE);
@ -1946,9 +2062,6 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
acc += 30; acc += 30;
} }
// remember lore about victim...
slev = getlorelevel(lf, victim->race->raceclass->id);
// modify for defender's evasion // modify for defender's evasion
if (isprone(victim) || !cansee(victim, lf)) { if (isprone(victim) || !cansee(victim, lf)) {
ev = 0; ev = 0;
@ -1975,8 +2088,8 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
} }
// modify for lore level // modify for lore level
if (slev != PR_INEPT) { if (lorelev != PR_INEPT) {
acc += (slev*10); lorelev += (lorelev*10);
} }
limit(&acc, 0, 100); limit(&acc, 0, 100);
@ -2000,6 +2113,8 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
lifeform_t *owner = NULL; lifeform_t *owner = NULL;
object_t *wep; object_t *wep;
int i; int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (!where) return; if (!where) return;
@ -2015,7 +2130,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
} }
victim = where->lf; victim = where->lf;
getflags(fp, F_DISARMATTACK, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_REVENGE, F_TRIPATTACK, F_NONE); getflags(fp, retflag, &nretflags, F_DISARMATTACK, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_REVENGE, F_TRIPATTACK, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_FLAMESTRIKE) { if (f->id == F_FLAMESTRIKE) {

View File

@ -6,7 +6,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force);
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag); int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag); int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
void confereffects(flagpile_t *fp, lifeform_t *victim); void confereffects(flagpile_t *fp, lifeform_t *victim);
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype);
int damtypecausesbleed(enum DAMTYPE dt); int damtypecausesbleed(enum DAMTYPE dt);
int damtypecausescriteffects(enum DAMTYPE dt);
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype); int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
void getarrange(int arating, int *min, int *max); void getarrange(int arating, int *min, int *max);
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp); char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);

Binary file not shown.

29
defs.h
View File

@ -334,7 +334,7 @@ enum MODTYPE {
#define MAXPILEOBS 52 #define MAXPILEOBS 52
#define MAXSPELLLEV 9 #define MAXSPELLLEV 6
#define MAXRETCELLS 80 #define MAXRETCELLS 80
@ -662,6 +662,7 @@ enum RACECLASS {
RC_UNDEAD, RC_UNDEAD,
}; };
#define R_GODFIRST R_GODPURITY
#define MAXGODS 4 #define MAXGODS 4
enum RACE { enum RACE {
@ -678,7 +679,7 @@ enum RACE {
R_PRISONER, R_PRISONER,
R_TOWNGUARD, R_TOWNGUARD,
// gods // gods
R_GODPURITY, // amberon R_GODPURITY, // amberon - R_FIRSTGOD
R_GODTHIEVES, // felix R_GODTHIEVES, // felix
R_GODDEATH, // hecta R_GODDEATH, // hecta
R_GODMERCY, // yumi R_GODMERCY, // yumi
@ -718,6 +719,7 @@ enum RACE {
R_SATYR, R_SATYR,
R_SHADOWCAT, R_SHADOWCAT,
R_SPRITEFIRE, R_SPRITEFIRE,
R_SPRITEICE,
R_TROGLODYTE, R_TROGLODYTE,
R_TROLL, R_TROLL,
R_VAMPIRE, R_VAMPIRE,
@ -1726,7 +1728,7 @@ enum FLAG {
// v0 = up/down // v0 = up/down
//F_STAIRDIR//, // val0 = direcion //F_STAIRDIR//, // val0 = direcion
F_OPPOSITESTAIRS, // val0 = opposite kind of stairs F_OPPOSITESTAIRS, // val0 = opposite kind of stairs
F_MAPLINK, // val0 = map to link to. F_MAPLINK, // val0 = map id to link to.
// v1/v2 = x/y // v1/v2 = x/y
// OR // OR
// text = obid to link to // text = obid to link to
@ -1777,6 +1779,7 @@ enum FLAG {
F_ATTREQ, // requires attrib v0 to be at least v1 F_ATTREQ, // requires attrib v0 to be at least v1
//F_DAMTYPE, // val0 = damage type //F_DAMTYPE, // val0 = damage type
//F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod //F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
F_CRITCHANCE, // v0 = %chance of critical hit with this weapon
F_DAM, // v0 = damtype, text = 1d1+1 F_DAM, // v0 = damtype, text = 1d1+1
F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier) F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier)
F_ACCURACY, // 100 - val0 = modify to tohit% (ie. higher is better) F_ACCURACY, // 100 - val0 = modify to tohit% (ie. higher is better)
@ -2000,6 +2003,7 @@ enum FLAG {
F_LASTDIR, // this is the last direction we moved. F_LASTDIR, // this is the last direction we moved.
//F_OWNERLASTDIR, // for pets, this it the last dir our owner moved //F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
// when we could see them. // when we could see them.
F_ISPRISONER, // this lf wants to escape to the surface
F_PETOF, // this lf is a pet of lfid v0 F_PETOF, // this lf is a pet of lfid v0
// v1/2 = last known location of my owner. // v1/2 = last known location of my owner.
// optional text is last known movement dir. // optional text is last known movement dir.
@ -2173,6 +2177,7 @@ enum FLAG {
F_GRABBING, // you are grabbing lf id v0 F_GRABBING, // you are grabbing lf id v0
F_HURRICANESTRIKE, // lf is performing a hurricane strike F_HURRICANESTRIKE, // lf is performing a hurricane strike
F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks. F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks.
F_INJURY, // v0 = where, v1 = damtype
F_INVISIBLE, // lifeform is invisible F_INVISIBLE, // lifeform is invisible
F_INVULNERABLE,// immune to most damage F_INVULNERABLE,// immune to most damage
// this can apply to objects too! // this can apply to objects too!
@ -2285,9 +2290,11 @@ enum FLAG {
// doorway with no door). // doorway with no door).
F_AUTOPOPULATE, // fill this vault with obs/mons/pillars like normal rooms F_AUTOPOPULATE, // fill this vault with obs/mons/pillars like normal rooms
F_NORANDOM, // this vault does not randomly appear F_NORANDOM, // this vault does not randomly appear
F_VAULTATOB, // v0/1=x/y, v1=pctchance, text=obname F_VAULTATOB, // v0/1=x/y, v2=pctchance, text=obname
F_VAULTATLF, // v0/1=x/y, v1=pctchance, text=lfname F_VAULTATLF, // v0/1=x/y, v2=pctchance, text=lfname
F_VAULTATCELL, // v0/1=x/y, v1=pctchance, text=cellname F_VAULTATCELL, // v0/1=x/y, v2=pctchance, text=cellname
F_VAULTATONEOF, // v0=thingtype, v1 = pctchance
// text=(x,y)(x,y)(x,y)...(x,y) thingname
F_VAULTBOX, // v0=thingtype, v1=pctchance, v2=fill?, text=x1,y1,x2,y2,thingname F_VAULTBOX, // v0=thingtype, v1=pctchance, v2=fill?, text=x1,y1,x2,y2,thingname
F_VAULTDLEVMIN, // v0 = mininum map depth/difficulty for this vault F_VAULTDLEVMIN, // v0 = mininum map depth/difficulty for this vault
F_VAULTDLEVMAX, // v0 = maximum map depth/difficulty for this vault F_VAULTDLEVMAX, // v0 = maximum map depth/difficulty for this vault
@ -2636,10 +2643,17 @@ typedef struct habitat_s {
struct habitat_s *next, *prev; struct habitat_s *next, *prev;
} habitat_t; } habitat_t;
typedef struct room_s {
int id;
int x1,y1,x2,y2;
struct vault_s *vault;
} room_t;
typedef struct map_s { typedef struct map_s {
int id; int id;
region_t *region; region_t *region;
int depth; int depth;
struct room_s room[MAXROOMS];
int nrooms; // how many rooms on this map int nrooms; // how many rooms on this map
char *name; // name of this map char *name; // name of this map
habitat_t *habitat; habitat_t *habitat;
@ -2713,8 +2727,7 @@ typedef struct glyph_s {
typedef struct cell_s { typedef struct cell_s {
map_t *map; // pointer back to map map_t *map; // pointer back to map
int x,y; // map coords int x,y; // map coords
int roomid; struct room_s *room;
vault_t *vault;
struct celltype_s *type; struct celltype_s *type;
struct obpile_s *obpile; struct obpile_s *obpile;
enum LIGHTLEV lit; enum LIGHTLEV lit;

View File

@ -31,6 +31,9 @@ Flags can be:
'type' can be: ob, mon, cell 'type' can be: ob, mon, cell
coords can be negative ("count back from right/bottom") coords can be negative ("count back from right/bottom")
atoneof(x,y)(x,y)...(x,y) type:what[:pct]
// place 'what' at one of the given positions (picked randomly)
exitat(x,y) // vault exit is at position x,y exitat(x,y) // vault exit is at position x,y
box(x,y,x2,y2) type:what[:pct] // outline box with what box(x,y,x2,y2) type:what[:pct] // outline box with what

77
flag.c
View File

@ -11,9 +11,6 @@
#include "spell.h" #include "spell.h"
#include "text.h" #include "text.h"
flag_t *retflag[MAXCANDIDATES];
int nretflags;
extern enum GAMEMODE gamemode; extern enum GAMEMODE gamemode;
extern int needredraw; extern int needredraw;
extern int statdirty; extern int statdirty;
@ -261,6 +258,23 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
} }
} }
if (flagcausesloscalc(f->id)) {
cell_t *where = NULL;
// everyone who can see this cell recalcs their los
where = getflagpilelocation(f->pile);
if (where) {
lifeform_t *l;
for (l = where->map->lf ; l ; l = l->next) {
if (haslos(l, where)) {
precalclos(l);
if (isplayer(l)) {
redrawscreenatend = B_TRUE;
}
}
}
}
}
// special effects // special effects
if (f->pile->owner) { if (f->pile->owner) {
float pct; float pct;
@ -349,6 +363,15 @@ int countflags(flagpile_t *fp) {
return count; return count;
} }
int flagcausesloscalc(enum FLAG fid) {
switch (fid) {
case F_BLOCKSVIEW:
return B_TRUE;
default: break;
}
return B_FALSE;
}
int flagcausesredraw(lifeform_t *lf, enum FLAG fid) { int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
if (!lf) return B_FALSE; if (!lf) return B_FALSE;
@ -366,6 +389,7 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
case F_PRODUCESLIGHT: case F_PRODUCESLIGHT:
case F_PRONE: case F_PRONE:
case F_RAGE: case F_RAGE:
case F_SECRET:
case F_SEEINDARK: case F_SEEINDARK:
case F_SEEINVIS: case F_SEEINVIS:
case F_SPRINTING: case F_SPRINTING:
@ -687,6 +711,7 @@ void killflag(flag_t *f) {
flag_t *nextone, *lastone; flag_t *nextone, *lastone;
lifeform_t *lf; lifeform_t *lf;
map_t *redolight = NULL; map_t *redolight = NULL;
cell_t *redolos = NULL;
int redostat = B_FALSE; int redostat = B_FALSE;
int redoscreen = B_FALSE; int redoscreen = B_FALSE;
int i,dopleasegod[MAXGODS]; int i,dopleasegod[MAXGODS];
@ -722,7 +747,9 @@ void killflag(flag_t *f) {
// ie. this lf was fleeing from the player, and // ie. this lf was fleeing from the player, and
// got away. // got away.
if (isplayer(fleefrom) && !cansee(lf, fleefrom)) { if (isplayer(fleefrom) && !cansee(lf, fleefrom)) {
dopleasegod[R_GODMERCY] += 5; for (i = 0; i < ngodlfs; i++) {
if (godlf[i]->race->id == R_GODMERCY) dopleasegod[i] += 5;
}
} }
} }
} }
@ -732,8 +759,12 @@ void killflag(flag_t *f) {
if (flagcausesredraw(f->pile->owner, f->id)) redoscreen = B_TRUE; if (flagcausesredraw(f->pile->owner, f->id)) redoscreen = B_TRUE;
if (flagcausesstatredraw(f->pile->owner, f->id)) redostat = B_TRUE; if (flagcausesstatredraw(f->pile->owner, f->id)) redostat = B_TRUE;
if (flagcausesloscalc(f->id)) {
redolos = getflagpilelocation(f->pile);
}
// notify // notify
if ((gamemode == GM_GAMESTARTED)) { if (gamemode == GM_GAMESTARTED) {
if (lf) { if (lf) {
// special cases // special cases
if (f->id == F_FLEEFROM) { if (f->id == F_FLEEFROM) {
@ -817,17 +848,28 @@ void killflag(flag_t *f) {
pleasegodmaybe(godlf[i]->race->id, dopleasegod[i]); pleasegodmaybe(godlf[i]->race->id, dopleasegod[i]);
} }
} }
if (redolos) {
// everyone who can see this cell recalcs their los
lifeform_t *l;
for (l = redolos->map->lf ; l ; l = l->next) {
if (haslos(l, redolos)) {
precalclos(l);
if (isplayer(l)) redoscreen = B_TRUE;
}
}
}
if (redolight) { if (redolight) {
calclight(redolight); calclight(redolight);
precalclos(player); precalclos(player);
needredraw = B_TRUE;
} }
if (redoscreen || redolight) { if (redoscreen) {
needredraw = B_TRUE; needredraw = B_TRUE;
} }
if (redostat) { if (redostat) {
statdirty = B_TRUE; statdirty = B_TRUE;
} }
if (statdirty || needredraw || redolight) { if (statdirty || needredraw ) {
drawscreen(); drawscreen();
} }
} }
@ -1065,14 +1107,25 @@ void timeeffectsflag(flag_t *f, int howlong) {
} }
} }
cell_t *getflagpilelocation(flagpile_t *fp) {
cell_t *where = NULL;
// everyone who can see this cell recalcs their los
if (fp->owner) {
where = fp->owner->cell;
} else if (fp->ob) {
where = getoblocation(fp->ob);
}
return where;
}
// populates retflag & nretflags with matching flags // populates retflag & nretflags with matching flags
int getflags(flagpile_t *fp, ... ) { int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... ) {
va_list flags; va_list flags;
enum FLAG wantflag[MAXCANDIDATES]; enum FLAG wantflag[MAXCANDIDATES];
int nwantflags,i; int nwantflags,i;
flag_t *f; flag_t *f;
va_start(flags, fp); va_start(flags, nretflags);
nwantflags = 0; nwantflags = 0;
wantflag[nwantflags] = va_arg(flags, enum FLAG); wantflag[nwantflags] = va_arg(flags, enum FLAG);
while (wantflag[nwantflags] != F_NONE) { while (wantflag[nwantflags] != F_NONE) {
@ -1082,15 +1135,15 @@ int getflags(flagpile_t *fp, ... ) {
va_end(flags); va_end(flags);
// now populate retflag[] with matches flags // now populate retflag[] with matches flags
nretflags = 0; *nretflags = 0;
for (i = 0; i < nwantflags; i++) { for (i = 0; i < nwantflags; i++) {
f = hasflag(fp, wantflag[i]); f = hasflag(fp, wantflag[i]);
while (f && (f->id == wantflag[i])) { while (f && (f->id == wantflag[i])) {
retflag[nretflags++] = f; retflag[(*nretflags)++] = f;
f = f->next; f = f->next;
} }
} }
return nretflags; return *nretflags;
} }
int modcounter(flagpile_t *fp, int amt) { int modcounter(flagpile_t *fp, int amt) {

4
flag.h
View File

@ -12,10 +12,12 @@ void changeflagtext(flag_t *f, char *newtext);
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id); void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime); void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int countflags(flagpile_t *fp); int countflags(flagpile_t *fp);
int flagcausesloscalc(enum FLAG fid);
int flagcausesredraw(lifeform_t *lf, enum FLAG fid); int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid); int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid);
int flagstacks(enum FLAG fid); int flagstacks(enum FLAG fid);
int getflags(flagpile_t *fp, ... ); cell_t *getflagpilelocation(flagpile_t *fp);
int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... );
int modcounter(flagpile_t *fp, int amt); int modcounter(flagpile_t *fp, int amt);
flag_t *hasflag(flagpile_t *fp, int id); flag_t *hasflag(flagpile_t *fp, int id);
flag_t *hasflagknown(flagpile_t *fp, int id); flag_t *hasflagknown(flagpile_t *fp, int id);

169
io.c
View File

@ -45,9 +45,6 @@ extern int nmsghist;
extern lifeform_t *godlf[]; extern lifeform_t *godlf[];
extern int ngodlfs; extern int ngodlfs;
extern flag_t *retflag[];
extern int nretflags;
extern prompt_t prompt; extern prompt_t prompt;
extern object_t *retobs[MAXPILEOBS+1]; extern object_t *retobs[MAXPILEOBS+1];
@ -528,6 +525,8 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
int x,y; int x,y;
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL); iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL);
flag_t *retflag[MAXCANDIDATES];
int nretflags;
// remember previously targetted lifeforms // remember previously targetted lifeforms
if (startlf > 0) { if (startlf > 0) {
@ -791,7 +790,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
strcat(extrainfo, "enraged"); strcat(extrainfo, "enraged");
} }
getflags(c->lf->flags, F_RETALIATE, F_NONE); getflags(c->lf->flags, retflag, &nretflags, F_RETALIATE, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (strlen(extrainfo)) strcat(extrainfo, ", "); if (strlen(extrainfo)) strcat(extrainfo, ", ");
@ -1060,6 +1059,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
lifeform_t *lf2; lifeform_t *lf2;
char lfname[BUFLEN]; char lfname[BUFLEN];
char buf[BUFLEN]; char buf[BUFLEN];
char buf3[BUFLEN];
char *buf2; char *buf2;
if (isdead(player)) { if (isdead(player)) {
@ -1300,6 +1300,19 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_INJURY:
strcpy(buf, getinjuredbpname(f->val[0]));
strcpy(buf3, getinjuryname(f->val[1]));
if (isplayer(lf)) {
msg("^%cYour %s %s %s!", getlfcol(lf, CC_VBAD), buf,
(f->val[1] == DT_SLASH) ? "starts" : "is", buf3);
} else {
msg("^%c%s%s %s %s %s!", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname), buf,
(f->val[1] == DT_SLASH) ? "starts" : "is",
buf3);
}
break;
case F_INVISIBLE: case F_INVISIBLE:
if (isplayer(lf)) { if (isplayer(lf)) {
if (lfhasflag(player, F_SEEINVIS)) { if (lfhasflag(player, F_SEEINVIS)) {
@ -1625,6 +1638,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) {
char lfname[BUFLEN]; char lfname[BUFLEN];
char buf[BUFLEN], buf3[BUFLEN];
lifeform_t *lf2; lifeform_t *lf2;
int donesomething = B_FALSE; int donesomething = B_FALSE;
@ -1866,6 +1880,16 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_INJURY:
strcpy(buf, getinjuredbpname(f->val[0]));
strcpy(buf3, getinjuryname(f->val[1]));
if (isplayer(lf)) {
msg("^%cYour %s %s has healed.", getlfcol(lf, CC_VGOOD), buf3, buf);
} else {
msg("^%c%s%s %s %s has healed.", getlfcol(lf, CC_VGOOD),
lfname, getpossessive(lfname), buf3, buf);
}
break;
case F_INVISIBLE: case F_INVISIBLE:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your are no longer invisible."); msg("Your are no longer invisible.");
@ -2968,6 +2992,8 @@ void describegod(lifeform_t *god) {
char goddesc[BUFLEN]; char goddesc[BUFLEN];
int i; int i;
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
cls(); cls();
f = hasflag(god->flags, F_GODOF); f = hasflag(god->flags, F_GODOF);
@ -2982,7 +3008,7 @@ void describegod(lifeform_t *god) {
wmove(mainwin, 2, 0); wmove(mainwin, 2, 0);
wprintw(mainwin, "%s likes ", godname); wprintw(mainwin, "%s likes ", godname);
getflags(god->flags, F_GODLIKES, F_NONE); getflags(god->flags, retflag, &nretflags, F_GODLIKES, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (i == 0) { if (i == 0) {
@ -2995,7 +3021,7 @@ void describegod(lifeform_t *god) {
} }
wprintw(mainwin, ".\n\n"); wprintw(mainwin, ".\n\n");
wprintw(mainwin, "%s dislikes ", godname); wprintw(mainwin, "%s dislikes ", godname);
getflags(god->flags, F_GODDISLIKES, F_NONE); getflags(god->flags, retflag, &nretflags, F_GODDISLIKES, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (i == 0) { if (i == 0) {
@ -3024,6 +3050,8 @@ void describeob(object_t *o) {
int obknown; int obknown;
int i; int i;
int throwrange; int throwrange;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
cls(); cls();
@ -3141,8 +3169,7 @@ void describeob(object_t *o) {
y++; y++;
strcpy(buf, ""); strcpy(buf, "");
getflags(o->flags, retflag, &nretflags, F_AMMOOB, F_NONE);
getflags(o->flags, F_AMMOOB, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
objecttype_t *ot; objecttype_t *ot;
ff = retflag[i]; ff = retflag[i];
@ -3179,6 +3206,7 @@ void describeob(object_t *o) {
} else if (o->type->obclass->id == OC_WEAPON) { } else if (o->type->obclass->id == OC_WEAPON) {
flag_t *damflag; flag_t *damflag;
int delay; int delay;
int critchance;
sprintf(buf, "It is a %s weapon", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed"); sprintf(buf, "It is a %s weapon", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed");
damflag = hasflag(o->flags, F_DAM); damflag = hasflag(o->flags, F_DAM);
if (damflag) { if (damflag) {
@ -3239,6 +3267,12 @@ void describeob(object_t *o) {
mvwprintw(mainwin, y, 0, " Its attack delay is %d%%.",delay - 100); mvwprintw(mainwin, y, 0, " Its attack delay is %d%%.",delay - 100);
y++; y++;
critchance = getcritchance(player, o);
if (critchance > 0) {
mvwprintw(mainwin, y, 0, " You have a %d%% critical hit chance with it.", critchance);
y++;
}
f = hasflag(o->flags, F_ACCURACY); f = hasflag(o->flags, F_ACCURACY);
if (f) { if (f) {
int acc; int acc;
@ -4127,7 +4161,7 @@ void docomms(lifeform_t *lf) {
addchoice(&prompt, '>', "Keep your distance.", NULL, NULL); addchoice(&prompt, '>', "Keep your distance.", NULL, NULL);
} }
} else if (ishirable(lf) ) { } else if (ishirable(lf) ) {
if (lf->race->id == R_PRISONER) { if (lfhasflag(lf, F_ISPRISONER)) {
addchoice(&prompt, 'j', "Join me, and I will help you escape.", NULL, NULL); addchoice(&prompt, 'j', "Join me, and I will help you escape.", NULL, NULL);
} else { } else {
addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL); addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL);
@ -4285,7 +4319,7 @@ void docomms(lifeform_t *lf) {
} }
} }
// TODO: only get speech bonus if humanoid+intelligent // TODO: only get speech bonus if humanoid (ie they can understand you)
mod += getskill(player, SK_SPEECH); mod += getskill(player, SK_SPEECH);
if (skillcheckvs(player, SC_MORALE, mod, lf, SC_MORALE, 0)) { if (skillcheckvs(player, SC_MORALE, mod, lf, SC_MORALE, 0)) {
@ -5353,8 +5387,8 @@ void dohelp(char helpmode) {
if (helpmode == '?') { if (helpmode == '?') {
initprompt(&prompt, "What would you like help with (ESC when done)?"); initprompt(&prompt, "What would you like help with (ESC when done)?");
addchoice(&prompt, '?', "Keyboard Commands", NULL, NULL); addchoice(&prompt, '?', "Keyboard Commands", NULL, NULL);
addchoice(&prompt, 'g', "Skill Descriptions", NULL, NULL); addchoice(&prompt, 's', "Skill Descriptions", NULL, NULL);
addchoice(&prompt, 's', "God Descriptions", NULL, NULL); addchoice(&prompt, 'g', "God Descriptions", NULL, NULL);
addchoice(&prompt, '-', "(done)", NULL, NULL); addchoice(&prompt, '-', "(done)", NULL, NULL);
prompt.maycancel = B_TRUE; prompt.maycancel = B_TRUE;
ch = getchoice(&prompt); ch = getchoice(&prompt);
@ -5363,6 +5397,7 @@ void dohelp(char helpmode) {
case 'g': case 'g':
case 's': case 's':
helpmode = ch; helpmode = ch;
break;
default: default:
done = B_TRUE; done = B_TRUE;
break; break;
@ -6697,7 +6732,7 @@ void handleinput(void) {
stopnow = B_TRUE; stopnow = B_TRUE;
} }
// stop if enter/exit a room // stop if enter/exit a room
if (player->prevcell[0] && (player->cell->roomid != player->prevcell[0]->roomid)) { if (player->prevcell[0] && (getroomid(player->cell) != getroomid(player->prevcell[0]))) {
stopnow = B_TRUE; stopnow = B_TRUE;
} }
@ -7829,6 +7864,8 @@ void showlfstats(lifeform_t *lf, int showall) {
enum SKILLLEVEL lorelev; enum SKILLLEVEL lorelev;
enum COLOUR lorecol; enum COLOUR lorecol;
int min,max; int min,max;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
h = getmaxy(mainwin); h = getmaxy(mainwin);
@ -8430,6 +8467,22 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, "%s %s hiding.", you(lf), is(lf)); mvwprintw(mainwin, y, 0, "%s %s hiding.", you(lf), is(lf));
y++; y++;
} }
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
char buf[BUFLEN], buf2[BUFLEN],buf3[BUFLEN];
f = retflag[i];
strcpy(buf, getinjuredbpname(f->val[0]));
strcpy(buf2, getinjuryname(f->val[1]));
strcpy(buf3, getinjurydesc(f->val[0], f->val[1]));
if (isplayer(lf)) {
msg("^%cYour %s is %s%s.", getlfcol(lf, CC_VBAD), buf, buf2, buf3);
} else {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s%s %s is %s%s.", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname), buf, buf2, buf3);
}
}
f = lfhasknownflag(lf, F_INVISIBLE); f = lfhasknownflag(lf, F_INVISIBLE);
if (f && (f->known)) { if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), is(lf)); mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), is(lf));
@ -9055,47 +9108,61 @@ void showlfstats(lifeform_t *lf, int showall) {
y++; y++;
} }
// extra dam - can have it multiple times getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
for (f = lf->flags->first ; f; f = f->next) { for (i = 0; i < nretflags; i++) {
if (f->id == F_EXTRADAM) { char buf[BUFLEN], buf2[BUFLEN];
int ndice,nsides,bonus; f = retflag[i];
char dicebuf[BUFLEN]; strcpy(buf, getinjuredbpname(f->val[0]));
char mmbuf[BUFLEN]; strcpy(buf2, getinjuryname(f->val[1]));
char damtypebuf[BUFLEN]; if (isplayer(lf)) {
int min = 0,max = 0; msg("^%cYour %s is %s.", getlfcol(lf, CC_VBAD), buf, buf2);
texttodice(f->text, &ndice,&nsides,&bonus); } else {
char lfname[BUFLEN];
if ((f->lifetime == FROMOBEQUIP) || getlfname(lf, lfname);
(f->lifetime == FROMOBHOLD) || msg("^%c%s%s %s is %s.", getlfcol(lf, CC_VBAD),
(f->lifetime == FROMOBACTIVATE) ) { lfname, getpossessive(lfname), buf, buf2);
object_t *obfrom;
obfrom = findobbyid(lf->pack, f->obfrom);
if (obfrom) {
int bonusdam;
sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL);
bonus += bonusdam;
}
}
if (f->val[0] == NA) {
strcpy(damtypebuf, "damage");
} else {
sprintf(damtypebuf, "%s damage", getdamname(f->val[0]));
}
dicetotext(ndice, nsides, bonus, &min, &max, dicebuf, mmbuf);
if (strcmp(dicebuf, mmbuf)) {
mvwprintw(mainwin, y, 0, "%s deal%s %s (%s) extra %s each hit.", you(lf),
isplayer(lf) ? "" : "s", dicebuf, mmbuf, damtypebuf);
} else {
mvwprintw(mainwin, y, 0, "%s deal%s %s extra %s each hit.", you(lf),
isplayer(lf) ? "" : "s", dicebuf, damtypebuf);
}
y++;
} }
} }
getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
for (i = 0; i < nretflags; i++) {
int ndice,nsides,bonus;
char dicebuf[BUFLEN];
char mmbuf[BUFLEN];
char damtypebuf[BUFLEN];
int min = 0,max = 0;
f = retflag[i];
texttodice(f->text, &ndice,&nsides,&bonus);
if ((f->lifetime == FROMOBEQUIP) ||
(f->lifetime == FROMOBHOLD) ||
(f->lifetime == FROMOBACTIVATE) ) {
object_t *obfrom;
obfrom = findobbyid(lf->pack, f->obfrom);
if (obfrom) {
int bonusdam;
sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL);
bonus += bonusdam;
}
}
if (f->val[0] == NA) {
strcpy(damtypebuf, "damage");
} else {
sprintf(damtypebuf, "%s damage", getdamname(f->val[0]));
}
dicetotext(ndice, nsides, bonus, &min, &max, dicebuf, mmbuf);
if (strcmp(dicebuf, mmbuf)) {
mvwprintw(mainwin, y, 0, "%s deal%s %s (%s) extra %s each hit.", you(lf),
isplayer(lf) ? "" : "s", dicebuf, mmbuf, damtypebuf);
} else {
mvwprintw(mainwin, y, 0, "%s deal%s %s extra %s each hit.", you(lf),
isplayer(lf) ? "" : "s", dicebuf, damtypebuf);
}
y++;
}
f = lfhasknownflag(lf, F_EXTRALUCK); f = lfhasknownflag(lf, F_EXTRALUCK);
if (f) { if (f) {
mvwprintw(mainwin, y, 0, "Your luck is being boosted.", you(lf)); mvwprintw(mainwin, y, 0, "Your luck is being boosted.", you(lf));

761
lf.c

File diff suppressed because it is too large Load Diff

5
lf.h
View File

@ -38,6 +38,7 @@ int canpolymorphto(enum RACE rid);
int canpush(lifeform_t *lf, object_t *o, int dir); int canpush(lifeform_t *lf, object_t *o, int dir);
int canquaff(lifeform_t *lf, object_t *o); int canquaff(lifeform_t *lf, object_t *o);
int cansee(lifeform_t *viewer, lifeform_t *viewee); int cansee(lifeform_t *viewer, lifeform_t *viewee);
int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos);
int cansleep(lifeform_t *lf); int cansleep(lifeform_t *lf);
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where); int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
int canweild(lifeform_t *lf, object_t *o); int canweild(lifeform_t *lf, object_t *o);
@ -175,6 +176,7 @@ enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
int getraceclass(lifeform_t *lf); int getraceclass(lifeform_t *lf);
int getracerarity(map_t *map, enum RACE rid); int getracerarity(map_t *map, enum RACE rid);
object_t *getrandomarmour(lifeform_t *lf); object_t *getrandomarmour(lifeform_t *lf);
enum BODYPART getrandomcorebp(lifeform_t *lf);
job_t *getrandomjob(int onlyplayerjobs); job_t *getrandomjob(int onlyplayerjobs);
int getrandommonlevel(race_t *r, map_t *m); int getrandommonlevel(race_t *r, map_t *m);
race_t *getrandomrace(cell_t *c, int forcedepth); race_t *getrandomrace(cell_t *c, int forcedepth);
@ -204,6 +206,7 @@ map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
int gotosleep(lifeform_t *lf, int onpurpose); int gotosleep(lifeform_t *lf, int onpurpose);
int hasfreeaction(lifeform_t *lf); int hasfreeaction(lifeform_t *lf);
job_t *hasjob(lifeform_t *lf, enum JOB job); job_t *hasjob(lifeform_t *lf, enum JOB job);
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype);
int lfcanbestoned(lifeform_t *lf); int lfcanbestoned(lifeform_t *lf);
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid); flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text); flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
@ -216,6 +219,7 @@ int hasbp(lifeform_t *lf, enum BODYPART bp);
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid); flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid);
int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest); int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
int haslos(lifeform_t *viewer, cell_t *dest); int haslos(lifeform_t *viewer, cell_t *dest);
int haslos_fast(lifeform_t *viewer, cell_t *dest);
void initjobs(void); void initjobs(void);
void initrace(void); void initrace(void);
void initskills(void); void initskills(void);
@ -320,6 +324,7 @@ void stopeating(lifeform_t *lf);
void stopresting(lifeform_t *lf); void stopresting(lifeform_t *lf);
void stoprunning(lifeform_t *lf); void stoprunning(lifeform_t *lf);
void stopsprinting(lifeform_t *lf); void stopsprinting(lifeform_t *lf);
int stun(lifeform_t *lf, int nturns);
lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, char *racename, int lifetime, int wantfriendly); lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, char *racename, int lifetime, int wantfriendly);
//int testammo(lifeform_t *lf, object_t *o); //int testammo(lifeform_t *lf, object_t *o);
int takeoff(lifeform_t *lf, object_t *o); int takeoff(lifeform_t *lf, object_t *o);

304
map.c
View File

@ -30,9 +30,6 @@ extern lifeform_t *player;
extern lifeform_t *godlf[]; extern lifeform_t *godlf[];
extern int ngodlfs; extern int ngodlfs;
extern flag_t *retflag[];
extern int nretflags;
extern glyph_t tempglyph; extern glyph_t tempglyph;
extern enum OBCLASS sortorder[]; extern enum OBCLASS sortorder[];
@ -55,8 +52,7 @@ cell_t *addcell(map_t *m, int x, int y) {
cell->visited = B_FALSE; cell->visited = B_FALSE;
cell->obpile = addobpile(NOOWNER, cell, NOOB); cell->obpile = addobpile(NOOWNER, cell, NOOB);
cell->lf = NULL; cell->lf = NULL;
cell->roomid = -1; cell->room = NULL;
cell->vault = NULL;
cell->lit = L_NOTLIT; cell->lit = L_NOTLIT;
cell->origlit = L_NOTLIT; cell->origlit = L_NOTLIT;
cell->littimer = 0; cell->littimer = 0;
@ -499,6 +495,13 @@ void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlo
} }
} }
int getroomid(cell_t *c) {
if (c->room) {
return c->room->id;
}
return -1;
}
// whichside should be D_ORTH // whichside should be D_ORTH
// for now, this function will NOT include room corners // for now, this function will NOT include room corners
void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid) { void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid) {
@ -779,6 +782,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);
doorsadded++; doorsadded++;
} }
} }
@ -1172,6 +1176,7 @@ int getmapdifficulty(map_t *m) {
return diff; return diff;
} }
// forglyph will be true if we are using this function for the purpose // forglyph will be true if we are using this function for the purpose
// of figuring out which glyph to draw // of figuring out which glyph to draw
object_t *gettopobject(cell_t *where, int forglyph) { object_t *gettopobject(cell_t *where, int forglyph) {
@ -1501,6 +1506,21 @@ int countlfs(map_t *map) {
return count; return count;
} }
int countmapobs(map_t *m, enum OBTYPE oid) {
cell_t *c;
int count = 0,x,y;
for (y = 0; y < m->h; y++) {
for (x = 0; x < m->w; x++) {
c = getcellat(m, x, y);
if (c) {
count += countobsoftype(c->obpile, oid);
}
}
}
return count;
}
// //
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int wantrooms = B_TRUE; int wantrooms = B_TRUE;
@ -1728,11 +1748,16 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
// just do a normal room // just do a normal room
createroom(map, i, NA, NA, 0, 0, &rx, &ry, &roomw[i],&roomh[i], 50, B_FALSE); createroom(map, i, NA, NA, 0, 0, &rx, &ry, &roomw[i],&roomh[i], 50, B_FALSE);
roomvault[i] = B_FALSE; roomvault[i] = B_FALSE;
linkexits(map, i, rx, ry, rx+roomw[i]-1, ry+roomh[i]-1);
} }
} }
} }
// link up room exits
for (i = 0; i < map->nrooms; i++) {
linkexits(map, map->room[i].id);
}
// add staircases. // add staircases.
// first dungeon level has 1 up stairs, 3 down. // first dungeon level has 1 up stairs, 3 down.
// subsequent levels always have 3 up and down stairs // subsequent levels always have 3 up and down stairs
@ -1856,6 +1881,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} // end foreach room } // end foreach room
} // end if wantrooms & nrooms>0 } // end if wantrooms & nrooms>0
if (db) dblog("Finished adding objects."); if (db) dblog("Finished adding objects.");
// now do a border // now do a border
@ -2453,7 +2479,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
cell_t *c; cell_t *c;
c = getcellat(map, x, y); c = getcellat(map, x, y);
// no random obs in vaults // no random obs in vaults
if (c && isempty(c) && !c->vault) { if (c && isempty(c) && !getcellvault(c)) {
if (rnd(1,100) <= c->habitat->randthingpct) { if (rnd(1,100) <= c->habitat->randthingpct) {
addrandomthing(c, c->habitat->randobpct, NULL); addrandomthing(c, c->habitat->randobpct, NULL);
} }
@ -2507,6 +2533,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
int minx,miny,maxx,maxy; int minx,miny,maxx,maxy;
int db = B_FALSE; int db = B_FALSE;
int rotation = 0; int rotation = 0;
room_t *thisroom = NULL;
flag_t *f; flag_t *f;
// default // default
@ -2556,6 +2583,16 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
maxx = minx + (w-1); maxx = minx + (w-1);
maxy = miny + (h-1); maxy = miny + (h-1);
map->room[map->nrooms].id = roomid;
map->room[map->nrooms].x1 = minx;
map->room[map->nrooms].y1 = miny;
map->room[map->nrooms].x2 = maxx;
map->room[map->nrooms].y2 = maxy;
map->room[map->nrooms].vault = v;
thisroom = &(map->room[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++) {
@ -2570,7 +2607,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
ct = getvaultcelltype(v, x-minx,y-miny, rotation); ct = getvaultcelltype(v, x-minx,y-miny, rotation);
setcelltype(cell, ct ? ct->id : cell->habitat->emptycelltype); setcelltype(cell, ct ? ct->id : cell->habitat->emptycelltype);
// set roomid // set roomid
cell->roomid = roomid; cell->room = thisroom;
// add objects // add objects
addvaultcellcontents(cell, v, x-minx,y-miny, rotation); addvaultcellcontents(cell, v, x-minx,y-miny, rotation);
} }
@ -2593,22 +2630,41 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
autodoors(map, roomid, minx, miny, maxx, maxy, f->val[0], B_NODOORS); autodoors(map, roomid, minx, miny, maxx, maxy, f->val[0], B_NODOORS);
} }
linkexits(map, roomid, minx, miny, maxx,maxy);
map->nrooms++;
return B_FALSE; return B_FALSE;
} }
// make sure exits/doors in a given room link up to the rest of the map. // make sure exits/doors in a given room link up to the rest of the map.
int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) { int linkexits(map_t *m, int roomid) {
int x,y,i; int x,y,i;
cell_t *poss[MAXCANDIDATES],*c; cell_t *poss[MAXCANDIDATES],*c;
int nposs = 0; int nposs = 0;
int db = B_FALSE; int db = B_FALSE;
int nadded = 0; int nadded = 0;
int minx = -1, miny = -1, maxx = -1, maxy = -1;
if (db) dblog("linkexits for roomid %d", roomid); // figure out room coords
for (i = 0; i < m->nrooms; i++) {
if (m->room[i].id == roomid) {
minx = m->room[i].x1;
miny = m->room[i].y1;
maxx = m->room[i].x2;
maxy = m->room[i].y2;
break;
}
}
assert(minx != -1);
if (db) {
char buf[BUFLEN];
vault_t *v;
c = getrandomroomcell(m, roomid);
v = getcellvault(c);
sprintf(buf, "*** linkexits for roomid %d (%s) [%d,%d-%d,%d]", roomid,
v ? v->id : "novault",
minx,miny,maxx,maxy);
dblog("%s", buf);
}
// find all doors or f_roomexits // find all doors or f_roomexits
for (y = miny; y <= maxy; y++) { for (y = miny; y <= maxy; y++) {
@ -2616,8 +2672,11 @@ int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
c = getcellat(m, x, y); c = getcellat(m, x, y);
if (!c) continue; if (!c) continue;
if (hasobwithflag(c->obpile, F_DOOR) || hasflagval(m->flags, F_ROOMEXIT, roomid, x, y, NULL)) { if (hasobwithflag(c->obpile, F_DOOR)) {
if (db) dblog("found door/exit at %d,%d",x,y); if (db) dblog("found door at %d,%d",x,y);
poss[nposs++] = c;
} else if (hasflagval(m->flags, F_ROOMEXIT, roomid, x, y, NULL)) {
if (db) dblog("found roomexit at %d,%d",x,y);
poss[nposs++] = c; poss[nposs++] = c;
} }
} }
@ -2630,9 +2689,9 @@ int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
for (i = 0; i < nposs; i++) { for (i = 0; i < nposs; i++) {
int d; int d;
int ncorridors = 0; int ncorridors = 0;
for (d = DC_N; d <= DC_NW; d++) { for (d = D_N; d <= D_W; d++) {
c = getcellindir(poss[i], d); c = getcellindir(poss[i], d);
if (c && cellwalkable(NULL, c, NULL) && (c->roomid != roomid)) { if (c && cellwalkable(NULL, c, NULL) && (getroomid(c) != roomid)) {
ncorridors++; ncorridors++;
} }
} }
@ -2642,37 +2701,170 @@ int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
if (ncorridors == 0) { if (ncorridors == 0) {
int poss2[MAXCANDIDATES],nposs2; int poss2[MAXCANDIDATES],nposs2;
int dist[MAXDIR_ORTH]; int dist[MAXDIR_ORTH];
int bestdist = 999; int hitsedge[MAXDIR_ORTH];
int mindist = 999,maxdist = -1;
if (db) dblog(" Need to link."); if (db) dblog(" Need to link.");
// link it. starting from the door, count the number of cells in // link it. starting from the door, count the number of cells in
// each direction until we hit an empty (walkable) cell which isn't a room. // each direction until we hit an empty (walkable) cell which isn't a room.
// if we hit a cell of this roomid, mark this dir as invalid. // if we hit a cell of this roomid, mark this dir as invalid.
for (d = D_N; d <= D_W; d++) { for (d = D_N; d <= D_W; d++) {
dist[d] = 0; dist[d] = 0;
hitsedge[d] = B_TRUE;
c = getcellindir(poss[i], d); c = getcellindir(poss[i], d);
while (c) { while (c) {
dist[d]++; dist[d]++;
if (isroom(c)) { if (getroomid(c) == roomid) {
// mark dir as invalid // mark dir as invalid
dist[d] = 999; dist[d] = 999;
break; break;
} else if (cellwalkable(NULL, c, NULL)) { } else if (cellwalkable(NULL, c, NULL)) {
// walkable and not in this vault. finished. // walkable and not in this vault. finished.
hitsedge[d] = B_FALSE;
break; break;
} else {
int perpdir[2],n;
cell_t *pcell = NULL;
perpdir[0] = d - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
perpdir[1] = d + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
// is there an adjacent walkable cell in a perpendicular direction
// which isn't from the starting room?
for (n = 0; n <= 1; n++) {
pcell = getcellindir(c, perpdir[n]);
if (pcell) {
if ((getroomid(pcell) != roomid) && cellwalkable(NULL, pcell, NULL)) {
// finished.
hitsedge[d] = B_FALSE;
break;
}
}
}
} }
// check next cell // check next cell
c = getcellindir(c, d); // getting the same cell! c = getcellindir(c, d); // getting the same cell!
} }
if (dist[d] < bestdist) bestdist = dist[d]; if (dist[d] != 999) {
if (!hitsedge[d]) {
if (dist[d] < mindist) mindist = dist[d];
}
if (dist[d] > maxdist) maxdist = dist[d];
}
} }
if (bestdist != 999) { if (mindist == 999) {
cell_t *turncell = NULL,*endcell = NULL;
int perpdir[2];
int startdir = D_NONE;
int turndir = D_NONE;
int startdist = 0;
// no good directions.
if (db) dblog(" No directions lead to rooms. Trying turns.");
// starting at the LONGEST distance, traverse up each dir,
// branching off looking for rooms.
// find longest distance
for (d = D_N; d <= D_W; d++) {
if (dist[d] == maxdist) {
startdir = d;
break;
}
}
assert(startdir != D_NONE);
// figure out perpendicular dirs
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
if (db) dblog(" Will walk %s (dist %d), checking %s and %s.", getdirname(startdir), maxdist,
getdirname(perpdir[0]), getdirname(perpdir[1]));
// check in startdir
c = getcellindir(poss[i], startdir);
while (c && !turncell) {
int n;
cell_t *c2;
startdist++;
// check left/right from this door for rooms
for (n = 0; n <= 1; n++) {
int turndist = 0;
c2 = getcellindir(c, perpdir[n]);
while (c2) {
int gotsolution = B_FALSE;
turndist++;
if (getroomid(c2) == roomid) {
// hits same room, not ok.
break;
} else if (cellwalkable(NULL, c2, NULL)) {
if (db) dblog(" Got to an empty cell here.");
gotsolution = B_TRUE;
} else if (turndist > 1) {
// check l/r too
int perpdir2[2],nn;
cell_t *pcell = NULL;
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
for (nn = 0; nn <= 1; nn++) {
pcell = getcellindir(c2, perpdir2[nn]);
if (pcell) {
if ((getroomid(pcell) != roomid) &&
cellwalkable(NULL, pcell, NULL)) {
// finished.
if (db) dblog(" Got to an empty cell next to us.");
gotsolution = B_TRUE;
break;
}
}
}
}
if (gotsolution) {
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
startdist, getdirname(startdir),
turndist, getdirname(perpdir[n]));
// walkable and not in this roomid. ok!
turncell = c;
endcell = c2;
turndir = perpdir[n];
break;
}
// check next cell
c2 = getcellindir(c2, perpdir[n]);
}
if (turncell) break;
}
// now keep going in main direction.
c = getcellindir(c, startdir);
}
if (turncell) {
// make a path up to the turn point.
if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir));
nadded++;
c = getcellindir(poss[i], startdir);
while (c != turncell) {
setcelltype(c, c->habitat->emptycelltype);
c = getcellindir(c, startdir);
}
// clear the corner cell
setcelltype(c, c->habitat->emptycelltype);
if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir));
// now turn and clear up to the next room/empty cell
c = getcellindir(c, turndir);
while (c != endcell) {
setcelltype(c, c->habitat->emptycelltype);
c = getcellindir(c, turndir);
}
} else {
// give up??
if (db) dblog(" Cannot find a way to link up.");
}
} else {
int whichway,sel; int whichway,sel;
// now pick the shortest one // now pick the shortest one which hits the edge
// get list of all the maximums and randomly tie-break // get list of all the minimums and randomly tie-break
nposs2 = 0; nposs2 = 0;
for (d = D_N; d <= D_W; d++) { for (d = D_N; d <= D_W; d++) {
if (dist[d] == bestdist) { if (dist[d] == mindist) {
poss2[nposs2++] = d; poss2[nposs2++] = d;
} }
} }
@ -2680,7 +2872,7 @@ int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
whichway = poss2[sel]; whichway = poss2[sel];
// now create a path // now create a path
if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), bestdist); if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), mindist);
nadded++; nadded++;
c = getcellindir(poss[i], whichway); c = getcellindir(poss[i], whichway);
while (c && !cellwalkable(NULL, c, NULL)) { while (c && !cellwalkable(NULL, c, NULL)) {
@ -2752,6 +2944,7 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
int minroomh = MIN_ROOMH; int minroomh = MIN_ROOMH;
int maxroomw = MAX_ROOMW; int maxroomw = MAX_ROOMW;
int maxroomh = MAX_ROOMH; int maxroomh = MAX_ROOMH;
room_t *thisroom = NULL;
if (overrideminw != NA) { if (overrideminw != NA) {
minroomw = overrideminw; minroomw = overrideminw;
@ -2783,6 +2976,15 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
maxx = minx + (w-1); maxx = minx + (w-1);
maxy = miny + (h-1); maxy = miny + (h-1);
map->room[map->nrooms].id = roomid;
map->room[map->nrooms].x1 = minx;
map->room[map->nrooms].y1 = miny;
map->room[map->nrooms].x2 = maxx;
map->room[map->nrooms].y2 = maxy;
map->room[map->nrooms].vault = NULL;
thisroom = &(map->room[map->nrooms]);
map->nrooms++;
for (y = miny; y <= maxy; y++) { for (y = miny; y <= maxy; y++) {
for (x = minx; x <= maxx; x++) { for (x = minx; x <= maxx; x++) {
cell = getcellat(map, x, y); cell = getcellat(map, x, y);
@ -2801,7 +3003,7 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
} else { } else {
setcelltype(cell, CT_ROOM); setcelltype(cell, CT_ROOM);
} }
cell->roomid = roomid; cell->room = thisroom;
} }
} }
} }
@ -2811,8 +3013,6 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
autodoors(map, roomid, minx, miny, maxx, maxy, doorpct, 50); autodoors(map, roomid, minx, miny, maxx, maxy, doorpct, 50);
} }
map->nrooms++;
return B_FALSE; return B_FALSE;
} }
@ -3188,6 +3388,16 @@ regiontype_t *findregiontype(enum REGIONTYPE rtype) {
return NULL; return NULL;
} }
room_t *findroom(map_t *m, int roomid) {
int i;
for (i = 0; i < m->nrooms; i++) {
if (m->room[i].id == roomid) {
return &(m->room[i]);
}
}
return NULL;
}
map_t *findsurfaceexitmap(map_t *m) { map_t *findsurfaceexitmap(map_t *m) {
object_t *o; object_t *o;
cell_t *c; cell_t *c;
@ -3281,13 +3491,20 @@ cell_t *getcellindir(cell_t *cell, int dir) {
return newcell; return newcell;
} }
vault_t *getcellvault(cell_t *c) {
if (c->room) {
return c->room->vault;
}
return NULL;
}
cell_t *getclosestroomcell(lifeform_t *lf, int roomid) { cell_t *getclosestroomcell(lifeform_t *lf, int roomid) {
int i; int i;
cell_t *c,*best = NULL; cell_t *c,*best = NULL;
int closest = 9999; int closest = 9999;
for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) { for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
c = lf->cell->map->cell[i]; c = lf->cell->map->cell[i];
if ((c->roomid == roomid) & cellwalkable(lf, c, NULL)) { if ((getroomid(c) == roomid) & cellwalkable(lf, c, NULL)) {
if (getcelldist(lf->cell, c) < closest) { if (getcelldist(lf->cell, c) < closest) {
best = c; best = c;
} }
@ -3591,10 +3808,10 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
//if (c && cellwalkable(NULL, c, NULL)) { //if (c && cellwalkable(NULL, c, NULL)) {
if (c && !c->type->solid) { if (c && !c->type->solid) {
int ok = B_FALSE; int ok = B_FALSE;
if (c->roomid == roomid) { if (getroomid(c) == roomid) {
ok = B_TRUE; ok = B_TRUE;
} else if (roomid == ANYROOM) { } else if (roomid == ANYROOM) {
if (c->roomid != -1) { if (isroom(c) != -1) {
ok = B_TRUE; ok = B_TRUE;
} }
} }
@ -3623,7 +3840,7 @@ void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells) {
*ncells = 0; *ncells = 0;
for (i = 0; i < m->w*m->h; i++) { for (i = 0; i < m->w*m->h; i++) {
c = m->cell[i]; c = m->cell[i];
if (c && (c->roomid == roomid)) { if (c && (getroomid(c) == roomid)) {
retcell[*ncells] = c; retcell[*ncells] = c;
(*ncells)++; (*ncells)++;
} }
@ -3878,6 +4095,8 @@ int isempty(cell_t *c) {
//returns TT_ based on what you can scan there //returns TT_ based on what you can scan there
int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) { int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int i; int i;
// handle scanner // handle scanner
f = lfhasflag(player, F_DETECTLIFE); f = lfhasflag(player, F_DETECTLIFE);
@ -3952,8 +4171,7 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
} }
// get list of all detected ob ids. // get list of all detected ob ids.
getflags(player->flags, F_DETECTOBS, F_NONE); getflags(player->flags, retflag, &nretflags, F_DETECTOBS, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (getcelldistorth(player->cell, c) <= f->val[0]) { if (getcelldistorth(player->cell, c) <= f->val[0]) {
@ -4057,7 +4275,7 @@ int isoutdoors(map_t *m) {
} }
int isroom(cell_t *c) { int isroom(cell_t *c) {
if (c && (c->roomid >= 0)) { if (c && (getroomid(c) >= 0)) {
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -4147,6 +4365,8 @@ int linkstairs(object_t *o, object_t *o2) {
cell_t *staircell; cell_t *staircell;
flag_t *f; flag_t *f;
assert(o);
staircell = getoblocation(o); staircell = getoblocation(o);
stairmap = staircell->map; stairmap = staircell->map;
@ -4198,10 +4418,9 @@ int linkstairs(object_t *o, object_t *o2) {
} }
} }
if (!found) { if (!found) {
dblog("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id); dblog("ERROR - stairs link to existing map %d(depth %d), but it has no free stairs.",othermap->id, othermap->depth);
msg("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id); msg("ERROR - stairs link to existing map %d(depth %d), but it has no free stairs.",othermap->id, othermap->depth);
more(); more();
assert(0 == 1);
} }
} // end if othermap } // end if othermap
} // end if !o2 } // end if !o2
@ -4332,6 +4551,7 @@ void mapentereffects(map_t *m) {
cell_t *c; cell_t *c;
flag_t *f; flag_t *f;
for (i = 0; i < m->w * m->h; i++) { for (i = 0; i < m->w * m->h; i++) {
vault_t *v;
// teleport shopkeepers back to their shops // teleport shopkeepers back to their shops
c = m->cell[i]; c = m->cell[i];
if (c->lf && hasjob(c->lf, J_SHOPKEEPER) && !isplayer(c->lf)) { if (c->lf && hasjob(c->lf, J_SHOPKEEPER) && !isplayer(c->lf)) {
@ -4347,12 +4567,13 @@ void mapentereffects(map_t *m) {
} }
} }
} }
v = getcellvault(c);
// replace people in the Inn // replace people in the Inn
if (c->vault && streq(c->vault->id, "inn") && c->lf && (c->lf->race->id == R_HUMAN)) { if (v && streq(v->id, "inn") && c->lf && (c->lf->race->id == R_HUMAN)) {
lifeform_t *lf; lifeform_t *lf;
killlf(c->lf); killlf(c->lf);
lf = addmonster(c, R_HUMAN, NULL, B_TRUE, 1, B_FALSE, NULL); lf = addmonster(c, R_HUMAN, NULL, B_TRUE, 1, B_FALSE, NULL);
addflag(lf->flags, F_STAYINROOM, c->roomid, B_MAYCHASE, NA, NULL); addflag(lf->flags, F_STAYINROOM, getroomid(c), B_MAYCHASE, NA, NULL);
} }
} }
} }
@ -4464,7 +4685,6 @@ void setcelltype(cell_t *cell, enum CELLTYPE id) {
assert(cell); assert(cell);
cell->type = findcelltype(id); cell->type = findcelltype(id);
assert(cell->type); assert(cell->type);
//cell->roomid = -1;
if ((gamemode == GM_GAMESTARTED) && haslos(player, cell)) { if ((gamemode == GM_GAMESTARTED) && haslos(player, cell)) {
needredraw = B_TRUE; needredraw = B_TRUE;
} }

6
map.h
View File

@ -26,6 +26,7 @@ flag_t *getmapcoords(map_t *m, int *x, int *y);
int getmapdifficulty(map_t *m); int getmapdifficulty(map_t *m);
map_t *getmapindir(map_t *src, int dir); map_t *getmapindir(map_t *src, int dir);
void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells); void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells);
int getroomid(cell_t *c);
void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid); void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid);
object_t *gettopobject(cell_t *where, int forglyph); object_t *gettopobject(cell_t *where, int forglyph);
void calclight(map_t *map); void calclight(map_t *map);
@ -36,6 +37,7 @@ int countadjcellswithflag(cell_t *cell, enum FLAG fid, int dirtype);
int countadjwalls(cell_t *cell); int countadjwalls(cell_t *cell);
int countcellexits(cell_t *cell); int countcellexits(cell_t *cell);
int countcellexitsfor(lifeform_t *lf); int countcellexitsfor(lifeform_t *lf);
int countmapobs(map_t *m, enum OBTYPE oid);
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings); void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings);
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
@ -64,9 +66,11 @@ region_t *findregion(int regionid);
region_t *findregionbytype(enum REGIONTYPE rtid); region_t *findregionbytype(enum REGIONTYPE rtid);
map_t *findregionmap(int regionid, int depth); map_t *findregionmap(int regionid, int depth);
regiontype_t *findregiontype(enum REGIONTYPE rtype); regiontype_t *findregiontype(enum REGIONTYPE rtype);
room_t *findroom(map_t *m, int roomid);
map_t *findsurfaceexitmap(map_t *m); map_t *findsurfaceexitmap(map_t *m);
void forgetcells(map_t *map, int amt); void forgetcells(map_t *map, int amt);
cell_t *getcellindir(cell_t *cell, int dir); cell_t *getcellindir(cell_t *cell, int dir);
vault_t *getcellvault(cell_t *c);
cell_t *getclosestroomcell(lifeform_t *lf, int roomid); cell_t *getclosestroomcell(lifeform_t *lf, int roomid);
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved); int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
int getobchance(int habitat); int getobchance(int habitat);
@ -102,7 +106,7 @@ int isonmap(map_t *map, int x, int y);
int isoutdoors(map_t *m); int isoutdoors(map_t *m);
int isroom(cell_t *c); int isroom(cell_t *c);
int iswallindir(cell_t *cell, int dir); int iswallindir(cell_t *cell, int dir);
int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy); int linkexits(map_t *m, int roomid);
int linkholes(map_t *map); int linkholes(map_t *map);
int linkstairs(object_t *o, object_t *o2); int linkstairs(object_t *o, object_t *o2);
void makedoor(cell_t *cell, int openchance); void makedoor(cell_t *cell, int openchance);

54
move.c
View File

@ -882,8 +882,13 @@ int moveeffects(lifeform_t *lf) {
int didmsg = B_FALSE; int didmsg = B_FALSE;
if (isbleeding(lf)) { if (isbleeding(lf)) {
if (rnd(1,2) == 1) { if (lfhasflagval(lf, F_INJURY, BP_LEGS, DT_SLASH, NA, NULL)) {
bleed(lf); bleed(lf);
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
} else {
if (rnd(1,2) == 1) {
bleed(lf);
}
} }
} }
@ -928,6 +933,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
int preshop = -1; int preshop = -1;
int prespeed = B_FALSE, postspeed = B_FALSE; int prespeed = B_FALSE, postspeed = B_FALSE;
int prewater = B_FALSE; int prewater = B_FALSE;
vault_t *v;
assert(newcell); assert(newcell);
@ -943,9 +949,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// update current cell + room id // update current cell + room id
prespeed = getmovespeed(lf); prespeed = getmovespeed(lf);
preroom = lf->cell->roomid; preroom = getroomid(lf->cell);
if (lf->cell->vault && hasflag(lf->cell->vault->flags, F_VAULTISSHOP)) { v = getcellvault(lf->cell);
preshop = lf->cell->roomid; if (v && hasflag(v->flags, F_VAULTISSHOP)) {
preshop = getroomid(lf->cell);
} }
// getting out of water? // getting out of water?
@ -979,7 +986,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
assert(!newcell->lf); assert(!newcell->lf);
// remember new room... // remember new room...
postroom = lf->cell->roomid; postroom = getroomid(lf->cell);
postspeed = getmovespeed(lf); postspeed = getmovespeed(lf);
// update new cell // update new cell
@ -1198,6 +1205,11 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (cansee(l, lf)) { if (cansee(l, lf)) {
int dointerrupt = B_FALSE; int dointerrupt = B_FALSE;
// much larger creatures moving will cause our los to be recalculated
if (getlfsize(lf) - getlfsize(l) >= 2) {
precalclos(l);
}
if (isplayer(l)) { if (isplayer(l)) {
if (areenemies(lf, l)) { if (areenemies(lf, l)) {
if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_TRAINING)) { if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_TRAINING)) {
@ -1238,7 +1250,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// leaving a shop // leaving a shop
if (preshop) { if (preshop) {
// are you about to go outside a shop with stolen goods? // are you about to go outside a shop with stolen goods?
if ((lf->cell->roomid == preshop) && (lf->cell->type->id != CT_FLOORSHOP)) { if ((getroomid(lf->cell) == preshop) && (lf->cell->type->id != CT_FLOORSHOP)) {
lifeform_t *shk; lifeform_t *shk;
int nitems = 0; int nitems = 0;
shk = findshopkeeper(lf->cell->map, preshop); shk = findshopkeeper(lf->cell->map, preshop);
@ -1248,7 +1260,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
sayphrase(shk, SP_PAYWARN, SV_SHOUT, NA, (nitems == 1) ? "that" : "those" ); sayphrase(shk, SP_PAYWARN, SV_SHOUT, NA, (nitems == 1) ? "that" : "those" );
didmsg = B_TRUE; didmsg = B_TRUE;
} }
} else if (lf->cell->roomid != preshop) { } else if (getroomid(lf->cell) != preshop) {
// you've left the shop // you've left the shop
lifeform_t *shk; lifeform_t *shk;
shk = findshopkeeper(lf->cell->map, preshop); shk = findshopkeeper(lf->cell->map, preshop);
@ -1592,17 +1604,19 @@ int opendoor(lifeform_t *lf, object_t *o) {
} }
where = getoblocation(o); where = getoblocation(o);
if (!haslos(player, where)) {
// don't anonuce this if we can see it. if (player) {
// normally 'noise()' takes care of this by if (haslos(player, where)) {
// checking if we have LOS to the lifeform making needredraw = B_TRUE;
// sound, but in this case it's the door making drawscreen();
// the sound, not the lf. } else {
noise(where, NULL, NC_OTHER, 2, "a door opening.", NULL); // don't anonuce this if we can see it.
} // normally 'noise()' takes care of this by
if (player && haslos(player, where)) { // checking if we have LOS to the lifeform making
needredraw = B_TRUE; // sound, but in this case it's the door making
drawscreen(); // the sound, not the lf.
noise(where, NULL, NC_OTHER, 2, "a door opening.", NULL);
}
} }
} }
return B_FALSE; return B_FALSE;
@ -2551,7 +2565,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
roomid = f->val[0]; roomid = f->val[0];
if (roomid == NA) { if (roomid == NA) {
// don't move out of ANY room. // don't move out of ANY room.
if ((lf->cell->roomid != cell->roomid)) { if ((getroomid(lf->cell) != getroomid(cell))) {
if ((f->val[1] != NA) && aihastarget(lf)) { if ((f->val[1] != NA) && aihastarget(lf)) {
// exception! // exception!
} else { } else {
@ -2561,7 +2575,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
} }
} else { } else {
// don't move out of the given room. // don't move out of the given room.
if ((lf->cell->roomid == roomid) && (lf->cell->roomid != cell->roomid)) { if ((getroomid(lf->cell) == roomid) && (getroomid(lf->cell) != getroomid(cell))) {
if ((f->val[1] != NA) && aihastarget(lf)) { if ((f->val[1] != NA) && aihastarget(lf)) {
// exception! // exception!
} else { } else {

View File

@ -1272,7 +1272,7 @@ int rollmpdice(lifeform_t *lf) {
} else { } else {
return 0; return 0;
} }
mod = 100 + getstatmod(lf, A_IQ); mod = 100 + getstatmod(lf, A_IQ) + (getskill(lf, SK_SPELLCASTING)/2);
roll = rolldie(ndice, 4) + plus; roll = rolldie(ndice, 4) + plus;
@ -1426,6 +1426,8 @@ void sortcommands(void) {
void timeeffectsworld(map_t *map) { void timeeffectsworld(map_t *map) {
flag_t *retflag[MAXCANDIDATES];
int nretflags;
lifeform_t *l; lifeform_t *l;
int db = B_FALSE; int db = B_FALSE;
object_t *o,*nexto; object_t *o,*nexto;
@ -1515,7 +1517,7 @@ void timeeffectsworld(map_t *map) {
// now finish off water spread // now finish off water spread
noredraw = B_TRUE; noredraw = B_TRUE;
getflags(map->flags, F_NEWWATERDEPTH, F_NONE); getflags(map->flags, retflag, &nretflags, F_NEWWATERDEPTH, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
cell_t *c; cell_t *c;
f = retflag[i]; f = retflag[i];

336
objects.c
View File

@ -26,9 +26,6 @@ extern obmod_t *firstobmod,*lastobmod;
extern material_t *material,*lastmaterial; extern material_t *material,*lastmaterial;
extern skill_t *firstskill, *lastskill; extern skill_t *firstskill, *lastskill;
extern flag_t *retflag[];
extern int nretflags;
void (*precalclos)(lifeform_t *); void (*precalclos)(lifeform_t *);
extern object_t *retobs[MAXPILEOBS+1]; extern object_t *retobs[MAXPILEOBS+1];
@ -442,6 +439,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
int wantlit = B_FALSE; int wantlit = B_FALSE;
int wantrarity = RR_NONE; int wantrarity = RR_NONE;
int wantgoodness = G_NA; int wantgoodness = G_NA;
map_t *targetmap = NULL; // for portals
cell_t *targetcell = NULL; // for portals
int donesomething; int donesomething;
object_t *addedob[MAXPILEOBS]; object_t *addedob[MAXPILEOBS];
int nadded = 0; int nadded = 0;
@ -708,6 +707,36 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
corpserace = findracebyname(racename); corpserace = findracebyname(racename);
ot = findot(OT_HEAD); ot = findot(OT_HEAD);
} else if (strstarts(p, "portal to lv")) {
char *pp;
int dlev;
pp = p + strlen("portal to lv");
dlev = atoi(pp);
if (dlev > 0) {
cell_t *c;
c = getobpilelocation(where);
if (c) {
// find map within this region with the given depth
targetmap = findregionmap(c->map->region->id, dlev);
if (!targetmap) {
// create it
targetmap = addmap();
createmap(targetmap, dlev, c->map->region, NULL, D_NONE, NULL);
}
targetcell = getrandomroomcell(targetmap, ANYROOM);
while (!cellwalkable(NULL, targetcell, NULL)) {
targetcell = getrandomadjcell(targetcell, WE_WALKABLE, B_ALLOWEXPAND);
}
} else {
// ie. adding to dummy cell
targetmap = NULL;
targetcell = NULL;
}
} else {
return NULL;
}
ot = findot(OT_PORTAL);
} else if (strstarts(p, "sign ")) { } else if (strstarts(p, "sign ")) {
char *pp; char *pp;
pp = strchr(p, '\"'); pp = strchr(p, '\"');
@ -1008,6 +1037,16 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
addflag(o->flags, F_SIGNTEXT, NA, NA, NA, signtext); addflag(o->flags, F_SIGNTEXT, NA, NA, NA, signtext);
} }
// fill in portal destinations
if (targetmap) {
int tx = NA,ty = NA;
if (targetcell) {
tx = targetcell->x;
ty = targetcell->y;
}
addflag(o->flags, F_MAPLINK, targetmap->id, tx, ty, NULL);
}
// fill in door flags // fill in door flags
if (ndoorflags && isdoor(o, NULL)) { if (ndoorflags && isdoor(o, NULL)) {
int n; int n;
@ -1492,9 +1531,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
} }
// apply cost to shop items // apply cost to shop items
if (o->pile->where && o->pile->where->vault && hasflag(o->pile->where->vault->flags, F_VAULTISSHOP)) { if (o->pile->where) {
if (canpickup(NULL, o, 1)) { vault_t *v;
addflag(o->flags, F_SHOPITEM, getobvalue(o), o->pile->where->roomid, NA, NULL); v = getcellvault(o->pile->where);
if (v && hasflag(v->flags, F_VAULTISSHOP)) {
if (canpickup(NULL, o, 1)) {
addflag(o->flags, F_SHOPITEM, getobvalue(o), getroomid(o->pile->where), NA, NULL);
}
} }
} }
@ -2381,6 +2424,18 @@ int countobs(obpile_t *op, int onlyifknown) {
return count; return count;
} }
int countobsoftype(obpile_t *op, enum OBTYPE oid) {
object_t *o;
int count = 0;
for (o = op->first ; o ; o = o->next) {
if (o->id == oid) {
count++;
}
}
return count;
}
int countnoncosmeticobs(obpile_t *op, int onlyifknown) { int countnoncosmeticobs(obpile_t *op, int onlyifknown) {
object_t *o; object_t *o;
@ -2471,6 +2526,12 @@ int doobtraps(object_t *o, lifeform_t *lf) {
trapid = f->val[0]; trapid = f->val[0];
trapeffects(NULL, trapid, lf); trapeffects(NULL, trapid, lf);
killflag(f); // now the trap gets removed killflag(f); // now the trap gets removed
// explosion traps kill the object
if (trapid == OT_TRAPMINE) {
killob(o);
}
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -3057,8 +3118,10 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder) {
int getobbonus(object_t *o) { int getobbonus(object_t *o) {
int bonus = 0,i; int bonus = 0,i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
getflags(o->flags, F_BONUS, F_NONE); getflags(o->flags, retflag, &nretflags, F_BONUS, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
bonus += retflag[i]->val[0]; bonus += retflag[i]->val[0];
} }
@ -3128,6 +3191,8 @@ int getobvalue(object_t *o) {
flag_t *f; flag_t *f;
int rarity = 0,i; int rarity = 0,i;
enum RARITY rr = RR_COMMON; enum RARITY rr = RR_COMMON;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (o->type->id == OT_GOLD) { if (o->type->id == OT_GOLD) {
return o->amt; return o->amt;
@ -3143,7 +3208,7 @@ int getobvalue(object_t *o) {
price += f->val[0]; price += f->val[0];
} }
getflags(o->flags, F_ARMOURRATING, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE); getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
// damage // damage
@ -3306,12 +3371,23 @@ char *getoperateverb(object_t *o) {
// ie if you call this on a gem inside a bag inside // ie if you call this on a gem inside a bag inside
// a barrel, will return the barrel. // a barrel, will return the barrel.
object_t *getoutercontainer(object_t *o) { object_t *getoutercontainer(object_t *o) {
/*
while (o->pile->parentob) { while (o->pile->parentob) {
o = o->pile->parentob; o = o->pile->parentob;
} }
return o; return o;
*/
return getoutercontainerop(o->pile);
} }
object_t *getoutercontainerop(obpile_t *op) {
object_t *o = NULL;
while (op->parentob) {
o = op->parentob;
op = o->pile;
}
return o;
}
// ie. "it has xxx accuracy" // ie. "it has xxx accuracy"
char *getaccuracyname(int accpct) { char *getaccuracyname(int accpct) {
@ -3368,6 +3444,8 @@ object_t *getrandomammo(lifeform_t *lf) {
object_t *o; object_t *o;
flag_t *f; flag_t *f;
int i; int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
gun = getfirearm(lf); gun = getfirearm(lf);
if (!gun) { if (!gun) {
return NULL; return NULL;
@ -3377,7 +3455,7 @@ object_t *getrandomammo(lifeform_t *lf) {
// pick a specific ammo to use. USe a flag on wep // pick a specific ammo to use. USe a flag on wep
// to do this? Or a flag on the player? // to do this? Or a flag on the player?
getflags(gun->flags, F_AMMOOB, F_NONE); getflags(gun->flags, retflag, &nretflags, F_AMMOOB, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
@ -3967,6 +4045,8 @@ char *getobextrainfo(object_t *o, char *buf) {
} }
cell_t *getoblocation(object_t *o) { cell_t *getoblocation(object_t *o) {
return getobpilelocation(o->pile);
/*
if (o->pile->owner) { // held by someone if (o->pile->owner) { // held by someone
return o->pile->owner->cell; return o->pile->owner->cell;
} else if (o->pile->where) { // on the ground } else if (o->pile->where) { // on the ground
@ -3979,6 +4059,22 @@ cell_t *getoblocation(object_t *o) {
} }
// in a dummy cell // in a dummy cell
return NULL; return NULL;
*/
}
cell_t *getobpilelocation(obpile_t *op) {
if (op->owner) { // held by someone
return op->owner->cell;
} else if (op->where) { // on the ground
return op->where;
} else if (op->parentob) { // inside another object
object_t *outerob;
// get outside object
outerob = getoutercontainerop(op);
return getoblocation(outerob);
}
// in a dummy cell
return NULL;
} }
char *getobname(object_t *o, char *buf, int count) { char *getobname(object_t *o, char *buf, int count) {
@ -4004,6 +4100,8 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
int hasunknownmod = B_FALSE; int hasunknownmod = B_FALSE;
cell_t *where; cell_t *where;
int no_a = B_FALSE; int no_a = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
// default to normal name // default to normal name
if (hasflag(o->flags, F_VENDITEM)) { if (hasflag(o->flags, F_VENDITEM)) {
@ -4404,7 +4502,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
// are all of the brand flags known? // are all of the brand flags known?
for (brf = br->flags->first ; brf ; brf = brf->next) { for (brf = br->flags->first ; brf ; brf = brf->next) {
int i; int i;
getflags(o->flags, brf->id, F_NONE); getflags(o->flags, retflag, &nretflags, brf->id, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->lifetime == FROMBRAND) { if (f->lifetime == FROMBRAND) {
@ -6567,7 +6665,7 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l3 // l3
addot(OT_S_POISONBOLT, "poison bolt", "Fires a glob of venom at the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_POISONBOLT, "venom bolt", "Fires a glob of venom at the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
@ -6597,27 +6695,27 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l5
addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
// TODO: should be "castnearob ot_corpse" // TODO: should be "castnearob ot_corpse"
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
// l5 addot(OT_S_FEEBLEMIND, "brain freeze", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addot(OT_S_FEEBLEMIND, "feeblemind", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l7 // l6
addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l8
addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL); addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
/////////////////// ///////////////////
@ -6635,35 +6733,36 @@ void initobjects(void) {
addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
// l3
addot(OT_S_SEEINVIS, "see invisible", "Allows the caster to see invisible creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SEEINVIS, "see invisible", "Allows the caster to see invisible creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
// l3 // l4
addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
// l4 // l5
addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
// l8 // l6
addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
/////////////////// ///////////////////
// enchantment // enchantment
@ -6671,14 +6770,14 @@ void initobjects(void) {
// l7 // l7
addot(OT_S_ENCHANT, "enchantment", "Magically enhances a weapon or piece of armour.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_ENCHANT, "enchantment", "Magically enhances a weapon or piece of armour.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
// TODO: hardcode how ai casts this spell // TODO: hardcode how ai casts this spell
/////////////////// ///////////////////
// elemental - air // elemental - air
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_MIST, "obscuring mist", "Hides the caster from view with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_MIST, "pea soup", "Hides the caster from view with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
@ -6731,7 +6830,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
// l5 // l5
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs between all nearby enemies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 2d6 damage, the next deals 2d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -6747,13 +6846,13 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l2 // l2
addot(OT_S_BLADEBURN, "bladeburn", "Ignites the target's bladed weapon, causing it to temporarily deal fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_BLADEBURN, "bladeburn", "Ignites the target's bladed weapon, causing it to temporarily deal fire damage. The spell's power determines how long it will last.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+power fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+^bpower^n fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -6787,7 +6886,7 @@ void initobjects(void) {
// elemental - ice // elemental - ice
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_FROSTBITE, "frostbite", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CHILL, "chill", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -6797,6 +6896,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_ICEEDGE, "ice edge", "Enhances the edge of a bladed weapon with a layer of ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_ICEEDGE, "ice edge", "Enhances the edge of a bladed weapon with a layer of ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
@ -6821,7 +6921,7 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l4 // l4
addot(OT_S_CHILL, "chill", "Deals 3-24 cold damage to target creature per exposed body part.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FROSTBITE, "frostbite", "Deals 3-24 cold damage to target creature per exposed body part.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
@ -6957,14 +7057,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addot(OT_S_HAILSTORM, "hail storm", "Creates an intense storm of hail, causing damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SATEHUNGER, "sate hunger", "Immediately satisfies the hunger of one living creature.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SATEHUNGER, "sate hunger", "Immediately satisfies the hunger of one living creature.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
@ -6980,6 +7072,15 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
// l5
addot(OT_S_HAILSTORM, "hail storm", "Creates an intense storm of hail, causing damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l6 // l6
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
@ -6991,7 +7092,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addot(OT_S_FLOOD, "flood", "Converts the earth directly into water, creating a deep pool.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FLOOD, "flood", "Creates a massive ball of water.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -6999,28 +7100,29 @@ void initobjects(void) {
// gravity // gravity
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_TRUESTRIKE, "true strike", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_TRUESTRIKE, "weapon attraction", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
// l3 // l2
addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
// l3
addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
// l4 // l4
addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
@ -7056,6 +7158,7 @@ void initobjects(void) {
// l2 // l2
addot(OT_S_SPEAKDEAD, "speak with dead", "Temporarily allow a corpse to answer questions about its former life.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SPEAKDEAD, "speak with dead", "Temporarily allow a corpse to answer questions about its former life.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addot(OT_S_SMITEEVIL, "smite evil", "Instantly deals 1-^bpower*2^n damage to evil creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SMITEEVIL, "smite evil", "Instantly deals 1-^bpower*2^n damage to evil creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
@ -7173,16 +7276,16 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
// l2
addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addot(OT_S_MENDING, "mending", "Repairs minor damage to objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_MENDING, "mending", "Repairs minor damage to objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
// l2
addot(OT_S_GREASE, "grease", "Creates a large pool of greasy oil.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GREASE, "grease", "Creates a large pool of greasy oil.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -7197,14 +7300,20 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
//addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL); //addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through a single wall.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
// l5
addot(OT_S_GASEOUSFORM, "gaseous form", "Changes the caster into a cloud of gas.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
// l6 // l6
addot(OT_S_PETRIFY, "petrify", "Causes the target mosnter to turn into stone.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PETRIFY, "petrify", "Causes a living creature to turn into stone.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -7213,12 +7322,6 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
// l7
addot(OT_S_GASEOUSFORM, "gaseous form", "Changes the caster into a cloud of gas.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
/////////////////// ///////////////////
// summoning // summoning
@ -7270,21 +7373,20 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
// l5
addot(OT_S_DISPERSAL, "dispersal", "Scatters everything in the target cell around the area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DISPERSAL, "dispersal", "Scatters everything in the target cell around the area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l6 // l5
addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
// l9 // l6
addot(OT_S_PLANESHIFT, "planeshift", "Instantly transports the caster to a different plane of existence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PLANESHIFT, "planeshift", "Instantly transports the caster to a different plane of existence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
@ -7340,25 +7442,25 @@ void initobjects(void) {
addot(OT_A_LEVELUP, "levelup", "Bestow the given xp level.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_LEVELUP, "levelup", "Bestow the given xp level.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_S_WISH, "wish", "Grants the caster any item of their choice. Beware - casting this powerful spell will reduce the caster's hit points by 50%.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_WISH, "wish", "Grants the caster any item of their choice. Beware - casting this powerful spell will reduce the caster's hit points by 50%.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addot(OT_S_WISHLIMITED, "limited wish", "Grants the caster a wish of their choice. Beware - casting this powerful spell will reduce the caster's hit points by 25%.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_WISHLIMITED, "limited wish", "Grants the caster a wish of their choice. Beware - casting this powerful spell will reduce the caster's hit points by 25%.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addot(OT_S_CONFISCATE, "confiscate", "Takes any object from the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CONFISCATE, "confiscate", "Takes any object from the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addot(OT_S_CLEARLEVEL, "blank level", "Blanks out the current map.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CLEARLEVEL, "blank level", "Blanks out the current map.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_CREATEVAULT, "create vault", "Create a vault of the given type.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CREATEVAULT, "create vault", "Create a vault of the given type.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
@ -8878,6 +8980,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
// this one is for the pirate // this one is for the pirate
addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON, SZ_TINY); addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON, SZ_TINY);
@ -8897,6 +9000,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2");
@ -8910,6 +9014,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_HOOF, "hooves", "hoof object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_HOOF, "hooves", "hoof object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2");
@ -8917,6 +9022,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_BUTT, "headbutt", "headbutt object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_BUTT, "headbutt", "headbutt object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2");
@ -8924,6 +9030,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_STING, "sting", "sting object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_STING, "sting", "sting object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting");
@ -8939,12 +9046,14 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY); addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_ELECTRIC, NA, NA, "1d2"); addflag(lastot->flags, F_DAM, DT_ELECTRIC, NA, NA, "1d2");
@ -9051,6 +9160,7 @@ void initobjects(void) {
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, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
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");
@ -9073,6 +9183,7 @@ void initobjects(void) {
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, 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, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM); addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1"); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1");
@ -9090,6 +9201,7 @@ void initobjects(void) {
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
@ -9099,6 +9211,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON, SZ_SMALL); addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d3"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d3");
@ -9122,12 +9235,14 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM); addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8"); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8");
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL); addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
@ -9141,11 +9256,13 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6");
addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL); addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2");
@ -9162,6 +9279,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_GREATSWORD, "greatsword", "A massive two-handed sword.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addot(OT_GREATSWORD, "greatsword", "A massive two-handed sword.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
@ -9170,12 +9288,14 @@ void initobjects(void) {
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, 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_SLASH, NA, NA, "1d8"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8");
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON, SZ_MEDIUM); addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
@ -9189,12 +9309,14 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7");
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
// polearms // polearms
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN);
@ -9205,6 +9327,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
@ -9215,6 +9338,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_DEX, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 7, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
@ -9225,6 +9349,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
@ -9233,6 +9358,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
@ -9261,12 +9387,14 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 5, OC_WEAPON, SZ_HUMAN); addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 5, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d10"); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d10");
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
// staves // staves
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON, SZ_HUMAN);
@ -9278,6 +9406,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, 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_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON, SZ_HUMAN); addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
@ -9287,6 +9416,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, 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_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON, SZ_HUMAN); addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
@ -9298,6 +9428,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 9, 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_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON, SZ_HUMAN); addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
@ -9308,6 +9439,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, 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_CRITCHANCE, 8, NA, NA, NULL);
// clubs (bashing) // clubs (bashing)
@ -9317,12 +9449,14 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM); addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4");
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL);
@ -9330,6 +9464,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM); addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
@ -9344,6 +9479,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, 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_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
@ -9352,6 +9488,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM); addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
@ -9359,6 +9496,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON, SZ_MEDIUM); addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, 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_BASH, NA, NA, "1d4"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4");
@ -9474,6 +9612,7 @@ void initobjects(void) {
addot(OT_ENERGYBLADE, "energy blade", "A summoned weapon made of pure magical energy.", MT_MAGIC, 0, OC_WEAPON, SZ_MEDIUM); addot(OT_ENERGYBLADE, "energy blade", "A summoned weapon made of pure magical energy.", MT_MAGIC, 0, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_DAM, DT_MAGIC, NA, NA, "1d4"); // will be replaced when summoned addflag(lastot->flags, F_DAM, DT_MAGIC, NA, NA, "1d4"); // will be replaced when summoned
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_HANDOFGOD, "hand of god", "The ultimate power.", MT_FLESH, 0.1, OC_WEAPON, SZ_MEDIUM); addot(OT_HANDOFGOD, "hand of god", "The ultimate power.", MT_FLESH, 0.1, OC_WEAPON, SZ_MEDIUM);
//addflag(lastot->flags, F_RARITY, H_DUNGEON, RR_UNIQUE, NA, NULL); //addflag(lastot->flags, F_RARITY, H_DUNGEON, RR_UNIQUE, NA, NULL);
@ -10304,6 +10443,8 @@ void makeknown(enum OBTYPE otid) {
enum FLAG fttogive[MAXPILEOBS*3]; enum FLAG fttogive[MAXPILEOBS*3];
int nobs = 0; int nobs = 0;
int i; int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (player) { if (player) {
// if player is holding an object of that type with F_CONFER.. IFKNOWN... and isn't known... // if player is holding an object of that type with F_CONFER.. IFKNOWN... and isn't known...
@ -10312,7 +10453,7 @@ void makeknown(enum OBTYPE otid) {
// keep a list of objects and flags here, then give them afterwards. // keep a list of objects and flags here, then give them afterwards.
for (o = player->pack->first ; o ; o = o->next) { for (o = player->pack->first ; o ; o = o->next) {
if ((o->type->id == otid) && !isknown(o)) { if ((o->type->id == otid) && !isknown(o)) {
getflags(o->flags, F_ACTIVATECONFER, F_EQUIPCONFER, F_HOLDCONFER, F_NONE); getflags(o->flags, retflag, &nretflags, F_ACTIVATECONFER, F_EQUIPCONFER, F_HOLDCONFER, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -12861,7 +13002,13 @@ int readsomething(lifeform_t *lf, object_t *o) {
dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE); dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE);
} }
} }
if (seen) makeknown(o->type->id); if (seen) {
makeknown(o->type->id);
} else {
if (isplayer(lf) || cansee(player, lf)) nothinghappens();
}
if (isplayer(lf)) msg("The scroll crumbles to dust.");
removeob(o, 1);
} else if (o->type->obclass->id == OC_SCROLL) { // cast linked spell } else if (o->type->obclass->id == OC_SCROLL) { // cast linked spell
object_t *targob = NULL; object_t *targob = NULL;
@ -14533,6 +14680,8 @@ void timeeffectsob(object_t *o) {
object_t *sg; object_t *sg;
char obname[BUFLEN],ownername[BUFLEN]; char obname[BUFLEN],ownername[BUFLEN];
int i; int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (hasflag(o->flags, F_DEAD)) return; if (hasflag(o->flags, F_DEAD)) return;
@ -14577,7 +14726,7 @@ void timeeffectsob(object_t *o) {
int nearundead = B_FALSE; int nearundead = B_FALSE;
// are we glowing? // are we glowing?
getflags(o->flags, F_PRODUCESLIGHT, F_NONE); getflags(o->flags, retflag, &nretflags, F_PRODUCESLIGHT, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if ((f->id == F_PRODUCESLIGHT) && (f->lifetime == FROMBLESSING)) { if ((f->id == F_PRODUCESLIGHT) && (f->lifetime == FROMBLESSING)) {
@ -14749,7 +14898,7 @@ void timeeffectsob(object_t *o) {
// check each flag for this object... // check each flag for this object...
getflags(o->flags, F_ACTIVATED, F_EDIBLE, F_MATCONVERT, F_OBHPDRAIN, F_ONFIRE, F_RECHARGE, F_WALKDAM, F_WET, F_NONE); getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_MATCONVERT, F_OBHPDRAIN, F_ONFIRE, F_RECHARGE, F_WALKDAM, F_WET, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
object_t *oo,*nextoo; object_t *oo,*nextoo;
f = retflag[i]; f = retflag[i];
@ -15357,6 +15506,11 @@ int validateobs(void) {
printf("ERROR - spell %s doesn't have F_SPELLLEVEL.\n", ot->name); printf("ERROR - spell %s doesn't have F_SPELLLEVEL.\n", ot->name);
goterror = B_TRUE; goterror = B_TRUE;
} }
f = hasflag(ot->flags, F_SPELLLEVEL);
if (f && (f->val[0] > MAXSPELLLEV)) {
printf("ERROR - spell %s level (%d) > MAXSPELLLEVEL (%d).\n", ot->name, f->val[0], MAXSPELLLEV);
goterror = B_TRUE;
}
} else if (ot->obclass->id == OC_SCROLL) { } else if (ot->obclass->id == OC_SCROLL) {
if (foundspells) { if (foundspells) {
printf("ERROR in object '%s' - all Scrolls must be defined before Spells.\n", ot->name); printf("ERROR in object '%s' - all Scrolls must be defined before Spells.\n", ot->name);
@ -15507,6 +15661,32 @@ int willshatter(enum MATERIAL mat) {
return B_FALSE; return B_FALSE;
} }
int getcritchance(lifeform_t *lf, object_t *o) {
flag_t *f;
int chance = 0;
if (!o) return 0;
f = hasflag(o->flags, F_CRITCHANCE);
if (f) {
return chance += f->val[0];
}
if (lf) {
enum SKILLLEVEL weplev = PR_INEPT;
skill_t *wepsk = NULL;
wepsk = getobskill(o);
if (wepsk) {
weplev = getskill(lf, wepsk->id);
if (weplev != PR_INEPT) {
chance += (weplev*5); // ie. up to 30% bonus
}
}
}
return chance;
}
// determine how long a conferred effect should last, based on its blessed/cursed status. // determine how long a conferred effect should last, based on its blessed/cursed status.
// blessed: always max // blessed: always max
// uncursed: random number between min & max // uncursed: random number between min & max

View File

@ -38,6 +38,7 @@ void colourmatchob(object_t *o, lifeform_t *lf);
void copyobprops(object_t *dst, object_t *src); void copyobprops(object_t *dst, object_t *src);
int countnames(char **list); int countnames(char **list);
int countobs(obpile_t *op, int onlyifknown); int countobs(obpile_t *op, int onlyifknown);
int countobsoftype(obpile_t *op, enum OBTYPE oid);
int countnoncosmeticobs(obpile_t *op, int onlyifknown); int countnoncosmeticobs(obpile_t *op, int onlyifknown);
int curseob(object_t *o); int curseob(object_t *o);
void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype); void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype);
@ -58,6 +59,7 @@ void genhiddennames(void);
object_t *getbestcontainer(obpile_t *op); object_t *getbestcontainer(obpile_t *op);
int getchargeinfo(object_t *o, int *cur, int *max); int getchargeinfo(object_t *o, int *cur, int *max);
int getcharges(object_t *o); int getcharges(object_t *o);
int getcritchance(lifeform_t *lf, object_t *o);
int geteffecttime(int min, int max, enum BLESSTYPE isblessed); int geteffecttime(int min, int max, enum BLESSTYPE isblessed);
objecttype_t *getlinkspell(object_t *o); objecttype_t *getlinkspell(object_t *o);
enum COLOUR getmaterialcolour(enum MATERIAL mat ); enum COLOUR getmaterialcolour(enum MATERIAL mat );
@ -72,6 +74,7 @@ int getobspellpower(object_t *o, lifeform_t *lf);
int getobvalue(object_t *o); int getobvalue(object_t *o);
char *getoperateverb(object_t *o); char *getoperateverb(object_t *o);
object_t *getoutercontainer(object_t *o); object_t *getoutercontainer(object_t *o);
object_t *getoutercontainerop(obpile_t *op);
//int getobtypevalue(objecttype_t *ot); //int getobtypevalue(objecttype_t *ot);
char *getaccuracyname(int accpct); char *getaccuracyname(int accpct);
object_t *getammo(object_t *gun); object_t *getammo(object_t *gun);
@ -103,6 +106,7 @@ char *getobdesc(object_t *o, char *buf);
char *getobequipinfo(object_t *o, char *buf); char *getobequipinfo(object_t *o, char *buf);
char *getobextrainfo(object_t *o, char *buf); char *getobextrainfo(object_t *o, char *buf);
cell_t *getoblocation(object_t *o); cell_t *getoblocation(object_t *o);
cell_t *getobpilelocation(obpile_t *op);
char *getobname(object_t *o, char *buf, int count); char *getobname(object_t *o, char *buf, int count);
char *getobnametrue(object_t *o, char *buf, int count); char *getobnametrue(object_t *o, char *buf, int count);
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall); char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall);

45
save.c
View File

@ -329,6 +329,16 @@ map_t *loadmap(char *basefile) {
fscanf(f, "%s\n",buf); fscanf(f, "%s\n",buf);
} }
// load room defs
fscanf(f, "nrooms:%d\n",&m->nrooms);
for (i = 0; i < m->nrooms; i++) {
fscanf(f, "%d,%d,%d,%d,%d,%s\n",&m->room[i].id,
&m->room[i].x1, &m->room[i].y1,
&m->room[i].x2, &m->room[i].y2, buf);
m->room[i].vault = findvault(buf);
}
// load cells // load cells
if (db) dblog("--> Loading map cells...\n"); if (db) dblog("--> Loading map cells...\n");
fscanf(f, "cells:\n"); fscanf(f, "cells:\n");
@ -339,32 +349,19 @@ map_t *loadmap(char *basefile) {
int celltypeid; int celltypeid;
long obid; long obid;
int temphab; int temphab;
int vid; int roomid;
//if (db) dblog("cell %d,%d...",x,y); //if (db) dblog("cell %d,%d...",x,y);
// allocate this cell // allocate this cell
c = addcell(m, x, y); c = addcell(m, x, y);
/*
c = m->cell[y * m->w + x];
c->map = m;
c->obpile = addobpile(NULL, c);
c->lf = NULL;
c->x = x;
c->y = y;
c->roomid = -1;
*/
// cell info // cell info
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
&c->roomid, &celltypeid, &c->known, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer,&temphab,&vid); &roomid, &celltypeid, &c->known, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer,&temphab);
c->habitat = findhabitat(temphab); c->habitat = findhabitat(temphab);
if (vid == -1) {
c->vault = NULL;
} else {
c->vault = findvaultbyid(vid);
}
c->room = findroom(m, roomid);
ct = findcelltype(celltypeid); ct = findcelltype(celltypeid);
if (ct) { if (ct) {
@ -878,6 +875,15 @@ int savemap(map_t *m) {
} }
fprintf(f, "endlifeforms\n"); fprintf(f, "endlifeforms\n");
// save room defs
fprintf(f, "nrooms:%d\n",m->nrooms);
for (i = 0; i < m->nrooms; i++) {
fprintf(f, "%d,%d,%d,%d,%d,%s\n",m->room[i].id,
m->room[i].x1, m->room[i].y1,
m->room[i].x2, m->room[i].y2,
m->room[i].vault ? m->room[i].vault->id : "^^^");
}
// cells // cells
fprintf(f, "cells:\n"); fprintf(f, "cells:\n");
for (y = 0; y < m->h; y++) { for (y = 0; y < m->h; y++) {
@ -885,8 +891,8 @@ int savemap(map_t *m) {
cell_t *c; cell_t *c;
c = getcellat(m, x, y); c = getcellat(m, x, y);
// cell info // cell info
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
c->roomid, c->type->id, c->known, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer,c->habitat->id, c->vault ? c->vault->numid : -1); c->room ? c->room->id : -1, c->type->id, c->known, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer,c->habitat->id );
// cell objects // cell objects
for (o = c->obpile->first ; o ; o = o->next) { for (o = c->obpile->first ; o ; o = o->next) {
fprintf(f, "ob:%ld\n",o->id); fprintf(f, "ob:%ld\n",o->id);
@ -896,6 +902,7 @@ int savemap(map_t *m) {
} }
} }
// save object definitions from map cells // save object definitions from map cells
fprintf(f, "MAPOBS:%d\n",obcount); fprintf(f, "MAPOBS:%d\n",obcount);
for (y = 0; y < m->h; y++) { for (y = 0; y < m->h; y++) {

40
spell.c
View File

@ -1516,7 +1516,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
// stealing shop items // stealing shop items
if (isroom(user->cell) && hasobwithflagval(user->cell->obpile, F_SHOPITEM, NA, user->cell->roomid, NA, NULL)) { if (isroom(user->cell) && hasobwithflagval(user->cell->obpile, F_SHOPITEM, NA, getroomid(user->cell), NA, NULL)) {
// stealing from a shop // stealing from a shop
char yn; char yn;
yn = askchar("Steal something from this shop?", "yn","n", B_TRUE); yn = askchar("Steal something from this shop?", "yn","n", B_TRUE);
@ -1529,7 +1529,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
value = 0; value = 0;
for (o = user->cell->obpile->first ; o ; o = o->next) { for (o = user->cell->obpile->first ; o ; o = o->next) {
f = hasflagval(o->flags, F_SHOPITEM, NA, user->cell->roomid, NA, NULL); f = hasflagval(o->flags, F_SHOPITEM, NA, getroomid(user->cell), NA, NULL);
if (f) { if (f) {
value += f->val[0]; value += f->val[0];
} }
@ -1554,7 +1554,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
lifeform_t *shk; lifeform_t *shk;
msg("You try to steal something, but fail."); msg("You try to steal something, but fail.");
// failed // failed
shk = findshopkeeper(user->cell->map, user->cell->roomid); shk = findshopkeeper(user->cell->map, getroomid(user->cell));
if (shk) { // doesn't need to see you - he SENSES it! if (shk) { // doesn't need to see you - he SENSES it!
say(shk, "THIEF!", SV_ROAR); say(shk, "THIEF!", SV_ROAR);
fightback(shk, user); fightback(shk, user);
@ -2712,7 +2712,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_CHILL) { } else if (spellid == OT_S_CHILL) {
char lfname[BUFLEN]; char lfname[BUFLEN];
int exposedlimbs,dam;
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
target = targcell->lf; target = targcell->lf;
if (!target) { if (!target) {
@ -2721,23 +2720,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
getlfname(target, lfname); getlfname(target, lfname);
// how many body parts are impacted?
exposedlimbs = getexposedlimbs(target);
dam = rolldie(exposedlimbs, 3);
if (isplayer(target)) { if (isplayer(target)) {
if (isimmuneto(target->flags, DT_COLD)) { if (isimmuneto(target->flags, DT_COLD)) {
msg("You feel mildly chilly."); msg("You feel mildly chilly.");
} else { } else {
msg("You feel extremely cold!"); msg("You feel very cold!");
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
if (isimmuneto(target->flags, DT_COLD)) { if (isimmuneto(target->flags, DT_COLD)) {
msg("%s looks mildly chilly.", lfname); msg("%s looks mildly chilly.", lfname);
} else { } else {
msg("%s looks extremely cold!", lfname); msg("%s looks very cold!", lfname);
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -2745,7 +2739,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// target takes magical damage // target takes magical damage
// always hit // always hit
if (!isimmuneto(target->flags, DT_COLD)) { if (!isimmuneto(target->flags, DT_COLD)) {
losehp(target, dam, DT_COLD, caster, "a chill spell"); losehp(target, roll("1d3"), DT_COLD, caster, "a frostbite spell");
} }
} else if (spellid == OT_S_COLDBURST) { } else if (spellid == OT_S_COLDBURST) {
int range = 1; int range = 1;
@ -3997,6 +3991,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_FROSTBITE) { } else if (spellid == OT_S_FROSTBITE) {
char lfname[BUFLEN]; char lfname[BUFLEN];
int exposedlimbs,dam;
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
target = targcell->lf; target = targcell->lf;
if (!target) { if (!target) {
@ -4005,18 +4000,23 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
getlfname(target, lfname); getlfname(target, lfname);
// how many body parts are impacted?
exposedlimbs = getexposedlimbs(target);
dam = rolldie(exposedlimbs, 3);
if (isplayer(target)) { if (isplayer(target)) {
if (isimmuneto(target->flags, DT_COLD)) { if (isimmuneto(target->flags, DT_COLD)) {
msg("You feel mildly chilly."); msg("You feel mildly chilly.");
} else { } else {
msg("You feel very cold!"); msg("You feel extremely cold!");
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
if (isimmuneto(target->flags, DT_COLD)) { if (isimmuneto(target->flags, DT_COLD)) {
msg("%s looks mildly chilly.", lfname); msg("%s looks mildly chilly.", lfname);
} else { } else {
msg("%s looks very cold!", lfname); msg("%s looks extremely cold!", lfname);
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -4024,7 +4024,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// target takes magical damage // target takes magical damage
// always hit // always hit
if (!isimmuneto(target->flags, DT_COLD)) { if (!isimmuneto(target->flags, DT_COLD)) {
losehp(target, roll("1d3"), DT_COLD, caster, "a frostbite spell"); losehp(target, dam, DT_COLD, caster, "a chill spell");
} }
} else if (spellid == OT_S_GASEOUSFORM) { } else if (spellid == OT_S_GASEOUSFORM) {
if (!target) target = caster; if (!target) target = caster;
@ -5098,7 +5098,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
createmap(newmap, newdepth, caster->cell->map->region, NULL, D_NONE, NULL); createmap(newmap, newdepth, caster->cell->map->region, NULL, D_NONE, NULL);
} }
// find a random cell there // find a random cell there
newcell = getrandomcell(newmap); newcell = getrandomcell(newmap);
while (!cellwalkable(caster, newcell, NULL) || hasenterableobject(newcell)) { while (!cellwalkable(caster, newcell, NULL) || hasenterableobject(newcell)) {
@ -6574,15 +6573,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
return B_FALSE; return B_FALSE;
} else { } else {
if (isplayer(target)) { stun(target, 2);
msg("You are stunned!"); if (isplayer(target) || cansee(player, target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (haslos(player, target->cell)) {
getlfname(target, buf);
msg("%s is stunned!", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
taketime(target, getactspeed(target)*2);
} }
} else if (spellid == OT_S_SUCK) { } else if (spellid == OT_S_SUCK) {
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;

38
text.c
View File

@ -252,6 +252,44 @@ char *getdrunktext(flag_t *drunkflag) {
return "??drunk??"; return "??drunk??";
} }
char *getinjuredbpname(enum BODYPART bp) {
switch (bp) {
case BP_HEAD: return "head";
case BP_HANDS: return "arm";
case BP_LEGS: return "leg";
default: break;
}
return "body";
}
char *getinjuryname(enum DAMTYPE dt) {
switch (dt) {
case DT_BASH: return "bruised";
case DT_SLASH: return "bleeding";
default: break;
}
return "injured";
}
char *getinjurydesc(enum BODYPART where, enum DAMTYPE dt) {
if (dt == DT_SLASH) {
if (where == BP_LEGS) {
return " (moving causes damage)";
} else if (where == BP_HANDS) {
return " (attacking causes damage)";
} else if (where == BP_BODY) {
return " (take extra damage from melee hits)";
}
} else if (dt == DT_BASH) {
if (where == BP_LEGS) {
return " (penalty to movement speed)";
} else if (where == BP_HANDS) {
return " (penalty to attack accuracy)";
}
}
return "";
}
char *getrarityname(enum RARITY rr) { char *getrarityname(enum RARITY rr) {
switch (rr) { switch (rr) {
case RR_UNIQUE: return "Unique"; case RR_UNIQUE: return "Unique";

3
text.h
View File

@ -11,6 +11,9 @@ char *getattrname(enum ATTRIB att);
int gethitconferlifetime(char *text, int *min, int *max); int gethitconferlifetime(char *text, int *min, int *max);
char *getpossessive(char *text); char *getpossessive(char *text);
char *getdrunktext(flag_t *drunkflag); char *getdrunktext(flag_t *drunkflag);
char *getinjuredbpname(enum BODYPART bp);
char *getinjuryname(enum DAMTYPE dt);
char *getinjurydesc(enum BODYPART bp, enum DAMTYPE dt);
char *getrarityname(enum RARITY rr); char *getrarityname(enum RARITY rr);
char *getsizetext(enum LFSIZE sz); char *getsizetext(enum LFSIZE sz);
char *gettimetext(char *retbuf); char *gettimetext(char *retbuf);

View File

@ -27,6 +27,7 @@ c:ob:lit candelabrum
@flags @flags
goesin:dungeon goesin:dungeon
norandom norandom
atoneof(10,1)(10,3)(10,5) ob:portal to lv1
scatter(1,1,-2,-2) ob:wooden footstool:0-3 scatter(1,1,-2,-2) ob:wooden footstool:0-3
scatter(1,1,-2,-2) ob:random food:0-2 scatter(1,1,-2,-2) ob:random food:0-2
mayrotate mayrotate