- [+] replace usage of controller == ...

- [+] change f_dam to use text field and combine with f_damtype
- [+] reduce unskilled weapon penalty
* [+] war cry - all make morale check vs user  or flee
* [+] change 'scare' fail results:
- [+] once you something flees form you, it is immune to fear from you
      for a while.
* [+] hurricanestrike ablity
- [+] check whether thrown poisoned dart works. didn't, but does now.
* [+] multiple staircases
- [+] CRASH - infinite death, then vomitted, then crash.
- [+] more wand of wonder effects 
- [+] armour skill
- [+] f_deaf
- [+] add size to lfstats
- [+] now runnign checkobdeath for lf's pack before checklfdeath.
* [+] add "{tried}" when you've traied an object but it's not ID'd
- [+] listening - at high levels this should let you detect life around
      you?
* [+] add more rings
* [+] 4leaf clover
* [+] possession spell
- [+] crash when getting job skills. You have learned the ability
      'warcry'.  Your training is interrupted!
* [+] nothing is doing much damage.
- [+] move physical details to 'effects' tab
- [+] make hexer appear with other goblins
- [+] brown snake shouldnt slip
- [+] make kobolds more common
- [+] make poison gas green
- [+] wand of invisibility should get known if we have seeinvis
- [+] when learning new skills, use askchoicestr
- [+] sunglasses should have f_noqual
- [+] make haste/slow more powerful
- [+] F_MAXATTACKS
* [+] hiddenname colour issues.
This commit is contained in:
Rob Pearce 2011-04-08 03:18:54 +00:00
parent 7e8aecf958
commit 975d3c6e4f
17 changed files with 2321 additions and 1178 deletions

15
ai.c
View File

@ -63,6 +63,7 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
if (!hasflag(lf->flags, F_HOSTILE)) {
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
}
killflagsofid(lf->flags, F_FRIENDLY);
}
}
@ -274,6 +275,7 @@ void aigoto(lifeform_t *lf, cell_t *c, int timelimit) {
void aimove(lifeform_t *lf) {
int db = B_FALSE;
object_t *curwep,*bestwep, *o;
int icanattack = B_FALSE;
object_t *curgun,*bestgun;
flag_t *f;
//flag_t *nextf;
@ -282,10 +284,6 @@ void aimove(lifeform_t *lf) {
enum BODYPART bp;
int x,y;
cell_t *c;
obpile_t *unarmedpile = NULL;
flag_t *unarmedflag = NULL;
/*
if (wantdb && haslos(player, lf->cell)) {
@ -365,8 +363,9 @@ void aimove(lifeform_t *lf) {
// now check whetehr we have ANY weapon
curwep = getattackwep(lf, &unarmedpile, &unarmedflag);
if (unarmedpile) killobpile(unarmedpile);
if (curwep || lfhasflag(lf, F_HASATTACK)) {
icanattack = B_TRUE;
}
// before attacking targets,
// look for any object which we _covet_.
@ -562,7 +561,7 @@ void aimove(lifeform_t *lf) {
}
// do we have a valid melee attack?
if (!curwep) {
if (!icanattack) {
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
goingtomove = B_FALSE;
}
@ -669,7 +668,7 @@ void aimove(lifeform_t *lf) {
// then move towards them...
if (db) dblog(".oO { moving towards my new target }");
if (curwep) {
if (icanattack) {
if (!movetowards(lf, c, DT_ORTH)) return;
} else {
if (db) dblog(".oO { won't move towards target - i have no weapon. }");

422
attack.c
View File

@ -97,24 +97,151 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
int attackcell(lifeform_t *lf, cell_t *c) {
int validwep[MAXCANDIDATES];
object_t *wep[MAXCANDIDATES];
flag_t *damflag[MAXCANDIDATES], *f;
obpile_t *op = NULL;
enum {
AT_NONE = 0,
AT_LF = 1,
AT_OB = 2,
} attacktype = AT_NONE;
void *attacktarget;
int nweps = 0;
int i;
int attacktime;
int gotweapon = B_FALSE;
// anyone there? if so just attack.
if (c->lf) {
attacklf(lf, c->lf);
if (isplayer(lf) && !areenemies(lf,c->lf)) {
char ch;
char victimname[BUFLEN];
char buf[BUFLEN];
getlfname(c->lf, victimname);
switch (getallegiance(c->lf)) {
case AL_PEACEFUL:
sprintf(buf, "Really attack the peaceful %s?",noprefix(victimname));
break;
case AL_FRIENDLY:
sprintf(buf, "Really attack the allied %s?",noprefix(victimname));
break;
default:
sprintf(buf, "Really attack the allied %s?",noprefix(victimname));
break;
}
ch = askchar(buf, "yn","n", B_TRUE);
if (ch == 'n') {
// cancel.
return B_TRUE;
}
}
attacktype = AT_LF;
attacktarget = c->lf;
} else {
object_t *o;
// has an mpassable object?
// has an impassable object?
o = hasobwithflag(c->obpile, F_IMPASSABLE);
if (o) {
attackob(lf, o);
attacktype = AT_OB;
attacktarget = o;
} else {
// TODO: attack wall?
return B_TRUE;
}
}
// first use our weapon...
wep[0] = getweapon(lf);
if (wep[0]) {
damflag[0] = hasflag(wep[0]->flags, F_DAM);
validwep[0] = B_TRUE;
nweps++;
gotweapon = B_TRUE;
}
// then use all our innate attacks..
for (f = lf->flags->first ; f; f = f->next) {
if (f->id == F_HASATTACK) {
objecttype_t *ot;
if (!op) {
op = addobpile(NULL, NULL);
}
ot = findot(f->val[0]);
if (ot) {
wep[nweps] = addob(op, ot->name);
validwep[nweps] = B_TRUE;
damflag[nweps] = f;
nweps++;
}
}
}
// take time
attacktime = getattackspeed(lf);
taketime(lf, attacktime);
// if we have a weapon, this takes the place of one of our
// attacks.
// for monsters, pick which one to replace randomly.
// for players, never pick the weapon which one to replace randomly.
if (gotweapon && (nweps > 1)) {
if (isplayer(lf)) {
validwep[rnd(1,nweps-1)] = B_FALSE;
} else {
validwep[rnd(0,nweps-1)] = B_FALSE;
}
}
// # valid attacks higher than our allowed attacks?
f = lfhasflag(lf, F_MAXATTACKS);
if (f) {
int max = f->val[0];
int nvalid;
nvalid = 0;
for (i = 0; i < nweps; i++) {
if (validwep[i]) nvalid++;
}
while (nvalid > max) {
int sel;
// mark a random one as invalid
sel = rnd(0,nweps-1);
while (!validwep[sel]) {
sel = rnd(0,nweps-1);
}
validwep[sel] = B_FALSE;
// re-count...
nvalid = 0;
for (i = 0; i < nweps; i++) {
if (validwep[i]) nvalid++;
}
}
}
for (i = 0; i < nweps; i++) {
if (validwep[i]) {
if (attacktype == AT_LF) {
attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i]);
} else if (attacktype == AT_OB) {
attackob(lf, (object_t *)attacktarget, wep[i], damflag[i]);
}
}
}
// now kill all temp obs
if (op) {
killobpile(op);
}
return B_FALSE;
}
int attacklf(lifeform_t *lf, lifeform_t *victim) {
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) {
int dam[100];
enum DAMTYPE damtype[100];
int ndam = 0;
@ -123,10 +250,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
char victimname[BUFLEN];
int fatal = B_FALSE;
int firstisbackstab = B_FALSE;
flag_t *unarmedflag = NULL;
object_t *wep;
obpile_t *op = NULL;
int attacktime;
int hit = B_FALSE;
int critical = 0;
char wepname[BUFLEN];
@ -134,6 +257,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
//int ev;
int i;
int willheal = B_FALSE;
int isunarmed = B_FALSE;
int aidb = B_FALSE;
@ -142,6 +266,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
aidb = B_TRUE;
}
if (hasflag(wep->flags, F_UNARMEDWEP)) {
isunarmed = B_TRUE;
}
moveeffects(lf);
if (isdead(lf)) {
@ -161,54 +289,16 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
getlfname(victim, victimname);
}
if (isplayer(lf) && !areenemies(lf,victim)) {
char ch;
switch (getallegiance(victim)) {
case AL_PEACEFUL:
sprintf(buf, "Really attack the peaceful %s?",noprefix(victimname));
break;
case AL_FRIENDLY:
sprintf(buf, "Really attack the allied %s?",noprefix(victimname));
break;
default:
sprintf(buf, "Really attack the allied %s?",noprefix(victimname));
break;
}
ch = askchar(buf, "yn","n", B_TRUE);
if (ch == 'n') {
// cancel.
return B_TRUE;
}
}
if (aidb) dblog(".oO { trying to attack %s }", victimname);
// get weapon
//wep = getweapon(lf);
wep = getattackwep(lf, &op, &unarmedflag);
if (!wep) {
if (isplayer(lf)) {
msg("You cannot attack!");
} else if (cansee(player, lf)) {
//msg("%s looks like it wants to attack!",attackername);
}
if (op) killobpile(op);
return B_TRUE;
}
getobname(wep, wepname, 1);
if (aidb) dblog(".oO { my weapon is %s %s }", wepname, unarmedflag ? "(unarmed)" : "");
// depends on weapon, race attackspeed modifier flag, etc
attacktime = getattackspeed(lf);
taketime(lf, attacktime);
if (aidb) dblog(".oO { my weapon is %s }", wepname);
// did you hit?
ndam = 0;
if (rolltohit(lf, victim, &critical)) {
if (rolltohit(lf, victim, wep, &critical)) {
int n;
hit = B_TRUE;
if (aidb) dblog(".oO { i hit! }");
@ -233,9 +323,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
msg("%s drops to the ground.", buf);
}
}
if (op) {
killobpile(op);
}
return B_FALSE;
}
}
@ -244,19 +331,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
// determine base damage
// determine damage
//if (unarmed && (unarmedflag->val[0] != NA)) {
// ie. if critical is 0, do this once.
// if critical is 1, do this twice.
// etc.
dam[0] = 0;
for (n = 0; n < critical+1; n++) {
if (unarmedflag) {
// this mosnter's unarmed attack will
// override normal damage calculation
dam[0] += getdamrollfromflag(unarmedflag);
} else {
dam[0] += getdamroll(wep, victim);
}
dam[0] += getdamroll(wep, victim, damflag);
}
if (aidb) dblog("rolled dam[%d] = %d",0,dam[0]);
@ -416,7 +493,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
strcpy(buf, attackername);
capitalise(buf);
if (wep && !unarmedflag && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
sprintf(withwep, " with %s", wepname);
} else {
strcpy(withwep, "");
@ -451,7 +528,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
real_getlfname(lf, attackername2, B_FALSE);
// victim loses hp
// don't adjust damage - we've already done that
if (wep && !unarmedflag) {
if (wep && !isunarmed) {
char wepname[BUFLEN];
getobname(wep, wepname, 1);
sprintf(buf, "%s^%s %s",attackername2,
@ -471,10 +548,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
} // end foreach damtype
// special weapon effects
wepeffects(wep->flags, victim->cell, dam[0]);
wepeffects(wep->flags, victim->cell, damflag, dam[0]);
if (!isdead(victim)) {
if (unarmedflag) {
if (isunarmed) {
f = lfhasflag(lf, F_FREEZINGTOUCH);
if (f) {
// victim turns to ice for a while!
@ -522,7 +599,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
}
// confer flags from attacker?
wepeffects(lf->flags, victim->cell, dam[0]);
wepeffects(lf->flags, victim->cell, damflag, dam[0]);
// special lifeform-based effects
if ((lf->race->id == R_COCKATRICE) && dam[0]) {
@ -595,12 +672,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
}
}
// get rid of temp unarmed object pile
if (op) {
killobpile(op);
}
// induction of fear?
if (!isdead(victim)) {
if (lfhasflag(victim, F_INDUCEFEAR)) {
@ -612,19 +683,15 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
return B_FALSE;
}
int attackob(lifeform_t *lf, object_t *o) {
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
int dam[100];
enum DAMTYPE damtype[100];
int ndam = 0;
char attackername[BUFLEN];
char obname[BUFLEN];
flag_t *f;
flag_t *unarmedflag = NULL;
object_t *wep;
obpile_t *op = NULL;
int isunarmed = B_FALSE;
cell_t *obloc = NULL;
int attacktime;
int unarmed = B_FALSE;
char wepname[BUFLEN];
int i;
//int aidb = B_TRUE;
@ -646,41 +713,15 @@ int attackob(lifeform_t *lf, object_t *o) {
maxhp = 1;
}
// get weapon
wep = getattackwep(lf, &op, &unarmedflag);
if (!wep) {
if (isplayer(lf)) {
msg("You cannot attack!");
} else if (cansee(player, lf)) {
//msg("%s looks like it wants to attack!",attackername);
}
if (!isplayer(lf)) {
// if ai, take some time to avoid infinite loops!
taketime(lf, getactspeed(lf));
}
if (op) killobpile(op);
return B_TRUE;
}
getobname(wep, wepname, 1);
// depends on weapon, race attackspeed modifier flag, etc
attacktime = getattackspeed(lf);
taketime(lf, attacktime);
// don't need to figure out accuracy - we always hit.
// determine damage
ndam = 0;
//if (unarmedflag && (unarmedflag->val[0] != NA)) {
if (unarmedflag) {
// this mosnter's unarmed attack will
// override normal damage calculation
dam[ndam] = getdamrollfromflag(unarmedflag);
} else {
dam[ndam] = getdamroll(wep, NULL);
}
dam[ndam] = getdamroll(wep, NULL, damflag);
// modify for strength
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
@ -712,7 +753,7 @@ int attackob(lifeform_t *lf, object_t *o) {
} else if (cansee(player, lf)) {
char withwep[BUFLEN];
if (wep && !unarmed && !isblind(player)) { // announce weapon used
if (wep && !isunarmed && !isblind(player)) { // announce weapon used
sprintf(withwep, " with %s", wepname);
} else {
strcpy(withwep, "");
@ -724,7 +765,7 @@ int attackob(lifeform_t *lf, object_t *o) {
noise(lf->cell, NULL, "sounds of fighting.", NULL);
}
if ((i == 0) && unarmedflag && hasflag(o->flags, F_HARD)) {
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARD)) {
char buf[BUFLEN];
sprintf(buf, "punching %s", obname);
if ( losehp(lf, 1, DT_BASH, lf, buf)) {
@ -740,9 +781,9 @@ int attackob(lifeform_t *lf, object_t *o) {
} // end foreach damtype
// special weapon effects
wepeffects(wep->flags, obloc, dam[0]);
wepeffects(wep->flags, obloc, damflag, dam[0]);
if (unarmedflag) {
if (isunarmed) {
// touch effects
touch(lf, o);
} else {
@ -760,12 +801,6 @@ int attackob(lifeform_t *lf, object_t *o) {
}
}
// get rid of temp unarmed object pile
if (op) {
killobpile(op);
}
return B_FALSE;
}
@ -943,6 +978,7 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
return "hit";
}
/*
object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag) {
object_t *wep;
@ -959,12 +995,13 @@ object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedf
}
return wep;
}
*/
enum DAMTYPE getdamtype(object_t *wep) {
flag_t *f;
enum DAMTYPE dt = DT_NONE;
f = hasflag(wep->flags, F_DAMTYPE);
f = hasflag(wep->flags, F_DAM);
if (f) {
dt = f->val[0];
} else {
@ -1078,20 +1115,12 @@ char *getkillverb(lifeform_t *victim, enum DAMTYPE damtype, int dam, int maxhp)
void getdamrange(flagpile_t *fp, int *min, int *max) {
void getdamrange(flag_t *f, int *min, int *max) {
int mindam,maxdam;
flag_t *f;
f = hasflag(fp, F_DAM);
if (f) {
int mod,ndice,sides;
ndice = f->val[0];
sides = f->val[1];
if (f->val[2] == NA) {
mod = 0;
} else {
mod = f->val[2];
}
texttodice(f->text, &ndice,&sides,&mod);
mindam = (ndice * 1) + mod;
maxdam = (ndice * sides) + mod;
@ -1104,71 +1133,68 @@ void getdamrange(flagpile_t *fp, int *min, int *max) {
if (max) *max = maxdam;
}
/*
void getdamrangeunarmed(flag_t *f, int *min, int *max) {
obpile_t *op;
object_t *o;
op = addobpile(NULL, NULL);
o = addob(op, f->text);
if (o) {
obpile_t *op = NULL;
object_t *o = NULL;
flag_t *damflag = NULL;
if (strlen(f->text)) {
damflag = f;
} else {
objecttype_t *ot;
ot = findot(f->val[0]);
op = addobpile(NULL, NULL);
// create the fake weapon
o = addob(op, ot->name);
if (o) {
damflag = hasflag(o->flags, F_DAM);
}
}
if (damflag) {
int ndice,nsides,mod;
flag_t *damflag;
damflag = hasflag(o->flags, F_DAM);
if (f->val[0] == NA) {
ndice = damflag->val[0];
} else {
ndice = f->val[0];
}
if (f->val[1] == NA) {
nsides = damflag->val[1];
} else {
nsides = f->val[1];
}
if (f->val[2] == NA) {
if (damflag->val[2] != NA) {
mod = damflag->val[2];
} else {
mod = 0;
}
} else {
mod = f->val[2];
}
texttodice(damflag->text, &ndice, &nsides, &mod);
if (min) *min = (ndice * 1) + mod;
if (max) *max = (ndice * nsides) + mod;
killob(o);
} else {
if (min) *min = 0;
if (max) *max = 0;
}
free(op);
if (o) {
killob(o);
}
if (op) {
free(op);
}
}
*/
// roll for damage
int getdamroll(object_t *o, lifeform_t *victim) {
int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
int dam;
int bonusdam = 0;
flag_t *f;
f = hasflag(o->flags, F_DAM);
if (f) {
dam = getdamrollfromflag(f);
if (damflag) {
dam = roll(damflag->text);
if (isblessed(o)) {
int dam2;
// blessed weapons get two rolls, and take the best
dam2 = getdamrollfromflag(f);
dam2 = roll(damflag->text);
if (dam2 > dam) dam = dam2;
} else if (iscursed(o)) {
int dam2;
// cursed weapons get two rolls, and take the worst
dam2 = getdamrollfromflag(f);
dam2 = roll(damflag->text);
if (dam2 < dam) dam = dam2;
}
} else {
// TODO wepaon does bashing damage based on weight
// TODO weapon does bashing damage based on weight
dam = rnd(1,2);
}
@ -1206,55 +1232,31 @@ float getdamreducepct(float armourrating) {
return reducepct;
}
int getdamrollfromflag(flag_t *f) {
objecttype_t *ot;
/*
int getunarmeddamroll(flag_t *f) {
int dam;
int ndice, sides, mod;
flag_t *damflag = NULL;
ot = findotn(f->text);
if (ot) {
if (f->text) {
// take damage from unarmed flag
damflag = f;
} else {
// take damage from wep type
objecttype_t *ot;
ot = findot(f->val[0]);
assert(ot);
damflag = hasflag(ot->flags, F_DAM);
}
// how many dice?
ndice = f->val[0];
if (ndice == NA) {
// get it from weapon definition
if (damflag && (damflag->val[0] != NA)) {
ndice = damflag->val[0];
} else {
ndice = 1;
}
}
sides = f->val[1];
if (sides == NA) {
// get it from weapon definition
if (damflag && (damflag->val[1] != NA)) {
sides = damflag->val[1];
} else {
sides = 1;
}
}
mod = f->val[2];
if (mod == NA) {
// get it from weapon definition
if (damflag && (damflag->val[2] != NA)) {
mod = damflag->val[2];
} else {
mod = 0;
}
}
dam = rolldie(ndice, sides) + mod;
dam = roll(damflag->text);
assert(dam < 1000);
assert(dam >= 0);
return dam;
}
*/
// returns a multiplier
@ -1299,6 +1301,7 @@ float getstrdammod(lifeform_t *lf) {
// determine attack type for lifeform.
// allocate a pile and add weapon to it.
// return the pile. remember to free it!
/*
obpile_t *getunarmedweapon(lifeform_t *lf,flag_t **uflag) {
int nposs;
flag_t *f;
@ -1331,6 +1334,7 @@ obpile_t *getunarmedweapon(lifeform_t *lf,flag_t **uflag) {
}
return op;
}
*/
int isphysicaldam(enum DAMTYPE damtype) {
switch (damtype) {
@ -1356,10 +1360,8 @@ int isphysicaldam(enum DAMTYPE damtype) {
return B_FALSE;
}
int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) {
int acc,ev;
object_t *wep;
obpile_t *op = NULL;
int gothit;
enum LFSIZE szlf,szvictim;
@ -1367,8 +1369,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
*critical = 0;
}
acc = getlfaccuracy(lf);
wep = getattackwep(lf, &op, NULL);
acc = getlfaccuracy(lf, wep);
// modify for defender's evasion
ev = getevasion(victim);
@ -1422,11 +1423,10 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
}
if (op) killobpile(op);
return gothit;
}
void wepeffects(flagpile_t *fp, cell_t *where, int dam) {
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
flag_t *f;
lifeform_t *victim;
lifeform_t *owner;
@ -1471,7 +1471,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, int dam) {
dampct = (ratio * 100); // ie. lower hp% = higher dampct
if (dampct >= 50) {
getdamrange(wep->flags, NULL, &maxdam);
getdamrange(damflag, NULL, &maxdam);
extradam = (int)(dampct * (float)maxdam);
if (extradam > 0) {
char buf[BUFLEN];

View File

@ -3,23 +3,23 @@
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *dam, enum DAMTYPE damtype);
int attackcell(lifeform_t *lf, cell_t *c);
int attacklf(lifeform_t *lf, lifeform_t *victim);
int attackob(lifeform_t *lf, object_t *o);
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
void confereffects(flagpile_t *fp, lifeform_t *victim);
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
//object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
enum DAMTYPE getdamtype(object_t *wep);
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam);
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam);
char *getkillverb(lifeform_t *victim, enum DAMTYPE damtype, int dam, int maxhp);
void getdamrange(flagpile_t *fp, int *min, int *max);
void getdamrangeunarmed(flag_t *f, int *min, int *max);
void getdamrange(flag_t *f, int *min, int *max);
//void getdamrangeunarmed(flag_t *f, int *min, int *max);
float getdamreducepct(float armourrating);
int getdamroll(object_t *o, lifeform_t *victim);
int getdamrollfromflag(flag_t *f);
int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag);
//int getunarmeddamroll(flag_t *f);
float getstrdammod(lifeform_t *lf);
obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
//obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
int isphysicaldam(enum DAMTYPE damtype);
int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical);
void wepeffects(flagpile_t *fp, cell_t *where, int dam);
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical);
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam);

49
defs.h
View File

@ -676,6 +676,7 @@ enum OBTYPE {
OT_SCR_TURNUNDEAD,
OT_SCR_WISH,
// BOOKS
OT_MAN_ARMOUR,
OT_MAN_ATHLETICS,
OT_MAN_BACKSTAB,
OT_MAN_FIRSTAID,
@ -876,8 +877,11 @@ enum OBTYPE {
OT_A_EMPLOY,
OT_A_HEAVYBLOW,
OT_A_INSPECT,
OT_A_HURRICANESTRIKE,
OT_A_POLYREVERT,
OT_A_STINGACID, // need to define dam in f_canwill
OT_A_WARCRY, // uses F_NOISETEXT -> N_WARCRY if it is there.
// otherwise 'shouts a blood-curdling war cry'
// wands
OT_WAND_COLD,
OT_WAND_DETONATION,
@ -1011,6 +1015,7 @@ enum OBTYPE {
OT_RING_MIRACLES,
OT_RING_MPREGEN,
OT_RING_PROTFIRE,
OT_RING_PROTCOLD,
OT_RING_REGENERATION,
OT_RING_RESISTMAG,
OT_RING_SIGHT,
@ -1119,6 +1124,7 @@ enum NOISETYPE {
N_GETANGRY,
N_WALK,
N_FLY,
N_WARCRY,
};
enum LFSIZE {
@ -1238,10 +1244,13 @@ enum FLAG {
F_LOCKED,// door is locked
F_JAMMED, // is this door jammed?
// stairs / teleporters / portals
F_CLIMBABLE, // this is a stiarcase
F_STAIRDIR, // val0 = direcion
F_CLIMBABLE, // this is a stiarcase, v0 = up/down
//F_STAIRDIR//, // val0 = direcion
F_OPPOSITESTAIRS, // val0 = opposite kind of stairs
F_MAPLINK, // val0 = map to link to. optional v1/v2 = x/y
F_MAPLINK, // val0 = map to link to.
// v1/v2 = x/y
// OR
// text = obid to link to
// ob interaction flags
F_HARD, // object is hard (ie. punching it will hurt!)
@ -1265,10 +1274,12 @@ enum FLAG {
F_USESSKILL, // weapon needs skill sk_v0
F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied
F_ATTREQ, // requires attrib v0 to be at least bracket v1
F_DAMTYPE, // val0 = damage type
F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
//F_DAMTYPE, // val0 = damage type
//F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
F_DAM, // v0 = damtype, text = 1d1+1
F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier)
F_ACCURACY, // 100 - val0 = penalty to tohit% (ie. higher is better)
F_UNARMEDWEP, // this is not a real weapon, ie. claws, teeth etc
F_ARMOURPIERCE, // goes through armour
F_TWOHANDED, // weapon uses two hands to weild
F_TRIPATTACK, // weapon can trip the victim
@ -1341,7 +1352,8 @@ enum FLAG {
F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
// lifeform flags / lf flags
F_DEBUG, // debugging enabled
F_SHIELDPENALTY, // modify your accuracy by val0 due to a cumbersome
F_ACCURACYMOD, // modify your accuracy by val0
F_SHIELDPENALTY, // lower your accuracy by val0 due to a cumbersome
// shield
F_ATTRMOD, // modify attribute val0 by val1. ie. 0=A_STR,1=-3
F_ATTRSET, // forces attribute val0 to be val1. ie. 0=A_STR,1=18
@ -1376,6 +1388,8 @@ enum FLAG {
F_SWOOPRANGE, // v0 = how far a flying creature can swoop
// MONSTER AI FLAGS
F_XPVAL, // force xp val for killing this lf to v0
// ...OR... monsters with this abil are worth
// v0 more xp.
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
@ -1392,6 +1406,7 @@ enum FLAG {
F_STABBEDBY, // lf has been stabbed by lfid v0. can't be stabbed
// by them again until they go out of sight.
F_FLEEFROM, // lf will run away from this lf id
F_NOFLEEFROM, // lf can not get f_fleefrom lfid v0
// TEMP FLAGS
F_KILLEDBYPLAYER, // did the player kill this lf?
@ -1408,6 +1423,7 @@ enum FLAG {
F_SPELLSPEED, // override default spellcast speed (ie. movespeed)
F_RARITY, // val[0] = habitat, val[1] = rarity
F_NUMAPPEAR, // when randomly appearing, can have > 1. val[0] = min, val[1] = max
F_MINIONS, // val0 % chance of appearing with v1-v2 lf of type text
F_HITDICE, // val0: # d4 to roll for maxhp per level. val1: +xx
F_MPDICE, // val0: # d4 to roll for maxmp per level. val1: +xx
F_JOB, // val0 = player's class/job
@ -1438,12 +1454,14 @@ enum FLAG {
// v2 or more monsters matching f->text next
// to the victim
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
F_MORALE, // gain +v0 in morale checks.
// INTRINSICS
F_MAGICARMOUR,// armour is magically boosted. f->text is the description
// ie 'magic armour', 'force field'
F_ASLEEP, // is asleep
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
F_BLIND, // cannot see anything
F_DEAF, // cannot hear
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.
@ -1519,14 +1537,15 @@ enum FLAG {
F_HASSKILL, // lf has skill v0 at level v1
F_PRACTICINGSKILL, // lf is pract skill v0
// COMBAT
F_HASATTACK, // objecttype id to use when attacking unarmed
// if val0-3 are filled in, they override the object's
// damage (x y-sided dice + z)
F_MAXATTACKS, // v0 = max # attacks this lf can make per round
F_HASATTACK, // v0 = obid to use when attacking unarmed
// if text is set, it overrides the damage
F_EVASION, // % chance of evading an attack
// healing/resting/training
F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times
// we can do it.
F_INTERRUPTED, // somethign interrupted our rest. stop!
F_RESTING, // are we resting? cleared on any action other than rest.
// v2 = if not, NA it is the training counter.
// when it hits 0, you finish trainign.
@ -1544,6 +1563,13 @@ enum FLAG {
F_IFMONSTER,
F_ENDIFPLAYER,
F_ENDIFMONSTER,
F_LEVSKILL, // at level v0, this job gains 1 point in skill v1
F_LEVABIL, // at level v0, this job gains f_canwill v1.
// v2 = how often you can do it (or NA for unlimited)
// text = options
F_LEVSPELL, // at level v0, this job gains f_cancast v1.
F_LEVFLAG, // at level v0, this job gains flagid v1, flagval0=v2,
// flagtext = text
//
F_NULL = -1
@ -1610,6 +1636,7 @@ enum SPELLTARGET {
#define B_UNKNOWN (0)
#define B_KNOWN (-1)
#define B_TRIED (1)
#define B_NOBADMOVES (0)
#define B_BADMOVESOK (1)
@ -1897,6 +1924,7 @@ typedef struct material_s {
#define SK_NONE -1
enum SKILL {
SK_ARMOUR,
SK_ATHLETICS,
SK_BACKSTAB,
SK_FIRSTAID,
@ -1931,7 +1959,7 @@ enum SKILL {
SK_SS_TRANSLOCATION,
SK_SS_WILD,
};
#define MAXSKILLS 32
#define MAXSKILLS 33
// proficiency levels
enum SKILLLEVEL {
@ -1959,6 +1987,7 @@ typedef struct hiddenname_s {
struct hiddenname_s *next, *prev;
} hiddenname_t;
typedef struct knowledge_s {
enum OBTYPE id;
char *hiddenname;

18
flag.c
View File

@ -105,7 +105,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
if ((gamemode == GM_GAMESTARTED)) {
if (f->pile->owner) {
if (announceflaggain(f->pile->owner, f)) {
interrupt(f->pile->owner);
addflag(f->pile, F_INTERRUPTED, B_TRUE, NA, NA, NULL); // note: recursive call!
f->known = B_TRUE;
if (f->obfrom) {
object_t *ob;
@ -322,8 +322,18 @@ void killflag(flag_t *f) {
// notify
if ((gamemode == GM_GAMESTARTED)) {
if (f->pile->owner) {
if (announceflagloss(f->pile->owner, f)) {
if (lf) {
// special cases
if (f->id == F_FLEEFROM) {
// once you recover from fleeing from something,
// you don't find it scary for a little while.
if (!lfhasflagval(lf, F_NOFLEEFROM, f->val[0], NA, NA, NULL)) {
addtempflag(lf->flags, F_NOFLEEFROM, f->val[0], NA, NA, NULL, 10);
}
}
// announce
if (announceflagloss(lf, f)) {
// don't include flags which interrupt will kill!
switch (f->id) {
case F_RESTING:
@ -331,7 +341,7 @@ void killflag(flag_t *f) {
case F_AUTOCMD:
break;
default:
interrupt(f->pile->owner);
addflag(lf->flags, F_INTERRUPTED, B_TRUE, NA, NA, NULL);
break;
}
}

438
io.c
View File

@ -382,7 +382,7 @@ cell_t *askcoords(char *prompt, int targettype) {
int valid = B_FALSE;
if ((targettype & TT_MONSTER) && haslf(c) && cansee(player, c->lf) && (c->lf->controller != C_PLAYER)) {
valid = B_TRUE;
} else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && (c->lf->controller == C_PLAYER)) {
} else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) {
valid = B_TRUE;
} else if ((targettype & TT_OBJECT) && hasobject(c)) {
valid = B_TRUE;
@ -775,7 +775,17 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
objecttype_t *ot;
ot = findot(f->val[0]);
if (ot && (!hasflag(ot->flags, F_NOANNOUNCE))) {
msg("You have learned the ability '%s'.", ot->name);
char buf[BUFLEN];
sprintf(buf, "You have learned the ability '%s'.", ot->name);
/*
if (f->val[2] != NA) {
char turnbuf[BUFLEN];
sprintf(turnbuf, " (every %d turn%s)",f->val[2], (f->val[2] == 1) ? "" : "s");
strcat(buf, turnbuf);
}
strcat(buf, ".");
*/
msg(buf, ot->name);
donesomething = B_TRUE;
}
}
@ -876,8 +886,13 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, buf);
msg("%s turn%s to flee from %s!", lfname, isplayer(lf) ? "" : "s",
(cansee(player, lf2) || isplayer(lf2)) ? buf : "something");
if ((f->lifetime == PERMENANT) || (f->lifetime >= 4)) {
msg("%s turn%s to flee from %s!", lfname, isplayer(lf) ? "" : "s",
(cansee(player, lf2) || isplayer(lf2)) ? buf : "something");
} else { // jsut scared a little bit
msg("%s cower%s away from %s!", lfname, isplayer(lf) ? "" : "s",
(cansee(player, lf2) || isplayer(lf2)) ? buf : "something");
}
}
break;
case F_POISONED:
@ -1706,7 +1721,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
// if picking form a player's pack, use the object's letters.
// otherwise just label them a, b, c, etc.
if (op->owner && (op->owner->controller == C_PLAYER)) {
if (op->owner && isplayer(op->owner)) {
useobletters = B_TRUE;
} else {
useobletters = B_FALSE;
@ -1919,7 +1934,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
// if picking form a player's pack, use the object's letters.
// otherwise just label them a, b, c, etc.
if (op->owner && (op->owner->controller == C_PLAYER)) {
if (op->owner && isplayer(op->owner)) {
useobletters = B_TRUE;
} else {
useobletters = B_FALSE;
@ -2282,11 +2297,8 @@ void describeob(object_t *o) {
// weapons?
if (o->type->obclass->id == OC_WEAPON) {
int delay;
f = hasflag(o->flags, F_DAMTYPE);
if (f) {
if (hasflag(o->flags, F_DAM)) {
int bonus = 0;
int damtype;
damtype = f->val[0];
f = hasflag(o->flags, F_BONUS);
if (f && f->known) {
@ -2297,9 +2309,10 @@ void describeob(object_t *o) {
f = hasflag(o->flags, F_DAM);
if (f) {
char buf[BUFLEN];
char dicebuf[BUFLEN];
int mindam,maxdam;
getdamrange(o->flags, &mindam, &maxdam);
enum DAMTYPE damtype;
damtype = f->val[0];
getdamrange(f, &mindam, &maxdam);
mindam += bonus;
maxdam += bonus;
if (mindam < 0) mindam = 0;
@ -2311,27 +2324,14 @@ void describeob(object_t *o) {
sprintf(buf, "It inflicts %d-%d %s damage",mindam,maxdam, getdamname(damtype));
}
dicetotext(f->val[0], f->val[1], f->val[2], NULL, NULL, dicebuf, NULL);
//dicetotext(f->val[0], f->val[1], f->val[2], NULL, NULL, dicebuf, NULL);
strcat(buf, " (");
strcat(buf, dicebuf);
strcat(buf, f->text);
strcat(buf, ").");
/*
if (f->val[2] == NA) {
sprintf(dicebuf, " (%dd%d).", f->val[0], f->val[1]);
} else {
sprintf(dicebuf, " (%dd%d%c%d).", f->val[0], f->val[1],
(f->val[2] > 0) ? '+' : '-',
abs(f->val[2]));
}
strcat(buf,dicebuf);
*/
mvwprintw(mainwin, y, 0, "%s",buf);
y++;
} else {
mvwprintw(mainwin, y, 0, "It inflicts %s damage.",getdamname(damtype));
y++;
}
}
@ -2383,6 +2383,19 @@ void describeob(object_t *o) {
}
}
if (o->type->obclass->id == OC_WAND) {
if (isidentified(o)) {
int charges;
charges = getcharges(o);
if (charges) {
mvwprintw(mainwin, y, 0, "It has %d charges left.",charges);
} else {
mvwprintw(mainwin, y, 0, "It has no charges left.");
}
y++;
}
}
f = hasflag(o->flags, F_THROWMISSILE);
if (f) {
@ -5844,14 +5857,12 @@ void showlfstats(lifeform_t *lf, int showall) {
objecttype_t *ot;
int first;
int i;
int unarmed = B_FALSE;
flag_t *uflag = NULL;
float dammod;
int accmod;
enum BODYPART bp;
enum BODYPART missingbp[MAXBODYPARTS];
int nmissingbp;
obpile_t *op = NULL;
char ch;
char mode = '@';
char prompt[BUFLEN];
@ -5912,6 +5923,12 @@ void showlfstats(lifeform_t *lf, int showall) {
wprintw(mainwin, "%-20s", j->name); y++;
}
// size
mvwprintw(mainwin, y, 0, ftext, "Size");
wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++;
if (showall) {
float w;
w = getlfweight(lf, B_NOOBS);
@ -6067,38 +6084,128 @@ void showlfstats(lifeform_t *lf, int showall) {
// now go to second column
// WEAPON STUFF
// current weapon + dam
w = getweapon(lf);
if (w) {
int mindam,maxdam;
int bonus;
// weapon
sprintf(buf, "%s", w->type->name);
} else {
obpile_t *op = NULL;
op = getunarmedweapon(lf, &uflag); // will return a random weapon. TODO: show all?
if (op->first) {
w = op->first;
sprintf(buf, "%s (unarmed)", w->type->name);
unarmed = B_TRUE;
} else {
sprintf(buf, "N/A");
}
killobpile(op);
}
mvwprintw(mainwin, y2, x2, ftext, "Current Weapon");
wprintw(mainwin, "%-20s", buf); y2++;
mvwprintw(mainwin, y2, x2, ftext, "Weapon");
wprintw(mainwin, "%-20s", buf); y2++;
if (showall) {
// damage
f = hasflag(w->flags, F_BONUS);
if (f && f->known) {
// only tell player about bonuses if they are known.!
bonus = f->val[0];
} else {
bonus = 0;
}
f = hasflag(w->flags, F_DAM);
if (f) {
getdamrange(f, &mindam, &maxdam);
} else {
mindam = 0;
maxdam = 0;
}
mindam += bonus;
maxdam += bonus;
// apply damage mod for strength
if (!hasflag(w->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
mindam = (int)((float)mindam * dammod);
maxdam = (int)((float)maxdam * dammod);
}
if (mindam < 0) mindam = 0;
if (maxdam < 0) maxdam = 0;
sprintf(buf, "%d-%d",(int)mindam,(int)maxdam);
mvwprintw(mainwin, y2, x2, ftext, "Weapon Dmg");
wprintw(mainwin, "%-20s", buf); y2++;
if (showall) {
if (w) {
// chance to hit
acc = getlfaccuracy(lf);
mvwprintw(mainwin, y2, x2, ftext, "Accuracy");
acc = getlfaccuracy(lf, w);
mvwprintw(mainwin, y2, x2, ftext, "Wep.Accuracy");
wprintw(mainwin, "%d%%", acc); y2++;
}
} else {
// no damage
sprintf(buf, "N/A");
mvwprintw(mainwin, y2, x2, ftext, "Current Weapon");
wprintw(mainwin, "%-20s", buf); y2++;
}
// skip a line
y2++;
/*
if (showall) {
mvwprintw(mainwin, y2, x2, ftext, "Attack Dmg");
wprintw(mainwin, "%-20s", buf); y2++;
}
*/
// unarmed attacks
op = addobpile(NULL, NULL);
for (f = lf->flags->first ; f ; f = f->next) {
if (f->id == F_HASATTACK) {
object_t *o;
objecttype_t *ot;
ot = findot(f->val[0]);
o = addob(op, ot->name);
if (o) {
sprintf(buf, "%s", o->type->name);
// damage
if (showall) {
char dambuf[BUFLEN];
int mindam,maxdam;
getdamrange(f, &mindam, &maxdam);
// apply damage mod for strength
if (!hasflag(o->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
mindam = (int)((float)mindam * dammod);
maxdam = (int)((float)maxdam * dammod);
}
if (mindam < 0) mindam = 0;
if (maxdam < 0) maxdam = 0;
sprintf(dambuf, " (%d-%d dmg)",(int)mindam,(int)maxdam);
strcat(buf, dambuf);
}
mvwprintw(mainwin, y2, x2, ftext, "Innate Attack");
wprintw(mainwin, "%-20s", buf); y2++;
} // end if o
} // end if fid == hasattack
} // end for each flag
// no attacks at all?
if (!w && !op->first) {
sprintf(buf, "N/A");
mvwprintw(mainwin, y2, x2, ftext, "Attack");
wprintw(mainwin, "%-20s", buf); y2++;
}
// skip line
y2++;
// attack speed
if (w) {
if (w || op->first) {
speed = getattackspeed(lf);
getspeedname(speed, buf);
capitalise(buf);
@ -6106,55 +6213,7 @@ void showlfstats(lifeform_t *lf, int showall) {
wprintw(mainwin, "%-20s", buf); y2++;
}
// damage
if (w) {
int mindam,maxdam;
int bonus;
f = hasflag(w->flags, F_BONUS);
if (f && f->known) {
// only tell player about bonuses if they are known.!
bonus = f->val[0];
} else {
bonus = 0;
}
if (uflag) {
getdamrangeunarmed(uflag, &mindam, &maxdam);
} else {
f = hasflag(w->flags, F_DAM);
if (f) {
getdamrange(w->flags, &mindam, &maxdam);
} else {
mindam = 0;
maxdam = 0;
}
}
mindam += bonus;
maxdam += bonus;
// apply damage mod for strength
if (!hasflag(w->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
mindam = (int)((float)mindam * dammod);
maxdam = (int)((float)maxdam * dammod);
}
if (mindam < 0) mindam = 0;
if (maxdam < 0) maxdam = 0;
sprintf(buf, "%d-%d",(int)mindam,(int)maxdam);
} else {
// no damage
sprintf(buf, "N/A");
}
if (showall) {
mvwprintw(mainwin, y2, x2, ftext, "Attack Dmg");
wprintw(mainwin, "%-20s", buf); y2++;
}
killobpile(op);
y2++; // skip line
@ -6403,90 +6462,6 @@ void showlfstats(lifeform_t *lf, int showall) {
}
}
// obvious physical effects
// (NON-obvious intrinsics etc go on next page)
f = lfhasknownflag(lf, F_ASLEEP);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_BEINGSTONED);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s being turning to stone.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_FLYING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s flying.", you(lf), isplayer(lf) ? "are" : "is");
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");
y++;
}
f = lfhasknownflag(lf, F_GRABBEDBY);
if (f && (f->known)) {
lifeform_t *lf2;
char grabbername[BUFLEN];
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, grabbername);
} else {
strcpy(grabbername, "something");
}
sprintf(buf,"%s %s being held by %s.",you(lf), isplayer(lf) ? "are" : "is", grabbername);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_GRABBING);
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 holding on to %s.",you(lf), isplayer(lf) ? "are" : "is", grabeename);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_INVISIBLE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_LEVITATING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s levitating.", you(lf), isplayer(lf) ? "are" : "is");
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");
y++;
}
f = lfhasflag(lf, F_PRODUCESLIGHT);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s produce%s light.", you(lf), isplayer(lf) ? "" : "s");
y++;
}
f = lfhasknownflag(lf, F_SPRINTING);
if (f) {
if (f->val[0]) {
mvwprintw(mainwin, y, 0, "%s %s sprinting.", you(lf), isplayer(lf) ? "are" : "is");
y++;
} else {
mvwprintw(mainwin, y, 0, "%s %s exhausted.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
}
} else if (mode == 's') {
int exitnow = B_FALSE;
@ -6638,6 +6613,90 @@ void showlfstats(lifeform_t *lf, int showall) {
y++;
}
// obvious physical effects first.
f = lfhasknownflag(lf, F_ASLEEP);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_BEINGSTONED);
if (f) {
mvwprintw(mainwin, y, 0, "%s %s being turning to stone.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_FLYING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s flying.", you(lf), isplayer(lf) ? "are" : "is");
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");
y++;
}
f = lfhasknownflag(lf, F_GRABBEDBY);
if (f && (f->known)) {
lifeform_t *lf2;
char grabbername[BUFLEN];
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
getlfname(lf2, grabbername);
} else {
strcpy(grabbername, "something");
}
sprintf(buf,"%s %s being held by %s.",you(lf), isplayer(lf) ? "are" : "is", grabbername);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_GRABBING);
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 holding on to %s.",you(lf), isplayer(lf) ? "are" : "is", grabeename);
mvwprintw(mainwin, y, 0, buf);
y++;
}
f = lfhasknownflag(lf, F_INVISIBLE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
f = lfhasknownflag(lf, F_LEVITATING);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s levitating.", you(lf), isplayer(lf) ? "are" : "is");
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");
y++;
}
f = lfhasflag(lf, F_PRODUCESLIGHT);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s produce%s light.", you(lf), isplayer(lf) ? "" : "s");
y++;
}
f = lfhasknownflag(lf, F_SPRINTING);
if (f) {
if (f->val[0]) {
mvwprintw(mainwin, y, 0, "%s %s sprinting.", you(lf), isplayer(lf) ? "are" : "is");
y++;
} else {
mvwprintw(mainwin, y, 0, "%s %s exhausted.", you(lf), isplayer(lf) ? "are" : "is");
y++;
}
}
// show intrinsics
f = lfhasknownflag(lf, F_ATTRSET);
if (f && (f->known)) {
@ -6784,9 +6843,18 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_POISONED);
if (f && (f->known)) {
sprintf(buf, "%s %s poisoned.", you(lf), isplayer(lf) ? "are" : "is");
int knownfatal = B_FALSE;
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
if (poisonthreatenslife(lf)) {
knownfatal = B_TRUE;
}
}
sprintf(buf, "%s %s poisoned%s.", you(lf), isplayer(lf) ? "are" : "is",
knownfatal ? ", potentially fatally" : "");
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
(getskill(lf, SK_FIRSTAID) >= PR_ADEPT) ) {
(getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) {
char buf2[BUFLEN];
sprintf(buf2, " [max %d turns left]", f->lifetime);
strcat(buf, buf2);

845
lf.c

File diff suppressed because it is too large Load Diff

3
lf.h
View File

@ -47,6 +47,7 @@ skill_t *findskill(enum SKILL id);
skill_t *findskillbyname(char *name);
enum SKILLLEVEL findskilllevbyname(char *name);
int flee(lifeform_t *lf);
void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong);
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong);
void gainhp(lifeform_t *lf, int amt);
void gainlevel(lifeform_t *lf);
@ -77,7 +78,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 getlfaccuracy(lifeform_t *lf);
int getlfaccuracy(lifeform_t *lf, object_t *wep);
enum LFCONDITION getlfcondition(lifeform_t *lf);
int getnightvisrange(lifeform_t *lf);
char *getlfconditionname(enum LFCONDITION cond);

628
log.txt
View File

@ -8,9 +8,11 @@ xxx
xxx
xxx
xxx
xxx
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -20,10 +22,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -33,10 +36,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -46,10 +50,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -59,10 +64,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -72,10 +78,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -85,10 +92,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -98,10 +106,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -111,10 +120,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -124,10 +134,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -137,10 +148,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -150,10 +162,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -163,10 +176,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -176,10 +190,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -189,10 +204,11 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
@ -202,24 +218,61 @@ finding random lf with rarity val 85-100
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 10 possibilities.
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
rollhitdice() - rolling 2d4 + 2
rollhitdice() - mod is +32%
rollhitdice() ---- die 1/2 == 4
rollhitdice() ---- die 2/2 == 4
TOTAL: 8
-> modified to: 10
rollhitdice() - mod is +44%
rollhitdice() ---- die 1/2 == 6
rollhitdice() ---- die 2/2 == 3
TOTAL: 9
-> modified to: 12
givejob() starting.
processing normal flag: 200
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
processing normal flag: 162
processing normal flag: 162
processing normal flag: 162
processing normal flag: 162
processing normal flag: 157
processing normal flag: 157
processing normal flag: 157
@ -230,92 +283,437 @@ processing normal flag: 158
processing normal flag: 158
processing normal flag: 158
processing normal flag: 158
processing normal flag: 158
processing normal flag: 156
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 229
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 227
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 156
processing normal flag: 304
processing normal flag: 304
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 0
initial dam[0] = 6
adjusted for lf to dam[0] = 6
reduced by armour to dam[0] = 6
calcxp: calculating xpval for giant rat
calcxp: a teeth: == 1-2 dam, avg is 1.5
calcxp: a claws: == 1-3 dam, avg is 1.9
calcxp: avg damage dealt is 3.4
calcxp: DEFENCE IS 1.0
calcxp: avg damage dealt (with abilities) is 3.4
calcxp: ATTACKVAL IS 34.0
calcxp: xpval: 35.0 --> 35.0
calcxp: ------ FINAL XPVAL: 34 ------
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 1
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 1
initial dam[0] = 6
adjusted for lf to dam[0] = 6
reduced by armour to dam[0] = 6
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 7
adjusted for lf to dam[0] = 7
reduced by armour to dam[0] = 6
calcxp: calculating xpval for giant worker ant
calcxp: a teeth: == 4-4 dam, avg is 4.3
calcxp: avg damage dealt is 4.3
calcxp: DEFENCE IS 4.0
calcxp: avg damage dealt (with abilities) is 4.3
calcxp: ATTACKVAL IS 42.8
calcxp: xpval: 46.8 --> 46.8
calcxp: ------ FINAL XPVAL: 46 ------
rollhitdice() - rolling 2d4 + 2
rollhitdice() - mod is +66%
rollhitdice() ---- die 1/2 == 6
rollhitdice() ---- die 2/2 == 6
TOTAL: 12
-> modified to: 19
nwantflags is 1
nwantflags is 0
nwantflags is 0
nwantflags is 0
nwantflags is 0
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 0
nwantflags is 0
fireat(): dam = throwdam(5) * speed(2) = 10
calcxp: calculating xpval for xat
calcxp: a teeth: == 1-3 dam, avg is 1.7
calcxp: avg damage dealt is 1.7
calcxp: DEFENCE IS 4.0
calcxp: avg damage dealt (with abilities) is 1.7
calcxp: ATTACKVAL IS 17.2
calcxp: xpval: 21.2 --> 21.2
calcxp: ------ FINAL XPVAL: 21 ------
nwantflags is 0
nwantflags is 0
initial dam[0] = 3
adjusted for lf to dam[0] = 3
reduced by armour to dam[0] = 2
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 0
initial dam[0] = 3
adjusted for lf to dam[0] = 3
reduced by armour to dam[0] = 3
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 0
initial dam[0] = 2
adjusted for lf to dam[0] = 2
reduced by armour to dam[0] = 2
calcxp: calculating xpval for giant bat
calcxp: a teeth: == 1-2 dam, avg is 2.2
calcxp: a claws: == 1-3 dam, avg is 2.9
calcxp: avg damage dealt is 5.1
calcxp: DEFENCE IS 2.0
calcxp: avg damage dealt (with abilities) is 5.1
calcxp: ATTACKVAL IS 51.1
calcxp: xpval: 53.1 --> 53.1
calcxp: ------ FINAL XPVAL: 53 ------
nwantflags is 0
nwantflags is 0
nwantflags is 0
nwantflags is 0
initial dam[0] = 7
adjusted for lf to dam[0] = 7
reduced by armour to dam[0] = 6
initial dam[0] = 6
adjusted for lf to dam[0] = 6
reduced by armour to dam[0] = 5
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 4
calcxp: calculating xpval for goblin
calcxp: a claws: == 1-4 dam, avg is 2.7
calcxp: a gold coin: == 0-0 dam, avg is 0.0
calcxp: a short sword: == 1-6 dam, avg is 3.4
calcxp: avg damage dealt is 6.1
calcxp: DEFENCE IS 7.0
calcxp: avg damage dealt (with abilities) is 6.1
calcxp: ATTACKVAL IS 60.7
calcxp: xpval: 67.7 --> 67.7
calcxp: ------ FINAL XPVAL: 67 ------
nwantflags is 0
nwantflags is 0
nwantflags is 0
initial dam[0] = 9
adjusted for lf to dam[0] = 9
reduced by armour to dam[0] = 9
calcxp: calculating xpval for giant newt
calcxp: avg damage dealt is 0.0
calcxp: DEFENCE IS 4.0
calcxp: avg damage dealt (with abilities) is 0.0
calcxp: ATTACKVAL IS 0.0
calcxp: xpval: 4.0 --> 4.0
calcxp: ------ FINAL XPVAL: 4 ------
xxx
xxx
xxx
xxx
xxx
xxx
xxx
xxx
xxx
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
finding random lf with rarity val 85-100
-> possibility: goblin, rarity=85
-> possibility: kobold, rarity=90
-> possibility: troglodyte, rarity=85
-> possibility: xat, rarity=90
-> possibility: giant bat, rarity=90
-> possibility: giant worker ant, rarity=85
-> possibility: giant newt, rarity=100
-> possibility: giant rat, rarity=90
-> possibility: brown snake, rarity=85
-> possibility: giant fly, rarity=85
-> possibility: glowbug, rarity=85
got 11 possibilities.
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
nwantflags is 1
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 8
adjusted for lf to dam[0] = 8
reduced by armour to dam[0] = 6
initial dam[0] = 4
adjusted for lf to dam[0] = 4
reduced by armour to dam[0] = 3
initial dam[0] = 14
adjusted for lf to dam[0] = 14
reduced by armour to dam[0] = 13
calcxp: calculating xpval for giant worker ant
calcxp: a teeth: == 4-4 dam, avg is 5.2
calcxp: avg damage dealt is 5.2
calcxp: DEFENCE IS 4.0
calcxp: avg damage dealt (with abilities) is 5.2
calcxp: ATTACKVAL IS 51.6
calcxp: xpval: 55.6 --> 55.6
calcxp: ------ FINAL XPVAL: 55 ------
nwantflags is 0
initial dam[0] = 6
adjusted for lf to dam[0] = 6
reduced by armour to dam[0] = 5
initial dam[0] = 1
adjusted for lf to dam[0] = 1
reduced by armour to dam[0] = 0
initial dam[0] = 7
adjusted for lf to dam[0] = 7
reduced by armour to dam[0] = 6

212
map.c
View File

@ -117,9 +117,11 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
if (lf->cell->map->beingcreated) {
// sometimes start off asleep in new maps
// TODO: base this on the time, and whether monster is nocturnal
if (rnd(1,2) == 1) {
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
if (!lfhasflag(lf, F_DEAF)) {
// TODO: base this on the time, and whether monster is nocturnal
if (rnd(1,2) == 1) {
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
}
}
}
@ -131,45 +133,59 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
}
if (amt > 1) {
cell_t *adjcell;
cell_t **moncell;
int nmoncells = 1;
moncell = malloc( amt * sizeof(cell_t *));
moncell[0] = c;
nmoncells = 1;
amt--; // we've already added one
//adjcell = c;
for ( ; amt > 0; amt--) {
int n;
lifeform_t *newlf;
// find an adjacent cell to one of the newly added monsters,
// starting with the first one
adjcell = NULL;
for (n = 0; n < nmoncells; n++) {
adjcell = getrandomadjcell(moncell[n], WE_WALKABLE, B_ALLOWEXPAND);
if (adjcell) break;
}
adjcell = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
// did we find one?
if (!adjcell) break;
//lf = addlf(adjcell, r->id, getrandommonlevel(adjcell->map->depth));
newlf = addlf(adjcell, r->id, 1);
if (!newlf) {
break;
}
newlf->born = B_FALSE;
if (lfhasflag(lf, F_ASLEEP)) addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
newlf->born = B_TRUE;
moncell[nmoncells] = adjcell;
nmoncells++;
}
free(moncell);
}
// minons?
f = hasflag(lf->flags, F_MINIONS);
if (f) {
if (rnd(1,100) <= f->val[0]) {
int n;
cell_t *adjcell;
int nminions;
// override amount
nminions = rnd(f->val[1], f->val[2]);
for (n = 0; n < nminions; n++) {
lifeform_t *newlf;
race_t *newr;
adjcell = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
if (!adjcell) break;
newr = findracebyname(f->text);
if (!newr) break;
newlf = addlf(adjcell, newr->id, 1);
if (!newlf) break;
newlf->born = B_FALSE;
if (lfhasflag(lf, F_ASLEEP)) addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
newlf->born = B_TRUE;
}
}
}
// sometimes give the lf random objects (extra monsters through
// 'numappears' don't get them.
if (lfhasflag(lf, F_HUMANOID) && !lfhasflag(lf, F_NOPACK)) {
@ -252,7 +268,6 @@ int cellhaslos(cell_t *c1, cell_t *dest) {
// can always see your own cell
if ((deltax == 0) && (deltay == 0)) {
//if (viewer->controller == C_HUMAN) wreck->mazelev[z].maze[y2*MAZEW+x2].known = B_PERM;
return B_TRUE;
}
@ -644,7 +659,7 @@ int countcellexits(cell_t *cell) {
looppct = percentage change of turning dead-end into loop
maxrooms = max # of rooms
*/
void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_t *returnstairtype) {
void createmap(map_t *map, int depth, int habitat) {
char buf[BUFLEN];
int wantrooms = B_TRUE;
int x,y;
@ -662,7 +677,6 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
int maxroomh = MAX_ROOMH;
int bestx,besty;
int w,h;
objecttype_t *ot;
//int startdir,forcex,forcey,ntries;
cell_t *cell, *c;
object_t *o;
@ -920,37 +934,23 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
}
// add return staircase to previous map
c = NULL;
while (!c || !isempty(c) || countobs(c->obpile)) {
c = getrandomroomcell(map, ANYROOM);
}
o = addob(c->obpile, returnstairtype->name);
if (parentmap) {
cell_t *parentstairs;
objecttype_t *ot;
ot = getoppositestairs(returnstairtype);
// find stairs in parent map
parentstairs = findobinmap(parentmap, ot->id);
assert(parentstairs);
// link stairs on new map to stairs on parent map
addflag_real(o->flags, F_MAPLINK, parentmap->id, parentstairs->x, parentstairs->y, NULL, PERMENANT, B_UNKNOWN, -1);
}
// add staircase continuing on (normally this will be down)
if ((map->depth >= MAXDEPTH) && (returnstairtype->id == OT_STAIRSUP)) {
// no need for a down staircase on the last level!
} else {
// add staircases
for (i = 0; i < 3; i++) {
// add up stairs
c = NULL;
while (!c || !isempty(c) || countobs(c->obpile)) {
c = getrandomroomcell(map, ANYROOM);
}
ot = getoppositestairs(returnstairtype);
addob(c->obpile, ot->name);
// don't add F_MAPLINK yet - this will cocur when we use the stairs
}
o = addob(c->obpile, "staircase going up");
linkstairs(o);
c = NULL;
while (!c || !isempty(c) || countobs(c->obpile)) {
c = getrandomroomcell(map, ANYROOM);
}
o = addob(c->obpile, "staircase going down");
linkstairs(o);
}
/* void around map
// N
@ -1670,6 +1670,22 @@ map_t *findmapofdepth(int depth) {
return NULL;
}
// find the object with id 'id' in map 'm'
object_t *findobidinmap(map_t *m, long id) {
cell_t *c;
int x,y;
for (y = 0; y < m->h; y++) {
for (x = 0; x < m->w; x++) {
object_t *o;
c = getcellat(m, x, y);
o = findobbyid(c->obpile, id);
if (o) return o;
}
}
return NULL;
}
// find the cell in 'map' which contains object oid
cell_t *findobinmap(map_t *m, enum OBCLASS oid) {
cell_t *c;
@ -2017,6 +2033,40 @@ int getslipperyness(cell_t *c, object_t **slipob) {
return totalslip;
}
cell_t *getstairdestination(object_t *o) {
flag_t *f;
cell_t *newcell = NULL;
f = hasflag(o->flags, F_MAPLINK);
if (f) {
map_t *newmap;
int newx,newy;
newmap = findmap(f->val[0]);
assert(newmap);
// prefer an object id if we have it
if (strlen(f->text)) {
object_t *o2;
long obid;
obid = atol(f->text);
o2 = findobidinmap(newmap, obid);
if (o2) {
newcell = getoblocation(o2);
} else {
dblog("stairs link to object %ld which no longer exists!",obid);
msg("stairs link to object %ld which no longer exists!",obid);
return NULL;
}
} else {
// otherwise look for x/y coors
newx = f->val[1];
newy = f->val[2];
// find dst x/y
newcell = getcellat(newmap, newx, newy);
}
}
return newcell;
}
object_t *hasenterableobject(cell_t *c) {
return hasobwithflag(c->obpile, F_CLIMBABLE);
}
@ -2247,6 +2297,68 @@ int iswallindir(cell_t *cell, int dir) {
return B_FALSE;
}
// link the staircase 'o' to a free one in map 'othermap'
// returns TRUE if it failed because othermap doesn't exist.
int linkstairs(object_t *o) {
map_t *othermap;
object_t *o2;
map_t *stairmap;
cell_t *staircell;
cell_t *c2;
objecttype_t *otherstairtype;
int n,found = B_FALSE;
int dir;
flag_t *f;
staircell = getoblocation(o);
stairmap = staircell->map;
otherstairtype = getoppositestairs(o->type);
f = hasflag(o->flags, F_CLIMBABLE);
if (f) {
if (f->val[0] == D_UP) {
dir = -1;
} else {
dir = 1;
}
} else {
dblog("ERROR: stair object has no f_climbable!");
msg("ERROR: stair object has no f_climbable!");
exit(1);
}
othermap = findmapofdepth(stairmap->depth + dir);
if (othermap) {
// find an empty staircase in other map
for (n = 0; n < othermap->w*othermap->h; n++) {
c2 = othermap->cell[n];
o2 = hasob(c2->obpile, otherstairtype->id);
// does it go nowhere?
if (o2 && !hasflag(o2->flags, F_MAPLINK)) {
char obid[BUFLEN];
// link it to here!
sprintf(obid, "%ld", o->id);
addflag(o2->flags, F_MAPLINK, stairmap->id, NA, NA, obid);
// link me to there
sprintf(obid, "%ld", o2->id);
addflag(o->flags, F_MAPLINK, othermap->id, NA, NA, obid);
found = B_TRUE;
break;
}
}
if (!found) {
dblog("ERROR - stairs link to existing map #%d, but it has no free stairs.",othermap->id);
msg("ERROR - stairs link to existing map #%d, but it has no free stairs.",othermap->id);
exit(1);
}
} else {
return B_TRUE;
}
return B_FALSE;
}
void makedoor(cell_t *cell) {
object_t *o;
map_t *m;

5
map.h
View File

@ -17,7 +17,7 @@ int calcroompos(map_t *map, int w, int h, int *bx, int *by);
int countadjcellsoftype(cell_t *cell, int id);
int countadjcellswithflag(cell_t *cell, enum FLAG fid);
int countcellexits(cell_t *cell);
void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_t *returnstairtype);
void createmap(map_t *map, int depth, int habitat);
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid);
int dirtox(int dt, int dir);
int dirtoy(int dt, int dir);
@ -26,6 +26,7 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int wantannounce);
map_t *findmap(int mid);
map_t *findmapofdepth(int depth);
object_t *findobidinmap(map_t *m, long id);
cell_t *findobinmap(map_t *m, enum OBCLASS oid);
void forgetcells(map_t *map, int amt);
cell_t *getcellindir(cell_t *cell, int dir);
@ -37,6 +38,7 @@ cell_t *getrandomcelloftype(map_t *map, int id);
int getrandomdir(int dirtype);
cell_t *getrandomroomcell(map_t *map, int roomid);
int getslipperyness(cell_t *c, object_t **slipob);
cell_t *getstairdestination(object_t *o);
object_t *hasenterableobject(cell_t *c);
lifeform_t *haslf(cell_t *c);
int hasobject(cell_t *c);
@ -50,6 +52,7 @@ int isloopdirok(cell_t *cell, int dir);
int isnewcellok(cell_t *cell, char *err);
int isonmap(map_t *map, int x, int y);
int iswallindir(cell_t *cell, int dir);
int linkstairs(object_t *o);
void makedoor(cell_t *cell);
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);

12
move.c
View File

@ -627,7 +627,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (!boots) {
// take damage
getobname(o, obname, 1);
if (lf->controller == C_PLAYER) {
if (isplayer(lf)) {
msg("Ow - you step on %s!",obname);
didmsg = B_TRUE;
} else if (haslos(player, newcell)) {
@ -935,7 +935,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
if (f) killflag(f);
if (lf) {
if (lf->controller == C_PLAYER) {
if (isplayer(lf)) {
msg("You open %s.",obname);
} else {
if (cansee(player, lf) && isadjacent(lf->cell, doorcell)) {
@ -1031,7 +1031,7 @@ int closedoor(lifeform_t *lf, object_t *o) {
f = hasflag(o->flags, F_OPEN);
if (!f) {
if (lf && (lf->controller == C_PLAYER)) {
if (lf && (isplayer(lf))) {
msg("It is already closed!");
}
return B_TRUE;
@ -1042,7 +1042,7 @@ int closedoor(lifeform_t *lf, object_t *o) {
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
if (lf) {
if (lf->controller == C_PLAYER) {
if (isplayer(lf)) {
msg("You close %s.", obname);
} else {
if (cansee(player, lf) && isadjacent(lf->cell, cell)) {
@ -1307,7 +1307,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
// push it!
push(lf, inway, dir);
} else {
if (lf->controller == C_PLAYER) {
if (isplayer(lf)) {
char obname[BUFLEN];
getobname(inway, obname, 1);
switch (reason) {
@ -1360,7 +1360,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
}
} else {
// attack!
return attacklf(lf, cell->lf);
return attackcell(lf, cell);
}
break;
case E_CANTMOVE:

10
nexus.c
View File

@ -109,7 +109,7 @@ int main(int argc, char **argv) {
if (!firstmap) {
newworld = B_TRUE;
addmap();
createmap(firstmap, 1, H_DUNGEON, NULL, findot(OT_STAIRSUP));
createmap(firstmap, 1, H_DUNGEON);
}
if (!knowledge) {
@ -329,14 +329,14 @@ void checkdeath(void) {
for (lf = player->cell->map->lf; lf ; lf = nextlf) {
nextlf = lf->next;
// check for object death
removedeadobs(lf->pack);
// check for death
if (lf->hp <= 0) {
// die!
die(lf);
continue;
}
// check for object death
removedeadobs(lf->pack);
}
// check for object death on map
@ -392,6 +392,7 @@ void donextturn(map_t *map) {
who = map->lf;
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
assert(who->timespent == 0);
turneffectslf(who);
@ -409,7 +410,6 @@ void donextturn(map_t *map) {
autotarget(who);
assert(who->timespent == 0);
// keep looping until they actually do something or are dead!
while (who->timespent == 0) {
if (isdead(who)) {
@ -703,7 +703,7 @@ void initcommands(void) {
int isplayerturn(void) {
if (!player) return B_FALSE;
if (player->cell->map->lf->controller == C_PLAYER) {
if (isplayer(player->cell->map->lf)) {
return B_TRUE;
}
return B_FALSE;

699
objects.c

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@ obpile_t *addobpile(lifeform_t *owner, cell_t *where);
objecttype_t *addot(int 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);
int adjustshieldpenalty(lifeform_t *lf, float amt);
//void adjustprice(objecttype_t *ot, float *price );
void appendinscription(object_t *o, char *text);
@ -139,7 +140,10 @@ int ispourable(object_t *o);
int ispushable(object_t *o);
int isreadable(object_t *o);
int isrotting(object_t *o);
flag_t *isshield(object_t *o);
int isthrownmissile(object_t *o);
int istried(object_t *o);
int istriedot(objecttype_t *ot);
int isweapon(object_t *o);
int iswearable(object_t *o);
void killmaterial(material_t *m);
@ -151,6 +155,7 @@ int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher)
lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level);
void makeduller(object_t *o, int howmuch);
void makeknown(enum OBTYPE otid);
void maketried(enum OBTYPE otid);
void makewet(object_t *o, int amt);
object_t *moveob(object_t *src, obpile_t *dst, int howmany);
void modbonus(object_t *o, int amt);

102
spell.c
View File

@ -617,6 +617,46 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
f = addflag(wep->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL);
attackcell(user, targcell);
killflag(f);
} else if (abilid == OT_A_WARCRY) {
// announce
if (isplayer(user)) {
msg("You shout a blood-curdling war cry!");
}
makenoise(user, N_WARCRY);
// take a lot of time
taketime(user, getactspeed(user)*4);
// all in range must pass a morale check or flee
for (target = user->cell->map->lf ; target ; target = target->next) {
if ((target != user) && cansee(target, user) && areenemies(target, user)) {
if (canhear(target, user->cell)) {
scare(target, user, rnd(5,10));
}
}
}
} else if (abilid == OT_A_HURRICANESTRIKE) {
int dir;
cell_t *c;
flag_t *f,*f2;
// take time
// - NOTE: purposely using action speed, not weapon speed.
taketime(user, getactspeed(user));
// now don't take any more time for the actual attacks.
f = addflag(user->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
// lower accuracy
f2 = addflag(user->flags, F_ACCURACYMOD, -20, NA, NA, NULL);
// attack all adjacent enemies
for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(user->cell, dir);
if (c) {
attackcell(user, c);
}
}
// remove temporary flags
killflag(f);
killflag(f2);
} else if (abilid == OT_A_INSPECT) {
object_t *o;
int difficulty;
@ -1229,7 +1269,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
rv = B_FALSE;
} else {
// didn't work for some reason
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
nothinghappens();
}
return B_TRUE;
@ -1641,7 +1681,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
failed = B_TRUE;
}
} else {
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
msg("You have no line of fire to there!");
}
failed = B_TRUE;
@ -1816,7 +1856,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
// next thing touched
addflag(caster->flags, F_FREEZINGTOUCH, 1, NA, NA, NULL);
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
msg("Your hands begin to glow blue!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, caster)) {
@ -1839,7 +1879,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
if (o->material->id == MT_ICE) { // already made of ice?
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
nothinghappens();
}
return B_TRUE;
@ -1850,7 +1890,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (rv) {
if (rv == E_NOEFFECT) {
if (o->pile->owner) {
if (o->pile->owner->controller == C_PLAYER) {
if (isplayer(o->pile->owner)) {
msg("Your %s glows blue for a moment.",noprefix(buf));
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (haslos(player, o->pile->owner->cell)) {
@ -1864,14 +1904,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else {
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
nothinghappens();
}
}
return B_TRUE;
} else {
if (o->pile->owner) {
if (o->pile->owner->controller == C_PLAYER) {
if (isplayer(o->pile->owner)) {
msg("Your %s turn%s to ice!",noprefix(buf), (o->amt == 1) ? "s" : "");
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (haslos(player, o->pile->owner->cell)) {
@ -1925,8 +1965,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
} else {
howlong = getspellduration(5,25,blessed) + power;
addtempflag(target->flags, F_FASTACT, 5, NA, NA, NULL, howlong);
addtempflag(target->flags, F_FASTMOVE, 5, NA, NA, NULL, howlong);
addtempflag(target->flags, F_FASTACT, 10, NA, NA, NULL, howlong);
addtempflag(target->flags, F_FASTMOVE, 10, NA, NA, NULL, howlong);
}
} else if (spellid == OT_S_HEALING) {
int donesomething = B_FALSE;
@ -2035,7 +2075,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
if (isidentified(o)) { // already identified?
nothinghappens();
return B_TRUE;
@ -2058,7 +2098,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
} else if (spellid == OT_S_INFINITEDEATH) {
lifeform_t *l;
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
msg("A wave of incalculable evil blasts outwards from you!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, caster)) {
@ -2189,7 +2229,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
}
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
msg("An image of your surroundings appears in your mind!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
@ -2273,7 +2313,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_MINDSCAN) {
cell_t *where;
int failed = B_FALSE;
if (caster->controller == C_PLAYER) {
if (isplayer(caster)) {
// ask for a target cell
sprintf(buf, "Whose mind will you scan?");
where = askcoords(buf, TT_MONSTER);
@ -2716,7 +2756,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (!newmap) {
// create new map
newmap = addmap();
createmap(newmap, newdepth, caster->cell->map->habitat, NULL, findot(OT_STAIRSUP));
createmap(newmap, newdepth, caster->cell->map->habitat);
}
@ -2809,12 +2849,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(target, targname);
howlong = getspellduration(20,40,blessed) + (power*2);
if (!isplayer(target) && cansee(player, target) && !lfhasflag(player, F_SEEINVIS)) {
if (!isplayer(target) && cansee(player, target) ) {
willannounce = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
addtempflag(target->flags, F_INVISIBLE, B_TRUE, NA, NA, NULL, howlong);
if (willannounce) {
if (willannounce && !lfhasflag(player, F_SEEINVIS)) {
msg("%s flicker%s then vanishes!",targname, isplayer(target) ? "" : "s");
}
} else if (spellid == OT_S_KNOCK) {
@ -3013,7 +3053,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
howlong = getspellduration(5,10,blessed) + (power/2);
addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong);
} else if (spellid == OT_S_POLYMORPH) {
race_t *r;
race_t *r = NULL;
// ask for target if required
if (!target && isplayer(caster)) {
@ -3050,7 +3090,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
if (isplayer(caster) && (power >= 5)) {
if (isplayer(target)) {
if (isplayer(target)) { // ie. polymorphing yourself
askstring("What will you become", '?', buf, BUFLEN, NULL);
} else {
char buf2[BUFLEN];
@ -3068,10 +3108,24 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
r = NULL;
}
} else {
// random race, but not the same!
r = target->race;
while (r == target->race) {
r = getrandomrace(NULL, 0);
if (isplayer(target) && lfhasflag(target, F_CONTROL)) {
askstring("What will you become", '?', buf, BUFLEN, NULL);
r = findracebyname(buf);
// make sure race is valid:
// - can't turn into monsters which aren't randomly generated.
// - can't turn into unique monsters
if (r && !appearsrandomly(r->id)) {
r = NULL;
}
}
if (!r) {
// random race, but not the same!
r = target->race;
while (r == target->race) {
r = getrandomrace(NULL, 0);
}
}
}
@ -3158,8 +3212,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
howlong = rnd(5,25) + power;
addtempflag(target->flags, F_SLOWACT, 5, NA, NA, NULL, howlong);
addtempflag(target->flags, F_SLOWMOVE, 5, NA, NA, NULL, howlong);
addtempflag(target->flags, F_SLOWACT, 10, NA, NA, NULL, howlong);
addtempflag(target->flags, F_SLOWMOVE, 10, NA, NA, NULL, howlong);
if (isplayer(target) || haslos(player, target->cell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}

4
text.c
View File

@ -572,6 +572,10 @@ void texttospellopts(char *text, int *power, char *damstr, int *needgrab) {
if (damstr) strcpy(damstr, "");
if (needgrab) *needgrab = B_FALSE;
if (!strlen(text)) {
return;
}
// for each arg
for (n = 0; argname[n]; n++) {
// search for it in text...