* [+] F_prone if you're knocked down

- [+] make sheilds very good against projectiles
- [+] make smoke just REDUCE vision, not block it.
- [+] noncorporeal should stop grabs!
* [+] don't say 'a javelin is damaged' when you throw it, just apply
      the damge
- [+]  increase damage bonus with every lore level.  +10% each time
      (ie. up to 50% at top)
* [+] give accuracy + critical bonus for lore levles too
- [+] typo: Enhance which skill enhance (1 left)? ['=next page,?=toggle]
- [+] Show Pain on botl.
* [+] more staves
- [+] low hitpoint warning for pets (or make them shriek, whine, etc)
- [+] CRITKNOCKDOWN
* [+] FINISH GRIZZLY
- [+] undead should be immune to poison!!
    - [+] make code to auto add flags to undead.
- [+] if you ever move a door (ie. airblast), automatically open it.
- [+] young wolf shouldn't be able to open a door!
* [+] You throw a dart at the carpet snake.  Your dart misses
      you.--More--
- [+] no sprinting while burdneed
- [+] blood should be drawn BELOW stairs
- [+] weilded torch should do 1d4 fire damage (counts as a club)
* [+] The skeleton touches a leather belt then recoils in pain!The
      skeleton drops a blessed leather belt.The skeleton puts on a
      leather belt.
- [+] don't show "you can cast it at power level xxx" for abilities
* [+] more item randomising
- [+] make grey ooze splatter into acid
- [+] "the vine grabs you" if you walk onto an entangling vine.
- [+] don't start monsters within player's los
- [+] properly randomise sticks to snakes
- [+] stirge
- [+] leech (like stirge but can charge/leap, and slightly more hp /
      damage)
- [+] treesnake
- [+] constrictor
- [+] cobra
- [+] stickes to snakes - make caster's weapon revert.
- [+] A something comes into view.
- [+] is invisibility code working properly when you see someone use
      the invis spell?
- [+] don't include cosmetic objects in 'you see xxx'
* [+] monsters: don't use spells if you don't have lof.
- [+] pets not following around corners if you move diagonally. fixed a
      little.
- [+] summon small animals (2-3 x SZ_SMALL)
* [+] jet of water
- [+] summon medium animals (2-4 x SZ_MEDIUM, wolf etc)
- [+] lightning storm (lightbning everyone within los, and more damage)
- [+] summon large animals (SZ_LARGE, horse, bear etc)
This commit is contained in:
Rob Pearce 2011-05-03 07:34:07 +00:00
parent b18dea83a3
commit 7099d01164
22 changed files with 3539 additions and 1312 deletions

147
ai.c
View File

@ -83,13 +83,20 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
enum OBTYPE poss[MAXPILEOBS];
int nposs = 0;
int db = B_FALSE;
int castok = B_TRUE;
if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE;
}
f = lfhasflag(lf, F_NEEDOBFORSPELLS);
if (f && !hasob(lf->pack, f->val[0])) {
castok = B_FALSE;
}
for (f = lf->flags->first ; f ; f = f->next) {
if ((f->id == F_CANCAST) || (f->id == F_CANWILL)) {
if ( (castok && (f->id == F_CANCAST)) ||
(f->id == F_CANWILL)) {
if (aispellok(lf, f->val[0], victim, F_AICASTTOATTACK)) {
poss[nposs] = f->val[0];
nposs++;
@ -100,6 +107,11 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
// select a random one
if (nposs > 0) {
int sel;
if (db) {
char lfname[BUFLEN];
getlfname(lf,lfname);
dblog(".oO { %s i have %d valid spells/abils. using one. }", lfname, nposs);
}
sel = rnd(0,nposs-1);
return poss[sel];
}
@ -266,6 +278,15 @@ flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int t
db = B_TRUE;
}
if (lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
dblog(".oO { %s cannot go to targecell %d,%d due to f_ignorecell flag }", lfname, c->x, c->y);
return NULL;
}
if (db) {
char lfname[BUFLEN];
getlfname(lf, lfname);
@ -283,8 +304,6 @@ flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int t
strcpy(whybuf, "");
}
if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) {
f = addflag(lf->flags, F_TARGETCELL, c->x, c->y, why, whybuf);
} else {
@ -432,6 +451,19 @@ void aiturn(lifeform_t *lf) {
// healing
///////////////////////////////////////////////
// special cases
if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) {
if (ispeaceful(lf)) {
int sleepval = 18;
if (modcounter(lf->flags, 1) >= sleepval) {
taketime(lf, getactspeed(lf));
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
return;
}
}
}
// need to heal?
if (lf->hp < (lf->maxhp/2)) {
if (!useitemwithflag(lf, F_AIHEALITEM)) {
@ -573,18 +605,20 @@ void aiturn(lifeform_t *lf) {
}
if (!lfhasflag(lf, F_HIDING)) {
objecttype_t *st;
// can we attack with spells (ie. ones which target the victim)?
// if target is adjacent, we will normally just attack rather than try a spell.
spell = aigetattackspell(lf, target);
if ( (spell != OT_NONE) && // found a valid spell/ability to use
((getcelldist(lf->cell, target->cell) != 1) || (rnd(1,3) == 1))
st = findot(spell);
if ( (spell != OT_NONE) && // found a valid spell/ability to use
((getcelldist(lf->cell, target->cell) != 1) || // there is distance between us and target
(st->obclass->id == OC_ABILITY) || // OR this works from adjacent
(rnd(1,3) == 1)) // OR random chance of using anyway...
) {
int spellfailed = B_FALSE;
lifeform_t *spelllf = NULL;
cell_t *spellcell = NULL;
object_t *spellob = NULL;
objecttype_t *st;
st = findot(spell);
if (db) {
dblog(".oO { will cast attack spell: %s }", st->name);
}
@ -751,7 +785,10 @@ void aiturn(lifeform_t *lf) {
// move towards their last known location instead
targcell = getcellat(lf->cell->map, lastx, lasty);
if (targcell) {
aigoto(lf, targcell, MR_LF, target, PERMENANT);
if (!aigoto(lf, targcell, MR_LF, target, PERMENANT)) {
if (db) dblog(".oO { aigoto target's last known loc failed! }");
}
} else {
if (db) dblog(".oO { go to target's last known loc failed! }");
}
@ -929,12 +966,35 @@ void aiturn(lifeform_t *lf) {
} else {
// try to move towards master's last known loc
if (mf->val[1] != NA) {
flag_t *movetoflag = NULL;
cell_t *newcell;
newcell = getcellat(lf->cell->map, mf->val[1], mf->val[2]);
if (db) dblog(".oO { cannot see my master - adding F_TARGETCELL for last known loc }");
f = aigoto(lf, newcell, MR_LF, master, PERMENANT);
aimovetotargetcell(lf, f);
if (newcell == lf->cell) {
int lastdir;
lastdir = getownerlastdir(lf);
if (lastdir != D_NONE) {
// try going in last known dir
if (db) dblog(".oO { cannot see my master and am at last known loc. trying last known dir (%s) }",getdirname(lastdir));
if (!trymove(lf, lastdir, B_TRUE)) {
if (db) dblog(".oO { ...successfully }");
killflagsofid(lf->flags, F_OWNERLASTDIR);
return;
}
}
} else {
if (db) dblog(".oO { cannot see my master - adding F_TARGETCELL for last known loc }");
movetoflag = aigoto(lf, newcell, MR_LF, master, PERMENANT);
}
if (movetoflag) {
aimovetotargetcell(lf, movetoflag);
} else {
if (db) dblog(".oO { cannot see my master and aigoto last known loc/dir failed. randommove. }");
dorandommove(lf, B_NOBADMOVES);
}
} else {
if (db) dblog(".oO { cannot see my master and dont have a last known location. randommove. }");
dorandommove(lf, B_NOBADMOVES);
@ -970,12 +1030,23 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
int ok = B_FALSE;
int specialcase = B_FALSE;
int specificcheckok = B_FALSE;
int needlos = B_TRUE;
enum LOFTYPE needlof = LOF_NEED;
if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE;
}
ot = findot(spellid);
if (ot) {
flag_t *f;
f = hasflag(ot->flags, F_LOSLOF);
if (f) {
needlos = f->val[0];
needlof = f->val[1];
}
}
// enough mp etc?
if (!cancast(lf, spellid, NULL)) {
if (db) {
@ -1047,6 +1118,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if (lfhasflag(lf, F_GRABBING)) {
ok = B_TRUE;
}
} else if (ot->id == OT_A_SUCKBLOOD) {
// must attach first
if (lfhasflag(lf, F_ATTACHEDTO)) {
ok = B_TRUE;
}
} else {
ok = B_TRUE;
}
@ -1061,13 +1137,30 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specialcase = B_TRUE;
break;
}
// now check for line of sight / fire
switch (f->val[0]) {
case ST_VICTIM:
case ST_ADJVICTIM:
if (needlos && (!victim || !cansee(lf, victim)) ) {
dblog(".oO { cant cast %s - no LOS to victim }", ot ? ot->name : "?unkownspell?");
return B_FALSE;
}
if (needlof && !haslof(lf->cell, victim->cell, needlof, NULL) ) {
dblog(".oO { cant cast %s - no LOF to victim }", ot ? ot->name : "?unkownspell?");
return B_FALSE;
}
break;
default:
break;
}
} else {
// invalid spell for this purpose
dblog(".oO { cant cast %s - not valid for given purpose }", ot ? ot->name : "?unkownspell?");
return B_FALSE;
}
if (specialcase) {
if (ot->id == OT_S_TELEKINESIS) {
int i,nposs;
@ -1117,7 +1210,8 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_S_DRAINLIFE) && isimmuneto(victim->flags, DT_NECROTIC)) {
specificcheckok = B_FALSE;
}
if (ot->id == OT_A_SWOOP) {
if ((ot->id == OT_A_SWOOP) || (ot->id == OT_A_CHARGE)) {
flag_t *willflag;
flag_t *srflag;
int srange = 5;
srflag = lfhasflag(lf, F_SWOOPRANGE);
@ -1125,12 +1219,23 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
srange = srflag->val[0];
}
willflag = lfhasflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
if (willflag) {
texttospellopts(f->text, NULL, NULL, NULL, &srange);
if (!srange) srange = 5;
}
if (!haslof(lf->cell, victim->cell, LOF_NEED,NULL)) {
specificcheckok = B_FALSE;
} else if (isimmobile(lf) || !lfhasflag(lf, F_FLYING)) {
} else if (isimmobile(lf)) {
specificcheckok = B_FALSE;
} else if ((ot->id == OT_A_SWOOP) && !lfhasflag(lf, F_FLYING)) {
specificcheckok = B_FALSE;
} else if (getcelldist(lf->cell, victim->cell) > srange) {
specificcheckok = B_FALSE;
} else if (getcelldist(lf->cell, victim->cell) == 1) { // ie already adjacent
specificcheckok = B_FALSE;
}
}
if ((ot->id == OT_S_HASTE) && (lfhasflag(victim, F_FASTACT) || lfhasflag(victim, F_FASTACTMOVE)) ) {
@ -1197,6 +1302,15 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
}
int getownerlastdir(lifeform_t *lf) {
flag_t *odflag;
odflag = lfhasflag(lf, F_OWNERLASTDIR);
if (odflag) {
return odflag->val[0];
}
return D_NONE;
}
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op) {
object_t *o;
@ -1380,8 +1494,9 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
if (gothere) {
// start walking towards target cell
aigoto(lf, c, MR_OB, o, AI_FOLLOWTIME);
return B_TRUE;
if (aigoto(lf, c, MR_OB, o, AI_FOLLOWTIME)) {
return B_FALSE;
}
}
}
}

3
ai.h
View File

@ -5,13 +5,14 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
enum OBTYPE aigetfleespell(lifeform_t *lf);
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
object_t * aigetwand(lifeform_t *lf, enum FLAG purpose);
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
void aimovetotargetcell(lifeform_t *lf, flag_t *f);
int aipickup(lifeform_t *lf, object_t *o);
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target);
int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG purpose);
void aiturn(lifeform_t *lf);
int getownerlastdir(lifeform_t *lf);
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op);
object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op);
int lookforobs(lifeform_t *lf, int covetsonly);

View File

@ -397,6 +397,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (!willheal) {
enum SKILLLEVEL slev;
skill_t *sk;
float loremult;
// blessed vs undead
if (isblessed(wep) && lfhasflagval(victim, F_DTVULN, DT_HOLY, NA, NA, NULL)) {
// a little extra damage
@ -427,12 +428,15 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
dam[0] += pctof(pctextra, dam[0]);
}
}
// bonus for knowledge about the other lf's race? applied LAST.
if (getlorelevel(lf, victim->race->raceclass->id) >= PR_MASTER) {
dam[0] = (int) ( (float)dam[0] * 1.5 );
} else if (getlorelevel(lf, victim->race->raceclass->id) >= PR_SKILLED) {
dam[0] = (int) ( (float)dam[0] * 1.25 );
slev = getlorelevel(lf, victim->race->raceclass->id);
if (slev == PR_INEPT) {
loremult = 1;
} else {
loremult = 1 + (slev * 0.1);
}
dam[0] = (int) ( (float)dam[0] * loremult );
}
if (aidb) dblog(".oO { dealing %d %s damage }", dam[0], getdamname(damtype[0]));
@ -463,7 +467,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
dblog("initial dam[%d] = %d",i,dam[i]);
if (lfhasflag(lf, F_HEAVYBLOW) || hasflag(wep->flags, F_HEAVYBLOW)) {
dam[i] = (int)((float)dam[i] * 1.5);
dam[i] = (int)pctof(110,dam[i]);
dblog("heavy blow makes dam[%d] = %d",i,dam[i]);
}
@ -616,6 +620,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// special weapon effects
wepeffects(wep->flags, victim->cell, damflag, dam[0]);
// other effects
if (!isdead(victim)) {
if (isunarmed) {
f = lfhasflag(lf, F_FREEZINGTOUCH);
@ -649,7 +654,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(victim->cell, dir);
if (c && c->lf) {
if (strcasestr(c->lf->race->name, f->text)) {
if (c->lf->race->baseid == lf->race->baseid) {
nmatched++;
}
}
@ -664,6 +669,13 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
// critical hit effects
if (critical) {
if (lfhasflag(lf, F_CRITKNOCKDOWN)) {
fall(victim, lf, B_TRUE);
}
}
// confer flags from attacker?
wepeffects(lf->flags, victim->cell, damflag, dam[0]);
@ -685,6 +697,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
}
} else if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) {
// automatically latch on
if (!lfhasflag(victim, F_NONCORPOREAL) && !hasflag(lf->flags, F_ATTACHEDTO)) {
addflag(lf->flags, F_ATTACHEDTO, victim->id, NA, NA, NULL);
}
}
}
@ -741,7 +758,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (!isdead(victim)) {
if (lfhasflag(victim, F_INDUCEFEAR)) {
if (cansee(lf, victim)) {
scare(lf, victim, rnd(2,3));
scare(lf, victim, rnd(2,3), 0);
}
}
}
@ -937,7 +954,7 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
if (pct <= 5) {
return "whack";
} else if (pct <= 20) {
if (rnd(1,2) == 1) {
if (onein(2)) {
return "hit";
} else {
return "bash";
@ -1037,7 +1054,7 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
} else if (damtype == DT_TOUCH) {
return "touch";
} else if (damtype == DT_UNARMED) {
if (rnd(1,2) == 1) {
if (onein(2)) {
return "punch";
} else {
return "hit";
@ -1190,7 +1207,7 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
if (lfhasflagval(victim, F_NOBODYPART, BP_HEAD, NA, NA, NULL)) {
return "bisect";
} else {
if ((getlfsize(victim) >= SZ_MEDIUM) && (rnd(1,3) == 1)) {
if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {
return "behead";
} else {
return "bisect";
@ -1356,7 +1373,14 @@ float getstrdammod(lifeform_t *lf) {
// <9 = penalty
// 9,10,11,12 = average
// >12 = bonus
base = getattr(lf, A_STR);
if (lfhasflag(lf, F_RAGE)) {
base = 20;
} else {
base = getattr(lf, A_STR);
}
if ((base >= 9) && (base <= 12)) {
mod = 1;
} else if (base > 12) {
@ -1453,15 +1477,28 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
int acc,ev;
int gothit;
enum LFSIZE szlf,szvictim;
enum SKILLLEVEL slev;
int myroll;
if (critical) {
*critical = 0;
}
acc = getlfaccuracy(lf, wep);
if (isprone(victim)) {
acc += 30;
}
// remember lore about victim...
slev = getlorelevel(lf, victim->race->raceclass->id);
// modify for defender's evasion
ev = getevasion(victim);
if (isprone(victim)) {
ev = 0;
} else {
ev = getevasion(victim);
}
acc -= ev;
// special case
@ -1503,15 +1540,34 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
acc += 50;
}
// base 5% critical chance
if (critical) {
if (rnd(1,20) == 20) *critical = 1;
int critroll;
critroll = rnd(1,100);
// modify for lore
if (slev != PR_INEPT) {
myroll += (slev*5); // ie. up to 30% bonus
}
if (critroll >= 95) *critical = 1;
}
if (acc < 0) acc = 0;
if (acc > 100) acc = 100;
//if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc);
if (rnd(1,100) <= acc) {
myroll = rnd(1,100);
if (slev != PR_INEPT) {
myroll += (slev*10);
}
// modify for lore
if (myroll <= acc) {
gothit = B_TRUE;
} else {
if (critical && *critical) {
@ -1644,13 +1700,13 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
if (cansee(player, owner)) {
msg("%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname);
}
fall(victim, B_TRUE);
fall(victim, NULL, B_TRUE);
}
} else if ((f->id == F_HEAVYBLOW) && victim && owner) {
int dir;
// knock back victim
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE, DT_COMPASS);
knockback(victim, dir , 2, owner);
knockback(victim, dir , 2, owner, 30);
f->known = B_TRUE;
} else if ((f->id == F_HITCONFER) && victim ) {
// only works if we did damage

81
defs.h
View File

@ -131,6 +131,8 @@ enum CHECKTYPE {
SC_CON,
//////////
SC_DODGE,
SC_SHIELDBLOCK,
SC_FALL,
SC_SLIP,
SC_LISTEN,
SC_MORALE,
@ -539,6 +541,7 @@ enum RARITY {
*/
enum RACECLASS {
RC_ANY, // not actually ever defined
RC_ANIMAL,
RC_DEMON,
RC_HUMANOID,
@ -556,6 +559,7 @@ enum RACE {
R_BEHOLDER,
R_BUGBEAR,
R_COCKATRICE,
R_CREEPINGCLAW,
R_DARKMANTLE,
R_EYEBAT,
R_GIANTHILL,
@ -581,24 +585,36 @@ enum RACE {
R_ORC,
R_ORCWARRIOR,
R_ORK,
R_PEGASUS,
R_POLTERGEIST,
R_SATYR,
R_SHADOWCAT,
R_SPRITEFIRE,
R_TROGLODYTE,
R_TROLL,
R_XAT,
// small animals
// animals
R_ANT,
R_ANTS,
R_ANTLION,
R_BAT,
R_BEAR,
R_BEARGRIZZLY,
R_DOGBLINK,
R_DOGDEATH,
R_DOGWAR,
R_HAWK,
R_HAWKYOUNG,
R_HAWKBLOOD,
R_HAWKFROST,
R_LEECH,
R_NEWT,
R_RAT,
R_SNAKE,
R_SNAKECARPET,
R_SNAKECOBRA,
R_SNAKECONSTRICTOR,
R_SNAKETREE,
R_SPIDER,
R_SPIDERFUNNELWEB,
R_SPIDERREDBACK,
@ -610,6 +626,7 @@ enum RACE {
R_GLOWBUG,
R_GIANTFLY,
R_GIANTBLOWFLY,
R_STIRGE,
// undead
R_GHAST,
R_GHOST,
@ -819,6 +836,7 @@ enum OBTYPE {
// -- death
OT_SB_ANIMATEDEAD,
OT_SB_DRAINLIFE,
OT_SB_FEAR,
OT_SB_PAIN,
OT_SB_PARALYZE,
OT_SB_POISONBOLT,
@ -837,6 +855,9 @@ enum OBTYPE {
OT_SB_AIRBLAST,
OT_SB_CALLLIGHTNING,
OT_SB_CLOUDKILL,
OT_SB_GUSTOFWIND,
OT_SB_LIGHTNINGSTORM,
OT_SB_WINDSHIELD,
// -- elemental - fire
OT_SB_SPARK,
OT_SB_FIREDART,
@ -900,6 +921,7 @@ enum OBTYPE {
// -- death
OT_S_ANIMATEDEAD,
OT_S_DRAINLIFE,
OT_S_FEAR,
OT_S_PAIN,
OT_S_PARALYZE,
OT_S_INFINITEDEATH,
@ -919,6 +941,7 @@ enum OBTYPE {
// -- elemental - air
OT_S_AIRBLAST,
OT_S_CLOUDKILL,
OT_S_GUSTOFWIND,
OT_S_WINDSHIELD,
// -- elemental - fire
OT_S_SPARK,
@ -975,6 +998,7 @@ enum OBTYPE {
OT_S_ENDUREELEMENTS,
OT_S_ENTANGLE,
OT_S_HAILSTORM,
OT_S_LIGHTNINGSTORM,
OT_S_PURIFYFOOD,
OT_S_QUENCH,
OT_S_LESSENPOISON,
@ -982,7 +1006,11 @@ enum OBTYPE {
OT_S_SLEETSTORM,
OT_S_SOFTENEARTH,
OT_S_STICKTOSNAKE,
OT_S_SUMMONANIMALSSM,
OT_S_SUMMONANIMALSMD,
OT_S_SUMMONANIMALSLG,
OT_S_WARPWOOD,
OT_S_WATERJET,
// -- summoning
OT_S_CREATEMONSTER,
// -- translocation
@ -1005,10 +1033,12 @@ enum OBTYPE {
OT_A_LEARN,
OT_A_LEVELUP,
// abilities
OT_A_SUCKBLOOD,
OT_A_GRAB,
OT_A_CHARGE,
OT_A_CRUSH,
OT_A_JUMP,
OT_A_RAGE,
OT_A_SPRINT,
OT_A_STINGACID, // need to define dam in f_canwill
OT_A_SWOOP,
@ -1044,6 +1074,7 @@ enum OBTYPE {
OT_LAMPOIL,
OT_LANTERNOIL,
OT_LOCKPICK,
OT_PANPIPES,
OT_PICKAXE,
OT_TORCH,
// tech
@ -1076,6 +1107,7 @@ enum OBTYPE {
OT_SPLASHWATER,
OT_PUDDLEWATER,
OT_PUDDLEWATERL,
OT_ACIDSPLASH,
OT_ACIDPUDDLE,
OT_ACIDPOOL,
OT_SLIMEPOOL,
@ -1174,6 +1206,8 @@ enum OBTYPE {
OT_FISTS,
OT_HOOKHAND, // for pirate
OT_STING,
OT_BUTT,
OT_HOOF,
OT_TAIL,
OT_TEETH,
OT_TEETHSM,
@ -1225,6 +1259,9 @@ enum OBTYPE {
OT_TRIDENT,
// staves
OT_QUARTERSTAFF,
OT_BAMBOOSTAFF,
OT_IRONSTAFF,
OT_BLADEDSTAFF,
// clubs
OT_CLUB,
OT_FLAIL,
@ -1277,9 +1314,11 @@ enum NOISETYPE {
N_WALK,
N_FLY,
N_WARCRY,
N_LOWHP,
};
enum LFSIZE {
SZ_ANY = -1,
SZ_MINI = 0, // ie. fly
SZ_TINY = 1, // ie. mouse
SZ_SMALL = 2, // ie. cat
@ -1329,10 +1368,12 @@ enum FLAG {
F_UNIQUE, // only one may appear
F_GLYPH, // override the glyph with the first char of text.
// v0 is either NA (white) or colourid (C_xxx).
F_COSMETIC, // this object is mostly cosmetic, don't say 'you see xx'
F_NOPICKUP, // cannot pick this up
F_IMPASSABLE, // cannot walk past this if your size if v0 or smaller
F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it
F_BLOCKSVIEW, // cannot see past this
F_BLOCKSVIEW, // if v0 = true, cannot see past this
// if v0 > 0, reduces your vision by v0.
F_BLOCKSTHROW, // cannot throw past this
F_THEREISHERE, // announce "there is xx here!", not "you see xx here"
// text[0] is punctuation to use.
@ -1361,6 +1402,7 @@ enum FLAG {
F_EQUIPCONFER, // gives flag v0+v1 when weilded/worn. v2 specifies if it must be id'd.
F_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit
F_HITCONFER, // hitting with this gives flagid=v0
// unless you pass a val1 skillcheck, diff val2
// with timeleft = text ("min-max")
@ -1460,7 +1502,7 @@ enum FLAG {
F_USESSKILL, // weapon needs skill sk_v0
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 bracket v1
F_ATTREQ, // requires attrib v0 to be at least v1
//F_DAMTYPE, // val0 = damage type
//F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
F_DAM, // v0 = damtype, text = 1d1+1
@ -1542,6 +1584,7 @@ enum FLAG {
F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
F_DONELISTEN, // supress further 'you hear xx' messages this turn.
// lifeform flags / lf flags
F_COUNTER, // generic counter flag for race abilities.
F_DEBUG, // debugging enabled
F_ACCURACYMOD, // modify your accuracy by val0
F_VEGETARIAN, // this lf will not eat meat.
@ -1584,14 +1627,23 @@ enum FLAG {
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
F_BOOSTSPELL, // v0 is active boost spell, v1 is ongoing mpcost, v2 is power
F_SWOOPRANGE, // v0 = how far a flying creature can swoop
F_LOSLOF, // v0 = whether this spell needs line of sight
// v1 = whether this spell needs line of fire
// MONSTER AI FLAGS
F_XPVAL, // force xp val for killing this lf to v0
// ...OR if applied to an ability...
// monsters with this abil/spell are worth
// v0 more xp.
F_XPMULTIPLY, // multiply xp val for killing this lf by v0
F_LASTDIR, // this is the last direction we moved.
F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
// when we could see them.
F_PETOF, // this lf is a pet of lfid v0
// v1/2 = last known location of my owner.
F_SUMMONEDBY, // this lf was summoned by lfid v0. if they die, we
// vanish.
// v1 is lifetime left. this decrements each turn.
// when at zero, lf vanishes.
F_HOSTILE, // lf will attack the player if in sight
F_FRIENDLY, // lf will attack all non-players if in sight
F_WANTS, // lf will try to pick up object type val0. if
@ -1637,6 +1689,10 @@ enum FLAG {
F_NAME, // text = player's name
F_XPMOD, // add/subtract this much from calculated xpval
F_BLOODOB, // text = type of object to drop for blood
F_DIESPLATTER, // this lf will splatter objcets of type 'text'
// when it dies.
// v0 = max distance to splatter (or UNLIMITED)
// text = type of object to splatter
F_OBESE, // double base weight for race!
F_ORIGRACE, // original player race (if you polymorphed)
F_ORIGJOB, // original player job (if you polymorphed)
@ -1647,7 +1703,6 @@ enum FLAG {
// for monsters
F_HUMANOID, // this race can wear armour / use weapons
F_INSECT, // this race is classed as an insect
F_ANIMAL, // this race is classed as an animal
F_UNDEAD, // this race is classed as undead
F_COLDBLOOD, // this race is coldblooded
F_NOBODYPART, // this race doesn't have bodypart val0
@ -1658,8 +1713,8 @@ enum FLAG {
F_AUTOCREATEOB, // produces obtype 'text' wherever it walks, v0=radius
// (only if ob of that type not already there)
F_PACKATTACK, // deal v0 extra damage of type v1 if there are
// v2 or more monsters matching f->text next
// to the victim
// v2 or more monsters of the same baseid
// next to the attacker
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
F_MORALE, // gain +v0 in morale checks.
F_SPOTTED, // you have spotted hiding lf id v0
@ -1668,12 +1723,16 @@ enum FLAG {
// ie 'magic armour', 'force field'
// v0 is power left.
F_ASLEEP, // is asleep
F_ATTACHEDTO, // you are attached to lf id v0, and will move with it
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
F_BLIND, // cannot see anything
F_DEAF, // cannot hear
F_NEEDOBFORSPELLS, // lf can only cast spells if it has object v0
F_CANCAST, // can cast the spell val0 (need MP)
F_CANHEARLF, // you can hear lifeform id v0 (show their glyph)
// this flag does not get announced.
F_BLEEDABIL, // will automatically use the ability v0 when
// this lf starts bleeding.
F_CANWILL, // can cast the spell/ability val0 without using MP
// v1 is counter untiluse
// v2 is what you need to use it
@ -1682,6 +1741,7 @@ enum FLAG {
// pw:xx; cast the spell at power xx
// dam:xdy+b; damage
// needgrab:xx; do you need to grab first?
// range:xx;
F_CHARMEDBY,// you've been charmed by lf id v0
F_CONTROL,// you control polymorphs, teleports and createmonsters
F_DETECTAURAS, // autodetect bless/curse
@ -1721,16 +1781,20 @@ enum FLAG {
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
// if text not set, default dam is 1d2
F_PARALYZED,// cannot do anything
F_PRONE, // lying on the ground
F_FROZEN, // made of ice
F_LEVITATING, // like flying but uncontrolled
F_MAGSHIELD,// magnetic shield
F_NAUSEATED, // lf has a stench penalty of v0 (-v0*10 to hit).
F_NONCORPOREAL,// can walk through walls
// when this comes from the passwall spell, 'obfrom'
// be set to the ot_s_passwall.
F_OMNIPOTENT, // knows extra info
F_PHOTOMEM, // you don't forget your surroundings
F_REGENERATES, // regenerate HP at val0 per turn
F_RESISTMAG, // immunity to magic effects. v0=amt (1-20)
F_MPREGEN, // regenerate MP at val0 per turn
F_RAGE, // you are enraged. v0/v1 will be set to player's old hp/maxhp
F_RISEASGHOST, // become a ghost when you die.
F_SEEINDARK, // nightvis range is val0
F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0
@ -1747,7 +1811,7 @@ enum FLAG {
F_XRAYVIS, //val0=num of walls we can see through
F_CANSEETHROUGHMAT, //val0=kind of material you can see through
F_SPRINTING, // v0=true: you are sprinting. false=you are tired
F_TIRED, // you are too tired to sprint
F_TIRED, // you are too tired to sprint, rage, etc
F_WINDSHIELD,// has a windshield protecting against missiles of speed
// v0 or lower.
F_DODGES, // you dodge missed attacks
@ -1954,6 +2018,7 @@ enum ERROR {
//
E_NOBP = 48,
E_VEGETARIAN = 49,
E_NOOB = 50,
};
@ -2043,7 +2108,7 @@ typedef struct cell_s {
} cell_t;
typedef struct glyph_s {
char ch;
int ch;
int colour;
} glyph_t;

39
flag.c
View File

@ -141,6 +141,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
// special effects
if (f->pile->owner) {
float pct;
switch (f->id) {
case F_ASLEEP:
stopallspells(f->pile->owner);
@ -148,6 +149,13 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
case F_NONCORPOREAL:
killflagsofid(f->pile->owner->flags, F_BEINGSTONED);
break;
case F_RAGE:
f->val[0] = f->pile->owner->hp; // remember old maxhp
f->val[1] = f->pile->owner->maxhp; // remember old maxhp
pct = (float)f->pile->owner->hp / (float)f->pile->owner->maxhp;
f->pile->owner->maxhp = (float)f->pile->owner->maxhp * 1.5;
f->pile->owner->hp = pct * (float)f->pile->owner->maxhp;
break;
default:
break;
}
@ -202,6 +210,7 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
case F_FASTMOVE:
case F_HIDING:
case F_INVISIBLE:
case F_RAGE:
case F_SEEINDARK:
case F_SEEINVIS:
case F_SPRINTING:
@ -274,6 +283,15 @@ flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, ch
return hasflagval_real(fp, id, val1, val2, val3, text, B_TRUE); // must be known
}
int getcounter(flagpile_t *fp) {
flag_t *f;
f = hasflag(fp, F_COUNTER);
if (f) {
return f->val[0];
}
return 0;
}
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown) {
flag_t *f;
lifeform_t *owner;
@ -331,6 +349,15 @@ void killflag(flag_t *f) {
if (!lfhasflagval(lf, F_NOFLEEFROM, f->val[0], NA, NA, NULL)) {
addtempflag(lf->flags, F_NOFLEEFROM, f->val[0], NA, NA, NULL, 10);
}
} else if (f->id == F_RAGE) {
if (!isdead(lf)) {
// restore original maxhp
float pct;
pct = (float)lf->hp / (float)lf->maxhp;
lf->maxhp = f->val[1];
lf->hp = pct * (float)lf->maxhp;
if (lf->hp < 1) lf->hp = 1;
}
}
// announce
@ -562,6 +589,18 @@ void timeeffectsflag(flag_t *f, int howlong) {
}
}
int modcounter(flagpile_t *fp, int amt) {
flag_t *f;
f = hasflag(fp, F_COUNTER);
if (f) {
f->val[0] += amt;
} else {
f = addflag(fp, F_COUNTER, amt, NA, NA, NULL);
}
return f->val[0];
}
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) {
flag_t *f;
if (val0) *val0 = 0;

2
flag.h
View File

@ -10,6 +10,7 @@ void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
int flagstacks(enum FLAG fid);
int modcounter(flagpile_t *fp, int amt);
flag_t *hasflag(flagpile_t *fp, int id);
flag_t *hasflagknown(flagpile_t *fp, int id);
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception);
@ -20,6 +21,7 @@ int killflagsofid(flagpile_t *fp, enum FLAG fid);
void killflag(flag_t *f);
void killflagpile(flagpile_t *fp);
void makeflagknown(flagpile_t *fp);
int modcounter(flagpile_t *fp, int amt);
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2);
void timeeffectsflag(flag_t *f, int howlong);
void timeeffectsflags(flagpile_t *fp);

296
io.c
View File

@ -1,5 +1,6 @@
#include <assert.h>
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -119,6 +120,7 @@ void addpromptq(prompt_t *p, char *q) {
p->nqs++;
}
void anim(cell_t *src, cell_t *dst, char ch, int colour) {
int deltax, deltay;
int numpixels;
@ -305,6 +307,38 @@ void animradialorth(cell_t *src, int radius, char ch,int colour) {
curs_set(1);
}
// bolt from the sky
void animsky(cell_t *src, char ch, int colour) {
glyph_t gl;
int y;
if (!haslos(player, src)) {
return;
}
gl.ch = ch;
gl.colour = colour;
// hide cursor
curs_set(0);
// update viewpoint
updateviewfor(src);
drawlevelfor(player);
// draw bolt coming down
for (y = 0; y <= src->y - viewy; y++) {
drawglyph(&gl, src->x - viewx, y);
}
wrefresh(gamewin);
usleep(ANIMDELAY);
// show cursor
curs_set(1);
}
char askchar(char *prompt, char *validchars, char *def, int showchars) {
char buf[BUFLEN];
char *p;
@ -460,7 +494,7 @@ cell_t *askcoords(char *prompt, int targettype) {
if (!isplayer(c->lf)) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
if (lfhasflagval(c->lf, F_PETOF, player->id, NA, NA, NULL)) {
if (lfhasflag(c->lf, F_ANIMAL)) {
if (getraceclass(c->lf) == RC_ANIMAL) {
strcat(extrainfo, "pet");
} else {
strcat(extrainfo, "ally");
@ -482,6 +516,10 @@ cell_t *askcoords(char *prompt, int targettype) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, "fleeing");
}
if (lfhasflag(c->lf, F_PRONE)) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, "prone");
}
if (lfhasflag(c->lf, F_RESTING)) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, "resting");
@ -490,6 +528,19 @@ cell_t *askcoords(char *prompt, int targettype) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, "asleep");
}
f = lfhasflag(c->lf, F_ATTACHEDTO);
if (lfhasflag(c->lf, F_ATTACHEDTO)) {
lifeform_t *alf;
alf = findlf(c->map, f->val[0]);
if (alf) {
char alfname[BUFLEN];
char buf2[BUFLEN];
getlfname(alf, alfname);
if (strlen(extrainfo)) strcat(extrainfo, ", ");
sprintf(buf2, "attached to %s",alfname);
strcat(extrainfo, buf2);
}
}
if ((getallegiance(c->lf) == AL_HOSTILE) &&
(getlorelevel(player, c->lf->race->raceclass->id) >= PR_ADEPT)) {
@ -517,7 +568,7 @@ cell_t *askcoords(char *prompt, int targettype) {
strcat(extrainfo, dangerbuf);
}
o = hasobwithflag(c->obpile, F_RESTRICTMOVEMENT);
o = isstuck(c->lf);
if (o) {
char buf2[BUFLEN];
char obname[BUFLEN];
@ -547,6 +598,11 @@ cell_t *askcoords(char *prompt, int targettype) {
}
if (lfhasflag(c->lf, F_RAGE)) {
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, "enraged");
}
wep = getweapon(c->lf);
if (wep && (c->lf->race->id != R_DANCINGWEAPON)) {
object_t *secwep;
@ -806,6 +862,14 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
break;
case F_ATTACHEDTO:
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, buf);
msg("%s %s on to %s!",lfname, isplayer(lf) ? "latch" : "latches", buf);
donesomething = B_TRUE;
}
break;
case F_BEINGSTONED:
msg("%s begin%s to turn to stone!",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
@ -852,7 +916,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, buf);
msg("%s %s now under %s%s power!",lfname, isplayer(lf) ? "are" : "is", buf,getpossessive(buf));
msg("%s %s now under %s%s power!",lfname, is(lf), buf,getpossessive(buf));
donesomething = B_TRUE;
}
break;
@ -1035,7 +1099,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break;
// don't announce grabbing.
case F_GRAVBOOSTED:
msg("%s %s stuck to the floor!",lfname, isplayer(lf) ? "are" : "is");
msg("%s %s incredibly heavy all of a sudden!",lfname, isplayer(lf) ? "feel" : "looks");
donesomething = B_TRUE;
break;
case F_LEVITATING:
@ -1043,7 +1107,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
break;
case F_MAGSHIELD:
msg("%s %s surrounded by a magnetic shield!",lfname, isplayer(lf) ? "are" : "is");
msg("%s %s surrounded by a magnetic shield!",lfname, is(lf));
donesomething = B_TRUE;
break;
case F_NAUSEATED:
@ -1078,6 +1142,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
msg("%s start%s producing light!", lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
break;
case F_RAGE:
msg("%s enter%s a berzerker rage!", lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
break;
case F_REGENERATES:
if (isplayer(lf)) { // don't know if monsters get it
msg("Your body's healing rate is enhanced!");
@ -1250,6 +1318,15 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
msg("%s%s %s vanishes.",lfname,getpossessive(lfname), f->text);
donesomething = B_TRUE;
break;
case F_ATTACHEDTO:
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
char buf[BUFLEN];
getlfname(lf2, buf);
msg("%s %s %s!",lfname, isplayer(lf) ? "release" : "releases", buf);
donesomething = B_TRUE;
}
break;
case F_ASLEEP:
msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
@ -1458,7 +1535,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
}
break;
case F_GRAVBOOSTED:
msg("%s %s no longer stuck to the floor.",lfname, isplayer(lf) ? "are" : "is");
msg("%s %s no longer stuck to the floor.",lfname, is(lf));
donesomething = B_TRUE;
break;
case F_LEVITATING:
@ -1500,7 +1577,11 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
}
break;
case F_PRODUCESLIGHT:
msg("%s %s no longer producing light.", lfname, isplayer(lf) ? "are" : "is");
msg("%s %s no longer producing light.", lfname, is(lf));
donesomething = B_TRUE;
break;
case F_RAGE:
msg("%s %s less angry now.", lfname, isplayer(lf) ? "feel" : "seems");
donesomething = B_TRUE;
break;
case F_REGENERATES:
@ -1655,7 +1736,7 @@ int announceobflaggain(object_t *o, flag_t *f) {
wantpremods = B_FALSE;
}
real_getobname(o, obname, o->amt, wantpremods, B_FALSE, B_TRUE, B_TRUE);
real_getobname(o, obname, o->amt, wantpremods, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
if (o->pile->owner) {
if (isplayer(o->pile->owner)) {
@ -1699,7 +1780,7 @@ void announceobflagloss(object_t *o, flag_t *f) {
if (!haslos(player, loc)) {
return;
}
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE);
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
if (o->pile->owner) {
if (isplayer(o->pile->owner)) {
@ -2802,6 +2883,9 @@ void describeob(object_t *o) {
case F_PRODUCESLIGHT:
mvwprintw(mainwin, y, 0, "%s produces light.", buf); y++;
break;
case F_RAGE:
mvwprintw(mainwin, y, 0, "%s makes you enraged.", buf); y++;
break;
case F_REGENERATES:
if (f->val[1] == 1) {
strcpy(buf2, "");
@ -2978,8 +3062,14 @@ void describespell(objecttype_t *ot) {
wprintw(mainwin, "\n");
power = getspellpower(player, ot->id);
wprintw(mainwin, "You can cast it at power level %d (maximum %d).\n",power, getspellmaxpower(ot->id));
if (ot->obclass->id == OC_SPELL) {
power = getspellpower(player, ot->id);
if (power > 0) {
wprintw(mainwin, "You can cast it at power level %d (maximum %d).\n",power, getspellmaxpower(ot->id));
} else {
wprintw(mainwin, "It is too powerful for you to cast (maximum power %d).\n",power, getspellmaxpower(ot->id));
}
}
wrefresh(mainwin);
@ -3602,10 +3692,13 @@ void dolook(cell_t *where) {
// doens't matter if you're blind
getobname(o, buf, o->amt);
msg("There is %s here%c", buf, f->text[0]);
interrupt(player);
seensomething = B_TRUE;
} else {
if (!numobs) firstob = o;
numobs++;
if (!hasflag(o->flags, F_COSMETIC)) {
if (!numobs) firstob = o;
numobs++;
}
}
}
@ -4620,58 +4713,15 @@ void drawunviscell(cell_t *cell, int x, int y) {
void drawglyph(glyph_t *g, int x, int y) {
int col;
col = g->colour;
setcol(gamewin, g->colour);
mvwprintw(gamewin, y, x, "%c", g->ch);
unsetcol(gamewin, g->colour);
}
/*
void drawcell(cell_t *cell, int x, int y) {
drawglyph(&cell->type->glyph, x, y);
}
*/
// draw a cell that we have LOS to.
/*
void drawcellwithcontents(cell_t *cell, int x, int y) {
if (cell->lf && cansee(player, cell->lf)) { // lifeform here that we can see
glyph_t *gl;
// draw the lf's race glyph
gl = getlfglyph(cell->lf);
drawglyph(gl, x, y);
return;
if ((gamemode == GM_GAMESTARTED) && lfhasflag(player, F_RAGE)) {
col = C_RED;
} else {
void *thing;
glyph_t glyph;
// scanned lf here?
if (isinscanrange(cell, &thing, NULL, &glyph) == TT_MONSTER) {
//mvwprintw(gamewin, y-viewy, x-viewx, "%c", glyph);
drawglyph(&glyph, x, y);
return;
}
}
if ((countobs(cell->obpile) > 0)) {
object_t *o;
// draw highest object in sort order
o = gettopobject(cell);
if (o) {
drawglyph(getglyph(o), x, y);
} else {
// should never happen. if it does, just show the
// first object
dblog("Warn: sorted object glyph drawing matching nothing!");
//mvwprintw(gamewin, y, x, "%c", cell->obpile->first->type->obclass->glyph);
drawglyph(&cell->obpile->first->type->obclass->glyph, x, y);
}
} else {
// draw cell normally
drawcell(cell, x, y);
col = g->colour;
}
setcol(gamewin, col);
mvwprintw(gamewin, y, x, "%lc", g->ch);
unsetcol(gamewin, col);
}
*/
void drawcursor(void) {
// move cursor to player position
@ -4736,6 +4786,9 @@ void doheading(WINDOW *win, int *y, int x, char *what) {
void initgfx(void) {
int msgwinh = 2;
int statwinh = 2;
setlocale(LC_CTYPE, "");
mainwin = initscr();
// colour setup
@ -5776,6 +5829,12 @@ void drawstatus(void) {
unsetcol(statwin, C_RED);
}
if (lfhasflag(player, F_RAGE)) {
setcol(statwin, C_RED);
wprintw(statwin, " Enraged");
unsetcol(statwin, C_RED);
}
// paralysed somehow?
if (isimmobile(player)) {
setcol(statwin, C_RED);
@ -5853,6 +5912,12 @@ void drawstatus(void) {
}
if (lfhasflag(player, F_PAIN)) {
setcol(statwin, C_YELLOW);
wprintw(statwin, " Pain");
unsetcol(statwin, C_YELLOW);
}
// show certain flags
f = isdrunk(player);
if (f) {
@ -6418,7 +6483,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} else if (accmod > 0) {
sprintf(buf, "%d (%s, +%d%% bonus)",dex, buf2, accmod );
} else { // ie. accmod < 0
sprintf(buf, "%d (%s, %d%% bonus)",dex, buf2, accmod );
sprintf(buf, "%d (%s, %d%% penalty)",dex, buf2, accmod );
}
if (dex != lf->baseatt[A_DEX]) strcat(buf, "*");
@ -6714,6 +6779,11 @@ void showlfstats(lifeform_t *lf, int showall) {
}
if (strlen(knowstring)) {
char dambonusstr[BUFLEN];
// append dam bonus
sprintf(dambonusstr, " (+%d%% bonus)",(lorelev*10));
strcat(knowstring, dambonusstr);
// print it
setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, "%s", knowstring);
unsetcol(mainwin, lorecol);
@ -6754,18 +6824,37 @@ void showlfstats(lifeform_t *lf, int showall) {
// obvious physical effects here.
f = lfhasknownflag(lf, F_ASLEEP);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_ATTACHEDTO);
if (f && (f->known)) {
lifeform_t *lf2;
char grabeename[BUFLEN];
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, grabeename);
} else {
strcpy(grabeename, "something");
}
sprintf(buf,"%s %s attached to %s.",you(lf), is(lf), grabeename);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_FLYING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s flying.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s flying.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_PRONE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s lying on the ground.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_FROZEN);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s been turned to ice, and %s slowly melting.", you(lf), isplayer(lf) ? "have" : "has",
isplayer(lf) ? "are" : "is");
is(lf));
y++;
}
f = lfhasknownflag(lf, F_GRABBEDBY);
@ -6778,7 +6867,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} else {
strcpy(grabbername, "something");
}
sprintf(buf,"%s %s being held by %s.",you(lf), isplayer(lf) ? "are" : "is", grabbername);
sprintf(buf,"%s %s being held by %s.",you(lf), is(lf), grabbername);
mvwprintw(mainwin, y, 0, buf);
y++;
}
@ -6792,28 +6881,28 @@ void showlfstats(lifeform_t *lf, int showall) {
} else {
strcpy(grabeename, "something");
}
sprintf(buf,"%s %s holding on to %s.",you(lf), isplayer(lf) ? "are" : "is", grabeename);
sprintf(buf,"%s %s holding on to %s.",you(lf), is(lf), grabeename);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_HIDING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s hiding.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s hiding.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_INVISIBLE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_LEVITATING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s levitating.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s levitating.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_NONCORPOREAL);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s noncorporeal and can walk through walls.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s noncorporeal and can walk through walls.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_PRODUCESLIGHT);
@ -6824,10 +6913,10 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasknownflag(lf, F_SPRINTING);
if (f) {
if (f->val[0]) {
mvwprintw(mainwin, y, 0, "%s %s sprinting.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s sprinting.", you(lf), is(lf));
y++;
} else {
mvwprintw(mainwin, y, 0, "%s %s exhausted.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s exhausted.", you(lf), is(lf));
y++;
}
}
@ -6836,7 +6925,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasknownflag(lf, F_UNDEAD);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s undead.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s undead.", you(lf), is(lf));
y++;
}
@ -6913,7 +7002,7 @@ void showlfstats(lifeform_t *lf, int showall) {
if (lf2) {
getlfname(lf2, buf);
mvwprintw(mainwin, y, 0, "%s %s fleeing from %s.",
you(lf), isplayer(lf) ? "are" : "is", buf);
you(lf), is(lf), buf);
y++;
}
}
@ -6922,7 +7011,7 @@ void showlfstats(lifeform_t *lf, int showall) {
// diff materials?
if (lf->race->material->id != MT_FLESH) {
mvwprintw(mainwin, y, 0, "%s %s made out of %s.",you(lf), isplayer(lf) ? "are" : "is", lf->race->material->name);
mvwprintw(mainwin, y, 0, "%s %s made out of %s.",you(lf), is(lf), lf->race->material->name);
y++;
}
@ -6931,14 +7020,14 @@ void showlfstats(lifeform_t *lf, int showall) {
strcpy(buf, "");
f = lfhasflagval(lf, F_DTRESIST, DT_ALL, NA, NA, NULL);
if (f && (showall || f->known)) {
sprintf(buf, "%s %s resistant to %s", you(lf), isplayer(lf) ? "are" : "is", getdamname(DT_ALL));
sprintf(buf, "%s %s resistant to %s", you(lf), is(lf), getdamname(DT_ALL));
} else {
first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
f = isresistantto(lf->flags, i);
if (f && (showall || f->known)) {
if (first) {
sprintf(buf2, "%s %s resistant to: %s", you(lf), isplayer(lf) ? "are" : "is",getdamnamenoun(i));
sprintf(buf2, "%s %s resistant to: %s", you(lf), is(lf),getdamnamenoun(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamnamenoun(i));
@ -6966,14 +7055,14 @@ void showlfstats(lifeform_t *lf, int showall) {
strcpy(buf, "");
f = lfhasflagval(lf, F_DTIMMUNE, DT_ALL, NA, NA, NULL);
if (f && (showall || f->known)) {
sprintf(buf, "%s %s immune to %s", you(lf), isplayer(lf) ? "are" : "is", getdamname(DT_ALL));
sprintf(buf, "%s %s immune to %s", you(lf), is(lf), getdamname(DT_ALL));
} else {
first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
f = isimmuneto(lf->flags, i);
if (f && (showall || f->known)) {
if (first) {
sprintf(buf2, "%s %s immune to: %s", you(lf), isplayer(lf) ? "are" : "is", getdamname(i));
sprintf(buf2, "%s %s immune to: %s", you(lf), is(lf), getdamname(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamname(i));
@ -6993,14 +7082,14 @@ void showlfstats(lifeform_t *lf, int showall) {
strcpy(buf, "");
f = lfhasflagval(lf, F_DTVULN, DT_ALL, NA, NA, NULL);
if (f && (showall || f->known)) {
sprintf(buf, "%s %s vulnerable to %s", you(lf), isplayer(lf) ? "are" : "is", getdamname(DT_ALL));
sprintf(buf, "%s %s vulnerable to %s", you(lf), is(lf), getdamname(DT_ALL));
} else {
first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
f = isvulnto(lf->flags, i);
if (f && (showall || f->known)) {
if (first) {
sprintf(buf2, "%s %s vulnerable to: %s", you(lf), isplayer(lf) ? "are" : "is", getdamnamenoun(i));
sprintf(buf2, "%s %s vulnerable to: %s", you(lf), is(lf), getdamnamenoun(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamnamenoun(i));
@ -7039,6 +7128,7 @@ void showlfstats(lifeform_t *lf, int showall) {
char expirebuf[BUFLEN];
char eb2[BUFLEN];
int needgrab = B_FALSE;
int range;
if (f->val[2] == NA) {
sprintf(expirebuf, "at will");
@ -7048,10 +7138,15 @@ void showlfstats(lifeform_t *lf, int showall) {
}
// extra options?
texttospellopts(f->text, NULL, NULL, &needgrab);
texttospellopts(f->text, NULL, NULL, &needgrab, &range);
if (needgrab) {
strcat(expirebuf, ",after grab");
}
if (range) {
char rbuf[BUFLEN];
sprintf(rbuf, ",range:%d",range);
strcat(expirebuf, rbuf);
}
if (strlen(expirebuf)) {
sprintf(eb2,"(%s)",expirebuf);
@ -7235,7 +7330,7 @@ void showlfstats(lifeform_t *lf, int showall) {
// obvious physical effects first.
f = lfhasknownflag(lf, F_BEINGSTONED);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s being turning to stone.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s being turning to stone.", you(lf), is(lf));
y++;
}
@ -7249,13 +7344,13 @@ void showlfstats(lifeform_t *lf, int showall) {
if (hasjob(lf, J_PIRATE)) {
mvwprintw(mainwin, y, 0, "%s can hold %s liquor well.", you(lf), isplayer(lf) ? "your" : "its");
y++;
mvwprintw(mainwin, y, 0, "%s %s missing one eye.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s missing one eye.", you(lf), is(lf));
y++;
}
// flags which aren't really intrinsics
if (lfhasflag(lf, F_VEGETARIAN)) {
mvwprintw(mainwin, y, 0, "%s %s a vegetarian.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s a vegetarian.", you(lf), is(lf));
y++;
}
@ -7275,7 +7370,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasknownflag(lf, F_MAGICARMOUR);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s protected by %s %s", you(lf), isplayer(lf) ? "are" : "is",
mvwprintw(mainwin, y, 0, "%s %s protected by %s %s", you(lf), is(lf),
needan(f->text) ? "an" : "a", f->text);
if (isplayer(lf)) {
wprintw(mainwin, " (+%d AR).",f->val[0]);
@ -7353,7 +7448,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasknownflag(lf, F_DRUNK);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s %s.", you(lf),
isplayer(lf) ? "are" : "is", getdrunktext(f));
is(lf), getdrunktext(f));
y++;
}
@ -7425,7 +7520,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
}
sprintf(buf, "%s %s sick with %s%s.", you(lf), isplayer(lf) ? "are" : "is",
sprintf(buf, "%s %s sick with %s%s.", you(lf), is(lf),
getpoisonname(f->val[0]),
knownfatal ? ", potentially fatally" : "");
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
@ -7441,7 +7536,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasflag(lf, F_NAUSEATED);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s nauseated.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s nauseated.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_PACKATTACK);
@ -7498,23 +7593,23 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasflag(lf, F_MAGSHIELD);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s surrounded by a magnetic shield.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s surrounded by a magnetic shield.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_PAIN);
if (f && (f->known)) {
if (isdrunk(lf)) {
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, somewhat mitigated by %s inebriation.", you(lf), isplayer(lf) ? "are" : "is", isplayer(lf) ? "your" : "its");
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, somewhat mitigated by %s inebriation.", you(lf), is(lf), isplayer(lf) ? "your" : "its");
} else {
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, and movement will cause %s damage.", you(lf), isplayer(lf) ? "are" : "is", isplayer(lf) ? "you" : "it");
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, and movement will cause %s damage.", you(lf), is(lf), isplayer(lf) ? "you" : "it");
}
y++;
}
f = lfhasflag(lf, F_PARALYZED);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s paralyzed.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s paralyzed.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_PHOTOMEM);
@ -7522,6 +7617,11 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, "%s do not forget your surroundings.", you(lf));
y++;
}
f = lfhasflag(lf, F_RAGE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s enraged.", you(lf), is(lf));
y++;
}
f = lfhasknownflag(lf, F_REGENERATES);
if (f) {
char regenspeed[BUFLEN];
@ -7553,7 +7653,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} else { // ie. 21 upwards
strcpy(adjective, "incredibly");
}
mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), isplayer(lf) ? "are" : "is", adjective);
mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), is(lf), adjective);
y++;
}
f = lfhasknownflag(lf, F_TREMORSENSE);
@ -7563,7 +7663,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_WINDSHIELD);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s protected from missiles by a cyclonic shield", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s protected from missiles by a cyclonic shield", you(lf), is(lf));
if (isplayer(lf)) {
wprintw(mainwin, " (power %d).",roman(f->val[0]));
@ -7574,7 +7674,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_TIRED);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s tired.", you(lf), isplayer(lf) ? "are" : "is");
mvwprintw(mainwin, y, 0, "%s %s tired.", you(lf), is(lf));
y++;
}

1
io.h
View File

@ -7,6 +7,7 @@ void addpromptq(prompt_t *p, char *q);
void anim(cell_t *src, cell_t *dst, char ch, int colour);
void animradial(cell_t *src, int radius, char ch, int colour);
void animradialorth(cell_t *src, int radius, char ch, int colour);
void animsky(cell_t *src, char ch, int colour);
//void announceob(enum OBTYPE oid);
int announceflaggain(lifeform_t *lf, flag_t *f);
int announceflagloss(lifeform_t *lf, flag_t *f);

2064
lf.c

File diff suppressed because it is too large Load Diff

12
lf.h
View File

@ -15,6 +15,7 @@ void autotarget(lifeform_t *lf);
void autoweild(lifeform_t *lf);
int appearsrandomly(enum RACE rid);
void bleed(lifeform_t *lf);
void breakallgrabs(lifeform_t *lf);
int calcxp(lifeform_t *lf);
int calcxprace(enum RACE rid);
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost);
@ -43,7 +44,7 @@ void dumpxp(void);
int eat(lifeform_t *lf, object_t *o);
void enhanceskills(lifeform_t *lf);
object_t *eyesshaded(lifeform_t *lf);
int fall(lifeform_t *lf, int announce);
int fall(lifeform_t *lf, lifeform_t *fromlf, int announce);
void fightback(lifeform_t *lf, lifeform_t *attacker);
job_t *findjob(enum JOB jobid);
job_t *findjobbyname(char *name);
@ -64,6 +65,7 @@ void gainxp(lifeform_t *lf, long amt);
void genxplist(void);
int getactspeed(lifeform_t *lf);
enum ALLEGIENCE getallegiance(lifeform_t *lf);
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
int getarmourrating(lifeform_t *lf);
int getattackspeed(lifeform_t *lf);
@ -71,6 +73,7 @@ int getattpoints(lifeform_t *lf);
int getattr(lifeform_t *lf, enum ATTRIB attr);
int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
int getavgdam(lifeform_t *lf, int forxp);
float getequippedweight(lifeform_t *lf);
int getevasion(lifeform_t *lf);
object_t *getbestthrowmissile(lifeform_t *lf);
object_t *getbestweapon(lifeform_t *lf);
@ -91,6 +94,7 @@ enum HUNGER gethungerlevel(int hunger);
char * gethungername(enum HUNGER hunger, char *buf);
int gethungerval(lifeform_t *lf);
job_t *getjob(lifeform_t *lf);
int getlastdir(lifeform_t *lf);
int getlfaccuracy(lifeform_t *lf, object_t *wep);
enum LFCONDITION getlfcondition(lifeform_t *lf);
int getnightvisrange(lifeform_t *lf);
@ -124,7 +128,7 @@ int getpoisondamchance(enum POISONTYPE ptype);
char *getpoisondamverb(enum POISONTYPE ptype);
char *getpoisonname(enum POISONTYPE ptype);
int getraceclass(lifeform_t *lf);
int getracerarity(enum RACE rid);
int getracerarity(map_t *map, enum RACE rid);
object_t *getrandomarmour(lifeform_t *lf);
//int getrandommonlevel(int depth);
race_t *getrandomrace(map_t *map, int forcedepth);
@ -187,7 +191,9 @@ int ispetof(lifeform_t *lf, lifeform_t *owner);
int isplayer(lifeform_t *lf);
flag_t *ispoisoned(lifeform_t *lf);
int ispolymorphed(lifeform_t *lf);
int isprone(lifeform_t *lf);
flag_t *isresistantto(flagpile_t *fp, enum DAMTYPE dt);
object_t *isstuck(lifeform_t *lf);
flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt);
void killjob(job_t *job);
void killlf(lifeform_t *lf);
@ -227,7 +233,7 @@ int rolliq(enum IQBRACKET bracket);
int rollstr(enum STRBRACKET bracket);
int rollstat(lifeform_t *lf, enum ATTRIB attr);
int safetorest(lifeform_t *lf);
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong);
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
int setammo(lifeform_t *lf, object_t *o);
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
void setguntarget(lifeform_t *lf, lifeform_t *targ);

617
log.txt
View File

@ -12,88 +12,6 @@ xxx
xxx
xxx
xxx
xxx
xxx
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
-> possibility: xat, rarity=95
-> possibility: giant bat, rarity=95
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=95
got 5 possibilities.
finding random lf with rarity val 92-100
-> possibility: kobold, rarity=95
@ -215,70 +133,481 @@ finding random lf with rarity val 92-100
-> possibility: giant rat, rarity=95
got 5 possibilities.
rollhitdice() - rolling 2d4 + 2
rollhitdice() - mod is +54%
rollhitdice() ---- die 1/2 == 5
rollhitdice() ---- die 2/2 == 3
rollhitdice() - mod is +44%
rollhitdice() ---- die 1/2 == 4
rollhitdice() ---- die 2/2 == 4
TOTAL: 8
-> modified to: 12
-> modified to: 11
test
givejob() starting.
processing normal flag: 171
processing normal flag: 171
processing normal flag: 171
processing normal flag: 220
processing normal flag: 221
processing normal flag: 176
processing normal flag: 176
processing normal flag: 176
processing normal flag: 172
processing normal flag: 172
processing normal flag: 170
processing normal flag: 170
processing normal flag: 337
processing normal flag: 337
processing normal flag: 337
processing normal flag: 172
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 251
processing normal flag: 326
processing normal flag: 158
processing normal flag: 228
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 174
processing normal flag: 175
processing normal flag: 175
processing normal flag: 175
processing normal flag: 175
processing normal flag: 175
processing normal flag: 175
processing normal flag: 175
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 173
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 263
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 175
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 260
processing normal flag: 338
test
rollhitdice() - rolling 1d4 + 1
rollhitdice() - mod is +54%
rollhitdice() ---- die 1/1 == 4
TOTAL: 4
-> modified to: 6
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { cannot see my master - adding F_TARGETCELL for last known loc }
.oO { something going to targecell: 1, 2 }
.oO { walking from 1,4 towards f_targetcell (1,2) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,3 }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving randomly }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { cannot see my master - adding F_TARGETCELL for last known loc }
.oO { your young wolf going to targecell: 1, 1 }
.oO { walking from 1,3 towards f_targetcell (1,1) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,2 }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { didn't find any obs i want }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving randomly }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { cannot see my master - adding F_TARGETCELL for last known loc }
.oO { something going to targecell: 1, 1 }
.oO { walking from 3,1 towards f_targetcell (1,1) ... }
.oO { successfully walked towards f_targetcell. arrived at 2,1 }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { didn't find any obs i want }
.oO { walking from 2,1 towards f_targetcell (1,1) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,1 }
.oO { arrived at f_targetcell. removing. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { i can see my master - moving towards them }
.oO { success. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { cannot see my master - adding F_TARGETCELL for last known loc }
.oO { something going to targecell: 1, 13 }
.oO { walking from 1,10 towards f_targetcell (1,13) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,11 }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { didn't find any obs i want }
.oO { walking from 1,11 towards f_targetcell (1,13) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,12 }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { didn't find any obs i want }
.oO { walking from 1,12 towards f_targetcell (1,13) ... }
.oO { successfully walked towards f_targetcell. arrived at 1,13 }
.oO { arrived at f_targetcell. removing. }
AIMOVE: your young wolf
.oO { looking for covetted objects... }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { looking for any ob which i want. }
.oO { no targetcell, so looking for remote objects }
.oO { didn't find any obs i want }
.oO { i do not have a target or can't move towards it. }
.oO { i am friendly to the player. looking for a target. }
.oO { cannot see my master and am at last known loc. trying last known dir (Southeast) }
.oO { ...successfully }

14
map.c
View File

@ -408,6 +408,9 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
if (c->lf && cansee(viewer, c->lf)) { // lifeform here which we can see
// draw the lf's race glyph
*g = *(getlfglyph(c->lf));
if (isprone(c->lf)) {
g->ch = flip(g->ch);
}
return;
} else { // we can see the floor here
void *thing;
@ -1676,11 +1679,13 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
for (y = c->y - range-1 ; y <= c->y + range+1 ; y++) {
for (x = c->x - range-1 ; x <= c->x + range+1 ; x++) {
cell_t *cc;
int mydist;
cc = getcellat(c->map, x,y);
if (cc && (getcelldist(c, cc) <= (range+1))) {
mydist = getcelldist(c,cc);
if (cc && (mydist <= (range+1))) {
if (cc->lf && !isdead(cc->lf)) {
// move away from centre of explosion
knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS), 2, NULL);
knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS), 2, NULL, 40-(mydist*10));
}
}
}
@ -1974,7 +1979,10 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum OB
for (y = c->y - radius ; y <= c->y + radius ; y++) {
for (x = c->x - radius ; x <= c->x + radius ; x++) {
new = getcellat(c->map, x, y);
if (new && (getcelldist(c,new) == radius) && haslof(c, new, LOF_WALLSTOP, NULL)) {
if (new &&
(new != c) &&
(getcelldist(c,new) == radius) &&
haslof(c, new, LOF_WALLSTOP, NULL)) {
enum OBTYPE *badoid;
int ok = B_FALSE;
numwithlof++;

233
move.c
View File

@ -11,6 +11,7 @@
#include "move.h"
#include "nexus.h"
#include "objects.h"
#include "spell.h"
#include "text.h"
extern lifeform_t *player;
@ -177,9 +178,11 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
if (cell->type->solid) {
// mover is noncorporeal?
if (lf && lfhasflag(lf, F_NONCORPOREAL)) {
if (error) *error = E_WALLINWAY; // ok but still set reason
// ok
} else if (cell->lf && (cell->lf != lf)) { // someone (else) in the wall?
// ok
if (error) *error = E_LFINWAY; // ok but still set reason
return B_FALSE;
} else {
if (error) *error = E_WALLINWAY;
return B_FALSE;
@ -200,7 +203,8 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
(lf->race->material->id == MT_SLIME)) {
// ok
} else if (lfhasflag(lf, F_NONCORPOREAL)) {
// ok
// ok but still set error
*error = E_OBINWAY;
} else {
rdata = o;
if (error) {
@ -480,10 +484,11 @@ int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, in
return bestdir;
}
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher) {
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff) {
int i;
char lfname[BUFLEN];
int seen;
int hitwall = B_FALSE;
getlfname(lf,lfname);
if (cansee(player, lf)) {
@ -505,7 +510,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher) {
for (i = 0; i < howfar; i++) {
if (canmove(lf, dir, &reason)) {
if ((i == 0) && seen) {
msg("%s %s knocked backwards!",lfname,isplayer(lf) ? "are" : "is");
msg("%s %s knocked backwards!",lfname,is(lf));
}
trymove(lf, dir, B_FALSE);
}
@ -516,6 +521,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher) {
case E_OFFMAP:
msg("%s slam%s into a wall!",lfname,isplayer(lf) ? "" : "s");
losehp(lf, rnd(1,6), DT_BASH, pusher, "slamming into a wall");
hitwall = B_TRUE;
// stop moving
i = howfar;
break;
@ -524,6 +530,20 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher) {
}
}
}
// if you ran into a wall, it will prevent you from falling back.
if (!hitwall) {
int diff;
if (fallcheckdiff) {
diff = fallcheckdiff;
} else {
diff = howfar*10;
}
// save to avoid falling
if (!skillcheck(lf, SC_FALL, howfar*10, 0)) {
fall(lf, NULL, B_TRUE);
}
}
return B_FALSE;
}
@ -644,7 +664,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
killflagsofid(lf->flags, F_HIDING);
// remove grabs
// remove grabs (but not attached things)
f = lfhasflag(lf, F_GRABBING);
if (f) {
lifeform_t *grabee;
@ -654,6 +674,20 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
killflagsofid(lf->flags, F_GRABBING);
}
// passwall ends when you walk onto a non-solid cell.
f = lfhasflag(lf, F_NONCORPOREAL);
if (f && (f->obfrom == OT_S_PASSWALL)) {
enum ERROR err;
cellwalkable(lf, lf->cell, &err);
if (err == E_OK) {
stopspell(lf, OT_S_PASSWALL);
killflag(f);
if (isplayer(lf)) {
didmsg = B_TRUE;
}
}
}
// check ground objects
if (!isairborne(lf)) {
@ -710,8 +744,19 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
}
// kill object
removeob(o, o->amt);
continue;
}
} // end if crushable
if (o->type->id == OT_VINE) {
char obname[BUFLEN];
getobname(o,obname,o->amt);
if (isplayer(lf)) {
msg("%s grab%s you!",obname,(o->amt == 1) ? "s" : "");
} else if (cansee(player, lf)) {
msg("%s grab%s %s!",obname, (o->amt == 1) ? "s" : "", lfname);
}
}
} // end foreach object in cell
} // end if !flying
@ -752,6 +797,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
}
}
// does anyone else see you?
if ((gamemode == GM_GAMESTARTED)) {
for (l = newcell->map->lf ; l ; l = l->next) {
@ -760,7 +806,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
int dointerrupt = B_FALSE;
if (isplayer(l)) {
if (areenemies(lf, l)) {
if (cansee(l, lf) && areenemies(lf, l)) {
if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_RESTING)) {
char lfname2[BUFLEN];
getlfname(lf, lfname);
@ -800,6 +846,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// does other game things like telling the player
// what is here.
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
object_t *o;
char lfname[BUFLEN];
int didmsg;
int predark = B_FALSE,postdark = B_FALSE;
@ -849,7 +896,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
if (!isdead(lf)) {
// some lifeforms can go through things
if (lf->race->material->id == MT_GAS) {
object_t *o;
char obname[BUFLEN];
for (o = newcell->obpile->first ; o ; o = o->next) {
if (isimpassableob(o, lf)) {
@ -862,7 +908,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
}
}
} else if (lf->race->material->id == MT_SLIME) {
object_t *o;
char obname[BUFLEN];
for (o = newcell->obpile->first ; o ; o = o->next) {
if (isimpassableob(o, lf)) {
@ -889,6 +934,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
}
}
// make some noise
// (stealth check to avoid this)
if (!lfhasflag(lf, F_SILENTMOVE)) {
@ -1123,7 +1169,7 @@ int closedoor(lifeform_t *lf, object_t *o) {
} else {
// close it
killflag(f);
addflag(o->flags, F_IMPASSABLE, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
if (lf) {
@ -1190,7 +1236,7 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
if (isplayer(lf) || cansee(player, lf)) {
char buf[BUFLEN];
getlfname(lf, buf);
msg("%s %s pulled %s!", buf, isplayer(lf) ? "are" : "is",
msg("%s %s pulled %s!", buf, is(lf),
isairborne(lf) ? "through the air" :
"along the ground");
}
@ -1207,49 +1253,22 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
char buf[BUFLEN];
flag_t *f;
// check for cursed objects in new cell + animals
// do this AFTER checking if we will move, so that
// they will actually try the move and fail (this lets
// the player find out about the cursed object).
//
// note however that if a monster is chasing a player (ie
// has F_TARGET,player) then they will simply avoid the cursed
// object rather than failing the movement.
if (cell) {
for (o = cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (!isplayer(lf)) {
if ((o->blessed == B_CURSED) && lfhasflag(lf, F_ANIMAL) && !isairborne(lf)) {
if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf,lfname);
getobname(o, buf, o->amt);
msg("%s %s away from %s!", lfname, isplayer(lf) ? "shy" : "shies", buf);
o->blessknown = B_TRUE;
if (didmsg) *didmsg = B_TRUE;
}
taketime(lf, getmovespeed(lf));
reason = E_OK;
// avoid this object in future
sprintf(buf, "%ld",o->id);
addflag(lf->flags, F_AVOIDCURSEDOB, NA, NA, NA, buf);
return B_TRUE;
}
}
}
}
// gravboosted
if (lfhasflag(lf, F_GRAVBOOSTED)) {
// make a saving throw to move
if (!skillcheck(lf, SC_STR, 25, 0)) {
if (isplayer(lf)) {
msg("You try to move but are unable to lift your feet!");
msg("You try to %s but are unable to %s!",
isprone(lf) ? "stand" : "move",
isprone(lf) ? "lift your arms" : "lift your feet");
if (didmsg) *didmsg = B_TRUE;
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s tries to move but is unable to lift its feet!",lfname);
msg("%s tries to %s but is unable to %s!", lfname,
isprone(lf) ? "stand" : "move",
isprone(lf) ? "get up" : "lift its feet");
if (didmsg) *didmsg = B_TRUE;
}
reason = E_OK;
@ -1258,7 +1277,6 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
}
}
// sticky objects in current cell?
for (o = lf->cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
@ -1319,6 +1337,31 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
}
}
// are we on the ground?
if (isprone(lf)) {
int howlong;
float quartermax;
int units;
if (isplayer(lf)) {
msg("You stand up.");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s stands up.",lfname);
}
killflagsofid(lf->flags, F_PRONE);
// time to get up depends on armour
// 1*movespeed for every 1/4 of maxcarryweight being worn.
quartermax = getmaxcarryweight(lf) / 4;
units = (getequippedweight(lf) / quartermax)+1;
howlong = getmovespeed(lf)*units;
taketime(lf, howlong);
reason = E_OK;
return B_TRUE;
}
// slipping on something before moving?
if (!isairborne(lf)) {
int slip;
@ -1332,6 +1375,38 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
return B_TRUE;
}
}
// check for cursed objects in new cell + animals
// do this AFTER checking if we will move, so that
// they will actually try the move and fail (this lets
// the player find out about the cursed object).
//
// note however that if a monster is chasing a player (ie
// has F_TARGET,player) then they will simply avoid the cursed
// object rather than failing the movement.
if (cell) {
for (o = cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (!isplayer(lf)) {
if ((o->blessed == B_CURSED) && (getraceclass(lf) == RC_ANIMAL) && !isairborne(lf)) {
if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf,lfname);
getobname(o, buf, o->amt);
msg("%s %s away from %s!", lfname, isplayer(lf) ? "shy" : "shies", buf);
o->blessknown = B_TRUE;
if (didmsg) *didmsg = B_TRUE;
}
taketime(lf, getmovespeed(lf));
reason = E_OK;
// avoid this object in future
sprintf(buf, "%ld",o->id);
addflag(lf->flags, F_AVOIDCURSEDOB, NA, NA, NA, buf);
return B_TRUE;
}
}
}
}
return B_FALSE;
}
@ -1388,6 +1463,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
enum ERROR errcode;
char buf[BUFLEN];
int dontclearmsg = B_FALSE;
int moveok;
flag_t *f;
f = isdrunk(lf);
@ -1401,15 +1477,64 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
}
cell = getcellindir(lf->cell, dir);
if (canandwillmove(lf, dir, &errcode)) {
moveok = B_FALSE;
if (onpurpose) {
if (canandwillmove(lf, dir, &errcode)) {
moveok = B_TRUE;
}
} else {
if (canmove(lf, dir, &errcode)) {
moveok = B_TRUE;
}
}
if (moveok) {
lifeform_t *alf;
if (initiatemove(lf, cell, &dontclearmsg)) {
// failed?
return B_FALSE;
}
// move to new cell
reason = E_OK;
// remember last dir we walked
killflagsofid(lf->flags, F_LASTDIR);
addflag(lf->flags, F_LASTDIR, dir, NA, NA, NULL);
// do your pets see you move?
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
lifeform_t *l;
for (l = lf->cell->map->lf ; l ; l = l->next) {
if (ispetof(l,lf) && cansee(l, lf)) {
killflagsofid(l->flags, F_OWNERLASTDIR);
addflag(l->flags, F_OWNERLASTDIR, dir, NA, NA, NULL);
}
}
}
moveto(lf, cell, onpurpose, dontclearmsg);
taketime(lf, getmovespeed(lf));
if (onpurpose) {
taketime(lf, getmovespeed(lf));
}
// attached things will move the same direction if they can
for (alf = cell->map->lf ; alf ; alf = alf->next) {
if (lfhasflagval(alf, F_ATTACHEDTO, lf->id, NA, NA, NULL)) {
// if the lifeform we were attached to just moved away from us,
// try to stay with them.
if (getcelldist(alf->cell,lf->cell) > 1) {
int newdir;
newdir = getdirtowards(alf->cell, lf->cell, alf, B_FALSE, DT_ORTH);
// do a manual canmove check here first, to avoid 'the stirge flies into a wall'
// if the move fails.
if ((newdir != D_NONE) && canmove(alf, newdir, NULL)) {
trymove(alf, newdir, B_FALSE);
}
}
}
}
} else {
object_t *inway = NULL;
int door, dooropen;
@ -1439,12 +1564,12 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
losehp(lf, 1, DT_BASH, NULL, buf);
// we now know there is a wall there.
cell->known = B_TRUE;
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
}
} else {
sprintf(buf, "%sing into a wall", getmoveverb(lf));
losehp(lf, 1, DT_BASH, NULL, buf);
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
}
}
break;
@ -1463,7 +1588,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
cell->known = B_TRUE;
sprintf(buf, "%sing into a door", getmoveverb(lf));
losehp(lf, 1, DT_BASH, NULL, buf);
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
}
} else {
if (cansee(player, lf)) {
@ -1472,7 +1597,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
}
sprintf(buf, "%sing into a door", getmoveverb(lf));
losehp(lf, 1, DT_BASH, NULL, buf);
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
}
} else {
// try to open it
@ -1531,7 +1656,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
// move you..
moveto(lf, cell, onpurpose, B_FALSE);
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
// move them...
lfinway->cell = oldcell;
@ -1551,7 +1676,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
if (isplayer(lf)) {
msg("You cannot move!");
}
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
break;
case E_GRABBEDBY:
if (rdata) {
@ -1576,13 +1701,13 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
msg("You cannot get away from whatever is holding you!");
}
}
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
break;
case E_TOOHEAVY:
if (isplayer(lf)) {
msg("Your load is too heavy to move with!");
}
taketime(lf, getmovespeed(lf));
if (onpurpose) taketime(lf, getmovespeed(lf));
break;
default:
break;

2
move.h
View File

@ -11,7 +11,7 @@ int diropposite(int dir);
void dorandommove(lifeform_t *lf, int badmovesok);
int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher);
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff);
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype);
int moveeffects(lifeform_t *lf);
int movelf(lifeform_t *lf, cell_t *newcell);

34
nexus.c
View File

@ -78,6 +78,8 @@ int main(int argc, char **argv) {
char welcomemsg[BUFLEN];
int ch;
FILE *playerfile = NULL;
int x,y;
cell_t *c;
atexit(cleanup);
@ -242,6 +244,7 @@ int main(int argc, char **argv) {
sprintf(welcomemsg, "Greetings %s, welcome to %snexus!", pname, newworld ? "the new " : "");
// 00:00 - 23:59
curtime = rnd(0,86399);
} else {
sprintf(welcomemsg, "Welcome back!");
}
@ -256,6 +259,18 @@ int main(int argc, char **argv) {
// pre-calc line-of-sight for player
precalclos(player);
// don't want any mosnters starting within los of player
for (y = 0; y < player->cell->map->h; y++) {
for (x = 0; x < player->cell->map->w; x++) {
c = getcellat(player->cell->map, x, y);
if (c && c->lf && haslos(player, c)) {
if (!isplayer(c->lf) && !ispetof(c->lf, player)) {
killlf(c->lf);
}
}
}
}
// show level
drawscreen();
@ -592,8 +607,20 @@ enum COLOUR getpctcol(float num, float max) {
return C_ORANGE;
}
void getrarity(int depth, int *min, int *max, int range) {
void getrarity(int depth, int *min, int *max, int range, int oodok) {
int mid;
int num;
// adjust depth for out-of-depth things
if (oodok && (onein(6))) {
// repeated 1/3 chances of incing level
num = rnd(1,6) - 4;
while (num > 0) {
depth += num;
num = rnd(1,6) - 4;
}
}
mid = 100 - (depth * 3);
*min = mid - range; if (*min < 0) *min = 0;
//*max = mid + range; if (*max > 100) *max = 100;
@ -766,6 +793,11 @@ int limit(int *what, int min, int max) {
return limited;
}
int onein(int howmany) {
if (rnd(1,howmany) == 1) return B_TRUE;
return B_FALSE;
}
int parseplayerfile(FILE *f, lifeform_t *lf) {
// add extra obs etc from f
char *pp;

View File

@ -9,13 +9,14 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in
void donextturn(map_t *map);
char *getdirname(int dir);
enum COLOUR getpctcol(float num, float max);
void getrarity(int depth, int *min, int *max, int range);
void getrarity(int depth, int *min, int *max, int range, int oodok);
int init(void);
void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels);
void initbresnham(int x1, int y1, int x2, int y2, int *xinc1, int *yinc1, int *dinc1, int *xinc2, int *yinc2, int *dinc2, int *numpixels, int *d);
void initcommands(void);
int isplayerturn(void);
int limit(int *what, int min, int max);
int onein(int howmany);
int parseplayerfile(FILE *f, lifeform_t *lf);
float pctof(float pct, float num);
int rnd(int min, int max);

497
objects.c

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fr
obmod_t *addobmod(enum OBMOD id, char *prefix);
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid);
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid);
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype);
int adjustarmourpenalty(lifeform_t *lf, float amt);
@ -46,7 +46,7 @@ brand_t *findbrand(enum BRAND id);
obmod_t *findobmod(enum OBMOD id);
objecttype_t *findot(enum OBTYPE id);
objecttype_t *findotn(char *name); // find objecttype by name
void fragments(cell_t *centre, char *what, int speed);
void fragments(cell_t *centre, char *what, int speed, int howfar);
void genhiddennames(void);
int getcharges(object_t *o);
int geteffecttime(int min, int max, enum BLESSTYPE isblessed);
@ -84,7 +84,8 @@ char *getobequipinfo(object_t *o, char *buf);
char *getobextrainfo(object_t *o, char *buf);
cell_t *getoblocation(object_t *o);
char *getobname(object_t *o, char *buf, int count);
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse);
char *getobnametrue(object_t *o, char *buf, int count);
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall);
float getobpileweight(obpile_t *op);
char *getobconditionname(object_t *o, char *buf);
char *getobhurtname(object_t *o, enum DAMTYPE damtype);
@ -193,6 +194,7 @@ void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
void shufflehiddennames(void);
object_t *splitob(object_t *o);
int takedamage(object_t *o, unsigned int howmuch, int damtype);
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce);
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
void timeeffectsob(object_t *o);
void turnoff(lifeform_t *lf, object_t *o);

644
spell.c

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,9 @@ char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
void pullobto(object_t *o, lifeform_t *lf);
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
void stopallspells(lifeform_t *lf);
int summonlfs(lifeform_t *caster, enum RACECLASS wantrc, enum LFSIZE wantsize, int howmany, int lifetime);
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target);
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlos, enum LOFTYPE needlof, enum OBTYPE spellid, int power);
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, enum OBTYPE spellid, int power);
lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
#endif

53
text.c
View File

@ -82,6 +82,39 @@ char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dic
return dicebuf;
}
int flip(int ch) {
switch (ch) {
case 'a': return 0x0250;
case 'b': return 'q';
case 'c': return 0x0254;
case 'd': return 'p';
case 'e': return 0x01dd;
case 'f': return 0x025f;
case 'g': return 0x0183;
case 'h': return 0x0265;
case 'i': return 0x0131;
case 'j': return 0x027e;
case 'k': return 0x029e;
case 'l': return 0x0283;
case 'm': return 0x026f;
case 'n': return 'u';
case 'r': return 0x0279;
case 't': return 0x0287;
case 'v': return 0x028c;
case 'w': return 0x028d;
case 'y': return 0x028e;
case '.': return 0x02d9;
case '[': return ']';
case '(': return ')';
case '{': return '}';
case '?': return 0x00bf;
case '!': return 0x00a1;
case '<': return '>';
case '_': return 0x203e;
}
return ch;
}
char *getattrabbrev(enum ATTRIB att) {
switch (att) {
case A_NONE:
@ -255,6 +288,11 @@ char *getweighttext(float weight, char *buf) {
return buf;
}
char *is(lifeform_t *lf) {
if (isplayer(lf)) return "are";
else return "is";
}
int isvowel (char c) {
switch (c) {
case 'a':
@ -308,6 +346,8 @@ char *makeplural(char *text) {
if (rv) return newtext;
newtext = strrep(newtext, "splash ", "splashes ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "set ", "sets ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "suit ", "suits ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "vial ", "vials ", &rv);
@ -321,9 +361,12 @@ char *makeplural(char *text) {
// default
lastlet = text[strlen(text)-1];
switch (lastlet) {
char *temptext;
case 'y': // change to 'ies'
text[strlen(text)-1] = '\0';
asprintf(&newtext, "%sies",text);
temptext = strdup(text);
temptext[strlen(temptext)-1] = '\0';
asprintf(&newtext, "%sies",temptext);
free(temptext);
break;
case 's':
case 'o': // append "es"
@ -606,25 +649,28 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
return B_FALSE;
}
void texttospellopts(char *text, int *power, char *damstr, int *needgrab) {
void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range) {
char *p;
int n;
char *argname[] = {
"pw:",
"dam:",
"needgrab:",
"range:",
NULL,
};
void *argval[] = {
power,
damstr,
needgrab,
range,
NULL,
};
char argtype[] = {
'i',
's',
'b',
'i',
'\0',
};
@ -632,6 +678,7 @@ void texttospellopts(char *text, int *power, char *damstr, int *needgrab) {
if (power) *power = 0;
if (damstr) strcpy(damstr, "");
if (needgrab) *needgrab = B_FALSE;
if (range) *range = 0;
if (!strlen(text)) {
return;

4
text.h
View File

@ -4,6 +4,7 @@ int needan(char *text);
char *capitalise(char *text);
char *capitaliseall(char *text);
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf);
int flip(int ch);
char *getattrabbrev(enum ATTRIB att);
char *getattrname(enum ATTRIB att);
int gethitconferlifetime(char *text, int *min, int *max);
@ -13,6 +14,7 @@ char *getsizetext(enum LFSIZE sz);
char *gettimetext(char *retbuf);
char *gettimetextfuzzy(char *retbuf, int wantpm);
char *getweighttext(float weight, char *buf);
char *is(lifeform_t *lf);
int isvowel(char c);
char *makeplural(char *text);
char *makeuppercase(char *text);
@ -26,7 +28,7 @@ char *strrep(char *text, char *oldtok, char *newtok, int *rv);
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
int strpixmatch(char *haystack, char *needle);
int texttodice(char *text, int *ndice, int *nsides, int *bonus);
void texttospellopts(char *text, int *power, char *damstr, int *needgrab);
void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range);
char *you(lifeform_t *lf);
char *you_l(lifeform_t *lf);
char *your(lifeform_t *lf);