- [+] vampire gas cloud not working for player
- [+] monsters should only weild weapons if they are better than their inbuilt attcaks! - [+] show dtected obkects in bold green - [+] bug: can blink into impassable objects - [+] infinite loop in ai turn for porcupine. - [+] movetowards() * [+] vampires - [+] vampire changes back to its original form. CRASH.
This commit is contained in:
parent
81c7f37eff
commit
00f9d4e0bf
15
ai.c
15
ai.c
|
@ -711,9 +711,16 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
} // end if attackok
|
||||
|
||||
// if we could see our traget, but everything we tried failed (spells, moving and ranged attack),
|
||||
// just rest.
|
||||
// either rest or move randomly.
|
||||
if (movefailed) {
|
||||
makenoise(lf, N_FRUSTRATED);
|
||||
if (onein(2)) {
|
||||
rest(lf, B_TRUE);
|
||||
} else {
|
||||
if (dorandommove(lf, B_NOBADMOVES, B_FALSE)) {
|
||||
rest(lf, B_TRUE);
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
|
@ -1494,6 +1501,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
|
||||
f = hasflag(ot->flags, purpose);
|
||||
if (f) {
|
||||
if ((f->val[1] == NA) || pctchance(f->val[1])) {
|
||||
int range;
|
||||
switch (f->val[0]) {
|
||||
case ST_VICTIM:
|
||||
|
@ -1561,7 +1569,10 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else { // failed pctchance for spell
|
||||
if (db) dblog(".oO { failed pct check for casting %s }", ot ? ot->name : "?unkownspell?");
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
// invalid spell for this purpose
|
||||
if (db) dblog(".oO { cant cast %s - not valid for given purpose }", ot ? ot->name : "?unkownspell?");
|
||||
|
|
21
attack.c
21
attack.c
|
@ -255,7 +255,6 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
}
|
||||
|
||||
// then use all our innate attacks..
|
||||
|
||||
getflags(lf->flags, F_HASATTACK, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
|
@ -2160,4 +2159,24 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
} // end if (fid == hitconfer)
|
||||
}
|
||||
|
||||
if (wep && owner && victim) {
|
||||
if ((wep->type->id == OT_TEETH) && lfhasflag(owner, F_VAMPIRIC) && isbleeding(victim)) {
|
||||
// drain life!
|
||||
gainhp(owner, dam);
|
||||
if (isplayer(owner)) {
|
||||
char lfname[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
getlfname(owner,lfname);
|
||||
getlfname(victim, victimname);
|
||||
msg("You suck %s%s blood!", victimname, getpossessive(victimname));
|
||||
} else if (cansee(player, owner)) {
|
||||
char lfname[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
getlfname(owner,lfname);
|
||||
getlfname(victim, victimname);
|
||||
msg("%s sucks %s%s blood!", lfname, victimname, getpossessive(victimname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
17
defs.h
17
defs.h
|
@ -735,6 +735,7 @@ enum RACE {
|
|||
R_ANTS,
|
||||
R_ANTLION,
|
||||
R_BAT,
|
||||
R_BATVAMPIRE,
|
||||
R_BEAR,
|
||||
R_BEARCUB,
|
||||
R_BEARGRIZZLY,
|
||||
|
@ -895,6 +896,7 @@ enum OBTYPE {
|
|||
OT_TREE,
|
||||
// food
|
||||
OT_BERRY,
|
||||
OT_GARLIC,
|
||||
OT_NUT,
|
||||
OT_BANANA,
|
||||
OT_BANANASKIN, // not really food
|
||||
|
@ -1489,6 +1491,7 @@ enum NOISETYPE {
|
|||
N_FLY,
|
||||
N_WARCRY,
|
||||
N_LOWHP,
|
||||
N_FRUSTRATED,
|
||||
};
|
||||
|
||||
enum LFSIZE {
|
||||
|
@ -1838,8 +1841,10 @@ enum FLAG {
|
|||
//F_SPELLLETTER, // text[0] = letter to cast this spell
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee/heal
|
||||
// v0 is who to target
|
||||
// v1 is pct chance of using this
|
||||
F_AICASTTOATTACK, // AI can cast this spell to attack
|
||||
// v0 is who to target
|
||||
// v1 is pct chance of using this
|
||||
F_AIBOOSTITEM, // ai will use this item to boost/buff itself.
|
||||
// if using this on wands, update aiobok() !
|
||||
F_AIHEALITEM, // ai will use this item when low on hp
|
||||
|
@ -1858,6 +1863,7 @@ enum FLAG {
|
|||
F_COUNTER, // generic counter flag for race abilities.
|
||||
F_DEBUG, // debugging enabled
|
||||
F_ACCURACYMOD, // modify your accuracy by val0
|
||||
F_VAMPIRIC, // successful bite attacks form this lf will heal it
|
||||
F_VEGETARIAN, // this lf will not eat meat.
|
||||
F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry'
|
||||
F_CARNIVORE, // this lf will only eat meat.
|
||||
|
@ -1934,8 +1940,13 @@ enum FLAG {
|
|||
// v2 is counter until casting
|
||||
// text is: "targlfid;targobid;mapid;cellx;celly;"
|
||||
|
||||
F_AVOIDCURSEDOB, // for AI animals - they will avoid walking on obid 'text'
|
||||
F_AVOIDOB, // for AI - they will avoid walking on obid 'text'
|
||||
// (text is a long)
|
||||
// if v0 is not NA, then only avoid it if its blessed
|
||||
// value == v0.
|
||||
F_AVOIDOBTYPE, // AI won't walk on top of obtype v0.
|
||||
// if v1 == B_TRUE, then avoid lfs weilding this
|
||||
// object too.
|
||||
F_STAYINHABITAT, // lf will not walk onto a cell of a different
|
||||
// habitat
|
||||
F_STAYINROOM, // lf will not walk out of roomid v0
|
||||
|
@ -2048,6 +2059,7 @@ enum FLAG {
|
|||
// v0 = max distance to splatter (or UNLIMITED)
|
||||
// text = type of object to splatter
|
||||
F_OBESE, // double base weight for race!
|
||||
F_FORCEPOLY, // when this lf polymorphs, always chance to raceid v0
|
||||
F_ORIGRACE, // original player race (if you polymorphed)
|
||||
F_ORIGJOB, // original player job (if you polymorphed)
|
||||
F_POLYMORPHED, // lf has been polymorphed
|
||||
|
@ -2113,7 +2125,8 @@ enum FLAG {
|
|||
// otherwise just an indicative size is shown
|
||||
F_DETECTMAGIC, // autodetect magic/special objects
|
||||
F_DETECTMETAL, // autodetect nearby metal
|
||||
F_DETECTOBS, // autodetect nearby obs in orthog dist v0
|
||||
F_DETECTOBS, // autodetect nearby obs of type v1 in orthog dist v0
|
||||
// v1 = NA means everything.
|
||||
F_DISEASEIMMUNE, // lf can't be diseased
|
||||
F_DRUNK, // v1 is drunknness - 1-5.
|
||||
F_ENHANCESEARCH, // gives v0 bonus on search checks.
|
||||
|
|
10
flag.c
10
flag.c
|
@ -100,6 +100,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
f->val[1] += val2;
|
||||
f->val[2] += val3;
|
||||
// TODO: how to handle text??
|
||||
f->text = strdup("");
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +304,15 @@ flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
|
|||
return fp;
|
||||
}
|
||||
|
||||
void changeflagtext(flag_t *f, char *newtext) {
|
||||
free(f->text);
|
||||
if (newtext) {
|
||||
f->text = strdup(newtext);
|
||||
} else {
|
||||
f->text = strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id) {
|
||||
flag_t *f;
|
||||
for (f = src->first ; f ; f = f->next) {
|
||||
|
|
1
flag.h
1
flag.h
|
@ -8,6 +8,7 @@ flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char
|
|||
flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft);
|
||||
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid);
|
||||
flagpile_t *addflagpile(lifeform_t *owner, object_t *o);
|
||||
void changeflagtext(flag_t *f, char *newtext);
|
||||
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
|
||||
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
||||
int countflags(flagpile_t *fp);
|
||||
|
|
13
god.c
13
god.c
|
@ -293,7 +293,7 @@ int godgiftmaybe(enum RACE rid) {
|
|||
int chance;
|
||||
// ie. 100 -> 2%
|
||||
// ie. 500 -> 10%
|
||||
chance = piety / 5;
|
||||
chance = piety / 50;
|
||||
if (pctchance(chance)) { // if this is true, you get a gift.
|
||||
char obtogive[BUFLEN];
|
||||
int rollagain = B_TRUE;
|
||||
|
@ -307,7 +307,7 @@ int godgiftmaybe(enum RACE rid) {
|
|||
flag_t *f;
|
||||
object_t *wep;
|
||||
rollagain = B_FALSE;
|
||||
switch (rnd(5,5)) {
|
||||
switch (rnd(1,5)) {
|
||||
case 1:
|
||||
sprintf(obtogive, "3-5 cursed potions of water");
|
||||
break;
|
||||
|
@ -338,7 +338,7 @@ int godgiftmaybe(enum RACE rid) {
|
|||
break;
|
||||
case 5:
|
||||
msg("\"Go forth and kill in my name!\"");
|
||||
setrace(player, R_VAMPIRE, B_TRUE);
|
||||
setrace(player, R_VAMPIRE, B_TRUE); // ie. don't set origrace!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -394,8 +394,9 @@ int godgiftmaybe(enum RACE rid) {
|
|||
}
|
||||
}
|
||||
|
||||
// since you got a gift, lower piety back to 100 (slightly pleased)
|
||||
setpiety(rid, 101);
|
||||
// since you got a gift, lower piety a little.
|
||||
//setpiety(rid, 101);
|
||||
modpiety(rid, -50);
|
||||
} // end if (pctchance enough to get a gift)
|
||||
} // end if (piety > 100)
|
||||
return gotgift;
|
||||
|
@ -444,7 +445,7 @@ void pleasegod(enum RACE rid, int amt) {
|
|||
modpiety(rid, amt);
|
||||
|
||||
// announce
|
||||
//msg("You feel like %s approves of your actions.", lfname);
|
||||
msg("You feel like %s approves of your actions.", lfname);
|
||||
godgiftmaybe(rid);
|
||||
}
|
||||
|
||||
|
|
4
io.c
4
io.c
|
@ -7384,7 +7384,7 @@ void drawstatus(void) {
|
|||
if (hlev == H_NONE) {
|
||||
strcpy(buf2, "");
|
||||
} else {
|
||||
gethungername(gethungerlevel(f->val[0]), buf2);
|
||||
gethungername(player, gethungerlevel(f->val[0]), buf2);
|
||||
capitalise(buf2);
|
||||
}
|
||||
} else {
|
||||
|
@ -8162,7 +8162,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (f) {
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Hunger");
|
||||
|
||||
gethungername(gethungerlevel(f->val[0]), buf);
|
||||
gethungername(lf, gethungerlevel(f->val[0]), buf);
|
||||
capitalise(buf);
|
||||
wprintw(mainwin, "%-14s", buf); y2++;
|
||||
/*
|
||||
|
|
192
lf.c
192
lf.c
|
@ -1236,6 +1236,16 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
// stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// willing this spell? reset counter!
|
||||
// do this _before_ casting the spell,
|
||||
// in case the spell causes us to lose
|
||||
// the f_canwill flag (eg. polymorph)
|
||||
if (willflag) {
|
||||
if (willflag->val[2] != NA) {
|
||||
willflag->val[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// cast the spell
|
||||
f = hasflag(sp->flags, F_CASTINGTIME);
|
||||
if (f) {
|
||||
|
@ -1284,13 +1294,6 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
}
|
||||
}
|
||||
|
||||
// willing this spell? reset counter!
|
||||
if (willflag) {
|
||||
if (willflag->val[2] != NA) {
|
||||
willflag->val[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// successful cast?
|
||||
if (!rv) {
|
||||
practice(lf, SK_SPELLCASTING, 1);
|
||||
|
@ -1330,6 +1333,16 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
|
||||
// will you drown?
|
||||
if (depth >= DP_HEAD) {
|
||||
if (lf->race->id == R_VAMPIRE) {
|
||||
if (isplayer(lf)) {
|
||||
msg("^BThe running water burns you!");
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("^%cThe running water burns %s!", getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
losehp(lf, roll("6d6"), DT_DIRECT, NULL, "running water");
|
||||
}
|
||||
if (!slev && !lfhasflag(lf, F_BREATHWATER)) {
|
||||
int damamt;
|
||||
|
||||
|
@ -1673,9 +1686,9 @@ void die(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
if (lf->race->id == R_VAMPIRE) {
|
||||
// if are asleep, we will die normally
|
||||
if (lfhasflag(lf, F_ASLEEP)) {
|
||||
if ((lf->race->id == R_VAMPIRE) && !hasflag(lf->flags, F_ORIGRACE)) {
|
||||
// if are asleep or killed by running water/sunlight, we will die normally
|
||||
if (lfhasflag(lf, F_ASLEEP) || (lf->lastdamtype == DT_DIRECT)) {
|
||||
noise(lf->cell, lf, NC_OTHER, 4, "a horrified scream!", "screams in horror!");
|
||||
} else if (findobinmap(lf->cell->map, OT_COFFIN)) { // coffin around?
|
||||
// restore 1 hp
|
||||
|
@ -1684,7 +1697,9 @@ void die(lifeform_t *lf) {
|
|||
// convert into a gas cloud!
|
||||
dospelleffects(NULL, OT_S_GASEOUSFORM, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
||||
// ai will now look for our coffin
|
||||
if (!isplayer(lf)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("^GYou feel the presence of a nearby coffin...");
|
||||
} else {
|
||||
addflag(lf->flags, F_WANTS, OT_COFFIN, B_COVETS, NA, NULL);
|
||||
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
@ -1854,8 +1869,7 @@ void die(lifeform_t *lf) {
|
|||
// remember what killed us.
|
||||
f = hasflag(corpse->flags, F_CORPSEOF);
|
||||
if (f) {
|
||||
free(f->text);
|
||||
f->text = strdup(lf->lastdam);
|
||||
changeflagtext(f, lf->lastdam);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2894,8 +2908,7 @@ void enhanceskills(lifeform_t *lf) {
|
|||
break;
|
||||
}
|
||||
if (!streq(newtext, f->text)) {
|
||||
free(f->text);
|
||||
f->text = strdup(newtext);
|
||||
changeflagtext(f, newtext);
|
||||
if (isplayer(lf)) msg("^gYour unarmed attack damage has increased!");
|
||||
}
|
||||
}
|
||||
|
@ -3252,7 +3265,6 @@ int flee(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// are we fleeing?
|
||||
|
||||
getflags(lf->flags, F_FLEEFROM, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
|
@ -4193,8 +4205,42 @@ object_t *getbestweapon(lifeform_t *lf) {
|
|||
object_t *bestwep = NULL;
|
||||
//int bestmaxdam = -999;
|
||||
object_t *o;
|
||||
obpile_t *op = NULL;
|
||||
|
||||
bestwep = getweapon(lf);
|
||||
if (!bestwep) {
|
||||
int i;
|
||||
// get best innate attack
|
||||
getflags(lf->flags, F_HASATTACK, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
objecttype_t *ot;
|
||||
|
||||
if (!op) {
|
||||
op = addobpile(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
ot = findot(retflag[i]->val[0]);
|
||||
if (ot) {
|
||||
o = addob(op, ot->name);
|
||||
|
||||
if (isweapon(o) && !isfirearm(o) && canweild(lf, o) && isbetterwepthan(o, bestwep)) {
|
||||
bestwep = o;
|
||||
// inherit damage from hasattack flag
|
||||
if (strlen(retflag[i]->text)) {
|
||||
flag_t *damflag;
|
||||
damflag = hasflag(bestwep->flags, F_DAM);
|
||||
if (damflag) {
|
||||
free(damflag->text);
|
||||
damflag->text = strdup(retflag[i]->text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
killob(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
// if it does damage and we can weild it...
|
||||
|
@ -4216,6 +4262,15 @@ object_t *getbestweapon(lifeform_t *lf) {
|
|||
}
|
||||
*/
|
||||
|
||||
if (bestwep && (bestwep->pile->owner == NULL)) {
|
||||
// ie. best weapon is an innate attack
|
||||
bestwep = NULL;
|
||||
}
|
||||
|
||||
if (op) {
|
||||
killobpile(op);
|
||||
}
|
||||
|
||||
return bestwep;
|
||||
}
|
||||
|
||||
|
@ -4442,7 +4497,7 @@ enum HUNGER gethungerlevel(int hunger) {
|
|||
return H_STARVED;
|
||||
}
|
||||
|
||||
char *gethungername(enum HUNGER hunger, char *buf) {
|
||||
char *gethungername(lifeform_t *lf, enum HUNGER hunger, char *buf) {
|
||||
switch (hunger) {
|
||||
case H_STUFFED:
|
||||
strcpy(buf, "stuffed");
|
||||
|
@ -4451,19 +4506,39 @@ char *gethungername(enum HUNGER hunger, char *buf) {
|
|||
strcpy(buf, "full");
|
||||
break;
|
||||
case H_NONE:
|
||||
if (lf && (lf->race->id == R_VAMPIRE)) {
|
||||
strcpy(buf, "not thirsty");
|
||||
} else {
|
||||
strcpy(buf, "not hungry");
|
||||
}
|
||||
break;
|
||||
case H_PECKISH:
|
||||
if (lf && (lf->race->id == R_VAMPIRE)) {
|
||||
strcpy(buf, "parched");
|
||||
} else {
|
||||
strcpy(buf, "peckish");
|
||||
}
|
||||
break;
|
||||
case H_HUNGRY:
|
||||
if (lf && (lf->race->id == R_VAMPIRE)) {
|
||||
strcpy(buf, "thirsty");
|
||||
} else {
|
||||
strcpy(buf, "hungry");
|
||||
}
|
||||
break;
|
||||
case H_VHUNGRY:
|
||||
if (lf && (lf->race->id == R_VAMPIRE)) {
|
||||
strcpy(buf, "very thirsty");
|
||||
} else {
|
||||
strcpy(buf, "very hungry");
|
||||
}
|
||||
break;
|
||||
case H_STARVING:
|
||||
if (lf && (lf->race->id == R_VAMPIRE)) {
|
||||
strcpy(buf, "dehydrating");
|
||||
} else {
|
||||
strcpy(buf, "starving");
|
||||
}
|
||||
break;
|
||||
case H_STARVED:
|
||||
strcpy(buf, "starved");
|
||||
|
@ -6262,16 +6337,14 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
|
|||
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL);
|
||||
if (f) {
|
||||
// monk fists do more damage
|
||||
free(f->text);
|
||||
f->text = strdup("1d4");
|
||||
changeflagtext(f, "1d4");
|
||||
}
|
||||
} else if (j->id == J_PIRATE) {
|
||||
flag_t *f;
|
||||
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL);
|
||||
if (f) {
|
||||
f->val[0] = OT_HOOKHAND;
|
||||
free(f->text);
|
||||
f->text = strdup("1d4");
|
||||
changeflagtext(f, "1d4");
|
||||
}
|
||||
} else if (j->id == J_SHOPKEEPER) {
|
||||
// shopkeepers are not hostile.
|
||||
|
@ -8330,7 +8403,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roars");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roar");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "roars^a roar");
|
||||
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_HEAVYBLOW, 2, 2, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
|
@ -9510,6 +9584,28 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
|
||||
addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 76, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, 84, NA, "");
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, "");
|
||||
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 2, 4, NA, "");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3");
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_VAMPIRIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
|
||||
addrace(R_BEAR, "black bear", 150, 'q', C_BLUE, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, NULL);
|
||||
|
@ -9679,6 +9775,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 60, NA, NA, "");
|
||||
addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL);
|
||||
|
@ -9703,6 +9801,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, NULL); // don't announce spellcasting
|
||||
addflag(lastrace->flags, F_CANWILL, OT_S_BLINK, 2, 2, "pw:1;");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 2, 6, NA, "");
|
||||
|
@ -9727,6 +9827,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "howls^a howl");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 24, "10-15");
|
||||
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL);
|
||||
|
@ -9751,6 +9853,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 2, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
|
||||
addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian
|
||||
|
@ -10184,6 +10288,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, 8, 8, NULL);
|
||||
addflag(lastrace->flags, F_LEVRACE, 5, R_WOLF, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 75, NA, NA, "");
|
||||
addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
|
||||
|
@ -10208,6 +10313,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, 5, 5, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
|
||||
|
||||
// insects
|
||||
|
@ -10460,21 +10566,33 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_VAMPIRIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "3d6");
|
||||
addflag(lastrace->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 8, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AVOIDOBTYPE, OT_GARLIC, B_TRUE, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_FAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 8, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "coffin");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+3");
|
||||
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_S_CHARM, 3, 3, "pw:6;");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, 5, 5, "range:3;");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_S_STUN, 5, 5, "pw:1;");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_S_POLYMORPH, 3, 3, "pw:1;");
|
||||
addflag(lastrace->flags, F_FORCEPOLY, R_BATVAMPIRE, 20, 20, "pw:3;");
|
||||
addflag(lastrace->flags, F_DETECTOBS, 10, OT_COFFIN, NA, NULL);
|
||||
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pile of ash");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "hisses angrily^an angry hiss");
|
||||
|
||||
// special: change to gas cloud with 1 hp on death, if not asleep
|
||||
// special: flee from garlic
|
||||
// TODO: can shapeshift to bat
|
||||
// TODO: flee from holy symbols / garlic
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
|
@ -12569,6 +12687,10 @@ void modhunger(lifeform_t *lf, int amt) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isundead(lf) && (lf->race->id != R_VAMPIRE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// modify for effects
|
||||
if (amt > 0) {
|
||||
int multiplier = 0;
|
||||
|
@ -12622,7 +12744,7 @@ void modhunger(lifeform_t *lf, int amt) {
|
|||
|
||||
|
||||
if (isplayer(lf)) {
|
||||
gethungername(posthlev, buf);
|
||||
gethungername(lf, posthlev, buf);
|
||||
msg("^wYou are %s%s%s%c",
|
||||
((amt < 0) && (posthlev > H_NONE)) ? "still " : "",
|
||||
needfeeling ? "feeling " : "",
|
||||
|
@ -12633,7 +12755,7 @@ void modhunger(lifeform_t *lf, int amt) {
|
|||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
gethungername(posthlev, buf);
|
||||
gethungername(lf, posthlev, buf);
|
||||
msg("^%c%s looks %s%c", getlfcol(lf, CC_BAD), lfname, buf, (needexclam) ? '!' : '.');
|
||||
}
|
||||
|
||||
|
@ -13792,6 +13914,7 @@ void setguntarget(lifeform_t *lf, lifeform_t *targ) {
|
|||
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
||||
flag_t *f,*nextf;
|
||||
int i;
|
||||
int nkilled = 0;
|
||||
race_t *newrace;
|
||||
char buf[BUFLEN];
|
||||
|
||||
|
@ -13862,8 +13985,10 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
nextf = f->next;
|
||||
if (f->lifetime == FROMRACE) {
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
} else if ((f->lifetime > 0) && (f->id != F_POLYMORPHED)) {
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14475,7 +14600,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
}
|
||||
break;
|
||||
case SC_RESISTMAG:
|
||||
attrib = (getattr(lf, A_CON)/4) + (getattr(lf, A_WIS)/4) + getmr(lf);
|
||||
attrib = (getattr(lf, A_CON)/6) + (getattr(lf, A_WIS)/4) + getmr(lf);
|
||||
break;
|
||||
case SC_SEARCH:
|
||||
attrib = (getskill(lf, SK_SPOTHIDDEN)*4);
|
||||
|
@ -15045,6 +15170,7 @@ int takeoff(lifeform_t *lf, object_t *o) {
|
|||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You take off %s.", obname);
|
||||
statdirty = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
capitalise(buf);
|
||||
|
@ -15335,6 +15461,18 @@ void turneffectslf(lifeform_t *lf) {
|
|||
if (isdead(lf)) return;
|
||||
}
|
||||
}
|
||||
// vampire in sunlight?
|
||||
if ((lf->race->id == R_VAMPIRE) && isoutdoors(lf->cell->map) && !isnighttime()) {
|
||||
if (isplayer(lf)) {
|
||||
msg("^bThe sunlight burns you!");
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("^%cThe sunlight burns %s!", getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
losehp(lf, roll("6d6"), DT_DIRECT, NULL, "sunlight");
|
||||
if (isdead(lf)) return;
|
||||
}
|
||||
|
||||
// float up into space?
|
||||
if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
|
|
2
lf.h
2
lf.h
|
@ -120,7 +120,7 @@ int gethidemodifier(lifeform_t *lf);
|
|||
int gethitdice(lifeform_t *lf);
|
||||
int gethppct(lifeform_t *lf);
|
||||
enum HUNGER gethungerlevel(int hunger);
|
||||
char * gethungername(enum HUNGER hunger, char *buf);
|
||||
char *gethungername(lifeform_t *lf, enum HUNGER hunger, char *buf);
|
||||
int gethungerval(lifeform_t *lf);
|
||||
job_t *getjob(lifeform_t *lf);
|
||||
int getlastdir(lifeform_t *lf);
|
||||
|
|
34
map.c
34
map.c
|
@ -30,6 +30,9 @@ extern lifeform_t *player;
|
|||
extern lifeform_t *godlf[];
|
||||
extern int ngodlfs;
|
||||
|
||||
extern flag_t *retflag[];
|
||||
extern int nretflags;
|
||||
|
||||
extern glyph_t tempglyph;
|
||||
|
||||
extern enum OBCLASS sortorder[];
|
||||
|
@ -1247,7 +1250,7 @@ void calclight(map_t *map) {
|
|||
if (isoutdoors(map)) {
|
||||
int hours,mins,secs;
|
||||
splittime(&hours,&mins,&secs);
|
||||
if ((hours < 5) || (hours >= 19)) {
|
||||
if (isnighttime()) {
|
||||
// ie. nighttime, after 7pm or before 5am
|
||||
} else {
|
||||
// ie. daytime
|
||||
|
@ -3861,6 +3864,7 @@ int isempty(cell_t *c) {
|
|||
//returns TT_ based on what you can scan there
|
||||
int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
|
||||
flag_t *f;
|
||||
int i;
|
||||
// handle scanner
|
||||
f = lfhasflag(player, F_DETECTLIFE);
|
||||
if (f) {
|
||||
|
@ -3933,23 +3937,34 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
|
|||
return TT_MONSTER;
|
||||
}
|
||||
|
||||
f = lfhasflag(player, F_DETECTOBS);
|
||||
if (f) {
|
||||
// get list of all detected ob ids.
|
||||
getflags(player->flags, F_DETECTOBS, F_NONE);
|
||||
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (getcelldistorth(player->cell, c) <= f->val[0]) {
|
||||
object_t *o;
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if ((f->val[1] == NA) || (o->type->id == f->val[1])) {
|
||||
if (!hasflag(o->flags, F_NOPICKUP) && !hasflag(o->flags, F_DOOR)) {
|
||||
*thing = o;
|
||||
if (glyph) {
|
||||
glyph->ch = '*';
|
||||
glyph->colour = C_GREY;
|
||||
glyph->colour = C_BOLDGREEN;
|
||||
}
|
||||
if (desc) {
|
||||
if (f->val[1] == NA) {
|
||||
strcpy(desc, "a detected object");
|
||||
} else {
|
||||
getobname(o, desc, o->amt);
|
||||
}
|
||||
}
|
||||
if (desc) sprintf(desc, "an object");
|
||||
return TT_OBJECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -4000,6 +4015,15 @@ int isnewcellok(cell_t *cell, char *err) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
int isnighttime(void) {
|
||||
int hours,mins,secs;
|
||||
splittime(&hours,&mins,&secs);
|
||||
if ((hours < 5) || (hours >= 19)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isonmap(map_t *map, int x, int y) {
|
||||
if ((x < 0) || (y < 0)) {
|
||||
return B_FALSE;
|
||||
|
|
1
map.h
1
map.h
|
@ -97,6 +97,7 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph);
|
|||
int islit(cell_t *c);
|
||||
int isloopdirok(cell_t *cell, int dir);
|
||||
int isnewcellok(cell_t *cell, char *err);
|
||||
int isnighttime(void);
|
||||
int isonmap(map_t *map, int x, int y);
|
||||
int isoutdoors(map_t *m);
|
||||
int isroom(cell_t *c);
|
||||
|
|
39
move.c
39
move.c
|
@ -26,6 +26,9 @@ extern enum GAMEMODE gamemode;
|
|||
extern enum ERROR reason;
|
||||
extern void *rdata;
|
||||
|
||||
extern flag_t *retflag[];
|
||||
extern int nretflags;
|
||||
|
||||
extern WINDOW *gamewin, *msgwin;
|
||||
|
||||
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||
|
@ -1946,7 +1949,22 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
|||
reason = E_OK;
|
||||
// avoid this object in future
|
||||
sprintf(buf, "%ld",o->id);
|
||||
addflag(lf->flags, F_AVOIDCURSEDOB, NA, NA, NA, buf);
|
||||
addflag(lf->flags, F_AVOIDOB, B_CURSED, NA, NA, buf);
|
||||
return B_TRUE;
|
||||
} else if (lfhasflagval(lf, F_AVOIDOBTYPE, o->type->id, NA, NA, NULL)) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf,lfname);
|
||||
getobname(o, buf, o->amt);
|
||||
msg("%s %s away from %s!", lfname, isplayer(lf) ? "shy" : "shies", buf);
|
||||
o->blessknown = B_TRUE;
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
}
|
||||
taketime(lf, getmovespeed(lf));
|
||||
reason = E_OK;
|
||||
// avoid this object in future
|
||||
sprintf(buf, "%ld",o->id);
|
||||
addflag(lf->flags, F_AVOIDOB, NA, NA, NA, buf);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -2317,8 +2335,12 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
msg("You swap places with %s.", lfname);
|
||||
}
|
||||
} else {
|
||||
// attack!
|
||||
if (!onpurpose || canandwillmove(lf, dir, &errcode)) {
|
||||
return attackcell(lf, cell, B_FALSE);
|
||||
} else {
|
||||
// won't attack for some reason.
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case E_CANTMOVE:
|
||||
|
@ -2540,6 +2562,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
|
||||
// don't attack other monsters
|
||||
if (cell->lf) { // if someone is in the way
|
||||
object_t *defenderwep = NULL;
|
||||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
if (hasactivespell(cell->lf, OT_S_REPELINSECTS)) {
|
||||
if (error) *error = E_WONT;
|
||||
|
@ -2547,6 +2570,14 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
}
|
||||
|
||||
defenderwep = getweapon(cell->lf);
|
||||
if (defenderwep) {
|
||||
if (lfhasflagval(lf, F_AVOIDOBTYPE, defenderwep->type->id, B_TRUE, NA, NULL)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isplayer(lf)) { // if we are a monster
|
||||
// if the person in the way isn't our enemy...
|
||||
if (!areenemies(lf, cell->lf)) {
|
||||
|
@ -2573,10 +2604,10 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
flag_t *f;
|
||||
sprintf(buf, "%ld",o->id);
|
||||
f = lfhasflagval(lf, F_AVOIDCURSEDOB, NA, NA, NA, buf);
|
||||
f = lfhasflagval(lf, F_AVOIDOB, NA, NA, NA, buf);
|
||||
if (f) {
|
||||
// still cursed?
|
||||
if (iscursed(o)) {
|
||||
if ((f->val[0] != NA) && (o->blessed == f->val[0])) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
} else {
|
||||
|
|
15
objects.c
15
objects.c
|
@ -2675,6 +2675,7 @@ objecttype_t *findotn(char *name) {
|
|||
modname = strrep(modname, "blocks ", "block ", NULL);
|
||||
modname = strrep(modname, "cans ", "can ", NULL);
|
||||
modname = strrep(modname, "chunks ", "chunk ", NULL);
|
||||
modname = strrep(modname, "cloves ", "clove ", NULL);
|
||||
modname = strrep(modname, "flasks ", "flask ", NULL);
|
||||
modname = strrep(modname, "gems ", "gem ", NULL);
|
||||
modname = strrep(modname, "leaves ", "leaf ", NULL);
|
||||
|
@ -6236,6 +6237,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, "");
|
||||
addot(OT_GARLIC, "clove of garlic", "A very pungent clove of raw garlic. ", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
||||
addot(OT_NUT, "peanut", "A species in the legume family.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 12, NA, "");
|
||||
|
@ -7088,6 +7095,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 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_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_LOWERMETAB, "lower metabolism", "Slow your body's functions, decreasing your rate of hunger but also your speed. At power level V your speed is no longer affected.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
|
@ -7199,6 +7207,8 @@ void initobjects(void) {
|
|||
addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.\nBecomes semi-controlled at Power V, and fully-controlled at power VIII.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, 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_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);
|
||||
|
@ -7390,6 +7400,7 @@ void initobjects(void) {
|
|||
addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL);
|
||||
addot(OT_A_QUIVERINGPALM, "quivering palm", "A deadly palm strike which knocks the molecules in the target's body out of alignment.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_PRAY, "pray", "Ask for help from a higher being.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
|
@ -9581,7 +9592,6 @@ int isbetterwepthan(object_t *a, object_t *b) {
|
|||
acca = getobaccuracy(a, a->pile->owner);
|
||||
accb = getobaccuracy(b, b->pile->owner);
|
||||
|
||||
|
||||
if (db) {
|
||||
msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
|
||||
}
|
||||
|
@ -12631,7 +12641,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
*seen = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (!isundead(lf)) {
|
||||
modhunger(lf, -pctof(0.05, (float)HUNGERCONST));
|
||||
}
|
||||
break;
|
||||
case OT_POT_BLOOD:
|
||||
if (lf->race->id == R_VAMPIRE) {
|
||||
|
@ -12643,6 +12655,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
b = B_BLESSED;
|
||||
}
|
||||
dospelleffects(lf, OT_S_HEALINGMAJ,b ? 5 : 1, lf, NULL, lf->cell, b, seen, B_TRUE);
|
||||
modhunger(lf, -HUNGERCONST);
|
||||
} else {
|
||||
if (isplayer(lf)) msg("Yuck, this tastes like blood!");
|
||||
}
|
||||
|
|
18
spell.c
18
spell.c
|
@ -1406,7 +1406,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char dirch;
|
||||
char targetname[BUFLEN];
|
||||
flag_t *f;
|
||||
int heavyamt = 8;
|
||||
int heavyamt = 5;
|
||||
int badweapon = B_FALSE;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
|
@ -2183,7 +2183,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// controlled
|
||||
// must be within line of sight.
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
if (!targcell) {
|
||||
if (!targcell || !cellwalkable(caster, targcell, NULL)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -4109,8 +4109,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
flag_t *f;
|
||||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
free(f->text);
|
||||
f->text = strdup(dambuf);
|
||||
changeflagtext(f, dambuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5819,6 +5818,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
breakallgrabs(caster);
|
||||
} else if (spellid == OT_S_POLYMORPH) {
|
||||
race_t *r = NULL;
|
||||
flag_t *f;
|
||||
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
|
@ -5828,7 +5828,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if ((target != caster) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily different.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -5840,6 +5840,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
f = lfhasflag(target, F_FORCEPOLY);
|
||||
if (f) {
|
||||
r = findrace(f->val[0]);
|
||||
} else {
|
||||
if (lfhasflag(caster, F_CONTROL)) {
|
||||
if (power < 5) {
|
||||
power = 5;
|
||||
|
@ -5880,6 +5884,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
}
|
||||
} // end if forcepoly
|
||||
|
||||
if (r == target->race) {
|
||||
fizzle(caster);
|
||||
|
@ -6984,9 +6989,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
f = hasflag(o->flags, F_DAM);
|
||||
if (f) {
|
||||
char buf[BUFLEN];
|
||||
free(f->text);
|
||||
sprintf(buf, "2d%d",power);
|
||||
f->text = strdup(buf);
|
||||
changeflagtext(f, buf);
|
||||
}
|
||||
} else {
|
||||
killob(o);
|
||||
|
|
2
text.c
2
text.c
|
@ -439,6 +439,8 @@ char *makeplural(char *text) {
|
|||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "chunk ", "chunks ", &rv);
|
||||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "clove ", "cloves ", &rv);
|
||||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "flask ", "flasks ", &rv);
|
||||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "gem ", "gems ", &rv);
|
||||
|
|
Loading…
Reference in New Issue