- [+] change real_getlfname():

- [+] take lifeform_t * for usevis instead of boolean
    - [+] add new option "useorigrace" for shapechangers
- [+] whips
    - [+] F_WHIP
    - [+] new skill: sk_whips
    - [+] basic trais:
        - [+] high accuracy
        - [+] lowish dam
        - [+] pierce/slash/bash damage
        - [+] some will let you cast 'snatch' and suck
        - [+] no crit chance
    - [+] examples:
        - [+] bull whip (lowest damage)
        - [+] flail (ie. chain whip ,change type from club to whip)
        - [+] heavy flail
        - [+] metal-tipped whip (flail with higher acc)
        - [+] barbed whip (causes piercing damage as well)
        - [+] io.c @@ should take extradam into account
        - [+] describbeob() should show F_EXTRADAM 
- [+] change morale values - this shoudl default to your TR, otherwise
      f_morale replaces it.
- [+] CRASH in doknowledgelist()
- [+] hecta bug: fixed!
    - [+] You bisect the kobold!  The dying kobold shouts "Nooooo!".
          Hecta's voice grates against your mind:
          "You allowed my sacrifice to escape!"
        - [+] is this because i'm calling "flee" after the lf takes
              fatal damage but before die() is called?
            - [+] NO, because flee() checks isdead(lf)
        - [+] it's happening when i kill a monster, and another one of
              the same type sees me!
        - [+] change:  only trigger this is the player has previously
              attacked the monster
- [+] replace fire titan with balrog
- [+] You bisect the giant gnat!  The dying giant gnat shouts "Nooooo!".
    - [+] fixed.
- [+] boggart -brown 'n'
    - [+] made of wood
    - [+] cause things to disappear
    - [+] cause milk to sour (low power blight)
    - [+] scared of salt
    - [+] demandgold 
- [+] briar thrash (spiky) - yellow 'T' (grab)
- [+] bingebark - red 'T'. wants edible, canwill snatch
- [+] leshy (human with leaves) - green 'h'
- [+] manticore - red 'm''
    - [+] lion, bat lings, man head, tail tipped with iron spikes
    - [+] carnivore
    - [+] human sized
    - [+] shoots 1-6 spikes. each spike does 1d6. too much!!
        - [+] change this to be 5d3 damage per volley.
            - [+] ie missiledam 4d3
        - [+] can do this once every 50 turns.
    - [+] can fly
    - [+] claws - 1d3 1d3
    - [+] want gold (non covet)
This commit is contained in:
Rob Pearce 2012-03-28 20:17:47 +00:00
parent eb859a4889
commit 984999d912
20 changed files with 1128 additions and 542 deletions

17
ai.c
View File

@ -108,7 +108,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
if (areallies(player, lf) && cantalk(lf)) {
char text[BUFLEN];
if (cansee(lf, victim)) {
real_getlfname(victim, text, B_FALSE, B_FALSE);
real_getlfname(victim, text, NULL, B_NOSHOWALL, B_CURRACE);
} else {
strcpy(text, "something");
}
@ -777,7 +777,7 @@ int ai_attack_existing_target(lifeform_t *lf) {
loseaitargets(lf);
if (areallies(lf, player) && cantalk(lf)) {
char text[BUFLEN];
real_getlfname(target, text, B_FALSE, B_FALSE);
real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE);
sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text);
}
} else {
@ -2036,7 +2036,7 @@ void aiturn(lifeform_t *lf) {
if (db) {
char lfname[BUFLEN];
real_getlfname(lf, lfname, B_FALSE, B_TRUE);
real_getlfname(lf, lfname, NULL, B_SHOWALL, B_CURRACE);
dblog("AIMOVE: %s, facing %s", lfname, getdirnameshort(lf->facing));
}
@ -2586,6 +2586,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_S_SMITEEVIL) && (getalignment(victim) != AL_EVIL)) {
specificcheckok = B_FALSE;
}
if (ot->id == OT_S_SPIKEVOLLEY) {
if ((lf->race->id == R_MANTICORE) && lfhasflagval(lf, F_INJURY, IJ_TAILBROKEN, NA, NA, NULL)) {
specificcheckok = B_FALSE;
}
}
if (ot->id == OT_A_SPRINT) {
if (lfhasflag(lf, F_SPRINTING) || !getstamina(lf) || (getstamina(lf) <= (getmaxstamina(lf)/2))) {
specificcheckok = B_FALSE;
@ -2923,6 +2928,12 @@ int lookforobs(lifeform_t *lf) {
return B_TRUE;
}
}
if (cancast(lf, OT_A_SNATCH, NULL) && haslof(lf->cell, c, LOF_NEED, NULL)) {
if (!useability(lf, OT_A_SNATCH, NULL, c)) {
// successful
return B_TRUE;
}
}
// start walking towards target cell
if (aigoto(lf, c, MR_OB, o, aigetchasetime(lf))) {
return B_FALSE;

View File

@ -941,8 +941,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// determine extra damage for flaming etc.
// getextradam from USER too
if (!willheal) {
getextradamwep(wep, &dam[0], &damtype[0], &ndam);
getextradamlf(lf, &dam[0], &damtype[0], &ndam);
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
}
} else {
@ -1144,7 +1144,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} else {
// actually deal the melee damage!
char attackername2[BUFLEN];
real_getlfname(lf, attackername2, B_FALSE, B_TRUE);
real_getlfname(lf, attackername2, NULL, B_SHOWALL, B_REALRACE);
if (lf->race->raceclass->id == RC_GOD) {
flag_t *gf;
gf = lfhasflag(lf, F_GODOF);
@ -1512,13 +1512,12 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
// don't need to check for blessed vs mosnters
// determine extra damage
getextradamwep(wep, &dam[0], &damtype[0], &ndam);
getextradamlf(lf, &dam[0], &damtype[0], &ndam);
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
for (i = 0; i < ndam; i++) {
// announce the hit
construct_hit_string(lf, NULL, attackername, obname, NULL, wep, damtype[i], dam[i], maxhp, i, B_FALSE, B_FALSE, B_FALSE, isunarmed, buf);
if (strlen(buf)) {
@ -1661,8 +1660,8 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
// don't need to check for blessed vs mosnters
// determine extra damage
getextradamwep(wep, &dam[0], &damtype[0], &ndam);
getextradamlf(lf, &dam[0], &damtype[0], &ndam);
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
for (i = 0; i < ndam; i++) {
@ -2061,7 +2060,7 @@ enum DAMTYPE getdamtype(object_t *wep) {
return dt;
}
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) {
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax) {
flag_t *f;
int i;
flag_t *retflag[MAXCANDIDATES];
@ -2085,13 +2084,13 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) {
// addition to the first one
damwhere = dam;
damtypewhere = damtype;
*(damwhere) += roll(f->text); // addition
*(damwhere) += real_roll(f->text, wantmax); // addition
} else {
// add a new damtype
damwhere = (dam + *ndam);
damtypewhere = (damtype + *ndam);
doinc = B_TRUE;
*(damwhere) = roll(f->text); // set
*(damwhere) = real_roll(f->text, wantmax); // set
*(damtypewhere) = f->val[0];
}
@ -2116,7 +2115,7 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam) {
return *dam;
}
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax) {
flag_t *f;
int i;
flag_t *retflag[MAXCANDIDATES];
@ -2134,36 +2133,61 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
f = hasflag(wep->flags, F_ENCHANTED);
if (f) {
if (strlen(f->text)) {
*(dam + *ndam) = roll(f->text);
*(dam + *ndam) = real_roll(f->text, wantmax);
} else {
*(dam + *ndam) = roll("1d2"); // default: 1d2 extra damage
*(dam + *ndam) = real_roll("1d2", wantmax); // default: 1d2 extra damage
}
*(damtype + *ndam) = DT_MAGIC;
(*ndam)++;
}
}
getflags(wep->flags, retflag, &nretflags, F_FROZEN, F_ONFIRE, F_NONE);
getflags(wep->flags, retflag, &nretflags, F_EXTRADAM, F_FROZEN, F_ONFIRE, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_EXTRADAM) {
int *damwhere;
int *damtypewhere;
int doinc = B_FALSE;
if ((f->val[0] == NA) || (f->val[0] == *damtype)) {
// addition to the first one
damwhere = dam;
damtypewhere = damtype;
*(damwhere) += real_roll(f->text, wantmax); // addition
} else {
// add a new damtype
damwhere = (dam + *ndam);
damtypewhere = (damtype + *ndam);
doinc = B_TRUE;
*(damwhere) = real_roll(f->text, wantmax); // set
*(damtypewhere) = f->val[0];
}
if (doinc) {
(*ndam)++;
}
}
if (f->id == F_ONFIRE) {
if (strlen(f->text)) {
*(dam + *ndam) = roll(f->text);
*(dam + *ndam) = real_roll(f->text, wantmax);
} else {
*(dam + *ndam) = rolldie(1,4);
*(dam + *ndam) = real_roll("1d4", wantmax);
}
*(damtype + *ndam) = DT_FIRE;
(*ndam)++;
} else if (f->id == F_HOT) {
if (strlen(f->text)) {
*(dam + *ndam) = roll(f->text);
*(dam + *ndam) = real_roll(f->text, wantmax);
} else {
*(dam + *ndam) = rolldie(1,2);
*(dam + *ndam) = real_roll("1d2", wantmax);
}
*(damtype + *ndam) = DT_HEAT;
(*ndam)++;
} else if (f->id == F_FROZEN) {
*(dam + *ndam) = rolldie(1,4);
*(dam + *ndam) = real_roll("1d4", wantmax);
*(damtype + *ndam) = DT_COLD;
(*ndam)++;
}
@ -2543,7 +2567,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
msg("^wA pulse of lethal power blasts %s!", vname);
f->known = B_KNOWN;
}
real_getlfname(owner, ownername, B_FALSE, B_TRUE);
real_getlfname(owner, ownername, NULL, B_SHOWALL, B_REALRACE);
getobname(wep, wepname, 1);
snprintf(damstring, BUFLEN, "%s%s %s",ownername, getpossessive(ownername), wepname);
losehp(victim, dam*3, DT_DIRECT, owner, damstring);
@ -2570,7 +2594,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
char damstring[BUFLEN];
char victimname[BUFLEN];
getlfname(owner, buf);
real_getlfname(owner, buf2, B_FALSE, B_FALSE);
real_getlfname(owner, buf2, NULL, B_SHOWALL, B_REALRACE);
getlfname(victim, victimname);
getobname(wep, obname, 1);

View File

@ -16,8 +16,8 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
void getarrange(int arating, int *min, int *max);
//object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
enum DAMTYPE getdamtype(object_t *wep);
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam);
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam);
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax);
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax);
void getdamrange(object_t *o, flag_t *f, int *min, int *max);
//void getdamrange(object_t *o, int *min, int *max);
//void getdamrangeunarmed(flag_t *f, int *min, int *max);

556
data.c

File diff suppressed because it is too large Load Diff

Binary file not shown.

42
defs.h
View File

@ -173,6 +173,10 @@
#define B_SHOWALL (-1)
#define B_NOSHOWALL (0)
// for real_getlfname
#define B_REALRACE (-1)
#define B_CURRACE (0)
// Limits
@ -620,6 +624,7 @@ enum SKILL {
SK_SHORTBLADES,
SK_STAVES,
SK_UNARMED,
SK_WHIPS,
// spell schools
SK_SS_ALLOMANCY,
SK_SS_MENTAL,
@ -635,7 +640,7 @@ enum SKILL {
SK_SS_TRANSLOCATION,
SK_SS_WILD,
};
#define MAXSKILLS 52
#define MAXSKILLS 53
// proficiency levels
enum SKILLLEVEL {
@ -993,6 +998,7 @@ enum RACE {
R_GODMAGIC, // lumara
// monsters
R_BEHOLDER,
R_BOGGART,
R_BUGBEAR,
R_CENTAUR,
R_COCKATRICE,
@ -1006,7 +1012,6 @@ enum RACE {
R_GIANTHILL,
R_GIANTFIRE,
R_GIANTFIREFC,
R_GIANTFIRETITAN,
R_GNOLL,
R_GOBLIN,
R_GOBLINR,
@ -1022,9 +1027,11 @@ enum RACE {
R_HOBGOBLINWAR,
R_KOBOLD,
R_LEPRECHAUN,
R_LESHY,
R_LAVAX,
R_LIZARDMAN,
R_MALIK,
R_MANTICORE,
R_MINOTAUR,
R_NAIAD,
R_NIXIE,
@ -1082,6 +1089,8 @@ enum RACE {
R_EELELEC,
R_EELGIANT,
// plants
R_BINGEBARK,
R_BRIARTHRASH,
R_CACTUS,
R_IVYRAPID,
R_FUNGUSDREAM,
@ -1169,6 +1178,7 @@ enum RACE {
R_STINKBUG,
R_STIRGE,
// demons
R_BALROG,
R_DRETCH,
R_GRIDDLER,
R_LURKINGHORROR,
@ -1712,6 +1722,7 @@ enum OBTYPE {
OT_S_FLASH,
OT_S_NULLIFY,
OT_S_REPLENISH,
OT_S_SPIKEVOLLEY,
// -- divine powers
OT_S_CREATEVAULT,
OT_S_GIFT,
@ -2048,6 +2059,7 @@ enum OBTYPE {
OT_TENTACLE,
OT_TRAMPLE,
OT_TONGUE,
OT_WHIPATTACK,
OT_ZAPPER,
// monster weapons
OT_ACIDATTACK,
@ -2072,6 +2084,7 @@ enum OBTYPE {
OT_BULLET,
OT_RUBBERBULLET,
OT_SHURIKEN,
OT_SPIKEVOLLEY,
// axes
OT_AXE,
OT_HANDAXE,
@ -2132,10 +2145,14 @@ enum OBTYPE {
OT_WIZARDSTAFF4,
OT_WIZARDSTAFF5,
OT_WIZARDSTAFF6,
// clubs
OT_CLUB,
// whips
OT_WHIPBARBED,
OT_WHIPBULL,
OT_WHIPMT,
OT_FLAIL,
OT_FLAILHEAVY,
// clubs
OT_CLUB,
OT_GREATCLUB,
OT_MACE,
OT_MORNINGSTAR,
@ -2656,6 +2673,7 @@ enum FLAG {
F_OBATTACKDELAY, // how long weapon takes to attack
F_USESSKILL, // weapon needs skill sk_v0
F_MAGICBOOST, // boost power of all spells by v0
F_WHIP, // this weapon is a whip - use different damtext.
F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied
// optional: v1 is chance of randomly having it
F_ATTREQ, // requires attrib v0 to be at least v1
@ -2680,7 +2698,8 @@ enum FLAG {
// (add this flag multiple times for each damtype,
// and remember to include the one listed in its
// F_DAM)
F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier)
F_MISSILEDAM, // text = dam if it hits (without speed multiplier)
F_MISSILEALWAYSDIES, // this object will always be destroyed when thrown
F_TANGLEMISSILE, // this object will trip anyone it is thrown at
// (if it hits), unless they pass a SC_SLIP
// check of difficulty v0
@ -3317,7 +3336,9 @@ enum FLAG {
F_DRUNK, // v0 is drunknness - 1-5.
F_ENHANCESEARCH, // gives v0 bonus on search checks.
F_ENHANCESMELL, // can 'see' scents with v0 range.
F_EXTRADAM, // do 'text' extra damage of damtype v0 when you hit
F_EXTRADAM, // FOR LIFEFORMS OR WEAPONS!
// this lf does 'text' extra damage of damtype v0
// when they hit
// if v1 is TRUE, also deal extra damage based on
// the flagpile's F_BONUS flag.
F_EXTRAINFO, // knows extra info
@ -3332,6 +3353,14 @@ enum FLAG {
// v0 is multiplier.
F_FASTMOVE, // modifier for move speed
F_FASTACTMOVE, // modifier for action and move speed
F_INCUBATING, // will become poisoned when v1 drops to 0.
// ie obfrom is being used as a timer.
// v0 = poison thpe
// v1 = invubation time left
// v2 = howlong
// obfrom = if you ate a corpse, this records its race
// otherwise, NA.
// text = power^fromwhat .eg'a bad egg'
F_POISONED, // has poisoning. v0 = poison type,
// v1 = power
// v2 = if you ate a corpse, this records its race
@ -3948,6 +3977,7 @@ typedef struct poisontype_s {
enum OBTYPE vomitob;
int dam;
int dampct;
int incubationtime;
enum POISONSEVERITY severity;
struct poisontype_s *next, *prev;
} poisontype_t;

68
god.c
View File

@ -222,7 +222,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
break;
case R_GODFIRE:
msg("\"Fire will burn away your sins!\"");
dospelleffects(NULL, OT_S_FLAMEPILLAR, 4, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_FLAMEPILLAR, 4, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
break;
case R_GODLIFE:
msg("\"Your body shall be slow to recover from wounds...\"");
@ -246,7 +246,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
break;
case R_GODNATURE:
msg("\"You have transgressed against nature!\"");
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
// note: you will also rot food on touch until god is appeased.
// see touch().
break;
@ -279,7 +279,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
} else {
// don't have any blessed objects.
msg("\"Perhaps you need some time without material wealth...\"");
dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, player->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, player->cell, B_UNCURSED, NULL, B_TRUE, NULL);
}
break;
case R_GODTHIEVES:
@ -317,7 +317,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
case 2: // bad armour
msg("\"A fool deserves a fool's armour!\"");
// remove all player's armour
dospelleffects(god, OT_S_INSTANTDISROBE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(god, OT_S_INSTANTDISROBE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
// give them cursed armour
o = addob(player->pack, "cursed -5 cotton shirt");
if (o) {
@ -361,7 +361,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
break;
case R_GODFIRE:
msg("\"Burn, infidel!\"");
dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
getradiuscells(player->cell, 1, DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, retcell, &nretcells, 0);
for (i = 0; i < nretcells; i++) {
if (!retcell[i]->type->solid) {
@ -435,13 +435,13 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
break;
case R_GODNATURE:
msg("\"You have violated the cardinal laws of nature!\"");
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
switch (rnd(1,3)) {
case 1:
dospelleffects(NULL, OT_S_CLOUDKILL, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_CLOUDKILL, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
break;
case 2:
dospelleffects(NULL, OT_S_HAILSTORM, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_HAILSTORM, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE, NULL);
break;
case 3:
msg("\"Destroy him, my pets!\"");
@ -622,7 +622,7 @@ void dooffer(void) {
addobsinradius(player->cell, 1, DT_COMPASS, splatterob, B_TRUE, NULL);
}
if (god->race->id == R_GODFIRE) {
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
}
} else {
nothinghappens();
@ -789,7 +789,7 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) {
lifeform_t *god;
char killedname[BUFLEN],godname[BUFLEN];
god = findgod(rid);
real_getlfname(god, godname, B_FALSE, B_FALSE);
real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE);
strcpy(killedname, "");
if (!where) {
// somewhere next to the player.
@ -1367,7 +1367,7 @@ void godsay(enum RACE rid, int says, char *format, ...) {
va_end(args);
god = findgod(rid);
real_getlfname(god, godname, B_FALSE, B_FALSE);
real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE);
switch (rid) {
case R_GODBATTLE:
@ -1608,7 +1608,7 @@ void pleasegod(enum RACE rid, int amt) {
lifeform_t *lf;
char lfname[BUFLEN];
lf = findgod(rid);
real_getlfname(lf, lfname, B_FALSE, B_FALSE);
real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_REALRACE);
modpiety(rid, amt);
@ -1798,11 +1798,11 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
break;
case 3: //
msg("\"I will guide your blade!\"");
dospelleffects(god, OT_S_TRUESTRIKE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_TRUESTRIKE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
break;
case 4: //
msg("\"Your blows will be as lightning!\"");
dospelleffects(god, OT_S_HASTE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_HASTE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
break;
} // end switch
}// end while redo
@ -1822,7 +1822,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
for (o = lf->pack->first ; o ; o = o->next) {
if (isequipped(o)) {
if (isdamaged(o) || (getobbonus(o, B_FALSE) < 0)) {
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE);
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE, NULL);
i++;
}
}
@ -1839,7 +1839,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
switch (rnd(1,2)) {
case 1: // detect life
msg("\"Seek out battle in my name!\"");
dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE, NULL);
break;
case 2: // bless weapon
msg("\"Fight in my name!\"");
@ -1859,7 +1859,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
msg("\"Witness the holy radiance of purity!\"");
c = getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND);
if (c) {
dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE);
dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE, NULL);
}
// uncurse ALL equipped obs
for (o = lf->pack->first ; o ; o = o->next) {
@ -1870,7 +1870,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
// cure poison
if (ispoisoned(lf)) {
dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
}
if (isinbattle(lf, B_TRUE)) {
@ -1922,7 +1922,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
// purify your food
if (!donesomething) {
if (!dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE)) {
if (!dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL)) {
donesomething = B_TRUE;
}
}
@ -1993,13 +1993,13 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
who->hp = 0;
} else {
//castspell(god, n, who, NULL, who->cell, NULL, NULL);
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL);
break;
}
}
}
}
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
break;
case R_GODFIRE:
// restore frozen weapons
@ -2016,7 +2016,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (c && cellhaslos(c, player->cell)) {
if (c->lf && (c->lf != player)) {
dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL,
c, B_BLESSED, NULL, B_TRUE);
c, B_BLESSED, NULL, B_TRUE, NULL);
} else if (countnoncosmeticobs(c->obpile, B_FALSE, B_FALSE)) {
addobfast(c->obpile, OT_FIRESMALL);
i++;
@ -2035,7 +2035,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
donesomething = B_TRUE;
}
if (gethungerlevel(gethungerval(player)) >= H_PECKISH) {
dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE;
}
if (lf->mp < (getmaxmp(lf)/2)) {
@ -2053,7 +2053,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
if (isinbattle(lf, B_TRUE)) {
if (plev >= PL_INDIFFERENT) {
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE;
}
}
@ -2065,7 +2065,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (!isblessed(o)) {
blessob(o);
} else if (!o->blessknown) {
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL);
}
}
}
@ -2081,7 +2081,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (islowhp(lf)) {
// teleport away
msg("\"Nothing like a quick getaway!\"");
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE;
} else {
int redo = B_TRUE;
@ -2120,7 +2120,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (!donesomething) {
// teleport away
msg("\"Nothing like a quick getaway!\"");
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
}
} else {
int redo = B_TRUE;
@ -2154,8 +2154,8 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
switch (rnd(1,2)) {
case 1:
msg("\"Allow me to reveal your surroundings...\"");
dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
break;
case 2: // identify objects
npossob = 0;
@ -2213,7 +2213,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (idnum) {
msg("\"One is granted the favour of knowledge!\"");
o = toid[rnd(0,idnum-1)];
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL);
} else if (uncursenum) {
msg("\"One is granted the favour of redemption!\"");
o = touncurse[rnd(0,uncursenum-1)];
@ -2303,7 +2303,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
// entangle your enemies
for (l = lf->cell->map->lf ; l ; l = l->next) {
if ((l != lf) && areenemies(l, lf) && cansee(l, player)) {
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE, NULL);
}
}
break;
@ -2315,7 +2315,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
msg("\"The powers of the sky will smite your foes!\"");
for (l = lf->cell->map->lf ; l ; l = l->next) {
if ((l != lf) && areenemies(l, lf) && cansee(l, player)) {
dospelleffects(god, OT_S_CALLLIGHTNING, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(god, OT_S_CALLLIGHTNING, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE, NULL);
}
}
break;
@ -2336,7 +2336,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
flag_t *f;
// fix any poison potions
dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
if (ispoisoned(lf)) {
msg("\"I will cure your poison...\"");
@ -2384,7 +2384,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
if (nposs) {
o = poss[rnd(0,nposs-1)];
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE);
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE;
}
}

69
io.c
View File

@ -1976,6 +1976,11 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
return B_FALSE;
}
// dont announce loss of flags yoh didnt know about
if (!f->known) {
return B_FALSE;
}
if (isdead(lf) || isdead(player)) return B_FALSE;
getlfname(lf, lfname);
@ -2261,6 +2266,15 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
case F_FRIENDLY:
msg("%s no longer looks quite so friendly!", lfname);
break;
case F_INCUBATING:
if (isplayer(lf)) {
poisontype_t *pt;
pt = findpoisontype(f->val[0]);
if (pt) {
msg("^%cYour body has fought off %s.", getlfcol(lf, CC_GOOD), pt->name);
}
}
break;
case F_POISONED:
msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks");
donesomething = B_TRUE;
@ -2764,7 +2778,7 @@ lifeform_t *askgod(char *prompttext, int onlyprayed) {
continue;
}
real_getlfname(lf, buf, B_FALSE, B_FALSE);
real_getlfname(lf, buf, NULL, B_NOSHOWALL, B_REALRACE);
f = hasflag(lf->flags, F_GODOF);
snprintf(godof, BUFLEN, " (%s of %s)", (f->val[0] == B_FEMALE) ? "goddess" : "god", f->text);
strcat(buf, godof);
@ -3724,7 +3738,7 @@ void describegod(lifeform_t *god) {
assert(god);
f = hasflag(god->flags, F_GODOF);
real_getlfname(god, godname, B_FALSE, B_FALSE);
real_getlfname(god, godname, NULL, B_NOSHOWALL, B_REALRACE);
snprintf(goddesc, BUFLEN, "(%s of %s)", (f->val[0] == B_FEMALE) ? "goddess" : "god", f->text);
// title
@ -4759,7 +4773,7 @@ void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) {
if (showit) {
char lfname[BUFLEN];
real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE);
real_getlfnamea(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE);
msg("\"There is %s living nearby...\"", lfname); more();
ndone++;
}
@ -5023,8 +5037,8 @@ void doknowledgelist(void) {
if (k->known == B_KNOWN) {
mvwprintw(mainwin, y, 0, " %-25s (%s)",ot->name, k->hiddenname);
} else { // ie. tried
mvwprintw(mainwin, y, 0, " %-25s (%s%s","???", k->hiddenname, strlen(k->triedon) ? "," : ")");
if (strlen(k->triedon)) {
mvwprintw(mainwin, y, 0, " %-25s (%s%s","???", k->hiddenname, k->triedon ? "," : ")");
if (k->triedon) {
y++;
mvwprintw(mainwin, y, 0, " %-25s tried on %s)"," ", k->triedon);
}
@ -5192,7 +5206,7 @@ char *makedesc_god(lifeform_t *god, char *retbuf) {
int nretflags,i;
f = hasflag(god->flags, F_GODOF);
real_getlfname(god, godname, B_FALSE, B_FALSE);
real_getlfname(god, godname, NULL, B_SHOWALL, B_REALRACE);
strcpy(retbuf, "");
@ -5820,16 +5834,22 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf,"@It also inflicts %s extra burning damage.\n", strlen(f->text) ? f->text : "1-2");
strncat(retbuf, buf, HUGEBUFLEN);
}
f = hasflag(o->flags, F_FROZEN);
if (f) {
sprintf(buf,"@It also inflicts %s extra cold damage.\n", strlen(f->text) ? f->text : "1-4");
strncat(retbuf, buf, HUGEBUFLEN);
}
f = hasflag(o->flags, F_ENCHANTED);
if (f) {
sprintf(buf,"@It also inflicts %s extra magical damage if the user has spare mana.\n", strlen(f->text) ? f->text : "1-2");
strncat(retbuf, buf, HUGEBUFLEN);
}
getflags(o->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
for (i = 0 ; i < nretflags; i++) {
f = retflag[i];
sprintf(buf,"@It also inflicts %s extra %s damage.\n", f->text, getdamname(f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN);
}
f = hasflag(o->flags, F_FROZEN);
if (f) {
sprintf(buf,"@It also inflicts %s extra cold damage.\n", strlen(f->text) ? f->text : "1-4");
strncat(retbuf, buf, HUGEBUFLEN);
}
} else {
strncat(retbuf, buf, HUGEBUFLEN);
strncat(retbuf, "\n", HUGEBUFLEN);
@ -11396,10 +11416,14 @@ void showlfstats(lifeform_t *lf, int showall) {
int mindam,maxdam;
int bonus,speed;
int accnum;
int edam[100];
enum DAMTYPE edt[100];
int ndam = 0;
// weapon
if (showall) {
char buf2[BUFLEN];
int n;
// calculate damage
f = hasflag(w[i]->flags, F_BONUS);
if (f && f->known) {
@ -11418,6 +11442,16 @@ void showlfstats(lifeform_t *lf, int showall) {
applylfdammod(&mindam, lf, w[i]);
applylfdammod(&maxdam, lf, w[i]);
// include extra damage for flaming, f_extradam, etc.
edam[0] = maxdam; // doesn't matter what this is
edt[0] = DT_NONE; //
ndam = 1;
getextradamwep(w[i], edam, edt, &ndam, B_TRUE);
for (n = 1; n < ndam; n++) {
mindam += edam[n];
maxdam += edam[n];
}
if (mindam < 0) mindam = 0;
if (maxdam < 0) maxdam = 0;
@ -12918,8 +12952,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
snprintf(buf, BUFLEN, "%s %s sick with %s%s.", you(lf), is(lf),
pt->name,
knownfatal ? ", potentially fatally" : "");
pt->name, knownfatal ? ", potentially fatally" : "");
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
(getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) {
char buf2[BUFLEN];
@ -12929,6 +12962,14 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, buf);
y++;
}
if (f->known && (f->id == F_INCUBATING)) {
poisontype_t *pt;
pt = findpoisontype(f->val[0]);
snprintf(buf, BUFLEN, "%s %s incubating %s.", you(lf), is(lf), pt->name);
mvwprintw(mainwin, y, 0, buf);
y++;
}
}
f = lfhasflag(lf, F_MUTABLE);
@ -13141,7 +13182,7 @@ void showlfstats(lifeform_t *lf, int showall) {
blocked = godblocked(god->race->id);
real_getlfname(god, godname, B_FALSE, B_FALSE);
real_getlfname(god, godname, NULL, B_SHOWALL, B_REALRACE);
f = lfhasflag(god, F_GODOF);
strcat(godname, " (");
strcat(godname, f->text);

269
lf.c
View File

@ -197,14 +197,18 @@ void awardxpfor(lifeform_t *killed, float pct) {
void bleed(lifeform_t *lf, int splatter) {
flag_t *f;
char obname[BUFLEN];
flag_t *retflag[MAXCANDIDATES];
int nretflags;
if (lf->cell->type->solid) return;
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) return;
if (hasequippedobid(lf->pack, OT_AMU_BLOOD)) return;
f = lfhasflag(lf, F_BLOODOB);
if (f) {
getflags(lf->flags, retflag, &nretflags, F_BLOODOB, F_NONE);
if (nretflags) {
// pick a random one
f = retflag[rnd(0,nretflags-1)];
if (f->text) {
strcpy(obname, f->text);
} else {
@ -1580,7 +1584,7 @@ int cantalk(lifeform_t *lf) {
}
// if the lf can't explicitly talk, check its race
if (!lfhasflag(lf, F_CANTALK)) {
if (!racecantalk(lf->race->raceclass->id)) {
if (!racecantalk(lf->race->id)) {
return B_FALSE;
}
}
@ -1940,8 +1944,21 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
msg("You start casting %s.", sp->name);
}
} else { // instant cast
int obfromid = -1;
addflag(lf->flags, F_CASTINGSPELL, sid, NA, NA, NULL);
rv = dospelleffects(lf, sid, power, targlf, targob, targcell, spellblessed, seen, B_FALSE);
// override obfrom if required
if (willflag && (willflag->obfrom != -1)) {
obfromid = willflag->obfrom;
} else if (castflag && (castflag->obfrom != -1)) {
obfromid = castflag->obfrom;
}
if (obfromid != -1) {
fromob = findobbyid(lf->pack, obfromid);
}
rv = dospelleffects(lf, sid, power, targlf, targob, targcell, spellblessed, seen, B_FALSE, fromob);
f = lfhasflag(lf, F_CASTINGSPELL);
if (f) {
killflag(f);
@ -2596,6 +2613,10 @@ int demandbribe(lifeform_t *lf) {
object_t *gold, *mongold;
int satisfied = B_FALSE;
int i,heard;
char saybuf[BUFLEN];
flag_t *demflag;
demflag = lfhasflag(lf, F_DEMANDSBRIBE);
hd = gettr(lf);
gold = hasob(player->pack, OT_GOLD);
@ -2608,7 +2629,14 @@ int demandbribe(lifeform_t *lf) {
amtwanted = rnd(hd*25, hd*100);
getlfname(lf, lfname);
if (say(lf, "Hand over all your gold!", SV_TALK)) {
if (demflag && strlen(demflag->text)) {
strcpy(saybuf, demflag->text);
} else {
strcpy(saybuf, "Hand over all your gold!");
}
if (say(lf, saybuf, SV_TALK)) {
heard = B_TRUE;
} else {
heard = B_FALSE;
@ -2748,7 +2776,7 @@ void die(lifeform_t *lf) {
lf->hp = lf->maxhp;
statdirty = B_TRUE;
// teleport away!
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
return;
}
@ -2809,7 +2837,7 @@ void die(lifeform_t *lf) {
lf->hp = 1;
killflagsofid(lf->flags, F_DEAD);
// convert into a gas cloud!
dospelleffects(NULL, OT_S_GASEOUSFORM, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_GASEOUSFORM, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
// ai will now look for our coffin
if (thisisplayer) {
msg("^GYou feel the presence of a nearby coffin...");
@ -2928,7 +2956,7 @@ void die(lifeform_t *lf) {
killflagsofid(lf->flags, F_DEAD);
statdirty = B_TRUE;
// teleport somewhere different.
dospelleffects(god, OT_S_TELEPORT, 3, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE);
dospelleffects(god, OT_S_TELEPORT, 3, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE, NULL);
return;
}
break;
@ -3010,12 +3038,13 @@ void die(lifeform_t *lf) {
//angergodmaybe(R_GODMERCY, 1, GA_MURDER);
}
// minions drop morale, and might flee
// minions who see this one die drop morale, and might flee
getminions(lf, minion, &nminions);
for (i = 0; i < nminions; i++) {
if (cansee(minion[i], lf)) {
f = lfhasflag(minion[i], F_MORALE);
if (f) {
f->val[0] -= 10;
f->val[0] -= 2;
// might flee?
if (killer && (f->val[0] <= 0)) {
scare(minion[i], killer, PERMENANT, 10);
@ -3023,6 +3052,7 @@ void die(lifeform_t *lf) {
}
}
}
}
// determine where to drop objects
corpsecell = lf->cell;
@ -4201,12 +4231,12 @@ int eat(lifeform_t *lf, object_t *o) {
char dambuf[BUFLEN];
snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname));
if (hasflag(corpserace->flags, F_AVIAN)) {
checkdiff = 30;
checkdiff = 20;
ptid = P_FOODBAD;
timemin = 30;
timemax = 50;
} else {
checkdiff = 20;
checkdiff = 13;
if (onein(3)) {
ptid = P_FOOD;
} else {
@ -4383,11 +4413,11 @@ int eat(lifeform_t *lf, object_t *o) {
// special cases even if not fully eaten
if (hasflagval(o->flags, F_CORPSEOF, R_DOGBLINK, NA, NA, NULL)) {
// blink!
dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE, NULL);
stopeating = B_TRUE;
} else if (hasflagval(o->flags, F_CORPSEOF, R_BLASTBUG, NA, NA, NULL)) {
dospelleffects(lf, OT_S_DETONATE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_DETONATE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
stopeating = B_TRUE;
}
// you can gain F_MUTABLE even if you don't fully eat the corpse.
@ -4512,7 +4542,7 @@ void endlfturn(lifeform_t *lf) {
if (ispetof(lf, player)) {
if (!canhear(player, lf->cell, 4)) {
char realname[BUFLEN];
real_getlfname(lf, realname, B_FALSE, B_FALSE);
real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE);
warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname));
} else if (cantalk(lf)) {
sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL);
@ -5550,7 +5580,7 @@ int flee(lifeform_t *lf) {
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
real_getlfname(lf, lfname, B_FALSE, B_FALSE);
real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_CURRACE);
if (isdead(lf)) return B_FALSE;
@ -5582,8 +5612,11 @@ int flee(lifeform_t *lf) {
// player let something flee?
if (isplayer(thisone)) {
pleasegodmaybe(R_GODMERCY, 5);
if ((lf->lastdamlf == player->id) || cansee(player, lf)) {
// ie. only if the player
angergodmaybe(R_GODDEATH, 10, GA_MERCY);
}
}
killflag(f);
} else {
// if the flag is temporary, keep fleeing and wait for it to time out normally
@ -7633,7 +7666,8 @@ int getmorale(lifeform_t *lf) {
flag_t *f;
f = hasflag(lf->flags, F_MORALE);
if (f) return f->val[0];
return 0;
// defaults to threat level
return gettr(lf);
}
int getnextshortcut(lifeform_t *lf) {
@ -8408,29 +8442,35 @@ char *getpitverb(lifeform_t *lf, int dir, int onpurpose, int climb) {
}
char *getlfname(lifeform_t *lf, char *buf) {
return real_getlfname(lf, buf, B_TRUE, B_FALSE);
return real_getlfname(lf, buf, player, B_NOSHOWALL, B_CURRACE);
}
char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace) {
char descstring[BUFLEN];
char jobstring[BUFLEN];
char the[6];
char lname[BUFLEN];
race_t *lfrace;
race_t *lfrace = NULL;
flag_t *f;
enum LFSIZE size,racesize;
int dobehaviour = B_TRUE;
enum SKILLLEVEL lorelev;
if (gamemode == GM_GAMESTARTED) {
lorelev = getlorelevel(player, lf->race->raceclass->id);
} else {
lorelev = PR_MASTER;
if (usevis && (gamemode != GM_GAMESTARTED)) {
usevis = NULL;
}
if (ispolymorphed(lf) && useorigrace) {
f = lfhasflag(lf, F_ORIGRACE);
if (f) {
lfrace = findrace(f->val[0]);
}
}
if (!lfrace) {
if (lfhasflag(lf, F_LYCANTHROPE)) {
// lycanthropes appear as human unless you know better
if (lorelev >= PR_ADEPT) {
if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) {
lfrace = lf->race;
} else {
lfrace = findrace(R_HUMAN);
@ -8438,6 +8478,13 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
} else {
lfrace = lf->race;
}
}
if (gamemode == GM_GAMESTARTED) {
lorelev = getlorelevel(player, lfrace->raceclass->id);
} else {
lorelev = PR_MASTER;
}
// 'the' or 'your' ?
f = lfhasflag(lf, F_NAME);
@ -8466,9 +8513,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
// construct description string
strcpy(descstring, "");
// if you lorelev is high enough, you can tell when the race is larger or smaller than
// they should be.
if (lorelev >= PR_BEGINNER) {
// are they larger or smaller than they should be?
f = hasflag(lfrace->flags, F_SIZE);
if (f) {
racesize = f->val[0];
@ -8480,7 +8525,6 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
strcat(descstring, getsizetext(size));
strcat(descstring, " ");
}
}
// need a certain amount of race knowledge to recognise ai traits
if (lorelev < PR_SKILLED) {
@ -8519,7 +8563,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
snprintf(buf, BUFLEN, "you");
} else {
//if (isblind(player)) {
if (usevis && !cansee(player, lf) && !showall) {
if (usevis && !cansee(usevis, lf) && !showall) {
snprintf(buf, BUFLEN, "something");
} else {
if (lf->race->id == R_DANCINGWEAPON) {
@ -8559,31 +8603,43 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
}
char *getlfnamea(lifeform_t *lf, char *buf) {
return real_getlfnamea(lf, buf, B_TRUE, B_FALSE);
return real_getlfnamea(lf, buf, player, B_NOSHOWALL, B_CURRACE);
}
char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) {
race_t *lfrace;
char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t * usevis, int showall, int useorigrace) {
race_t *lfrace = NULL;
enum SKILLLEVEL lorelev;
flag_t *f;
if (gamemode == GM_GAMESTARTED) {
lorelev = getlorelevel(player, lf->race->raceclass->id);
} else {
lorelev = PR_MASTER;
if (usevis && (gamemode != GM_GAMESTARTED)) {
usevis = NULL;
}
switch (lf->race->id) {
case R_WERERAT:
case R_WEREWOLF:
if (lorelev >= PR_ADEPT) {
if (ispolymorphed(lf) && useorigrace) {
f = lfhasflag(lf, F_ORIGRACE);
if (f) {
lfrace = findrace(f->val[0]);
}
}
if (!lfrace) {
if (lfhasflag(lf, F_LYCANTHROPE)) {
// lycanthropes appear as human unless you know better
if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) {
lfrace = lf->race;
} else {
lfrace = findrace(R_HUMAN);
}
break;
default:
} else {
lfrace = lf->race;
break;
}
}
if (gamemode == GM_GAMESTARTED) {
lorelev = getlorelevel(player, lfrace->raceclass->id);
} else {
lorelev = PR_MASTER;
}
if (isplayer(lf)) {
@ -8592,7 +8648,7 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) {
char buf2[BUFLEN];
char the[6];
real_getlfname(lf, buf2, usevis, showall);
real_getlfname(lf, buf2, usevis, showall, useorigrace);
if (lfhasflag(lf, F_NAME) || lfhasflag(lf, F_UNIQUE)) {
strcpy(the, "");
@ -12729,7 +12785,7 @@ object_t *isstuck(lifeform_t *lf) {
}
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity) {
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime) {
poisontype_t *a;
// add to the end of the list
@ -12756,6 +12812,7 @@ poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *da
a->dam = dam;
a->dampct = dampct;
a->severity = severity;
a->incubationtime = incubationtime;
return a;
}
@ -14057,6 +14114,7 @@ int isweaponskill(enum SKILL skid) {
case SK_POLEARMS:
case SK_SHORTBLADES:
case SK_STAVES:
case SK_WHIPS:
//case SK_UNARMED:
return B_TRUE;
default:
@ -14367,11 +14425,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
int prelowhp = B_FALSE,ko = B_FALSE;
int murder = B_FALSE;
flag_t *f;
int predead = B_FALSE;
if (gamemode < GM_GAMESTARTED) return 0;
getlfname(lf, lfname);
if (isdead(lf)) {
predead = B_TRUE;
}
if (isplayer(lf)) {
statdirty = B_TRUE;
}
@ -14535,6 +14598,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
lf->hp -= amt;
}
if (!predead) {
// fill in lastdam...
lf->lastdamtype = damtype;
@ -14543,6 +14607,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} else {
lf->lastdamlf = -1;
}
}
// if they died
if (lf->hp <= 0) {
@ -14555,6 +14620,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp);
}
if (!predead) {
//////////////////////////////////////////
// Figure out death text for tombstone.
// eg. Killed by something
@ -14622,6 +14688,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
break;
}
}
}
// update screen
drawstatus();
@ -14695,17 +14762,17 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of purple spores!", lfname);
sprintf(buf2, "^wSomething releases a cloud of purple spores!");
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE);
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE, NULL);
} else if (lf->race->id == R_FUNGUSRAGE) {
char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of red spores!", lfname);
sprintf(buf2, "^wSomething releases a cloud of red spores!");
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE);
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE, NULL);
} else if ((lf->race->id == R_UNYON) && ((damtype == DT_SLASH) || (damtype == DT_PIERCE))) {
char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of fumes!", lfname);
sprintf(buf2, "^wSomething releases a cloud of fumes!");
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE);
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL);
}
@ -15558,7 +15625,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
char distbuf[BUFLEN],distbufbad[BUFLEN];
char dirbuf[BUFLEN];
real_getlfnamea(noisemaker, lfname, B_FALSE, B_FALSE);
real_getlfnamea(noisemaker, lfname, NULL, B_NOSHOWALL, B_CURRACE);
getdisttext(l->cell, c, distbuf, distbufbad, dirbuf);
slev = getskill(l, SK_LISTEN);
@ -15971,37 +16038,77 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
}
if (!found) {
addtempflag(lf->flags, F_POISONED, ptype, power, srcrace ? srcrace->id : NA, fromwhat, howlong);
// incubation period?
if (pt->incubationtime && isplayer(lf)) {
flag_t *ii;
int multiplier = 0;
int tempmult;
// modify incubation time based on metabolism
sumflags(lf->flags, F_FASTMETAB, &tempmult, NULL, NULL);
multiplier += tempmult;
sumflags(lf->flags, F_SLOWMETAB, &tempmult, NULL, NULL);
multiplier -= tempmult;
// also apply specific poison effect
switch (ptype) {
if (multiplier > 0) {
howlong /= multiplier;
} else if (multiplier < 0) {
howlong *= abs(multiplier);
}
ii = lfhasflagval(lf, F_INCUBATING, ptype, NA, NA, NULL);
if (ii) {
// will happen faster
ii->val[2] /= 2;
if (ii->val[2] < 1) ii->val[2] = 1;
if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) {
ii->known = B_TRUE;
msg("You feel %s coming on more quickly.", pt->name);
}
} else {
char ftext[BUFLEN];
sprintf(ftext, "%d^%s", power, fromwhat);
ii = addflag(lf->flags, F_INCUBATING, ptype, power, pt->incubationtime, ftext);
ii->obfrom = srcrace ? srcrace->id : NA;
if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) {
ii->known = B_TRUE;
msg("You feel %s coming on.", pt->name);
}
}
} else {
addtempflag(lf->flags, F_POISONED, ptype, power, srcrace ? srcrace->id : NA, fromwhat, howlong);
poisoneffects(lf, ptype, power);
}
}
}
int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power) {
flag_t *f;
switch (ptid) {
case P_FOOD:
case P_GAS:
case P_VENOM:
default:
break;
default: return B_TRUE;
case P_MIGRAINE:
f = addtempflag(lf->flags, F_DTVULN, DT_SONIC, NA, NA, NULL, FROMPOISON); f->obfrom = ptype;
f = addtempflag(lf->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL, FROMPOISON); f->obfrom = ptype;
f = addtempflag(lf->flags, F_DTVULN, DT_SONIC, NA, NA, NULL, FROMPOISON); f->obfrom = ptid;
f = addtempflag(lf->flags, F_DTVULN, DT_LIGHT, NA, NA, NULL, FROMPOISON); f->obfrom = ptid;
break;
case P_WEAKNESS:
f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*10), NA, NULL, FROMPOISON);
f->obfrom = ptype; // poison type
f->obfrom = ptid; // poison type
break;
case P_ROT:
f = addtempflag(lf->flags, F_ATTRMOD, A_CHA, -(power*10), NA, NULL, FROMPOISON);
f->obfrom = ptype;
f->obfrom = ptid;
f = addtempflag(lf->flags, F_ATTRMOD, A_STR, -(power*5), NA, NULL, FROMPOISON);
f->obfrom = ptype;
f->obfrom = ptid;
f = addtempflag(lf->flags, F_ATTRMOD, A_CON, -(power*10), NA, NULL, FROMPOISON);
f->obfrom = ptype;
f->obfrom = ptid;
f = addtempflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL, FROMPOISON);
f->obfrom = ptype;
f->obfrom = ptid;
break;
}
return B_FALSE;
}
}
int poisonthreatenslife(lifeform_t *lf, flag_t *f) {
float time,dam,totaldam;
@ -18080,7 +18187,7 @@ int getskillcheckchance(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) {
attrib = (getattr(lf, A_IQ) / 10) + lf->level;
break;
case SC_MORALE: // based on morale, level/hitdice and size.
attrib = getmorale(lf) + gettr(lf);
attrib = getmorale(lf);
attrib += getlfsize(lf);
break;
case SC_SLIP:
@ -18861,7 +18968,7 @@ void startlfturn(lifeform_t *lf) {
if (isplayer(lf)) {
if (f->val[0] >= 5) {
char buf[BUFLEN];
real_getlfnamea(retcell[i]->lf, buf, B_FALSE, B_FALSE);
real_getlfnamea(retcell[i]->lf, buf, NULL, B_NOSHOWALL, B_CURRACE);
warn("^WYour sixth sense warns you of %s %s you!", buf,
(reldir == RD_BACKWARDS) ? "behind" : "beside" );
} else if (f->val[0] >= 3) {
@ -19580,7 +19687,7 @@ void startlfturn(lifeform_t *lf) {
// effects for/on your own flags
getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY,
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INCUBATING, F_INJURY,
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
@ -19649,6 +19756,25 @@ void startlfturn(lifeform_t *lf) {
}
}
if (f->id == F_INCUBATING) {
f->val[1]--;
if (f->val[1] <= 0) {
// parse text to get power & whatfrom
char *p;
char buf[BUFLEN];
int power;
enum POISONTYPE ptype;
ptype = f->val[0];
p = readuntil(buf, f->text, '^');
power = atoi(buf);
readuntil(buf, p, '^');
addtempflag(lf->flags, F_POISONED, ptype, power, f->obfrom, buf, f->val[2]);
poisoneffects(lf, ptype, power);
killflag(f);
continue;
}
}
// bleeding injuries can stain armour
if ((f->id == F_INJURY) && (f->val[2] == DT_SLASH)) {
object_t *arm;
@ -20337,7 +20463,7 @@ void timeeffectslf(lifeform_t *lf) {
if (amu) {
if (!polymorphto(lf, R_AVIAD, 5)) {
makeknown(amu->type->id);
dospelleffects(lf, OT_S_FLIGHT, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(lf, OT_S_FLIGHT, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
willfall = B_FALSE;
}
}
@ -20543,7 +20669,7 @@ int touch(lifeform_t *lf, object_t *o) {
// not wearing gloves?
if (!getequippedob(lf->pack, BP_HANDS)) {
// default power of 4
dospelleffects(lf, OT_S_FREEZEOB, 4, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
dospelleffects(lf, OT_S_FREEZEOB, 4, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE, NULL);
// we use val[0] here rather than timeleft, because we don't
// want to decrement it each turn.
@ -21038,7 +21164,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
for (n = 0; n < nadjallies; n++) {
if (seen[n]) {
char lname[BUFLEN];
real_getlfname(adjally[n], lname, B_FALSE, B_FALSE);
real_getlfname(adjally[n], lname, NULL, B_NOSHOWALL, B_CURRACE);
msg("%s follows you.", lname);
}
}
@ -22641,5 +22767,8 @@ int willeatlf(lifeform_t *eater, lifeform_t *eatee) {
if ((eatee->material->id == MT_PLANT) && lfhasflag(eater, F_VEGETARIAN)) {
return B_TRUE;
}
if (eater->race->id == R_BINGEBARK) {
return B_TRUE;
}
return B_FALSE;
}

7
lf.h
View File

@ -3,7 +3,7 @@
void addbodypart(race_t *r, enum BODYPART bp, char *name);
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity);
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime);
job_t *addjob(enum JOB id, char *name, char *desc);
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc);
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
@ -217,9 +217,9 @@ char *getmoveverbother(lifeform_t *lf);
lifeform_t *getnearbypeaceful(lifeform_t *lf);
char *getpitverb(lifeform_t *lf, int dir, int onpurpose, int climb);
char *getlfname(lifeform_t *lf, char *buf);
char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall);
char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace);
char *getlfnamea(lifeform_t *lf, char *buf);
char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall);
char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall, int useorigrace);
enum LFSIZE getlfsize(lifeform_t *lf);
float getlfweight(lifeform_t *lf, int withobs);
object_t *getsecmeleeweapon(lifeform_t *lf);
@ -392,6 +392,7 @@ void outfitlf(lifeform_t *lf);
void petify(lifeform_t *lf, lifeform_t *owner);
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int antannounce);
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid);
int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power);
int poisoncausesvomit(enum POISONTYPE ptype);
int poisonthreatenslife(lifeform_t *lf, flag_t *f);
int polymorphto(lifeform_t *lf, enum RACE rid, int howlong);

5
map.c
View File

@ -7559,7 +7559,7 @@ int remove_deadends(map_t *m, int howmuch) {
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph) {
if (targettype == TT_MONSTER) {
if (desc) {
real_getlfnamea((lifeform_t *)what, desc, B_FALSE, B_FALSE);
real_getlfnamea((lifeform_t *)what, desc, NULL, B_NOSHOWALL, B_CURRACE);
strcat(desc, descappend);
}
if (glyph) {
@ -7593,7 +7593,8 @@ void setcellknown(cell_t *cell, int forcelev) {
o = hassecretdoor(cell->obpile);
if (o) {
celltype_t *ct;
ct = findcelltype(getcellsolid(cell));
//ct = findcelltype(getcellsolid(cell));
ct = findcelltype(getmapsolid(cell->map));
cell->knownglyph = ct->glyph;
} else {
cell->knownglyph = cell->type->glyph;

6
move.c
View File

@ -1596,7 +1596,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (preseenbyplayer && !cansee(player, lf) && !changedlev) {
if (isadjacent(lf->cell, precell)) { // ie don't say this if we teleported/jumped
if (areenemies(player, lf)) {
real_getlfnamea(lf, lfname, B_FALSE, B_FALSE);
real_getlfnamea(lf, lfname, NULL, B_NOSHOWALL, B_CURRACE);
msg("%s %ss out of view.", lfname, getmoveverb(lf));
}
}
@ -2755,7 +2755,7 @@ void triggertrap(lifeform_t *lf, object_t *o, object_t *trapob, cell_t *where) {
if ((plev >= PL_PLEASED) && pctchance(plev*33)) {
godsay(R_GODMERCY, B_TRUE, "We all make mistakes...");
// bamf away
dospelleffects(NULL, OT_S_BLINK, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(NULL, OT_S_BLINK, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
}
}
@ -3385,7 +3385,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
for (n = 0; n < nadjallies; n++) {
if (seen[n]) {
char lname[BUFLEN];
real_getlfname(adjally[n], lname, B_FALSE, B_FALSE);
real_getlfname(adjally[n], lname, NULL, B_NOSHOWALL, B_CURRACE);
msg("%s follows you.", lname);
}
}

12
nexus.c
View File

@ -797,7 +797,7 @@ void donextturn(map_t *map) {
targcell = getcellat(targmap, x, y);
}
taketime(who, getspellspeed(who));
dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE);
dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE, NULL);
killflagsofid(who->flags, F_CASTINGSPELL);
} else {
if (isplayer(who)) {
@ -1426,14 +1426,22 @@ int rnd(int min, int max) {
}
int roll(char *string) {
int real_roll(char *string, int wantmax) {
int ndice,nsides,bonus;
int roll;
texttodice(string, &ndice,&nsides,&bonus);
if (wantmax) {
roll = (ndice * nsides) + bonus;
} else {
roll = rolldie(ndice, nsides) + bonus;
}
return roll;
}
int roll(char *string) {
return real_roll(string, B_FALSE);
}
// get a random number
int rolldie(int ndice, int sides) {
int i;

View File

@ -33,6 +33,7 @@ int parseplayerfile(FILE *f, lifeform_t *lf);
int pctchance(int pct);
float pctof(float pct, float num);
int rnd(int min, int max);
int real_roll(char *string, int wantmax);
int roll(char *string);
int rolldie(int ndice, int sides);
int rollhitdice(lifeform_t *lf, int wantmax);

148
objects.c
View File

@ -1577,7 +1577,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
assert(addobfast(o->contents, oid));
}
}
} else if (o->type->id == OT_GRIMOIRE) {
} else if ((o->type->id == OT_GRIMOIRE) && (gamemode != GM_LOADING)) {
// 1 spell from each school
int i;
int nschools = -1;
@ -1758,11 +1758,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
regiontype_t *dstrt = NULL;
int srcdepth;
char buf[BUFLEN];
// fill in map destination.
if (!wantregionthing) {
regionthing_t *poss[MAXCANDIDATES];
int nposs = 0;
// fill in map destination.
if (!wantregionthing) {
getbranchlinks(poss, &nposs);
if (nposs) {
@ -1770,7 +1769,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
}
}
if (dolinks) {
assert(wantregionthing);
if (wantregionthing) {
// we now have the destination regionlink thing which the
// map will lead to.
@ -1784,6 +1783,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
addflag(o->flags, F_MAPTO, srcregion->id, srcdepth, wantregionthing->id, buf);
}
}
} else if (o->type->id == OT_STATUE) {
flag_t *f, *rf;
float ratio;
@ -2681,6 +2681,7 @@ int blessob(object_t *o) {
char obname[BUFLEN];
int rv = B_FALSE;
lifeform_t *owner;
flag_t *f;
if (hasflag(o->flags, F_NOBLESS)) return B_TRUE;
@ -2714,6 +2715,11 @@ int blessob(object_t *o) {
msg("%s is bathed in a divine glow!", obname);
seen = B_TRUE;
}
// remove negative "bonuses". ie. "-3 sword" becomes "sword".
f = hasflag(o->flags, F_BONUS);
if (f && (f->val[0] < 0)) {
killflag(f);
}
} else {
// game not started yet.
owner = o->pile->owner;
@ -3676,7 +3682,7 @@ glyph_t *getglyph(object_t *o) {
if (isdoor(o, &isopen)) {
if (issecretdoor(o)) {
return &(findcelltype(obloc->map->habitat->solidcelltype)->glyph);
return &(findcelltype(getmapsolid(obloc->map))->glyph);
} else {
if (isopen) {
g = '-';
@ -5125,7 +5131,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
}
if (who) {
char lfname[BUFLEN];
real_getlfnamea(who, lfname, B_FALSE, B_FALSE);
real_getlfnamea(who, lfname, NULL, B_NOSHOWALL, B_REALRACE);
snprintf(buf, BUFLEN, "a %s%s scent",adjective,r->name);
} else {
snprintf(buf, BUFLEN, "%s%s scent",adjective, r->name );
@ -5573,7 +5579,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
strcat(localbuf, "secret ");
} else if (where) {
celltype_t *ct;
ct = findcelltype(where->map->habitat->solidcelltype);
ct = findcelltype(getmapsolid(where->map));
// solid cell description
strcpy(pluralname, ct->name);
}
@ -6539,7 +6545,7 @@ int getthrowdam(object_t *o) {
// modify if it has a damage value
f = hasflag(o->flags, F_MISSILEDAM);
if (f) {
dam = f->val[0];
dam = roll(f->text);
} else {
// base damage is = kilograms/5.
// ie. 1 kg object does 0 damage
@ -9228,7 +9234,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
default:
break;
}
dospelleffects(lf, spelltocast, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, spelltocast, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
// special wands
} else if (o->type->id == OT_WAND_WONDER) {
int power;
@ -9252,67 +9258,67 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
}
break;
case 1: // summon monster
dospelleffects(lf, OT_S_CREATEMONSTER, rnd(1,4), NULL, NULL, NULL, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_CREATEMONSTER, rnd(1,4), NULL, NULL, NULL, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 2: // animate dead
dospelleffects(lf, OT_S_ANIMATEDEAD, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_ANIMATEDEAD, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 3: // blindness
dospelleffects(lf, OT_S_BLINDNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_BLINDNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 4: // levitate
dospelleffects(lf, OT_S_LEVITATION, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_LEVITATION, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 5: // dispersal
dospelleffects(lf, OT_S_DISPERSAL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_DISPERSAL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 6: // flash
dospelleffects(lf, OT_S_FLASH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_FLASH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 7: // light
dospelleffects(lf, OT_S_LIGHT, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_LIGHT, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 8: // heal
dospelleffects(lf, OT_S_HEALING, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_HEALING, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 9: // minor heal
dospelleffects(lf, OT_S_HEALINGMIN, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_HEALINGMIN, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 10: // invis
dospelleffects(lf, OT_S_INVISIBILITY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_INVISIBILITY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 11: // haste
dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 12: // pull
dospelleffects(lf, OT_S_SUCK, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_SUCK, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 13: // blast
dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 14: // slow
dospelleffects(lf, OT_S_SLOW, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_SLOW, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 15: // sleep
dospelleffects(lf, OT_S_SLEEP, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_SLEEP, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 16: // gas
dospelleffects(lf, OT_S_CLOUDKILL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_CLOUDKILL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 17: // dark
dospelleffects(lf, OT_S_DARKNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_DARKNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 18: // stone
dospelleffects(lf, OT_S_PETRIFY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_PETRIFY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 19: // fireball
dospelleffects(lf, OT_S_FIREBALL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_FIREBALL, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 20: // poly
dospelleffects(lf, OT_S_POLYMORPH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_POLYMORPH, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 21: // teleport
dospelleffects(lf, OT_S_TELEPORT, power, lf , NULL, lf->cell, B_UNCURSED, &willid, B_FALSE);
dospelleffects(lf, OT_S_TELEPORT, power, lf , NULL, lf->cell, B_UNCURSED, &willid, B_FALSE, NULL);
break;
case 22: // create banana peel
if (where->type->solid) {
@ -9345,7 +9351,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} else if (o->type->id == OT_BUTANETORCH) {
int seen = B_FALSE;
// if above half charges, big spray
dospelleffects(lf, OT_S_SPARK, 1, NULL, NULL, where, B_UNCURSED, &seen, B_FALSE);
dospelleffects(lf, OT_S_SPARK, 1, NULL, NULL, where, B_UNCURSED, &seen, B_FALSE, o);
// announce
if (!seen) {
noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL);
@ -9398,7 +9404,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
// revert polymorphs
if (lfhasflag(c->lf, F_ORIGRACE)) {
dospelleffects(NULL, OT_A_POLYREVERT, 1,
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE);
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE, NULL);
}
// fix injuries ("deformities")
killflagsofid(c->lf->flags, F_INJURY);
@ -9438,7 +9444,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (c->lf) {
// restore
dospelleffects(NULL, OT_S_RESTORATION, 1,
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE);
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE, NULL);
} else {
object_t *oo, *nextoo;
// revive corpses
@ -9446,7 +9452,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
nextoo = oo->next;
if (oo->type->id == OT_CORPSE) {
dospelleffects(NULL, OT_S_RESSURECTION, 1,
NULL, oo, c, B_BLESSED, NULL, B_TRUE);
NULL, oo, c, B_BLESSED, NULL, B_TRUE, NULL);
}
}
}
@ -9465,7 +9471,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
object_t *oo, *nextoo;
// they get an injury
dospelleffects(NULL, OT_S_FLAYFLESH, 1, c->lf, NULL, c, B_BLESSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_FLAYFLESH, 1, c->lf, NULL, c, B_BLESSED, NULL, B_TRUE, NULL);
// they attack themself.
attackcell(c->lf, c, B_TRUE);
@ -10456,7 +10462,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
}
break;
case OT_POT_CANINETRACKING:
dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_COFFEE:
if (isplayer(lf)) {
@ -10550,7 +10556,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
}
break;
case OT_POT_ETHEREALNESS:
dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_EXPERIENCE:
// gain xp!
@ -10592,29 +10598,29 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
pleasegodmaybe(R_GODBATTLE, 15);
break;
case OT_POT_GASEOUSFORM:
dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_GROWTH:
i = getlfsize(lf);
if (iscursed(o)) {
dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE);
dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL);
} else {
dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE);
dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL);
}
// revert in a little while...
addflag(lf->flags, F_SIZETIMER, i, rnd(10,20), NA, NULL);
break;
case OT_POT_HEALING:
dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_HEALINGMIN:
dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_HEALINGMAJ:
dospelleffects(lf, OT_S_HEALINGMAJ,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_HEALINGMAJ,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_INVIS:
dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_INVULN:
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
@ -10669,14 +10675,14 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
case OT_POT_POLYMORPH:
if (potblessed == B_BLESSED) {
// controlled polymorph - you can chnage back.
dospelleffects(NULL, OT_S_POLYMORPH, 5, lf, NULL, lf->cell, potblessed, NULL, B_TRUE);
dospelleffects(NULL, OT_S_POLYMORPH, 5, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL);
} else {
// random polymorph
dospelleffects(NULL, OT_S_POLYMORPH, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE);
dospelleffects(NULL, OT_S_POLYMORPH, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL);
}
break;
case OT_POT_RESTORATION:
dospelleffects(NULL, OT_S_RESTORATION, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE);
dospelleffects(NULL, OT_S_RESTORATION, 1, lf, NULL, lf->cell, potblessed, NULL, B_TRUE, NULL);
break;
case OT_POT_SANCTUARY:
// how long for?
@ -10711,16 +10717,16 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
}
break;
case OT_POT_SLEEP:
dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
if (seen) *seen = B_TRUE;
break;
case OT_POT_SPEED:
if (potblessed == B_BLESSED) {
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE, NULL);
} else if (potblessed == B_CURSED) {
dospelleffects(lf, OT_S_SLOW, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_SLOW, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
} else { // uncursed
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
}
if (seen) *seen = B_TRUE;
break;
@ -10779,7 +10785,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
} else if (potblessed == B_CURSED) {
b = B_BLESSED;
}
dospelleffects(lf, OT_S_HEALINGMAJ,b ? 5 : 1, lf, NULL, lf->cell, b, seen, B_TRUE);
dospelleffects(lf, OT_S_HEALINGMAJ,b ? 5 : 1, lf, NULL, lf->cell, b, seen, B_TRUE, NULL);
modhunger(lf, -HUNGERCONST);
} else {
if (isplayer(lf)) msg("Yuck, this tastes like blood!");
@ -11009,7 +11015,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
// identify evertthing!
for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (!isidentified(oo)) {
dospelleffects(lf, OT_S_IDENTIFY, 10, NULL, oo, NULL, o->blessed, &seen, B_FALSE);
dospelleffects(lf, OT_S_IDENTIFY, 10, NULL, oo, NULL, o->blessed, &seen, B_FALSE, NULL);
}
}
}
@ -11027,7 +11033,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
power = getobspellpower(o, lf);
for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (isdamaged(oo)) {
dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE);
dospelleffects(lf, OT_S_MENDING, power, NULL, oo, NULL, o->blessed, &seen, B_FALSE, NULL);
}
}
if (seen) {
@ -11297,7 +11303,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
// make a piece of armour invulnerable
for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (isequipped(oo) && !hasflag(o->flags, F_INVULNERABLE)) {
if (isequipped(oo) && !hasflag(oo->flags, F_INVULNERABLE)) {
poss[nposs++] = oo;
}
}
@ -11305,17 +11311,18 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (nposs) {
oo = poss[rnd(0,nposs-1)];
addflag(oo->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
killflagsofid(oo->flags, F_DAMAGABLE);
if (isplayer(lf)) {
char ooname[BUFLEN];
getobname(oo, ooname, oo->amt);
msg("Your %s become%s ultra-dense!", obname, (oo->amt == 1) ? "s" : "");
msg("Your %s become%s ultra-dense!", ooname, (oo->amt == 1) ? "s" : "");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
char ooname[BUFLEN];
getlfname(lf, lfname);
getobname(oo, ooname, oo->amt);
msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname),
obname, (oo->amt == 1) ? "s" : "");
ooname, (oo->amt == 1) ? "s" : "");
}
ndone++;
}
@ -11772,7 +11779,7 @@ void setobcreatedby(object_t *o, lifeform_t *lf) {
if (!lf) {
return;
}
real_getlfnamea(lf, lfname, B_FALSE, B_TRUE);
real_getlfnamea(lf, lfname, NULL, B_SHOWALL, B_REALRACE);
addflag(o->flags, F_CREATEDBY, lf->id, NA, NA, lfname);
}
@ -12496,7 +12503,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
if (thrower) {
getlfname(thrower, throwername);
real_getlfname(thrower, realthrowername, B_FALSE, B_FALSE);
real_getlfname(thrower, realthrowername, NULL, B_NOSHOWALL, B_CURRACE);
if (isplayer(thrower)) {
strcpy(throwernamea, throwername);
@ -12685,7 +12692,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
radius = o->amt * 2;
if (radius > 10) radius = 10;
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE);
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL);
} else if (o->type->id == OT_ASHSLEEP) {
int radius;
char buf[BUFLEN];
@ -12698,7 +12705,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
radius = o->amt * 2;
if (radius > 10) radius = 10;
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE);
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL);
} else if (o->type->id == OT_SALT) {
int dist;
dist = getcelldist(srcloc, where);
@ -13030,7 +13037,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
adjustdamforblessings(&throwdam, target, o->blessed);
//dam = (int)((float)throwdam * multiplier);
dam = throwdam + speed;
dam = throwdam + (speed/2);
// firearm adjustments
if (firearm) {
@ -13177,6 +13184,9 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
if (thrower && isplayer(thrower)) {
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
}
} else if (hasflag(newob->flags, F_MISSILEALWAYSDIES)) {
killob(newob);
newob = NULL;
} else {
// object only gets damaged if it hit someone/something
if (missiledam) {
@ -13969,7 +13979,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
if (oid == OT_TRAPWIND) {
// can't be dodged
dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPNEEDLEP) {
if (lf) {
@ -14009,7 +14019,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
}
addob(c->obpile, "stone");
} else if (oid == OT_TRAPTELEPORT) {
dospelleffects(NULL, OT_S_DISPERSAL, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_DISPERSAL, 10, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
} else if (oid == OT_TRAPPIT) {
cell_t *escapeto = NULL;
addob(c->obpile, "hole in the ground");
@ -14086,10 +14096,10 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
// announcement.
}
// can't be dodged
dospelleffects(NULL, OT_S_ENERGYBLAST, 1, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_ENERGYBLAST, 1, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPFIRE) {
dospelleffects(NULL, OT_S_FLAMEPILLAR, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_FLAMEPILLAR, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
if (lf && avoided) {
cell_t *escapeto = NULL;
escapeto = getrandomadjcell(c, WE_WALKABLE, B_NOEXPAND);
@ -14105,11 +14115,11 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPLIGHTNING) {
// can't be dodged
dospelleffects(NULL, OT_S_CHAINLIGHTNING, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_CHAINLIGHTNING, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPGAS) {
// can't be dodged
dospelleffects(NULL, OT_S_CLOUDKILL, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE);
dospelleffects(NULL, OT_S_CLOUDKILL, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL);
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPMINE) {
// can't be dodged

4
save.c
View File

@ -881,7 +881,7 @@ int savebones(map_t *m, room_t *r) {
} else {
// the lf will appear in the bones file
char lfname[BUFLEN];
real_getlfname(c->lf, lfname, B_FALSE, B_TRUE);
real_getlfname(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE);
fprintf(f, "at(%d,%d) lf:%s\n", relx,rely, lfname);
}
}
@ -1183,6 +1183,8 @@ int saveobtobones(object_t *o, FILE *f, int x, int y) {
if (o->material->id == MT_BLOOD) {
sprintf(obname, "a blood stain");
} else if (o->type->id == OT_GRIMOIRE) {
sprintf(obname, "grimoire");
} else {
getobnametrue(o, obname, o->amt);
}

View File

@ -408,7 +408,7 @@ enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char *
ch = getch();
if (possible && (ch == 'y')) {
givemoney(player, NULL, cost);
dospelleffects(lf, OT_S_DETECTAURA, 10, lf, NULL, NULL, B_BLESSED, NULL, B_FALSE);
dospelleffects(lf, OT_S_DETECTAURA, 10, lf, NULL, NULL, B_BLESSED, NULL, B_FALSE, NULL);
more();
}
return SR_BACK;

126
spell.c
View File

@ -59,10 +59,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
int power = 0,needgrab = B_FALSE, range = 0;
char damstr[BUFLEN],racestr[BUFLEN];
objecttype_t *ot;
object_t *fromob = NULL;
char fromobname[BUFLEN];
flag_t *f;
strcpy(fromobname, "");
if (user && cwflag && (cwflag->obfrom != -1)) {
fromob = findobbyid(user->pack, cwflag->obfrom);
if (fromob) {
real_getobname(fromob, fromobname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
}
}
getlfname(user, username);
real_getlfname(user,killername, B_FALSE, B_FALSE);
real_getlfname(user,killername, NULL, B_NOSHOWALL, B_REALRACE);
// defaults
strcpy(damstr,"");
@ -321,7 +331,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else {
if (slev >= PR_EXPERT) {
// overwrite name
real_getlfnamea(inway, thismovetext, B_FALSE, B_FALSE);
real_getlfnamea(inway, thismovetext, NULL, B_NOSHOWALL, B_CURRACE);
}
movetext[0] = strdup(thismovetext);
movetextcount[0] = 1;
@ -335,7 +345,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (getnoisedetails(lf, N_WALK, NULL, thismovetext, NULL, &vol)) continue;
if (slev >= PR_EXPERT) {
// overwrite name
real_getlfnamea(lf, thismovetext, B_FALSE, B_FALSE);
real_getlfnamea(lf, thismovetext, NULL, B_NOSHOWALL, B_CURRACE);
}
if (canhear(user, lf->cell, vol)) {
// already have this text?
@ -1742,8 +1752,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
}
if (targcell->obpile->first) {
if (isplayer(user)) {
// select object from cell...
o = askobject(targcell->obpile, "Snatch which object", NULL, NULL, '\0', AO_NONE);
} else {
object_t *oo;
for (oo = targcell->obpile->first; oo ; oo = oo->next) {
if (aiwants(user, oo, NULL)) {
o = oo;
break;
}
}
}
} else {
if (isplayer(user)) msg("There is nothing there to snatch!");
return B_TRUE;
@ -1753,8 +1773,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
return B_TRUE;
}
// spell doesn't take any time, using an object does.
if (fromob) {
if (cansee(player, user)) {
char obname[BUFLEN];
getobname(o, obname, 1);
msg("%s%s %s wraps around %s.", username, getpossessive(username),
noprefix(fromobname), obname);
}
} else {
// setting v0 to spellid just in case pickup() changes flags
addflag(user->flags, F_NOTIME, OT_A_SNATCH, NA, NA, NULL);
}
pickup(user, o, 1, B_TRUE, B_TRUE);
f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL);
if (f) killflag(f);
@ -3438,7 +3468,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// returns TRUE on error
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot) {
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob) {
char buf[BUFLEN];
char castername[BUFLEN];
int rv = B_FALSE;
@ -4110,7 +4140,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
dam = rnd(1,power);
if (caster) {
char cname[BUFLEN];
real_getlfnamea(caster, cname, B_FALSE, B_FALSE);
real_getlfnamea(caster, cname, NULL, B_SHOWALL, B_REALRACE);
sprintf(damstr, "%s%s blight spell.", cname, getpossessive(cname));
} else {
strcpy(damstr, "a blight spell.");
@ -4304,7 +4334,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (!isimmuneto(c->lf->flags, DT_FIRE, B_FALSE)) {
msg("%s burn%s!",buf,isplayer(c->lf) ? "" : "s");
}
real_getlfname(caster, realcname, B_FALSE, B_TRUE);
real_getlfname(caster, realcname, NULL, B_SHOWALL, B_REALRACE);
snprintf(damstring, BUFLEN, "%s%s wave of fire", realcname, getpossessive(realcname));
losehp(c->lf, rolldie(2,10), DT_FIRE, caster, damstring);
}
@ -5268,7 +5298,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster);
return B_TRUE;
}
getflags(target->flags, retflag, &nretflags, F_POISONED, F_NONE);
getflags(target->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE);
for (i = 0; i < nretflags; i++) {
poisontype_t *pt;
pt = findpoisontype(retflag[i]->val[0]);
@ -5638,7 +5668,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_DETECTPOISON) {
if (isplayer(caster)) {
int npoisoned = 0;
int n;
int n,i;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
getflags(caster->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE);
for (i = 0; i < nretflags ; i++) {
flag_t *f;
poisontype_t *pt;
f = retflag[i];
pt = findpoisontype(f->val[0]);
msg("You detect %s in your body.", pt->name);
f->known = B_TRUE;
}
for (n = 0; n < caster->nlos; n++) {
object_t *o;
for (o = caster->los[n]->obpile->first ; o ; o = o->next) {
@ -6902,7 +6944,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (killflagsofid(target->flags, F_PAIN)) {
donesomething = B_TRUE;
}
getflags(target->flags, retflag, &nretflags, F_POISONED, F_NONE);
getflags(target->flags, retflag, &nretflags, F_INCUBATING, F_POISONED, F_NONE);
for (i = 0; i < nretflags; i++) {
poisontype_t *pt;
pt = findpoisontype(retflag[i]->val[0]);
@ -7365,7 +7407,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
char dambuf[BUFLEN];
char cname[BUFLEN];
real_getlfname(caster, cname, B_FALSE, B_TRUE);
real_getlfname(caster, cname, NULL, B_SHOWALL, B_REALRACE);
snprintf(dambuf, BUFLEN, "%s%s infinite death spell", cname, getpossessive(cname));
losehp(l, 500, DT_NECROTIC, NULL, dambuf);
}
@ -7381,7 +7423,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
char dambuf[BUFLEN];
char cname[BUFLEN];
real_getlfname(caster, cname, B_FALSE, B_TRUE);
real_getlfname(caster, cname, NULL, B_SHOWALL, B_REALRACE);
snprintf(dambuf, BUFLEN, "%s%s infinite death spell", cname, getpossessive(cname));
losehp(caster, 500, DT_NECROTIC, NULL, dambuf);
}
@ -7859,13 +7901,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (newsize != SZ_ANY) {
resizeobject(targob, newsize);
getobname(targob, newobname, 1);
getobname(targob, newobname, 1);
if (seen) msg("%s grows into %s!", obname, newobname);
} else if (newcelltype != CT_NONE) {
cell_t *where;
if (seen) {
celltype_t *ct;
ct = findcelltype(newcelltype);
msg("%s grows into %s %s!", needan(ct->name) ? "an" : "a", ct->name);
msg("%s grows into %s %s!", obname, needan(ct->name) ? "an" : "a", ct->name);
}
where = getoblocation(targob);
killob(targob);
@ -8972,7 +9015,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char distbuf[BUFLEN],dirbuf[BUFLEN];
char lfname[BUFLEN];
real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE);
real_getlfnamea(c->lf, lfname, NULL, B_SHOWALL, B_REALRACE);
getdisttext(caster->cell, c, distbuf, NULL, dirbuf);
sprintf(ptext, "%s: %s (%s to the %s, held by %s)",
mapname, obname, distbuf, dirbuf, lfname);
@ -9832,6 +9875,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
ndone++;
}
} else if (f->id == F_INCUBATING) {
f->val[1] *= 2;
}
}
if (ndone) {
@ -10595,6 +10640,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster);
return B_TRUE;
} // end if corpse
} else if (spellid == OT_S_SPIKEVOLLEY) {
object_t *o;
flag_t *f;
// create a volley of spikes
o = addobfast(caster->pack, OT_SPIKEVOLLEY);
if (!o) {
fizzle(caster);
}
if (isplayer(caster) || cansee(player, caster)) {
msg("%s fire%s a volley of spikes!",castername,isplayer(caster) ? "" : "s");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
f = hasflag(o->flags, F_MISSILEDAM);
if (f) { // should always be true
char dambuf[BUFLEN];
free(f->text);
sprintf(dambuf, "%dd3", power);
f->text = strdup(dambuf);
}
real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY);
} else if (spellid == OT_S_STENCH) {
int howlong;
@ -10802,9 +10868,33 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (target) {
int failed = B_FALSE;
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) {
if (!fromob && spellresisted(target, caster, spellid, power, seenbyplayer, B_TRUE)) {
failed = B_TRUE;
} else {
} else if (fromob && skillcheck(target, SC_DODGE, 12, 0)) {
failed = B_TRUE;
// announce whip failures
if (cansee(player, target)) {
char obname[BUFLEN];
char tname[BUFLEN];
real_getobname(fromob, obname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
getlfname(target, tname);
msg("%s%s %s misses %s.", castername, getpossessive(castername), noprefix(obname), tname);
}
return B_FALSE;
}
if (!failed) {
// announce whip attacks
if (fromob && cansee(player, target)) {
char obname[BUFLEN];
char tname[BUFLEN];
real_getobname(fromob, obname, 1, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
getlfname(target, tname);
msg("%s%s %s wraps around %s.", castername, getpossessive(castername), noprefix(obname), tname);
}
if (caster) {
fightback(target, caster);
}
// they get pulled towards caster
failed = pullnextto(target, caster->cell);
}
@ -10823,7 +10913,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE;
}
} else {
fizzle(caster);
if (!fromob) fizzle(caster);
return B_TRUE;
}
} else if (spellid == OT_S_SUPERHEAT) {
@ -13229,7 +13319,7 @@ int schoolappearsinbooks(enum SPELLSCHOOL ss) {
return B_TRUE;
}
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes) {
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob) {
int x,y;
objecttype_t *ot;
ot = findot(sid);
@ -13252,7 +13342,7 @@ void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE
if (getcelldistorth(srcloc, c) <= radius) {
// cast the spell
if (ot->obclass->id == OC_SPELL) {
dospelleffects(NULL, ot->id, power, c->lf, NULL, c, B_UNCURSED, NULL, frompot);
dospelleffects(NULL, ot->id, power, c->lf, NULL, c, B_UNCURSED, NULL, frompot, fromob);
} else if (ot->obclass->id == OC_ABILITY) {
abilityeffects(c->lf, ot->id, c, c->lf, NULL);
}

View File

@ -3,7 +3,7 @@
#include "defs.h"
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag);
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot);
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob);
objecttype_t *findspelln(char *buf);
enum SPELLSCHOOL findspellschoolbyname(char *buf);
void fizzle(lifeform_t *caster);
@ -35,7 +35,7 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair
object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat);
void pullobto(object_t *o, lifeform_t *lf);
int schoolappearsinbooks(enum SPELLSCHOOL ss);
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes);
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob);
int spellisfromschool(int spellid, enum SPELLSCHOOL school);
int spellokformonsters(int spellid);
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce);

38
text.c
View File

@ -246,11 +246,11 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
case DT_FIRE:
snprintf(retbuf, BUFLEN, "^n%s %s hot.", locvictimname, isplayer(victim) ? "don't feel" : "doesn't look");
break;
case DT_MAGIC:
strcpy(retbuf, "");
break;
//case DT_MAGIC:
//snprintf(retbuf, BUFLEN, "^n%s shrug%s off the effects.", locvictimname, isplayer(victim) ? "" : "s");
//break;
default:
snprintf(retbuf, BUFLEN, "^n%s shrug%s off the effects.", locvictimname, isplayer(victim) ? "" : "s");
strcpy(retbuf, "");
break;
}
} else if (fatal) { // fatal
@ -282,7 +282,8 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
snprintf(retbuf, BUFLEN, "^nMagical energy sears %s!", locvictimname);
break;
default:
snprintf(retbuf, BUFLEN, "^n%s %s hurt!", locvictimname, is(victim));
//snprintf(retbuf, BUFLEN, "^n%s %s hurt!", locvictimname, is(victim));
strcpy(retbuf, "");
break;
}
}
@ -452,6 +453,18 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
}
}
}
// whips deal normal damagetype(s), but have diferent attack
// verbs.
if (hasflagval(wep->flags, F_USESSKILL, SK_WHIPS, NA, NA, NULL)) {
if (dam <= 4) {
return "whip";
} else if (dam <= 8) {
return "thrash";
} else {
return "flay";
}
}
}
if (damtype == DT_ACID) {
@ -1121,8 +1134,8 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
int canbehead = B_TRUE;
if (wep) {
sk = getobskill(wep->flags);
if (sk && (sk->id == SK_SHORTBLADES)) {
// short blades can't behead/bisect.
if (sk && (sk->id != SK_LONGBLADES) && (sk->id != SK_EXOTICWEPS)) {
// only long blades can behead/bisect.
canbehead = B_FALSE;
}
}
@ -2193,9 +2206,15 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
char *p,*plusloc;
localtext = strdup(text);
// number of dice
if (strchr(localtext, 'c')) {
p = strtok_r(localtext, "d", &dummy);
if (!p) {
return B_TRUE;
} else {
// assume it's just a single number
*ndice = 0;
*nsides = 0;
*bonus = atoi(text);
free(localtext);
return B_FALSE;
}
if (ndice) {
*ndice = atoi(p);
@ -2203,6 +2222,7 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
// sides on each die
p = strtok_r(NULL, "d", &dummy);
if (!p) {
free(localtext);
return B_TRUE;
}