* [+] backstab
- [+] monsters start asleep and make spot checks ? - [+] make them start asleep - [+] then make this random - [+] sound will wake them (ie. "makenoise") - [+] when you move, make SC_STEALTH check. if you fail, you make noise! - [+] must pass LISTEN check OR have los to hear something. - [+] "the blowfly falls asleep" "the blowfly appears" when summoned. - [+] don't show 'falls asleep' while being created! * [+] don't start summoned mosnters asleep! * [+] clean up bresnham functions - [+] hearing - instead of just using distance, use distance modiied by # of walls! - [+] getcelldistsound() - each wall counts as an extra cell! - [+] add WALK/FLY noises to all monsters! - [+] don't show 'you hear xxx' when resting. - [+] extra damage for weapon skill (up to 50% extra) - [+] make broken glass crushable - [+] only interrupt rest for non-peaceful, non-friendly monsters - [+] save to fight off poison * [+] beholder is never using its BITE attack * [+] need a price for manuals!! * [+] change"dobresnham" to populate an array of cells - [+] make ai cast animate metal (if they ahve a second weapon) - [+] implement getallegiance() to clean up isfriendly / ispeaceful etc - [+] bug - f_else f_ifpct etc not working in startobs * [+] OT_S_CHARM - [+] update askcoords to show "weilding x AND Y" - [+] stop enemies from throwing firearm ammo somehow * [+] implement - [+] pacify spell - [+] make spellbooks less common - [+] detectmetal not wokring. fixed. - [+] detectobjects spell - [+] cleanup using flagcausesredraw() - [+] increase odds of weapons in rooms, and max ob count in rooms
This commit is contained in:
parent
4edc66af47
commit
290d91677e
160
ai.c
160
ai.c
|
@ -165,6 +165,14 @@ void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victi
|
|||
// cast spell at the victim
|
||||
if (spelllf) *spelllf = victim;
|
||||
if (spellcell) *spellcell = victim->cell;
|
||||
} else if (spelltype->id == OT_S_CHARM) {
|
||||
lifeform_t *l;
|
||||
l = getnearbypeaceful(lf);
|
||||
if (l) {
|
||||
if (spelllf) *spelllf = l;
|
||||
if (spellcell) *spellcell = l->cell;
|
||||
if (spellob) *spellob = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,9 +338,17 @@ void aimove(lifeform_t *lf) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (goingtomove && (getcelldist(lf->cell, target->cell) == 1)) {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if ( (spell != OT_NONE) && // found a valid spell/ability to use
|
||||
((getcelldist(lf->cell, target->cell) != 1) || (rnd(1,3) == 1))
|
||||
) {
|
||||
int spellfailed = B_FALSE;
|
||||
lifeform_t *spelllf = NULL;
|
||||
cell_t *spellcell = NULL;
|
||||
|
@ -400,7 +416,7 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// if not adjacent, check for guns, wands, throwing
|
||||
if (goingtomove && (getcelldist(lf->cell, target->cell) > 1) && haslof(lf, target->cell)) {
|
||||
if (goingtomove && (getcelldist(lf->cell, target->cell) > 1) && haslof(lf, target->cell, B_FALSE, NULL)) {
|
||||
// can we attack by firing something?
|
||||
gun = getfirearm(lf);
|
||||
if (goingtomove && gun && getammo(lf)) {
|
||||
|
@ -422,8 +438,8 @@ void aimove(lifeform_t *lf) {
|
|||
|
||||
// can we attack by throwing something?
|
||||
if (goingtomove) {
|
||||
// TODO: or firing! check if we have a firearm first.
|
||||
o = getbestmissile(lf);
|
||||
//
|
||||
o = getbestthrowmissile(lf);
|
||||
if (o) {
|
||||
if (db) dblog(".oO { will throw %s at my target instead of moving }", o->type->name);
|
||||
// try to throw it!
|
||||
|
@ -556,63 +572,63 @@ void aimove(lifeform_t *lf) {
|
|||
// not attacking anyone in particular
|
||||
if (db) dblog(".oO { i do not have a target or can't move towards it. }");
|
||||
// are we hostile? if so, look for a target
|
||||
f = hasflag(lf->flags, F_HOSTILE);
|
||||
if (f) {
|
||||
switch (getallegiance(lf)) {
|
||||
int i;
|
||||
if (db) dblog(".oO { i am hostile. looking for a target. }");
|
||||
|
||||
// look around for a target
|
||||
for (i = 0; i < lf->nlos; i++) {
|
||||
cell_t *c;
|
||||
c = lf->los[i];
|
||||
|
||||
if (c->lf && cansee(lf, c->lf)) {
|
||||
if (isplayer(c->lf)) { // TODO: change to if isenemy ?
|
||||
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||
// target them!
|
||||
addtempflag(lf->flags, F_TARGET, c->lf->id, c->x, c->y, NULL, AI_FOLLOWTIME);
|
||||
// tell the player
|
||||
if (cansee(player, lf)) {
|
||||
makenoise(lf, N_GETANGRY);
|
||||
}
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
|
||||
if (curwep) {
|
||||
if (!movetowards(lf, c)) return;
|
||||
} else {
|
||||
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// are we friendly? if so, look for a target
|
||||
f = hasflag(lf->flags, F_FRIENDLY);
|
||||
if (f) {
|
||||
int x,y;
|
||||
if (db) dblog(".oO { i am friendly to the player. looking for a target. }");
|
||||
// look around for a target
|
||||
// TODO: use our vis rang einstead of 10!
|
||||
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
|
||||
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
|
||||
c = getcellat(lf->cell->map, x, y);
|
||||
// cell exists and we can see it?
|
||||
if (c && c->lf && (c->lf != lf) && cansee(lf, c->lf)) {
|
||||
// player there?
|
||||
if (!isplayer(c->lf)) {
|
||||
case AL_HOSTILE:
|
||||
if (db) dblog(".oO { i am hostile. looking for a target. }");
|
||||
|
||||
// look around for a target
|
||||
for (i = 0; i < lf->nlos; i++) {
|
||||
cell_t *c;
|
||||
c = lf->los[i];
|
||||
|
||||
if (c->lf && cansee(lf, c->lf)) {
|
||||
if (isplayer(c->lf)) { // TODO: change to if isenemy ?
|
||||
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||
// target them!
|
||||
addtempflag(lf->flags, F_TARGET, c->lf->id, c->x, c->y, NULL, AI_FOLLOWTIME);
|
||||
// tell the player
|
||||
if (cansee(player, lf)) {
|
||||
makenoise(lf, N_GETANGRY);
|
||||
}
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
if (!movetowards(lf, c)) return;
|
||||
|
||||
if (curwep) {
|
||||
if (!movetowards(lf, c)) return;
|
||||
} else {
|
||||
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AL_FRIENDLY: // are we friendly? if so, look for a target
|
||||
if (db) dblog(".oO { i am friendly to the player. looking for a target. }");
|
||||
// look around for a target
|
||||
// TODO: use our vis rang einstead of 10!
|
||||
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
|
||||
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
|
||||
c = getcellat(lf->cell->map, x, y);
|
||||
// cell exists and we can see it?
|
||||
if (c && c->lf && (c->lf != lf) && cansee(lf, c->lf)) {
|
||||
// player there?
|
||||
if (!isplayer(c->lf)) {
|
||||
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||
// target them!
|
||||
addtempflag(lf->flags, F_TARGET, c->lf->id, c->x, c->y, NULL, AI_FOLLOWTIME);
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
if (!movetowards(lf, c)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -684,6 +700,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
int db = B_FALSE;
|
||||
int ok = B_FALSE;
|
||||
int specialcase = B_FALSE;
|
||||
int specificcheckok = B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
|
@ -801,6 +818,10 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if (ok) break;
|
||||
}
|
||||
}
|
||||
} else if (ot->id == OT_S_CHARM) {
|
||||
if (getnearbypeaceful(lf)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
dblog(".oO { cant cast %s - specialcase conditions not yet coded }", ot ? ot->name : "?unkownspell?");
|
||||
return B_FALSE;
|
||||
|
@ -812,45 +833,58 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// now check whether it meets spellcasting conditions
|
||||
// now check whether it meets specific spell conditions
|
||||
specificcheckok = B_TRUE;
|
||||
if (ot->id == OT_S_ANIMATEMETAL) {
|
||||
object_t *wep;
|
||||
wep = getweapon(lf);
|
||||
if (!wep || !ismetal(wep->material->id)) {
|
||||
specificcheckok = B_TRUE;
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_HASTE) && lfhasflag(lf, F_FASTACT)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_PAIN) && lfhasflag(victim, F_PAIN)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_HEALING) && (lf->hp >= lf->maxhp)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_HEALINGMIN) && (lf->hp >= lf->maxhp)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_SLEEP) && lfhasflag(victim, F_ASLEEP)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_SLOW) && lfhasflag(victim, F_SLOWACT)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_WEAKEN)) {
|
||||
flag_t *lff;
|
||||
for (lff = lf->flags->first; lff ; lff = lff->next) {
|
||||
if ((lff->id == F_ATTRMOD) && (lff->val[0] == A_STR) && (lff->obfrom == OT_S_WEAKEN)) {
|
||||
return B_FALSE;
|
||||
specificcheckok = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!specificcheckok) {
|
||||
dblog(".oO { cant cast %s - specific spell check failed }", ot ? ot->name : "?unkownspell?");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
|
341
attack.c
341
attack.c
|
@ -84,6 +84,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
char attackername[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
int fatal = B_FALSE;
|
||||
int firstisbackstab = B_FALSE;
|
||||
flag_t *unarmedflag = NULL;
|
||||
object_t *wep;
|
||||
obpile_t *op = NULL;
|
||||
|
@ -109,8 +110,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get names
|
||||
getlfname(lf, attackername);
|
||||
|
||||
|
@ -124,6 +123,25 @@ 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);
|
||||
|
||||
|
@ -192,43 +210,65 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
// ie. if critical is 0, do this once.
|
||||
// if critical is 1, do this twice.
|
||||
// etc.
|
||||
dam[ndam] = 0;
|
||||
dam[0] = 0;
|
||||
for (n = 0; n < critical+1; n++) {
|
||||
if (unarmedflag) {
|
||||
// this mosnter's unarmed attack will
|
||||
// override normal damage calculation
|
||||
dam[ndam] += getdamrollfromflag(unarmedflag);
|
||||
dam[0] += getdamrollfromflag(unarmedflag);
|
||||
} else {
|
||||
dam[ndam] += getdamroll(wep, victim);
|
||||
dam[0] += getdamroll(wep, victim);
|
||||
}
|
||||
}
|
||||
if (aidb) dblog("rolled dam[%d] = %d",ndam,dam[ndam]);
|
||||
if (aidb) dblog("rolled dam[%d] = %d",0,dam[0]);
|
||||
|
||||
if (dam[ndam] < 0) {
|
||||
if (dam[0] < 0) {
|
||||
willheal = B_TRUE;
|
||||
}
|
||||
|
||||
// damtype?
|
||||
damtype[0] = getdamtype(wep);
|
||||
|
||||
if (!willheal) {
|
||||
enum SKILLLEVEL slev;
|
||||
skill_t *sk;
|
||||
// blessed vs undead
|
||||
if (isblessed(wep) && lfhasflagval(victim, F_DTVULN, DT_HOLY, NA, NA, NULL)) {
|
||||
// a little extra damage
|
||||
dam[0] = (int) ( (float)dam[0] * 1.25 );
|
||||
}
|
||||
// modify for strength
|
||||
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
dam[ndam] = (int)((float)dam[ndam] * getstrdammod(lf));
|
||||
dam[0] = (int)((float)dam[0] * getstrdammod(lf));
|
||||
}
|
||||
// backstab?
|
||||
if ((damtype[0] == DT_PIERCE) && // using a stabbing weapon
|
||||
getskill(lf, SK_BACKSTAB) && // able to backstab
|
||||
!cansee(victim, lf) && // victim can't see us
|
||||
!lfhasflagval(victim, F_STABBEDBY, lf->id, NA, NA, NULL) && // haven't stabbed them before
|
||||
!lfhasflagval(victim, F_TARGET, lf->id, NA, NA, NULL) // victim isnt attacking us
|
||||
) {
|
||||
addflag(victim->flags, F_STABBEDBY, lf->id, NA, NA, NULL);
|
||||
dam[0] *= (getskill(lf, SK_BACKSTAB)*2);
|
||||
firstisbackstab = B_TRUE;
|
||||
}
|
||||
// extra damage for being skilled?
|
||||
sk = getobskill(wep);
|
||||
if (sk) {
|
||||
slev = getskill(lf, sk->id);
|
||||
if (slev > 1) {
|
||||
float pctextra;
|
||||
pctextra = ((slev - 1) * 10);
|
||||
dam[0] += pctof(pctextra, dam[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// damtype?
|
||||
damtype[ndam] = getdamtype(wep);
|
||||
if (aidb) dblog(".oO { dealing %d %s damage }", dam[ndam], getdamname(damtype[ndam]));
|
||||
ndam++;
|
||||
if (aidb) dblog(".oO { dealing %d %s damage }", dam[0], getdamname(damtype[0]));
|
||||
|
||||
|
||||
// blessed vs undead etc?
|
||||
ndam = 1;
|
||||
// determine extra damage for flaming etc.
|
||||
if (!willheal) {
|
||||
if (isblessed(wep) && lfhasflagval(victim, F_DTVULN, DT_HOLY, NA, NA, NULL)) {
|
||||
// a little extra damage
|
||||
dam[ndam] = (int) ( (float)dam[ndam] * 1.25 );
|
||||
}
|
||||
|
||||
// determine extra damage
|
||||
getextradam(wep, &dam[0], &damtype[0], &ndam);
|
||||
}
|
||||
} else {
|
||||
|
@ -243,9 +283,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
for (i = 0; i < ndam; i++) {
|
||||
int reduceamt;
|
||||
|
||||
int backstab = B_FALSE;
|
||||
|
||||
if (firstisbackstab && (i == 0)) backstab = B_TRUE;
|
||||
dblog("initial dam[%d] = %d",i,dam[i]);
|
||||
|
||||
if (lfhasflag(lf, F_HEAVYBLOW)) {
|
||||
if (lfhasflag(lf, F_HEAVYBLOW) || hasflag(wep->flags, F_HEAVYBLOW)) {
|
||||
dam[i] = (int)((float)dam[i] * 1.5);
|
||||
dblog("heavy blow makes dam[%d] = %d",i,dam[i]);
|
||||
}
|
||||
|
@ -254,12 +297,14 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
adjustdamlf(victim, &dam[i], damtype[i]);
|
||||
dblog("adjusted for lf to dam[%d] = %d",i,dam[i]);
|
||||
|
||||
// modify for defender's armour
|
||||
reduceamt = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
|
||||
if (!backstab) {
|
||||
// modify for defender's armour
|
||||
reduceamt = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
|
||||
|
||||
applyarmourdamreduction(victim, wep, reduceamt, &dam[i], damtype[i]);
|
||||
applyarmourdamreduction(victim, wep, reduceamt, &dam[i], damtype[i]);
|
||||
|
||||
dblog("reduced by armour to dam[%d] = %d",i,dam[i]);
|
||||
dblog("reduced by armour to dam[%d] = %d",i,dam[i]);
|
||||
}
|
||||
|
||||
// will this hit be fatal?
|
||||
if (dam[i] >= victim->hp) {
|
||||
|
@ -278,7 +323,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
strcpy(extradambuf, "");
|
||||
}
|
||||
|
||||
if (fatal) {
|
||||
if (backstab && (i == 0)) {
|
||||
verb = strdup("backstab");
|
||||
} else if (fatal) {
|
||||
verb = getkillverb(victim, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp);
|
||||
|
@ -286,7 +333,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
warn("You %s %s%s%s",
|
||||
verb,
|
||||
victimname, extradambuf,
|
||||
fatal ? "!" : ".");
|
||||
(fatal || backstab) ? "!" : ".");
|
||||
|
||||
if (fatal && strstr(verb, "behead")) {
|
||||
addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -296,6 +343,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
// don't also say "the xx dies"
|
||||
addflag(victim->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
if (!strcmp(verb, "backstab")) {
|
||||
free(verb);
|
||||
}
|
||||
} else {
|
||||
if (cansee(player, lf) || isplayer(victim)) {
|
||||
char withwep[BUFLEN];
|
||||
|
@ -303,7 +353,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
char nodamstr[BUFLEN];
|
||||
|
||||
// capitalise first letter
|
||||
sprintf(buf, "%s",attackername);
|
||||
strcpy(buf, attackername);
|
||||
capitalise(buf);
|
||||
|
||||
if (wep && !unarmedflag && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
|
||||
|
@ -319,11 +369,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
strcpy(nodamstr, "");
|
||||
}
|
||||
warn("%s %s%s %s%s%s.", buf, attackverb,
|
||||
attackverb[strlen(attackverb)-1] == 's' ? "es" : "s",
|
||||
needses(attackverb) ? "es" : "s",
|
||||
victimname,withwep, nodamstr);
|
||||
} else {
|
||||
youhear(lf->cell, "sounds of fighting");
|
||||
}
|
||||
}
|
||||
noise(lf->cell, lf, "sounds of fighting.", NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,9 +411,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
if (dam[0]) {
|
||||
wepeffects(wep->flags, victim->cell);
|
||||
}
|
||||
wepeffects(wep->flags, victim->cell, dam[0]);
|
||||
|
||||
if (!isdead(victim)) {
|
||||
if (unarmedflag) {
|
||||
|
@ -415,9 +462,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
|
||||
// confer flags from attacker?
|
||||
if (dam[0]) {
|
||||
wepeffects(lf->flags, victim->cell);
|
||||
}
|
||||
wepeffects(lf->flags, victim->cell, dam[0]);
|
||||
|
||||
// special lifeform-based effects
|
||||
if ((lf->race->id == R_COCKATRICE) && dam[0]) {
|
||||
|
@ -464,14 +509,16 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
|
||||
if (lfhasflag(victim, F_DODGES)) {
|
||||
flag_t *f;
|
||||
cell_t *adj;
|
||||
|
||||
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
||||
adj = getrandomadjcell(victim->cell, WE_NOTSOLID);
|
||||
moveto(lf, adj, B_FALSE);
|
||||
msg("%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
|
||||
killflag(f);
|
||||
if (adj) {
|
||||
flag_t *f;
|
||||
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
||||
moveto(victim, adj, B_FALSE);
|
||||
msg("%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -565,6 +612,11 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
dam[ndam] = getdamroll(wep, NULL);
|
||||
}
|
||||
|
||||
// modify for strength
|
||||
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
dam[ndam] = (int)((float)dam[ndam] * getstrdammod(lf));
|
||||
}
|
||||
|
||||
// damtype?
|
||||
damtype[ndam] = getdamtype(wep);
|
||||
ndam++;
|
||||
|
@ -598,7 +650,7 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
msg("%s %ss %s%s.", attackername,
|
||||
getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep);
|
||||
} else {
|
||||
youhear(lf->cell, "sounds of fighting");
|
||||
noise(lf->cell, NULL, "sounds of fighting.", NULL);
|
||||
}
|
||||
|
||||
if ((i == 0) && unarmedflag && hasflag(o->flags, F_HARD)) {
|
||||
|
@ -617,9 +669,7 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
if (dam[0]) {
|
||||
wepeffects(wep->flags, obloc);
|
||||
}
|
||||
wepeffects(wep->flags, obloc, dam[0]);
|
||||
|
||||
if (unarmedflag) {
|
||||
// touch effects
|
||||
|
@ -857,6 +907,10 @@ char *getkillverb(lifeform_t *victim, enum DAMTYPE damtype, int dam, int maxhp)
|
|||
float pct;
|
||||
pct = (int)(((float) dam / (float) maxhp) * 100.0);
|
||||
|
||||
if (victim->race->id == R_DANCINGWEAPON) {
|
||||
return "defeat";
|
||||
}
|
||||
|
||||
if ((damtype == DT_BASH) && lfhasflag(victim, F_FROZEN)) {
|
||||
return "shatter";
|
||||
}
|
||||
|
@ -1189,6 +1243,11 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
|
|||
acc -= 45;
|
||||
}
|
||||
|
||||
// victim immobile or asleep?
|
||||
if (isimmobile(victim)) {
|
||||
acc += 50;
|
||||
}
|
||||
|
||||
if (critical) {
|
||||
if (rnd(1,20) == 20) *critical = 1;
|
||||
}
|
||||
|
@ -1213,7 +1272,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
|
|||
return gothit;
|
||||
}
|
||||
|
||||
void wepeffects(flagpile_t *fp, cell_t *where) {
|
||||
void wepeffects(flagpile_t *fp, cell_t *where, int dam) {
|
||||
flag_t *f;
|
||||
lifeform_t *victim;
|
||||
lifeform_t *owner;
|
||||
|
@ -1222,7 +1281,15 @@ void wepeffects(flagpile_t *fp, cell_t *where) {
|
|||
if (!where) return;
|
||||
|
||||
wep = fp->ob;
|
||||
owner = fp->owner;
|
||||
if (wep) {
|
||||
cell_t *c;
|
||||
c = getoblocation(wep);
|
||||
if (c && c->lf) {
|
||||
owner = c->lf;
|
||||
}
|
||||
} else {
|
||||
owner = fp->owner;
|
||||
}
|
||||
victim = where->lf;
|
||||
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
|
@ -1237,100 +1304,128 @@ void wepeffects(flagpile_t *fp, cell_t *where) {
|
|||
}
|
||||
}
|
||||
} else if ((f->id == F_REVENGE) && victim && !isdead(victim)) {
|
||||
lifeform_t *owner;
|
||||
owner = wep->pile->owner;
|
||||
if (owner && victim) {
|
||||
float ratio;
|
||||
float dampct;
|
||||
int maxdam;
|
||||
int extradam;
|
||||
// figure out hp percentage
|
||||
ratio = 1.0 - ((float)owner->hp / (float)owner->maxhp);
|
||||
dampct = (ratio * 100); // ie. lower hp% = higher dampct
|
||||
|
||||
if (dampct >= 50) {
|
||||
getdamrange(wep->flags, NULL, &maxdam);
|
||||
extradam = (int)(dampct * (float)maxdam);
|
||||
if (extradam > 0) {
|
||||
char buf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
char damstring[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
getlfname(owner, buf);
|
||||
real_getlfname(owner, buf2, B_FALSE);
|
||||
getlfname(victim, victimname);
|
||||
getobname(wep, obname, 1);
|
||||
if (dam) { // only works if we did damage
|
||||
lifeform_t *owner;
|
||||
owner = wep->pile->owner;
|
||||
if (owner && victim) {
|
||||
float ratio;
|
||||
float dampct;
|
||||
int maxdam;
|
||||
int extradam;
|
||||
// figure out hp percentage
|
||||
ratio = 1.0 - ((float)owner->hp / (float)owner->maxhp);
|
||||
dampct = (ratio * 100); // ie. lower hp% = higher dampct
|
||||
|
||||
if (dampct >= 50) {
|
||||
getdamrange(wep->flags, NULL, &maxdam);
|
||||
extradam = (int)(dampct * (float)maxdam);
|
||||
if (extradam > 0) {
|
||||
char buf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
char damstring[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
getlfname(owner, buf);
|
||||
real_getlfname(owner, buf2, B_FALSE);
|
||||
getlfname(victim, victimname);
|
||||
getobname(wep, obname, 1);
|
||||
|
||||
// announce
|
||||
if (isplayer(owner)) {
|
||||
msg("Your %s blasts %s!",noprefix(obname),victimname);
|
||||
f->known = B_TRUE;
|
||||
} else if (cansee(player, owner)) {
|
||||
msg("%s%s %s blasts %s!",buf, getpossessive(buf),noprefix(obname),victimname);
|
||||
f->known = B_TRUE;
|
||||
// announce
|
||||
if (isplayer(owner)) {
|
||||
msg("Your %s blasts %s!",noprefix(obname),victimname);
|
||||
f->known = B_TRUE;
|
||||
} else if (cansee(player, owner)) {
|
||||
msg("%s%s %s blasts %s!",buf, getpossessive(buf),noprefix(obname),victimname);
|
||||
f->known = B_TRUE;
|
||||
}
|
||||
|
||||
sprintf(damstring, "%s%s blast of revenge",buf2, getpossessive(buf2));
|
||||
losehp(victim, extradam, DT_DIRECT, owner, damstring);
|
||||
}
|
||||
|
||||
sprintf(damstring, "%s%s blast of revenge",buf2, getpossessive(buf2));
|
||||
losehp(victim, extradam, DT_DIRECT, owner, damstring);
|
||||
}
|
||||
} // end if dampct > 50
|
||||
} // end if dampct > 50
|
||||
}
|
||||
}
|
||||
} else if ((f->id == F_HEAVYBLOW) && victim && owner) {
|
||||
int dir;
|
||||
// knock back victim
|
||||
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE);
|
||||
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE, DT_COMPASS);
|
||||
knockback(victim, dir , 2, owner);
|
||||
f->known = B_TRUE;
|
||||
} else if ((f->id == F_HITCONFER) && victim ) {
|
||||
enum FLAG fid;
|
||||
int min,max,howlong;
|
||||
fid = f->val[0];
|
||||
if (!lfhasflag(victim, fid)) {
|
||||
int passedcheck = B_FALSE;
|
||||
if (!f->val[1] == NA) {
|
||||
int scdiff;
|
||||
if (f->val[2] == NA) {
|
||||
scdiff = 20; // default
|
||||
} else {
|
||||
scdiff = f->val[2];
|
||||
// only works if we did damage
|
||||
if (dam) {
|
||||
enum FLAG fid;
|
||||
int min,max,howlong;
|
||||
fid = f->val[0];
|
||||
if (!lfhasflag(victim, fid)) {
|
||||
int passedcheck = B_FALSE;
|
||||
if (!f->val[1] == NA) {
|
||||
int scdiff;
|
||||
if (f->val[2] == NA) {
|
||||
scdiff = 20; // default
|
||||
} else {
|
||||
scdiff = f->val[2];
|
||||
}
|
||||
if (skillcheck(victim, f->val[1], scdiff, 0)) {
|
||||
passedcheck = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (skillcheck(victim, f->val[1], scdiff, 0)) {
|
||||
passedcheck = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!passedcheck) {
|
||||
int val0;
|
||||
val0 = f->val[1];
|
||||
if (f->text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,f->text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
min = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (!passedcheck) {
|
||||
int val0;
|
||||
val0 = f->val[1];
|
||||
if (f->text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,f->text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
max = atoi(word);
|
||||
howlong = rnd(min,max);
|
||||
min = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (word) {
|
||||
max = atoi(word);
|
||||
howlong = rnd(min,max);
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
|
||||
addtempflag(victim->flags, fid, val0, NA, NA, NULL, howlong);
|
||||
} // end if passedcheck
|
||||
} // end (if victim doesn't already have the flag)
|
||||
if (fid == F_POISONED) {
|
||||
// need to fill in the name of what poisoned us
|
||||
char frombuf[BUFLEN];
|
||||
if (wep) {
|
||||
if (owner) {
|
||||
char lfname[BUFLEN];
|
||||
char wepname[BUFLEN];
|
||||
getlfnamea(owner, lfname);
|
||||
getobname(wep, wepname, 1);
|
||||
// ie. "a goblin's poisoned short sword"
|
||||
sprintf(frombuf, "%s%s %s",lfname,getpossessive(lfname), wepname);
|
||||
} else {
|
||||
char wepname[BUFLEN];
|
||||
getobname(wep, wepname, 1);
|
||||
// ie "a poisoned short sword"
|
||||
sprintf(frombuf, "%s", wepname);
|
||||
}
|
||||
} else {
|
||||
strcpy(frombuf, "something unknown");
|
||||
}
|
||||
addtempflag(victim->flags, fid, val0, NA, NA, frombuf, howlong);
|
||||
} else {
|
||||
addtempflag(victim->flags, fid, val0, NA, NA, NULL, howlong);
|
||||
}
|
||||
} // end if passedcheck
|
||||
} // end (if victim doesn't already have the flag)
|
||||
|
||||
// was this from a poisoned weapon? if so the poison vanishes
|
||||
if ((f->val[0] == F_POISONED) && (f->lifetime == FROMOBMOD)) {
|
||||
killflag(f);
|
||||
// was this from a poisoned weapon? if so the poison vanishes
|
||||
if ((f->val[0] == F_POISONED) && (f->lifetime == FROMOBMOD)) {
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
} // end if (fid == hitconfer)
|
||||
}
|
||||
|
|
2
attack.h
2
attack.h
|
@ -20,4 +20,4 @@ int getdamrollfromflag(flag_t *f);
|
|||
float getstrdammod(lifeform_t *lf);
|
||||
obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
|
||||
int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical);
|
||||
void wepeffects(flagpile_t *fp, cell_t *where);
|
||||
void wepeffects(flagpile_t *fp, cell_t *where, int dam);
|
||||
|
|
52
defs.h
52
defs.h
|
@ -43,10 +43,12 @@ enum CHECKTYPE {
|
|||
//////////
|
||||
SC_DODGE,
|
||||
SC_SLIP,
|
||||
SC_LISTEN,
|
||||
SC_MORALE,
|
||||
SC_OPENLOCKS,
|
||||
SC_POISON,
|
||||
SC_RESISTMAG,
|
||||
SC_STEALTH,
|
||||
SC_WILL,
|
||||
};
|
||||
|
||||
|
@ -125,6 +127,8 @@ enum LFCONDITION {
|
|||
|
||||
#define MAXPILEOBS 52
|
||||
|
||||
#define MAXRETCELLS 80
|
||||
|
||||
#define MAXCHOICES 150
|
||||
|
||||
#define MAXDEPTH 25 // max dungeon depth
|
||||
|
@ -197,6 +201,14 @@ enum LFCONDITION {
|
|||
#define TR_NEEDLOS 1
|
||||
#define TR_NEEDLOF 2
|
||||
|
||||
// line of fire args
|
||||
enum LOFTYPE {
|
||||
LOF_DONTNEED = 0,
|
||||
LOF_WALLSTOP = 2,
|
||||
LOF_LFSSTOP = 4,
|
||||
LOF_NEED = 6, // walls AND lfs block
|
||||
};
|
||||
|
||||
// CONTROLLERS
|
||||
#define C_AI 0
|
||||
#define C_PLAYER 1
|
||||
|
@ -412,6 +424,8 @@ enum HABITAT {
|
|||
H_ALL = 999
|
||||
};
|
||||
|
||||
#define RARITYVARIANCE (25)
|
||||
|
||||
/*
|
||||
enum RARITY {
|
||||
RR_UNIQUE = 7,
|
||||
|
@ -611,6 +625,7 @@ enum OBTYPE {
|
|||
OT_SCR_CREATEMONSTER,
|
||||
OT_SCR_DETECTAURA,
|
||||
OT_SCR_DETECTLIFE,
|
||||
OT_SCR_DETECTOBS,
|
||||
OT_SCR_DETECTMAGIC,
|
||||
OT_SCR_FLAMEPILLAR,
|
||||
OT_SCR_FLAMEBURST,
|
||||
|
@ -627,11 +642,14 @@ enum OBTYPE {
|
|||
OT_SCR_WISH,
|
||||
// BOOKS
|
||||
OT_MAN_ATHLETICS,
|
||||
OT_MAN_BACKSTAB,
|
||||
OT_MAN_FIRSTAID,
|
||||
OT_MAN_LISTEN,
|
||||
OT_MAN_LOCKPICKING,
|
||||
OT_MAN_MAGITEMUSAGE,
|
||||
OT_MAN_RESEARCH,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_STEALTH,
|
||||
OT_MAN_TECHUSAGE,
|
||||
// manuals of weaponry
|
||||
OT_MAN_AXES,
|
||||
|
@ -667,6 +685,7 @@ enum OBTYPE {
|
|||
// -- divination
|
||||
OT_SB_DETECTAURA,
|
||||
OT_SB_DETECTLIFE,
|
||||
OT_SB_DETECTOBS,
|
||||
OT_SB_IDENTIFY,
|
||||
OT_SB_MAPPING,
|
||||
// -- elemental - air
|
||||
|
@ -695,8 +714,11 @@ enum OBTYPE {
|
|||
OT_SB_TURNUNDEAD,
|
||||
// -- mental / psionic
|
||||
OT_SB_MINDSCAN,
|
||||
OT_SB_SLEEP,
|
||||
OT_SB_TELEKINESIS,
|
||||
OT_SB_PACIFY,
|
||||
OT_SB_PSYARMOUR,
|
||||
OT_SB_CHARM,
|
||||
// -- modification
|
||||
OT_SB_GASEOUSFORM,
|
||||
OT_SB_KNOCK,
|
||||
|
@ -734,6 +756,7 @@ enum OBTYPE {
|
|||
// -- divination
|
||||
OT_S_DETECTAURA,
|
||||
OT_S_DETECTLIFE,
|
||||
OT_S_DETECTOBS,
|
||||
OT_S_DETECTMAGIC,
|
||||
OT_S_IDENTIFY,
|
||||
OT_S_MAPPING,
|
||||
|
@ -765,7 +788,9 @@ enum OBTYPE {
|
|||
OT_S_MINDSCAN,
|
||||
OT_S_SLEEP,
|
||||
OT_S_TELEKINESIS,
|
||||
OT_S_PACIFY,
|
||||
OT_S_PSYARMOUR,
|
||||
OT_S_CHARM,
|
||||
// -- modification
|
||||
OT_S_ENCHANT,
|
||||
OT_S_GASEOUSFORM,
|
||||
|
@ -782,6 +807,7 @@ enum OBTYPE {
|
|||
OT_S_CREATEMONSTER,
|
||||
// -- translocation
|
||||
OT_S_BLINK,
|
||||
OT_S_PULL,
|
||||
OT_S_DISPERSAL,
|
||||
OT_S_GATE,
|
||||
OT_S_TELEPORT,
|
||||
|
@ -795,6 +821,7 @@ enum OBTYPE {
|
|||
OT_S_WISH,
|
||||
OT_S_GIFT,
|
||||
OT_A_DEBUG,
|
||||
OT_A_ENHANCE,
|
||||
OT_A_LEARN,
|
||||
// abilities
|
||||
OT_A_GRAB,
|
||||
|
@ -1022,6 +1049,8 @@ enum BODYPART {
|
|||
|
||||
enum NOISETYPE {
|
||||
N_GETANGRY,
|
||||
N_WALK,
|
||||
N_FLY,
|
||||
};
|
||||
|
||||
enum LFSIZE {
|
||||
|
@ -1036,6 +1065,11 @@ enum LFSIZE {
|
|||
SZ_MAX = 100
|
||||
};
|
||||
|
||||
enum ALLEGIENCE {
|
||||
AL_HOSTILE, // will attack you on sight
|
||||
AL_PEACEFUL, // won't attack you on sight
|
||||
AL_FRIENDLY, // will help you fight
|
||||
};
|
||||
|
||||
enum FLAG {
|
||||
F_NONE, // dummy flag
|
||||
|
@ -1055,7 +1089,7 @@ enum FLAG {
|
|||
F_CURAMMO, // currently equipped ammo
|
||||
F_GOESON, // val0 = where it can be equipped.
|
||||
F_BONUS, // val0=bonus/penalty to damage/armour. ie. +1 sword
|
||||
F_MISSILE, // weapon would make a good missle - used by AI
|
||||
F_THROWMISSILE, // weapon would make a good thrown missle - used by AI
|
||||
F_UNIQUE, // only one may appear
|
||||
F_GLYPH, // override the glyph with the first char of text
|
||||
F_NOPICKUP, // cannot pick this up
|
||||
|
@ -1207,9 +1241,9 @@ enum FLAG {
|
|||
F_MPCOST, // v0=mp cost of spell. if missing, mpcost if splev^2
|
||||
F_ONGOING, // this spell has an ongoing cost
|
||||
//F_SPELLLETTER, // text[0] = letter to cast this spell
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee/heal
|
||||
// v0 is who to target
|
||||
F_AICASTTOATTACK, // AI can cast this spell to help flee
|
||||
F_AICASTTOATTACK, // AI can cast this spell to attack
|
||||
// v0 is who to target
|
||||
F_AIBOOSTITEM, // ai will use this item to boost/buff itself.
|
||||
// if using this on wands, update aiobok() !
|
||||
|
@ -1265,6 +1299,8 @@ enum FLAG {
|
|||
F_NOFLEE, // lf will not run away
|
||||
F_TARGET, // lf will attack lfid v0. lastknown x/y is v1/v2
|
||||
F_TARGETCELL, // lf will go towards this place. val0=x,val1=y
|
||||
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
|
||||
|
||||
// TEMP FLAGS
|
||||
|
@ -1276,6 +1312,7 @@ enum FLAG {
|
|||
F_SPELLCASTTEXT, // text is announcement for spellcast
|
||||
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
||||
F_BEHEADED, // use special corpse drop code
|
||||
F_SILENTMOVE, // lf makes no noise when walking/flying
|
||||
F_MOVESPEED, // override default move speed
|
||||
F_ACTIONSPEED, // override default action speed
|
||||
F_SPELLSPEED, // override default spellcast speed (ie. movespeed)
|
||||
|
@ -1322,15 +1359,17 @@ enum FLAG {
|
|||
// ie. when v1 == v2, ability is ready.
|
||||
// text is other options, semicolon seperated:
|
||||
// pw:xx; cast the spell at power xx
|
||||
F_CHARMEDBY,// you've been charmed by lf id v0
|
||||
F_DETECTAURAS, // autodetect bless/curse
|
||||
F_DETECTLIFE, // autodetect nearby lifeforms in orthogonal dist v0
|
||||
F_DETECTMAGIC, // autodetect magic/special objects
|
||||
F_DETECTMETAL, // autodetect nearby metal
|
||||
F_DETECTOBS, // autodetect nearby obs in orthog dist v0
|
||||
F_EXTRAINFO, // knows extra info
|
||||
F_FLYING, // lf is flying
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMOVE, // modifier for move speed
|
||||
F_POISONED, // has food poisoning
|
||||
F_POISONED, // has food poisoning. text = what from.eg'a bad egg'
|
||||
F_FREEZINGTOUCH,// next thing touched turns to ice!
|
||||
F_GRABBEDBY,// you've been grabbed by lf id v0
|
||||
F_GRABBING, // you are grabbing lf id v0
|
||||
|
@ -1369,6 +1408,7 @@ enum FLAG {
|
|||
F_TIRED, // you are too tired to sprint
|
||||
F_DODGES, // you dodge missed attacks
|
||||
F_NOTIME, // this lf's actions don't take time
|
||||
F_PERCEPTION, // v0 = 0-20. perception level.
|
||||
// skills
|
||||
F_HASSKILL, // lf has skill v0 at level v1
|
||||
// COMBAT
|
||||
|
@ -1584,6 +1624,7 @@ typedef struct map_s {
|
|||
int w,h; // width/height of this map
|
||||
struct cell_s *cell[MAX_MAPW*MAX_MAPH]; // list of cells in this map
|
||||
int nextmap[MAXDIR_ORTH]; // which map is in each direction
|
||||
int beingcreated;
|
||||
|
||||
struct lifeform_s *lf,*lastlf;
|
||||
|
||||
|
@ -1730,11 +1771,14 @@ typedef struct material_s {
|
|||
#define SK_NONE -1
|
||||
enum SKILL {
|
||||
SK_ATHLETICS,
|
||||
SK_BACKSTAB,
|
||||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_MAGITEMUSAGE,
|
||||
SK_RESEARCH,
|
||||
SK_SPELLCASTING,
|
||||
SK_STEALTH,
|
||||
SK_TECHUSAGE,
|
||||
// weaponry
|
||||
SK_AXES,
|
||||
|
|
|
@ -14,8 +14,7 @@ lf.c:
|
|||
update gainlevel() question
|
||||
update givejob()
|
||||
update modattr()
|
||||
|
||||
io.c:
|
||||
update announceflaggain() and loss() for this stat
|
||||
|
||||
|
||||
text.c:
|
||||
add getattrname()
|
||||
|
|
94
flag.c
94
flag.c
|
@ -124,31 +124,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
}
|
||||
}
|
||||
// player flags which cause a redraw
|
||||
if (isplayer(f->pile->owner)) {
|
||||
switch (f->id) {
|
||||
case F_BLIND:
|
||||
case F_SEEINDARK:
|
||||
case F_SPRINTING:
|
||||
case F_TIRED:
|
||||
case F_FASTMOVE:
|
||||
case F_SLOWMOVE:
|
||||
case F_INVISIBLE:
|
||||
case F_SEEINVIS:
|
||||
doredraw = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (haslos(player, f->pile->owner->cell)) {
|
||||
// monster flags which cause a redraw
|
||||
switch (f->id) {
|
||||
case F_INVISIBLE:
|
||||
doredraw = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
doredraw = flagcausesredraw(f->pile->owner, f->id);
|
||||
} else if (f->pile->ob) {
|
||||
if (announceobflaggain(f->pile->ob, f)) {
|
||||
f->known = B_TRUE;
|
||||
|
@ -197,6 +173,38 @@ void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime) {
|
|||
}
|
||||
}
|
||||
|
||||
int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
|
||||
if (!lf) return B_FALSE;
|
||||
|
||||
if (isplayer(lf)) {
|
||||
// player
|
||||
switch (fid) {
|
||||
case F_BLIND:
|
||||
case F_DETECTLIFE:
|
||||
case F_DETECTOBS:
|
||||
case F_FASTMOVE:
|
||||
case F_INVISIBLE:
|
||||
case F_SEEINDARK:
|
||||
case F_SEEINVIS:
|
||||
case F_SPRINTING:
|
||||
case F_SLOWMOVE:
|
||||
case F_TIRED:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (haslos(player, lf->cell)) {
|
||||
switch (fid) {
|
||||
case F_INVISIBLE:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// nonplayer
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int flagstacks(enum FLAG fid) {
|
||||
int res = B_FALSE;
|
||||
switch (fid) {
|
||||
|
@ -292,34 +300,8 @@ void killflag(flag_t *f) {
|
|||
|
||||
lf = f->pile->owner;
|
||||
|
||||
// player flags which cause a redraw
|
||||
if (lf) {
|
||||
if (isplayer(lf)) {
|
||||
switch (f->id) {
|
||||
case F_BLIND:
|
||||
case F_SEEINDARK:
|
||||
case F_SPRINTING:
|
||||
case F_TIRED:
|
||||
case F_FASTMOVE:
|
||||
case F_SLOWMOVE:
|
||||
case F_INVISIBLE:
|
||||
case F_SEEINVIS:
|
||||
doredraw = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (haslos(player, lf->cell)) {
|
||||
// monster flags which cause a redraw
|
||||
switch (f->id) {
|
||||
case F_INVISIBLE:
|
||||
doredraw = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// flags which cause a redraw
|
||||
doredraw = flagcausesredraw(f->pile->owner, f->id);
|
||||
|
||||
// notify
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
|
@ -390,9 +372,9 @@ void killflagpile(flagpile_t *fp) {
|
|||
free(fp);
|
||||
}
|
||||
|
||||
void timeeffectsflag(flag_t *f) {
|
||||
void timeeffectsflag(flag_t *f, int howlong) {
|
||||
if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) {
|
||||
f->lifetime--;
|
||||
f->lifetime -= howlong;
|
||||
if (f->lifetime <= 0) {
|
||||
killflag(f);
|
||||
return;
|
||||
|
@ -505,7 +487,7 @@ void timeeffectsflags(flagpile_t *fp) {
|
|||
flag_t *f,*nextf;
|
||||
for (f = fp->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
timeeffectsflag(f);
|
||||
timeeffectsflag(f, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
3
flag.h
3
flag.h
|
@ -7,6 +7,7 @@ flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid);
|
||||
flagpile_t *addflagpile(lifeform_t *owner, object_t *o);
|
||||
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
||||
int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
|
||||
int flagstacks(enum FLAG fid);
|
||||
flag_t *hasflag(flagpile_t *fp, int id);
|
||||
flag_t *hasflagknown(flagpile_t *fp, int id);
|
||||
|
@ -19,5 +20,5 @@ void killflag(flag_t *f);
|
|||
void killflagpile(flagpile_t *fp);
|
||||
void makeflagknown(flagpile_t *fp);
|
||||
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2);
|
||||
void timeeffectsflag(flag_t *f);
|
||||
void timeeffectsflag(flag_t *f, int howlong);
|
||||
void timeeffectsflags(flagpile_t *fp);
|
||||
|
|
148
io.c
148
io.c
|
@ -404,13 +404,21 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
sprintf(extrainfo, "level %d, ",c->lf->level);
|
||||
}
|
||||
*/
|
||||
if (isfriendly(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "ally");
|
||||
} else if (ispeaceful(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "peaceful");
|
||||
switch (getallegiance(c->lf)) {
|
||||
case AL_FRIENDLY:
|
||||
if (!isplayer(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "ally");
|
||||
}
|
||||
break;
|
||||
case AL_PEACEFUL:
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "peaceful");
|
||||
break;
|
||||
case AL_HOSTILE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isfleeing(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "fleeing");
|
||||
|
@ -438,12 +446,30 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
|
||||
wep = getweapon(c->lf);
|
||||
if (wep) {
|
||||
object_t *secwep;
|
||||
char obname[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
getobname(wep, obname, wep->amt);
|
||||
sprintf(buf2, "weilding %s",obname);
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
|
||||
secwep = getequippedob(c->lf->pack, BP_SECWEAPON);
|
||||
if (secwep) {
|
||||
getobname(secwep, obname, secwep->amt);
|
||||
strcat(buf2, " and ");
|
||||
strcat(buf2, obname);
|
||||
}
|
||||
strcat(extrainfo, buf2);
|
||||
} else {
|
||||
wep = getequippedob(c->lf->pack, BP_SECWEAPON);
|
||||
if (wep) {
|
||||
char obname[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
getobname(wep, obname, wep->amt);
|
||||
sprintf(buf2, "weilding %s",obname);
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, buf2);
|
||||
}
|
||||
}
|
||||
|
||||
f = lfhasflag(c->lf, F_GRABBING);
|
||||
|
@ -690,6 +716,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
ot = findot(f->val[0]);
|
||||
if (ot) {
|
||||
msg("You have learned the spell '%s'.", ot->name);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -699,9 +726,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
ot = findot(f->val[0]);
|
||||
if (ot) {
|
||||
msg("You have learned the ability '%s'.", ot->name);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_CHARMEDBY:
|
||||
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));
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel immune to %s!", getdamnamenoun(f->val[0]));
|
||||
|
@ -732,6 +768,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DETECTOBS:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You can now detect nearby objects.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DETECTMAGIC:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel sensitive to magical enchantments.");
|
||||
|
@ -779,7 +821,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
if (lf2) {
|
||||
getlfname(lf2, buf);
|
||||
msg("%s turn%s to flee from %s!", lfname, isplayer(lf) ? "" : "s",
|
||||
cansee(player, lf2) ? buf : "something");
|
||||
(cansee(player, lf2) || isplayer(lf2)) ? buf : "something");
|
||||
}
|
||||
break;
|
||||
case F_POISONED:
|
||||
|
@ -952,7 +994,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (isdead(player)) return B_FALSE;
|
||||
if (isdead(lf) || isdead(player)) return B_FALSE;
|
||||
getlfname(lf, lfname);
|
||||
|
||||
// player can't see?
|
||||
|
@ -1034,6 +1076,15 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case F_CHARMEDBY:
|
||||
lf2 = findlf(NULL, f->val[0]);
|
||||
if (lf2) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(lf2, buf);
|
||||
msg("%s break%s free of %s%s control!",lfname, isplayer(lf) ? "" : "s", buf,getpossessive(buf));
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You are no longer immune to %s.", getdamnamenoun(f->val[0]));
|
||||
|
@ -1064,6 +1115,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FRIENDLY:
|
||||
msg("%s no longer looks quite so friendly!", lfname);
|
||||
break;
|
||||
case F_POISONED:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You feel less sick now.");
|
||||
|
@ -1107,6 +1161,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DETECTOBS:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You can no longer detect nearby objects.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DETECTMAGIC:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You can no longer detect magical enchantments.");
|
||||
|
@ -2186,7 +2246,7 @@ void describeob(object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_MISSILE);
|
||||
f = hasflag(o->flags, F_THROWMISSILE);
|
||||
if (f) {
|
||||
if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT)) {
|
||||
int dam;
|
||||
|
@ -2299,6 +2359,9 @@ void describeob(object_t *o) {
|
|||
case F_DETECTLIFE:
|
||||
mvwprintw(mainwin, y, 0, "%s will detect nearby lifeforms.", buf); y++;
|
||||
break;
|
||||
case F_DETECTOBS:
|
||||
mvwprintw(mainwin, y, 0, "%s will detect nearby objects.", buf); y++;
|
||||
break;
|
||||
case F_DETECTMAGIC:
|
||||
mvwprintw(mainwin, y, 0, "%s will detect magical enchantemnts on objects.", buf); y++;
|
||||
break;
|
||||
|
@ -3591,7 +3654,7 @@ void donextguntarget(void) {
|
|||
cell_t *c;
|
||||
c = player->los[i];
|
||||
if (c->lf && (c->lf != player) && (c->lf != targ)) {
|
||||
if (haslof(player, c) && isingunrange(player, c)) {
|
||||
if (haslof(player, c, LOF_NEED, NULL) && isingunrange(player, c)) {
|
||||
// found one!
|
||||
setguntarget(player, c->lf);
|
||||
done = B_TRUE;
|
||||
|
@ -3676,7 +3739,7 @@ void dorest(void) {
|
|||
}
|
||||
|
||||
if (strchr(validchars, 'h') && strchr(validchars, 'm')) {
|
||||
strcat(validchars, "b");
|
||||
strcat(validchars, "bn");
|
||||
strcpy(ques, "Rest until full HP, Mana, Both or none");
|
||||
ch = askchar(ques, validchars, "b", B_TRUE);
|
||||
if (ch == 'b') {
|
||||
|
@ -3739,7 +3802,7 @@ void doselguntarget(void) {
|
|||
sprintf(buf, "Aim %s where?",gunname);
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
if (where) {
|
||||
if (where->lf && haslof(player, where)) {
|
||||
if (where->lf && haslof(player, where, LOF_NEED, NULL)) {
|
||||
setguntarget(player, where->lf);
|
||||
} else {
|
||||
setguntarget(player, NULL);
|
||||
|
@ -3807,13 +3870,22 @@ void dothrow(obpile_t *op) {
|
|||
where = askcoords(buf2, TT_MONSTER);
|
||||
|
||||
if (where) {
|
||||
if (!haslof(player, where)) {
|
||||
if (reason == E_NOLOS) {
|
||||
msg("You can't see there!");
|
||||
} else { // ie. E_NOLOF
|
||||
msg("You don't have a clear line of fire to there.");
|
||||
cell_t *newwhere = NULL;
|
||||
if (!haslof(player, where, LOF_WALLSTOP, &newwhere)) {
|
||||
if (newwhere) {
|
||||
// update destination cell.
|
||||
where = newwhere;
|
||||
} else {
|
||||
if (reason == E_NOLOS) {
|
||||
msg("You can't see there!");
|
||||
} else { // ie. E_NOLOF
|
||||
msg("You don't have a clear line of fire to there.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (getcelldist(player->cell, where) > maxdist) {
|
||||
}
|
||||
|
||||
if (getcelldist(player->cell, where) > maxdist) {
|
||||
msg("You can't throw %s that far!",buf);
|
||||
} else {
|
||||
throwat(player, o, where);
|
||||
|
@ -3929,7 +4001,7 @@ void drawcellwithcontents(cell_t *cell, int x, int y) {
|
|||
} else {
|
||||
void *thing;
|
||||
char glyph;
|
||||
// scanned lf here?
|
||||
// scanned lf here?
|
||||
if (isinscanrange(cell, &thing, NULL, &glyph) == TT_MONSTER) {
|
||||
//mvwprintw(gamewin, y-viewy, x-viewx, "%c", glyph);
|
||||
mvwprintw(gamewin, y, x, "%c", glyph);
|
||||
|
@ -4331,9 +4403,16 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
}
|
||||
|
||||
// fill in the name of the completed choice
|
||||
/*
|
||||
sprintf(promptstr, "%s %s %s",
|
||||
prompt->q[prompt->whichq], prompt->maycancel ? "[ESC=cancel, '=next page] " : "",
|
||||
prompt->choice[validone].text);
|
||||
*/
|
||||
sprintf(promptstr, "%s [%s%s] %s",
|
||||
prompt->q[prompt->whichq],
|
||||
prompt->maycancel ? "ESC," : "",
|
||||
showall ? "'=next page,?=toggle" : "?=list",
|
||||
prompt->choice[validone].text);
|
||||
mvwprintw(mainwin, 0, 0, "%s", promptstr);
|
||||
|
||||
// move the cursor back
|
||||
|
@ -4935,6 +5014,7 @@ void nothinghappens(void) {
|
|||
void drawstatus(void) {
|
||||
char buf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
char mpbuf[BUFLEN];
|
||||
char waitbuf[BUFLEN];
|
||||
char pname[BUFLEN];
|
||||
char maxmpstr[BUFLEN];
|
||||
|
@ -5046,10 +5126,17 @@ void drawstatus(void) {
|
|||
sprintf(maxmpstr, "(%d)",player->maxmp);
|
||||
}
|
||||
|
||||
sprintf(buf, "HP:%d/%d MP:%d/%d%s $:%d St:%d%c Dx:%d%c Iq:%d%c Cn:%d%c DLev:%d",
|
||||
if (getmaxmp(player) > 0) {
|
||||
sprintf(mpbuf, "%d/%d%s", player->mp, getmaxmp(player), maxmpstr);
|
||||
} else {
|
||||
strcpy(mpbuf, "-");
|
||||
}
|
||||
|
||||
sprintf(buf, "HP:%d/%d MP:%s $:%d AR:%d St:%d%c Dx:%d%c Iq:%d%c Cn:%d%c DLev:%d",
|
||||
player->hp,player->maxhp,
|
||||
player->mp, getmaxmp(player), maxmpstr,
|
||||
mpbuf,
|
||||
countmoney(player),
|
||||
getarmourrating(player),
|
||||
str, (str == player->baseatt[A_STR]) ? ' ' : '*',
|
||||
dex, (dex == player->baseatt[A_DEX]) ? ' ' : '*',
|
||||
iq, (iq == player->baseatt[A_IQ]) ? ' ' : '*',
|
||||
|
@ -6054,6 +6141,20 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s cannot see.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_CHARMEDBY);
|
||||
if (f) {
|
||||
lifeform_t *lf2;
|
||||
char charmername[BUFLEN];
|
||||
lf2 = findlf(NULL, f->val[0]);
|
||||
if (lf2) {
|
||||
getlfnamea(lf2, charmername);
|
||||
} else {
|
||||
strcpy(charmername, "something");
|
||||
}
|
||||
sprintf(buf,"%s %s been charmed by %s.",you(lf), isplayer(lf) ? "have" : "has", charmername);
|
||||
mvwprintw(mainwin, y, 0, buf);
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_DETECTAURAS);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s automatically detect blessings or curses.", you(lf));
|
||||
|
@ -6074,6 +6175,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s automatically detect nearby metal.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_DETECTOBS);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s automatically detect nearby objects.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_EXTRAINFO);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s receive enhanced knowledge about the world.", you(lf));
|
||||
|
|
17
lf.h
17
lf.h
|
@ -6,6 +6,8 @@ job_t *addjob(enum JOB id, char *name);
|
|||
race_t *addrace(enum RACE id, char *name, float weight, char glyph, enum MATERIAL mat);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
int areallies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
void autoskill(lifeform_t *lf);
|
||||
void autotarget(lifeform_t *lf);
|
||||
void autoweild(lifeform_t *lf);
|
||||
|
@ -40,6 +42,8 @@ lifeform_t *findlf(map_t *m, int lfid);
|
|||
race_t *findrace(enum RACE id);
|
||||
race_t *findracebyname(char *name);
|
||||
skill_t *findskill(enum SKILL id);
|
||||
skill_t *findskillbyname(char *name);
|
||||
enum SKILLLEVEL findskilllevbyname(char *name);
|
||||
int flee(lifeform_t *lf);
|
||||
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong);
|
||||
void gainhp(lifeform_t *lf, int amt);
|
||||
|
@ -47,12 +51,13 @@ void gainlevel(lifeform_t *lf);
|
|||
void gainmp(lifeform_t *lf, int amt);
|
||||
void gainxp(lifeform_t *lf, long amt);
|
||||
int getactspeed(lifeform_t *lf);
|
||||
enum ALLEGIENCE getallegiance(lifeform_t *lf);
|
||||
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||
int getarmourrating(lifeform_t *lf);
|
||||
int getattackspeed(lifeform_t *lf);
|
||||
int getattr(lifeform_t *lf, enum ATTRIB attr);
|
||||
int getevasion(lifeform_t *lf);
|
||||
object_t *getbestmissile(lifeform_t *lf);
|
||||
object_t *getbestthrowmissile(lifeform_t *lf);
|
||||
object_t *getbestweapon(lifeform_t *lf);
|
||||
object_t *getbestfirearm(lifeform_t *lf);
|
||||
int getbodyparthitchance(enum BODYPART bp);
|
||||
|
@ -85,6 +90,7 @@ int getvisrange(lifeform_t *lf);
|
|||
int getmovespeed(lifeform_t *lf);
|
||||
char *getmoveverb(lifeform_t *lf);
|
||||
char *getmoveverbother(lifeform_t *lf);
|
||||
lifeform_t *getnearbypeaceful(lifeform_t *lf);
|
||||
char *getlfname(lifeform_t *lf, char *buf);
|
||||
char *real_getlfname(lifeform_t *lf, char *buf, int usevis);
|
||||
char *getlfnamea(lifeform_t *lf, char *buf);
|
||||
|
@ -113,6 +119,7 @@ long getxpforlev(int level);
|
|||
void givejob(lifeform_t *lf, enum JOB jobid);
|
||||
void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype);
|
||||
int giveskill(lifeform_t *lf, enum SKILL id);
|
||||
int giveskilllev(lifeform_t *lf, enum SKILL id, enum SKILLLEVEL slev);
|
||||
void givestartobs(lifeform_t *lf, flagpile_t *fp);
|
||||
void givestartskills(lifeform_t *lf, flagpile_t *fp);
|
||||
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
|
||||
|
@ -125,7 +132,7 @@ flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int
|
|||
int lockpick(lifeform_t *lf, object_t *target, object_t *device);
|
||||
void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
||||
int hasbp(lifeform_t *lf, enum BODYPART bp);
|
||||
int haslof(lifeform_t *viewer, cell_t *dest);
|
||||
int haslof(lifeform_t *viewer, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
|
||||
int haslos(lifeform_t *viewer, cell_t *dest);
|
||||
void initjobs(void);
|
||||
void initrace(void);
|
||||
|
@ -154,7 +161,7 @@ void killlf(lifeform_t *lf);
|
|||
void killrace(race_t *race);
|
||||
int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam);
|
||||
void makefriendly(lifeform_t *lf);
|
||||
void makefriendly(lifeform_t *lf, int howlong);
|
||||
void makenauseated(lifeform_t *lf, int amt, int howlong);
|
||||
void makenoise(lifeform_t *lf, enum NOISETYPE nid);
|
||||
lifeform_t *makezombie(object_t *o);
|
||||
|
@ -162,6 +169,7 @@ void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how);
|
|||
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
||||
void modhunger(lifeform_t *lf, int amt);
|
||||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
void noise(cell_t *c, lifeform_t *noisemaker, char *text, char *seetext);
|
||||
void outfitlf(lifeform_t *lf);
|
||||
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
|
||||
void precalclos(lifeform_t *lf);
|
||||
|
@ -180,6 +188,7 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
|||
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
||||
void setrace(lifeform_t *lf, enum RACE rid);
|
||||
void setlastdam(lifeform_t *lf, char *buf);
|
||||
void setlftarget(lifeform_t *lf, lifeform_t *victim);
|
||||
int shoot(lifeform_t *lf);
|
||||
int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod);
|
||||
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result);
|
||||
|
@ -203,4 +212,4 @@ int validateraces(void);
|
|||
int wear(lifeform_t *lf, object_t *o);
|
||||
int weild(lifeform_t *lf, object_t *o);
|
||||
int willflee(lifeform_t *lf);
|
||||
int youhear(cell_t *c, char *text);
|
||||
//int youhear(cell_t *c, char *text);
|
||||
|
|
340
log.txt
340
log.txt
|
@ -2,421 +2,117 @@
|
|||
|
||||
|
||||
====== NEW LOGFILE ====
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'wooden door'
|
||||
checkobnames(): got exact match: 'wooden door'
|
||||
xxx
|
||||
findotn(): modname is 'staircase going up'
|
||||
checkobnames(): got exact match: 'staircase going up'
|
||||
findotn(): modname is 'staircase going down'
|
||||
checkobnames(): got exact match: 'staircase going down'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 2 x bolt ('bolts')
|
||||
findotn(): modname is 'bolts'
|
||||
checkobnames(): got match after stripping 's': 'bolt' -> 'bolts'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
adding random object with rarity value between 72 - 100
|
||||
(must have obclass = Potions)
|
||||
got 8 possibilities.
|
||||
random ob: 1 x potion of minor healing ('potion of minor healing')
|
||||
findotn(): modname is 'potion of minor healing'
|
||||
checkobnames(): got exact match: 'potion of minor healing'
|
||||
findotn(): modname is 'claws'
|
||||
checkobnames(): got exact match: 'claws'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'zapper'
|
||||
checkobnames(): got exact match: 'zapper'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
adding random object with rarity value between 72 - 100
|
||||
(must have obclass = Potions)
|
||||
got 8 possibilities.
|
||||
random ob: 1 x potion of magic ('potion of magic')
|
||||
findotn(): modname is 'potion of magic'
|
||||
checkobnames(): got exact match: 'potion of magic'
|
||||
findotn(): modname is 'claws'
|
||||
checkobnames(): got exact match: 'claws'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x potion of oil ('potion of oil')
|
||||
findotn(): modname is 'potion of oil'
|
||||
checkobnames(): got exact match: 'potion of oil'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x scimitar ('scimitar')
|
||||
findotn(): modname is 'scimitar'
|
||||
checkobnames(): got exact match: 'scimitar'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x potion of magic ('potion of magic')
|
||||
findotn(): modname is 'potion of magic'
|
||||
checkobnames(): got exact match: 'potion of magic'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x apple ('apple')
|
||||
findotn(): modname is 'apple'
|
||||
checkobnames(): got exact match: 'apple'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 6 x nanodart ('nanodarts')
|
||||
findotn(): modname is 'nanodarts'
|
||||
checkobnames(): got match after stripping 's': 'nanodart' -> 'nanodarts'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x knife ('knife')
|
||||
findotn(): modname is 'knife'
|
||||
checkobnames(): got exact match: 'knife'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> 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=95
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=95
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'claws'
|
||||
checkobnames(): got exact match: 'claws'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=95
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 3 x bolt ('bolts')
|
||||
findotn(): modname is 'bolts'
|
||||
checkobnames(): got match after stripping 's': 'bolt' -> 'bolts'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x spellbook of inscribe ('spellbook of inscribe')
|
||||
findotn(): modname is 'spellbook of inscribe'
|
||||
checkobnames(): got exact match: 'spellbook of inscribe'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x splash of blood ('splash of blood')
|
||||
findotn(): modname is 'splash of blood'
|
||||
checkobnames(): got exact match: 'splash of blood'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=95
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'short sword'
|
||||
checkobnames(): got exact match: 'short sword'
|
||||
findotn(): modname is 'claws'
|
||||
checkobnames(): got exact match: 'claws'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=95
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=95
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
findotn(): modname is 'teeth'
|
||||
checkobnames(): got exact match: 'teeth'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x potion of fruit juice ('potion of fruit juice')
|
||||
findotn(): modname is 'potion of fruit juice'
|
||||
checkobnames(): got exact match: 'potion of fruit juice'
|
||||
adding random object with rarity value between 72 - 100
|
||||
got 100 possibilities.
|
||||
random ob: 1 x boulder ('boulder')
|
||||
findotn(): modname is 'boulder'
|
||||
checkobnames(): got exact match: 'boulder'
|
||||
rollhitdice() - rolling 2d4 + 2
|
||||
rollhitdice() - mod is +88%
|
||||
rollhitdice() ---- die 1/2 == 4
|
||||
rollhitdice() ---- die 2/2 == 4
|
||||
TOTAL: 8
|
||||
-> modified to: 15
|
||||
findotn(): modname is 'fists'
|
||||
checkobnames(): got exact match: 'fists'
|
||||
givejob() starting.
|
||||
|
||||
processing normal flag: 183
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 144
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 210
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
processing normal flag: 209
|
||||
findotn(): modname is 'short sword'
|
||||
checkobnames(): got exact match: 'short sword'
|
||||
findotn(): modname is 'hand of god'
|
||||
checkobnames(): got exact match: 'hand of god'
|
||||
findotn(): modname is 'block of chocolate'
|
||||
checkobnames(): got exact match: 'block of chocolate'
|
||||
findotn(): modname is 'vial of ambrosia'
|
||||
checkobnames(): got exact match: 'vial of ambrosia'
|
||||
findotn(): modname is 'leather armour'
|
||||
checkobnames(): got exact match: 'leather armour'
|
||||
findotn(): modname is 'leather boots'
|
||||
findotn(): modname is 'leather gloves'
|
||||
findotn(): modname is 'graph paper'
|
||||
findotn(): modname is 'digital watch'
|
||||
checkobnames(): got exact match: 'digital watch'
|
||||
findotn(): modname is 'scroll of create monster'
|
||||
checkobnames(): got exact match: 'scroll of create monster'
|
||||
findotn(): modname is 'potion of experience'
|
||||
checkobnames(): got exact match: 'potion of experience'
|
||||
findotn(): modname is 'ring of invulnerability'
|
||||
checkobnames(): got exact match: 'ring of invulnerability'
|
||||
findotn(): modname is 'fists'
|
||||
checkobnames(): got exact match: 'fists'
|
||||
|
|
57
map.c
57
map.c
|
@ -72,6 +72,7 @@ map_t *addmap(void) {
|
|||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
a->nextmap[i] = -1;
|
||||
}
|
||||
a->beingcreated = B_TRUE;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -101,6 +102,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
if (lf) {
|
||||
flag_t *f;
|
||||
|
||||
lf->born = B_FALSE;
|
||||
if (jobok) {
|
||||
// has a job?
|
||||
f = hasflag(lf->flags, F_STARTJOB);
|
||||
|
@ -111,6 +113,14 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
// appears in groups?
|
||||
f = hasflag(lf->flags, F_NUMAPPEAR);
|
||||
if (f) {
|
||||
|
@ -130,6 +140,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
//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;
|
||||
|
@ -141,17 +152,25 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
if (!adjcell) break;
|
||||
|
||||
//lf = addlf(adjcell, r->id, getrandommonlevel(adjcell->map->depth));
|
||||
if (!addlf(adjcell, r->id, 1)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
lf->born = B_TRUE;
|
||||
} // end if lf
|
||||
}
|
||||
|
||||
return lf;
|
||||
}
|
||||
|
||||
|
@ -169,10 +188,10 @@ void addrandomob(cell_t *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void addrandomthing(cell_t *c) {
|
||||
void addrandomthing(cell_t *c, int obchance) {
|
||||
// if there's already someone there,
|
||||
// then add an object.
|
||||
if (c->lf || (rnd(1,2) == 1)) {
|
||||
if (c->lf || (rnd(1,100) <= obchance)) {
|
||||
// object
|
||||
addrandomob(c);
|
||||
} else {
|
||||
|
@ -564,6 +583,8 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
|
|||
|
||||
//int db = B_TRUE;
|
||||
|
||||
map->beingcreated = B_TRUE;
|
||||
|
||||
sprintf(buf, "Map %d",map->id);
|
||||
map->name = strdup(buf);
|
||||
map->habitat = habitat;
|
||||
|
@ -1008,7 +1029,7 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
|
|||
c = getcellat(map, x, y);
|
||||
if (c && isempty(c)) {
|
||||
if (rnd(1,100) <= getobchance(map->habitat)) {
|
||||
addrandomthing(c);
|
||||
addrandomthing(c, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1047,7 +1068,8 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
|
|||
} else {
|
||||
*/
|
||||
numobsmin = 0;
|
||||
numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||
numobsmax = MAXOF(roomw[i],roomh[i]);
|
||||
|
||||
//}
|
||||
|
||||
|
@ -1086,7 +1108,8 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
|
|||
}
|
||||
} else {
|
||||
*/
|
||||
addrandomthing(c);
|
||||
// slightly more chance of objects in rooms
|
||||
addrandomthing(c,60);
|
||||
done = B_TRUE;
|
||||
//dblog("----> Success ob at (%d,%d).",c->x,c->y);
|
||||
} else {
|
||||
|
@ -1232,7 +1255,7 @@ void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_
|
|||
|
||||
//printf("*** Level difficulty is %0.2f\n", getmazedifficulty(curz));
|
||||
|
||||
|
||||
map->beingcreated = B_FALSE;
|
||||
}
|
||||
|
||||
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||
|
@ -1472,7 +1495,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
msg("You see %s explosion!", (range > 0) ? "a huge" : "an");
|
||||
}
|
||||
} else {
|
||||
youhear(c, "an explosion!");
|
||||
noise(c, NULL, "an explosion!", NULL);
|
||||
}
|
||||
|
||||
for (y = c->y - range ; y <= c->y + range ; y++) {
|
||||
|
@ -1493,7 +1516,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
if (cc && (getcelldist(c, cc) <= (range+1))) {
|
||||
if (cc->lf && !isdead(cc->lf)) {
|
||||
// move away from centre of explosion
|
||||
knockback(cc->lf, getdiraway(cc, c, B_FALSE), 2, NULL);
|
||||
knockback(cc->lf, getdiraway(cc, c, B_FALSE, DT_COMPASS), 2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1980,6 +2003,20 @@ int isinscanrange(cell_t *c, void **thing, char *desc, char *glyph) {
|
|||
}
|
||||
}
|
||||
}
|
||||
f = lfhasflag(player, F_DETECTOBS);
|
||||
if (f) {
|
||||
if (getcelldistorth(player->cell, c) <= f->val[0]) {
|
||||
object_t *o;
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (!hasflag(o->flags, F_NOPICKUP) && !hasflag(o->flags, F_DOOR)) {
|
||||
*thing = o;
|
||||
if (glyph) *glyph = '*';
|
||||
if (desc) sprintf(desc, "an object");
|
||||
return TT_OBJECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
2
map.h
2
map.h
|
@ -4,7 +4,7 @@ cell_t *addcell(map_t *map, int x, int y);
|
|||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt);
|
||||
void addrandomob(cell_t *c);
|
||||
void addrandomthing(cell_t *c);
|
||||
void addrandomthing(cell_t *c, int obchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
cell_t *getcellat(map_t *map, int x, int y);
|
||||
int getcelldist(cell_t *src, cell_t *dst);
|
||||
|
|
137
move.c
137
move.c
|
@ -109,7 +109,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
// are we immune to this?
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[1], NA, NA, NULL)) {
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[0], NA, NA, NULL)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
|
@ -255,7 +255,7 @@ void dorandommove(lifeform_t *lf, int badmovesok) {
|
|||
// src is where something is
|
||||
// dst is what we are going away from
|
||||
// wantcheck is whether to check for dangerous things before considering a direction valid
|
||||
int getdiraway(cell_t *src, cell_t *dst, int wantcheck) {
|
||||
int getdiraway(cell_t *src, cell_t *dst, int wantcheck, int dirtype) {
|
||||
int d;
|
||||
cell_t *c;
|
||||
int maxdist=-1,bestdir=D_NONE;
|
||||
|
@ -290,8 +290,11 @@ int getdiraway(cell_t *src, cell_t *dst, int wantcheck) {
|
|||
}
|
||||
}
|
||||
if (ok) {
|
||||
//thisdist = getcelldistorth(c, dst);
|
||||
thisdist = getcelldist(c, dst);
|
||||
if (dirtype == DT_ORTH) {
|
||||
thisdist = getcelldistorth(c, dst);
|
||||
} else {
|
||||
thisdist = getcelldist(c, dst);
|
||||
}
|
||||
} else {
|
||||
thisdist = -1;
|
||||
}
|
||||
|
@ -324,7 +327,7 @@ int getdiraway(cell_t *src, cell_t *dst, int wantcheck) {
|
|||
}
|
||||
|
||||
|
||||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck) {
|
||||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype) {
|
||||
int d;
|
||||
cell_t *c;
|
||||
int mindist=9999,bestdir=D_NONE;
|
||||
|
@ -362,8 +365,11 @@ int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck) {
|
|||
}
|
||||
if (ok) {
|
||||
int thisdist;
|
||||
//thisdist = getcelldistorth(c, dst);
|
||||
thisdist = getcelldist(c, dst);
|
||||
if (dirtype == DT_ORTH) {
|
||||
thisdist = getcelldistorth(c, dst);
|
||||
} else {
|
||||
thisdist = getcelldist(c, dst);
|
||||
}
|
||||
dist[d - DC_N] = thisdist;
|
||||
if (thisdist < mindist) {
|
||||
mindist = thisdist;
|
||||
|
@ -449,7 +455,7 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst ) {
|
|||
}
|
||||
|
||||
// move away from them
|
||||
dir = getdiraway(lf->cell, dst, B_TRUE);
|
||||
dir = getdiraway(lf->cell, dst, B_TRUE, DT_COMPASS);
|
||||
if (dir == D_NONE) {
|
||||
rv = B_TRUE;
|
||||
} else {
|
||||
|
@ -606,15 +612,26 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
for (l = newcell->map->lf ; l ; l = l->next) {
|
||||
if (l != lf) {
|
||||
// cope with swapping locations with someone!
|
||||
if (haslos(l, newcell)) {
|
||||
interrupt(l);
|
||||
int dointerrupt = B_FALSE;
|
||||
|
||||
|
||||
if (isplayer(l)) {
|
||||
if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_RESTING)) {
|
||||
char lfname2[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
sprintf(lfname2, "%s",noprefix(lfname));
|
||||
msg("%s %s comes into view.",isvowel(lfname2[0]) ? "An" : "A", lfname2);
|
||||
if (areenemies(lf, l)) {
|
||||
if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_RESTING)) {
|
||||
char lfname2[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
sprintf(lfname2, "%s",noprefix(lfname));
|
||||
msg("%s %s comes into view.",isvowel(lfname2[0]) ? "An" : "A", lfname2);
|
||||
}
|
||||
dointerrupt = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
dointerrupt = B_TRUE;
|
||||
}
|
||||
if (dointerrupt) {
|
||||
interrupt(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -714,6 +731,29 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make some noise
|
||||
// (stealth check to avoid this)
|
||||
if (!lfhasflag(lf, F_SILENTMOVE)) {
|
||||
if (!skillcheck(lf, SC_STEALTH, 20, 0)) {
|
||||
if (isairborne(lf)) {
|
||||
makenoise(lf, N_FLY);
|
||||
} else {
|
||||
makenoise(lf, N_WALK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// slip on blood in new cell?
|
||||
if (!isairborne(lf)) {
|
||||
int slip;
|
||||
object_t *slipob;
|
||||
slip = getslipperyness(newcell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -727,7 +767,7 @@ int movetowards(lifeform_t *lf, cell_t *dst) {
|
|||
}
|
||||
|
||||
// move towards them
|
||||
dir = getdirtowards(lf->cell, dst, lf, B_TRUE);
|
||||
dir = getdirtowards(lf->cell, dst, lf, B_TRUE, DT_COMPASS);
|
||||
if (dir != D_NONE) {
|
||||
rv = trymove(lf, dir, B_TRUE);
|
||||
}
|
||||
|
@ -828,6 +868,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
|
||||
}
|
||||
where = getoblocation(o);
|
||||
noise(where, lf, "a door opening", NULL);
|
||||
if (player && haslos(player, where)) {
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
|
@ -943,11 +984,12 @@ int tryrun(lifeform_t *lf, int dir) {
|
|||
int pullnextto(lifeform_t *lf, cell_t *c) {
|
||||
int dir;
|
||||
cell_t *dst = NULL;
|
||||
cell_t *newdst = NULL;
|
||||
|
||||
dst = c;
|
||||
|
||||
while (dst->lf) {
|
||||
dir = getdirtowards(dst, lf->cell, lf, B_FALSE);
|
||||
dir = getdirtowards(dst, lf->cell, lf, B_FALSE, DT_COMPASS);
|
||||
if (dir == D_NONE) {
|
||||
return B_TRUE;
|
||||
} else {
|
||||
|
@ -957,11 +999,20 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// is the path clear?
|
||||
if (!dst || !haslof(lf, dst)) {
|
||||
if (!dst) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!haslof(lf, dst, B_FALSE, &newdst)) {
|
||||
if (newdst) {
|
||||
// update destination
|
||||
dst = newdst;
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(lf, buf);
|
||||
|
@ -1066,17 +1117,6 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
reason = E_OK;
|
||||
moveto(lf, cell, onpurpose);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// slip on blood in new cell?
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
object_t *inway;
|
||||
int door, dooropen;
|
||||
|
@ -1173,8 +1213,37 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
break;
|
||||
case E_LFINWAY:
|
||||
// attack!
|
||||
return attacklf(lf, cell->lf);
|
||||
if (areallies(lf, cell->lf)) {
|
||||
// if it's the player in the way...
|
||||
if (isplayer(cell->lf)) {
|
||||
return attacklf(lf, cell->lf);
|
||||
} else {
|
||||
lifeform_t *lfinway;
|
||||
cell_t *oldcell;
|
||||
// otherwise swap locations.
|
||||
|
||||
// make lf who is there vanish temporarily...
|
||||
lfinway = cell->lf;
|
||||
cell->lf = NULL;
|
||||
lfinway->cell = NULL;
|
||||
|
||||
// remember your cell
|
||||
oldcell = lf->cell;
|
||||
|
||||
// move you..
|
||||
moveto(lf, cell, onpurpose);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// move them...
|
||||
lfinway->cell = oldcell;
|
||||
oldcell->lf = lfinway;
|
||||
reason = E_OK;
|
||||
}
|
||||
} else {
|
||||
// attack!
|
||||
return attacklf(lf, cell->lf);
|
||||
}
|
||||
break;
|
||||
case E_GRAVBOOSTED:
|
||||
if (isplayer(lf)) {
|
||||
msg("You try to move but are unable to lift your feet!");
|
||||
|
@ -1254,8 +1323,11 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
if (cell->lf) {
|
||||
if (!isplayer(lf)) { // if we are a monster
|
||||
// friendly monsters: don't hit other friendlies
|
||||
if (isfriendly(lf) && (isfriendly(cell->lf) || isplayer(cell->lf)) ) {
|
||||
if (!areenemies(lf, cell->lf)) {
|
||||
// TODO: swap places instead!
|
||||
return B_FALSE;
|
||||
}
|
||||
/*
|
||||
} else if (ispeaceful(lf)) { // peaceful mosnters: don't hit anyone
|
||||
return B_FALSE;
|
||||
} else { // hostile/nonfriendly monsters - don't hit other monsters
|
||||
|
@ -1263,6 +1335,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
return B_TRUE;
|
||||
|
|
4
move.h
4
move.h
|
@ -8,8 +8,8 @@ int closedoorat(lifeform_t *lf, cell_t *c);
|
|||
int closedoor(lifeform_t *lf, object_t *o);
|
||||
int diropposite(int dir);
|
||||
void dorandommove(lifeform_t *lf, int badmovesok);
|
||||
int getdiraway(cell_t *src, cell_t *dst, int wantcheck);
|
||||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck);
|
||||
int getdiraway(cell_t *src, cell_t *dst, 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 moveawayfrom(lifeform_t *lf, cell_t *dst);
|
||||
void moveeffects(lifeform_t *lf);
|
||||
|
|
193
nexus.c
193
nexus.c
|
@ -4,6 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "ai.h"
|
||||
#include "attack.h"
|
||||
#include "io.h"
|
||||
|
@ -69,16 +70,33 @@ int main(int argc, char **argv) {
|
|||
int newworld = B_FALSE;
|
||||
object_t *o;
|
||||
char welcomemsg[BUFLEN];
|
||||
int ch;
|
||||
FILE *playerfile = NULL;
|
||||
|
||||
atexit(cleanup);
|
||||
|
||||
while ((ch = getopt(argc, argv, "f:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
playerfile = fopen(optarg, "rt");
|
||||
if (!playerfile) {
|
||||
fprintf(stderr, "cannot open player file: %s\n",optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// init params
|
||||
if (init()) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// load whatever maps are available
|
||||
loadall();
|
||||
|
||||
|
@ -101,20 +119,38 @@ int main(int argc, char **argv) {
|
|||
if (!player) {
|
||||
char *user;
|
||||
char pname[BUFLEN];
|
||||
job_t *j;
|
||||
char buf[BUFLEN];
|
||||
job_t *j = NULL;
|
||||
char ch;
|
||||
cell_t *where;
|
||||
|
||||
// ask for race
|
||||
initprompt(&prompt, "Select your race:");
|
||||
ch = 'a';
|
||||
for (j = firstjob ; j ; j = j->next) {
|
||||
addchoice(&prompt, ch++, j->name, NULL, j);
|
||||
// read from input file if required
|
||||
if (playerfile) {
|
||||
char *p;
|
||||
while (!feof(playerfile)) {
|
||||
fgets(buf, BUFLEN, playerfile);
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
if (strstr(buf, "job:") == buf) {
|
||||
p = buf + strlen("job:");
|
||||
j = findjobbyname(p);
|
||||
if (j) break;
|
||||
}
|
||||
}
|
||||
fseek(playerfile, 0, SEEK_SET);
|
||||
}
|
||||
j = NULL;
|
||||
while (!j) {
|
||||
getchoice(&prompt);
|
||||
j = prompt.result;
|
||||
|
||||
if (!j) {
|
||||
// ask for race
|
||||
initprompt(&prompt, "Select your job:");
|
||||
ch = 'a';
|
||||
for (j = firstjob ; j ; j = j->next) {
|
||||
addchoice(&prompt, ch++, j->name, NULL, j);
|
||||
}
|
||||
j = NULL;
|
||||
while (!j) {
|
||||
getchoice(&prompt);
|
||||
j = prompt.result;
|
||||
}
|
||||
}
|
||||
|
||||
// find staircase
|
||||
|
@ -135,6 +171,14 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
givejob(player, j->id);
|
||||
|
||||
if (playerfile) {
|
||||
if (parseplayerfile(playerfile, player)) {
|
||||
// error!
|
||||
exit(0);
|
||||
}
|
||||
fclose(playerfile);
|
||||
}
|
||||
|
||||
// player needs hunger
|
||||
addflag(player->flags, F_HUNGER, 0, NA, NA, NULL);
|
||||
|
||||
|
@ -325,6 +369,18 @@ void cleanup(void) {
|
|||
// free races
|
||||
}
|
||||
|
||||
void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, int dinc2, int *xinc, int *yinc, int *dinc) {
|
||||
if (d < 0) {
|
||||
*xinc = xinc1;
|
||||
*yinc = yinc1;
|
||||
*dinc = dinc1;
|
||||
} else {
|
||||
*xinc = xinc2;
|
||||
*yinc = yinc2;
|
||||
*dinc = dinc2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void donextturn(map_t *map) {
|
||||
lifeform_t *who;
|
||||
|
@ -512,6 +568,62 @@ int init(void) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels) {
|
||||
int xinc1,xinc2,yinc1,yinc2,dinc1,dinc2,d;
|
||||
int xinc,yinc,dinc;
|
||||
int i;
|
||||
int x,y;
|
||||
initbresnham( x1, y1, x2, y2, &xinc1, &yinc1, &dinc1, &xinc2, &yinc2, &dinc2, numpixels, &d);
|
||||
x = x1;
|
||||
y = y1;
|
||||
for (i = 0; i < *numpixels; i++) {
|
||||
retcell[i] = getcellat(m, x, y);
|
||||
dobresnham(d, xinc1, yinc1, dinc1, xinc2, yinc2, dinc2, &xinc, &yinc, &dinc);
|
||||
// move to next cell
|
||||
d += dinc;
|
||||
x += xinc;
|
||||
y += yinc;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
int deltax,deltay;
|
||||
|
||||
deltax = (x2 - x1);
|
||||
if (deltax < 0) deltax = -deltax;
|
||||
deltay = (y2 - y1);
|
||||
if (deltay < 0) deltay = -deltay;
|
||||
|
||||
if (deltax >= deltay) {
|
||||
*numpixels = deltax + 1;
|
||||
*d = (deltay*2) - deltax;
|
||||
*dinc1 = deltay << 1;
|
||||
*dinc2 = (deltay-deltax) << 1;
|
||||
*xinc1 = 1;
|
||||
*xinc2 = 1;
|
||||
*yinc1 = 0;
|
||||
*yinc2 = 1;
|
||||
} else {
|
||||
*numpixels = deltay + 1;
|
||||
*d = (deltax*2) - deltay;
|
||||
*dinc1 = deltax << 1;
|
||||
*dinc2 = (deltax - deltay) << 1;
|
||||
*xinc1 = 0;
|
||||
*xinc2 = 1;
|
||||
*yinc1 = 1;
|
||||
*yinc2 = 1;
|
||||
}
|
||||
|
||||
if (x1 > x2) {
|
||||
*xinc1 = - *xinc1;
|
||||
*xinc2 = - *xinc2;
|
||||
}
|
||||
if (y1 > y2) {
|
||||
*yinc1 = - *yinc1;
|
||||
*yinc2 = - *yinc2;
|
||||
}
|
||||
}
|
||||
|
||||
void initcommands(void) {
|
||||
// Actions
|
||||
addcommand(CMD_UP, '<', "Go up stairs.");
|
||||
|
@ -577,6 +689,57 @@ int limit(int *what, int min, int max) {
|
|||
return limited;
|
||||
}
|
||||
|
||||
int parseplayerfile(FILE *f, lifeform_t *lf) {
|
||||
// add extra obs etc from f
|
||||
char *pp;
|
||||
char localbuf[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
int goterror = B_FALSE;
|
||||
fgets(buf, BUFLEN, f);
|
||||
while (!feof(f)) {
|
||||
if (buf[strlen(buf)-1] == '\n') {
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
}
|
||||
//dblog("got line: [%s]",buf);
|
||||
if (strstr(buf, "skill:") == buf) {
|
||||
skill_t *sk;
|
||||
enum SKILLLEVEL slev;
|
||||
strcpy(localbuf, buf + strlen("skill:"));
|
||||
pp = strtok(localbuf, " ");
|
||||
if (!pp) {
|
||||
dblog("ERROR in playerfile. unknown skill level in this line:\n%s\n",buf);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
slev = findskilllevbyname(pp);
|
||||
|
||||
pp += (strlen(pp) + 1);
|
||||
if (!pp) {
|
||||
dblog("ERROR in playerfile. missing skill name in this line:\n%s\n",buf);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
sk = findskillbyname(pp);
|
||||
if (sk) {
|
||||
giveskilllev(lf, sk->id, slev);
|
||||
} else {
|
||||
dblog("ERROR in playerfile. unknown skill (%s) in this line:\n%s\n",pp, buf);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
} else if (strstr(buf, "ob:") == buf) {
|
||||
object_t *o;
|
||||
strcpy(localbuf, buf + strlen("ob:"));
|
||||
o = addob(lf->pack, localbuf);
|
||||
if (o) {
|
||||
identify(o);
|
||||
} else {
|
||||
dblog("ERROR in playerfile. unknown object in this line:\n%s\n",buf);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
fgets(buf, BUFLEN, f);
|
||||
}
|
||||
return goterror;
|
||||
}
|
||||
|
||||
float pctof(float pct, float num) {
|
||||
return ((pct / 100.0) * num);
|
||||
}
|
||||
|
@ -908,3 +1071,9 @@ void timeeffectsworld(map_t *map) {
|
|||
|
||||
if (db) dblog("cur time is %ld\n",curtime);
|
||||
}
|
||||
|
||||
void usage(char *progname) {
|
||||
printf("usage: %s [ -f playerfile ]\n",progname);
|
||||
printf("\t-f xx\tReads player details from file xx.\n");
|
||||
}
|
||||
|
||||
|
|
5
nexus.h
5
nexus.h
|
@ -5,14 +5,18 @@ command_t *addcommand(enum COMMAND id, char c, char *desc);
|
|||
void checkdeath(void);
|
||||
void checkendgame(void);
|
||||
void cleanup(void);
|
||||
void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, int dinc2, int *xinc, int *yinc, int *dinc);
|
||||
void donextturn(map_t *map);
|
||||
celltype_t *findcelltype(int id);
|
||||
char *getdirname(int dir);
|
||||
void getrarity(int depth, int *min, int *max, int range);
|
||||
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 parseplayerfile(FILE *f, lifeform_t *lf);
|
||||
float pctof(float pct, float num);
|
||||
int rnd(int min, int max);
|
||||
int roll(char *string);
|
||||
|
@ -22,3 +26,4 @@ int rollmpdice(lifeform_t *lf);
|
|||
//void sortlf(map_t *map);
|
||||
void sortcommands(void);
|
||||
void timeeffectsworld(map_t *map);
|
||||
void usage(char *progname);
|
||||
|
|
162
objects.c
162
objects.c
|
@ -1545,7 +1545,7 @@ int changemat(object_t *o, enum MATERIAL mat) {
|
|||
objecttype_t *checkobnames(char *haystack, char *needle) {
|
||||
objecttype_t *ot;
|
||||
char *pluralname;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
|
||||
// search for exact match
|
||||
if (!strcmp(haystack, needle)) {
|
||||
|
@ -1650,6 +1650,21 @@ void damageallobs(object_t *exception, obpile_t *op, int howmuch, int damtype) {
|
|||
}
|
||||
}
|
||||
|
||||
void dumprandomobs(int amt) {
|
||||
int i;
|
||||
char buf[BUFLEN];
|
||||
int min,max;
|
||||
int depth;
|
||||
depth = player->cell->map->depth;
|
||||
getrarity(depth, &min, &max, RARITYVARIANCE);
|
||||
dblog("Random object dump for depth %d (rarity %d-%d)",depth,min,max);
|
||||
for (i = 0; i < amt; i++) {
|
||||
getrandomob(player->cell->map, buf);
|
||||
dblog(" %s",buf);
|
||||
}
|
||||
dblog("END RANDOM OBJECT");
|
||||
}
|
||||
|
||||
void explodeob(object_t *o, flag_t *f, int bigness) {
|
||||
cell_t *c;
|
||||
int dam;
|
||||
|
@ -1776,9 +1791,13 @@ objecttype_t *findotn(char *name) {
|
|||
knowledge_t *k;
|
||||
char *modname;
|
||||
char *p;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
brand_t *om;
|
||||
|
||||
if (!strlen(name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modname = strdup(name);
|
||||
|
||||
// make some replacements
|
||||
|
@ -2126,6 +2145,8 @@ int getobvalue(object_t *o) {
|
|||
} else if (o->type->obclass->id == OC_WAND) {
|
||||
price *= 2.25;
|
||||
}
|
||||
} else if (f->id == F_MANUALOF) {
|
||||
price *= 124;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3107,7 +3128,7 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
int selidx;
|
||||
int amt;
|
||||
flag_t *f;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
char *pluralname;
|
||||
char brandname[BUFLEN];
|
||||
char cursestr[BUFLEN];
|
||||
|
@ -3124,7 +3145,7 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
depth = rnd(1,MAXDEPTH);
|
||||
}
|
||||
|
||||
getrarity(depth, &raritymin, &raritymax, 25);
|
||||
getrarity(depth, &raritymin, &raritymax, RARITYVARIANCE);
|
||||
|
||||
while (!done) {
|
||||
if (db) dblog("adding random object with rarity value between %d - %d",raritymin,raritymax);
|
||||
|
@ -3635,7 +3656,7 @@ int getthrowdam(object_t *o) {
|
|||
// ie. 1 tonne object does 1000 damage (car)
|
||||
dam = ceil((double)getobunitweight(o));
|
||||
// missile objects do extra damage
|
||||
if (hasflag(o->flags, F_MISSILE)) {
|
||||
if (hasflag(o->flags, F_THROWMISSILE)) {
|
||||
dam *= 2;
|
||||
}
|
||||
// max
|
||||
|
@ -4025,7 +4046,6 @@ void initobjects(void) {
|
|||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks.", '*');
|
||||
addoc(OC_FOOD, "Food", "Yum!", '%');
|
||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -4091,7 +4111,7 @@ void initobjects(void) {
|
|||
// addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones");
|
||||
|
||||
|
@ -4144,7 +4164,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_ASH, "pile of ash", "A pile of ash", MT_STONE, 0.1, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, B_TRUE, NA, NA, ",");
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -4254,7 +4274,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_MAGIC, "potion of magic", "Fully restores the drinker's magical energy.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_ACROBATICS, "potion of acrobatics", "Allows the drinker to leap large distances.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addot(OT_POT_ELEMENTENDURE, "potion of endure elements", "Grants the imbiber temporary resistance to both fire and cold.", MT_GLASS, 1, OC_POTION);
|
||||
|
@ -4293,7 +4313,7 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_POT_POLYMORPH, "potion of polymorph self", "Transmutes the drinker into another living race.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_INVULN, "potion of invulnerability", "Grants the drinker temporary immunity to physical harm.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL);
|
||||
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4328,6 +4348,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTLIFE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
|
||||
addot(OT_SCR_DETECTOBS, "scroll of detect objects", "Senses objects near the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTOBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
|
||||
|
||||
addot(OT_SCR_DETECTMAGIC, "scroll of detect magic", "Allows the reader to detect magical enchantments.", MT_PAPER, 0.5, OC_SCROLL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTMAGIC, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
|
@ -4400,12 +4425,14 @@ void initobjects(void) {
|
|||
addot(OT_S_PULLMETAL, "pull metal", "Pulls metal objects to the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_S_ACCELMETAL, "accelerate metal", "Greatly accelerates a metal object thrown by the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addot(OT_S_METALHEAL, "metal healing", "Uses nearby metal for accelerated healing.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_EXPLODEMETAL, "explode metal", "Causes all metal objects in a location explode.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
||||
|
@ -4417,6 +4444,7 @@ void initobjects(void) {
|
|||
addot(OT_S_ANIMATEMETAL, "animate metal", "Imbues a metallic weapon with temporary life, enabling it to fight on its own.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
|
||||
///////////////////
|
||||
// death
|
||||
|
@ -4461,6 +4489,9 @@ void initobjects(void) {
|
|||
addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
|
||||
// l3
|
||||
addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
|
@ -4599,6 +4630,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
// TODO: hardcode how ai casts this
|
||||
// l4
|
||||
addot(OT_S_PACIFY, "pacify", "Induces calmness in another, preventing them from attacking.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
||||
///////////////////
|
||||
// modification
|
||||
///////////////////
|
||||
|
@ -4662,6 +4701,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addot(OT_S_PULL, "pull", "Pulls lifeforms towards the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l4
|
||||
addot(OT_S_TELEPORT, "teleportation", "Causes the caster to teleport to a new location within the same level. Becomes controlled at high power.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
||||
|
@ -4712,6 +4755,8 @@ void initobjects(void) {
|
|||
// divine powers
|
||||
addot(OT_A_DEBUG, "debug", "You can toggle debugging for a lifeform.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_ENHANCE, "enhance", "Enhance a lifeform's stats.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_LEARN, "learn", "Learn new skills.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_S_WISH, "wish", "Grants the caster any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL);
|
||||
|
@ -4749,8 +4794,12 @@ void initobjects(void) {
|
|||
// manuals
|
||||
addot(OT_MAN_ATHLETICS, "manual of athletics", "Teaches you the skill 'athletics'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_ATHLETICS, NA, NA, NULL);
|
||||
addot(OT_MAN_BACKSTAB, "manual of stabbing", "Teaches you the skill 'backstab'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_BACKSTAB, NA, NA, NULL);
|
||||
addot(OT_MAN_FIRSTAID, "manual of first aid", "Teaches you the skill 'first aid'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_FIRSTAID, NA, NA, NULL);
|
||||
addot(OT_MAN_LISTEN, "manual of listening", "Teaches you the skill 'listen'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_LISTEN, NA, NA, NULL);
|
||||
addot(OT_MAN_LOCKPICKING, "manual of lockpicking", "Teaches you the skill 'lockpicking'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_LOCKPICKING, NA, NA, NULL);
|
||||
addot(OT_MAN_RESEARCH, "manual of research", "Teaches you the skill 'research'.", MT_PAPER, 3, OC_BOOK);
|
||||
|
@ -4759,6 +4808,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_MAGITEMUSAGE, NA, NA, NULL);
|
||||
addot(OT_MAN_SPELLCASTING, "manual of spellcasting", "Teaches you the skill 'spellcasting'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SPELLCASTING, NA, NA, NULL);
|
||||
addot(OT_MAN_STEALTH, "manual of stealth", "Teaches you the skill 'stealth'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_STEALTH, NA, NA, NULL);
|
||||
addot(OT_MAN_TECHUSAGE, "manual of technology", "Teaches you the skill 'technology'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_TECHUSAGE, NA, NA, NULL);
|
||||
// weapon manuals
|
||||
|
@ -4820,6 +4871,8 @@ void initobjects(void) {
|
|||
// divination
|
||||
addot(OT_SB_DETECTLIFE, "spellbook of detect life", "Teaches the spell 'detect life'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTLIFE, NA, NA, NULL);
|
||||
addot(OT_SB_DETECTOBS, "spellbook of detect objects", "Teaches the spell 'detect objects'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTOBS, NA, NA, NULL);
|
||||
addot(OT_SB_MAPPING, "spellbook of sense surroundings", "Teaches the spell 'surroundings'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, NA, NA, NULL);
|
||||
addot(OT_SB_DETECTAURA, "spellbook of detect aura", "Teaches the spell 'detect aura'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
|
@ -4867,10 +4920,16 @@ void initobjects(void) {
|
|||
// mental
|
||||
addot(OT_SB_MINDSCAN, "spellbook of mind scan", "Teaches the spell 'mind scan'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_MINDSCAN, NA, NA, NULL);
|
||||
addot(OT_SB_SLEEP, "spellbook of sleep", "Teaches the spell 'sleep'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_SLEEP, NA, NA, NULL);
|
||||
addot(OT_SB_TELEKINESIS, "spellbook of telekinesis", "Teaches the spell 'telekinesis'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEKINESIS, NA, NA, NULL);
|
||||
addot(OT_SB_PACIFY, "spellbook of pacify", "Teaches the spell 'pacify'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_PACIFY, NA, NA, NULL);
|
||||
addot(OT_SB_PSYARMOUR, "spellbook of psychic armour", "Teaches the spell 'psychic armour'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_PSYARMOUR, NA, NA, NULL);
|
||||
addot(OT_SB_CHARM, "spellbook of charm", "Teaches the spell 'charm'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CHARM, NA, NA, NULL);
|
||||
// modification
|
||||
addot(OT_SB_INSCRIBE, "spellbook of inscribe", "Teaches the spell 'inscribe'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_INSCRIBE, NA, NA, NULL);
|
||||
|
@ -4922,7 +4981,8 @@ void initobjects(void) {
|
|||
f2 = hasflag(spelltype->flags, F_SPELLLEVEL);
|
||||
if (f2) {
|
||||
int rarity;
|
||||
rarity = 90 - (f2->val[0]*12);
|
||||
// ie. 80 - spelllevel*12
|
||||
rarity = 80 - (f2->val[0]*12);
|
||||
addflag(ot->flags, F_RARITY, H_ALL, rarity, NA, NULL);
|
||||
} else {
|
||||
dblog("Spell %s has no spell level - can't determine rarity for spellbook.", spelltype->name);
|
||||
|
@ -5112,7 +5172,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERUSECHARGE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, "Where will you spray?");
|
||||
addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 1, 5, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_LANTERNLED, "LED lantern", "A low-powered but efficient lantern which will last almost forever.", MT_METAL, 0.5, OC_TECH);
|
||||
|
@ -5237,6 +5297,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "^");
|
||||
addflag(lastot->flags, F_SHARP, 1, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addot(OT_CALTROP, "caltrop", "Connected metal spikes arranged such that one will always point upwards.", MT_METAL, 0.2, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
||||
|
@ -5757,7 +5818,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 5, NA, NULL);
|
||||
// armour - shields
|
||||
addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
||||
|
@ -5879,6 +5940,7 @@ void initobjects(void) {
|
|||
// missiles
|
||||
addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
|
@ -5886,6 +5948,7 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, "");
|
||||
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
||||
|
@ -5894,6 +5957,7 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 1.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
||||
|
@ -5941,7 +6005,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 4, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
||||
|
@ -5952,7 +6016,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 2.5, OC_WEAPON);
|
||||
|
@ -5988,7 +6052,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
|
||||
|
@ -6006,7 +6070,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_CHOP, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 6, 1, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An axe specifically designed for combat.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
|
@ -6031,7 +6095,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
||||
|
@ -6041,7 +6105,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
|
@ -6104,7 +6168,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMTYPE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, 1, 8, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
|
@ -6498,8 +6562,8 @@ int ismetal(enum MATERIAL mat) {
|
|||
return metal;
|
||||
}
|
||||
|
||||
int ismissile(object_t *o) {
|
||||
if (hasflag(o->flags, F_MISSILE)) {
|
||||
int isthrowmissile(object_t *o) {
|
||||
if (hasflag(o->flags, F_THROWMISSILE)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
// special cases...
|
||||
|
@ -7355,13 +7419,19 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
return B_TRUE;
|
||||
} else {
|
||||
if (f->val[1] != NA) {
|
||||
cell_t *newwhere = NULL;
|
||||
if ((f->val[1] & TR_NEEDLOS) && !haslos(lf, where)) {
|
||||
msg("You can't see there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf, where)) {
|
||||
msg("You have no line of fire to there!");
|
||||
return B_TRUE;
|
||||
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf, where, B_TRUE, &newwhere)) {
|
||||
if (newwhere) {
|
||||
// update destination
|
||||
where = newwhere;
|
||||
} else {
|
||||
msg("You have no line of fire to there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7545,7 +7615,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
// announce
|
||||
if (!seen) {
|
||||
youhear(where, "something spraying.");
|
||||
noise(where, NULL, "something spraying.", NULL);
|
||||
}
|
||||
} else if ((o->type->id == OT_EMPTYFLASK) || (o->type->id == OT_EMPTYVIAL)) {
|
||||
object_t *oo,*nextoo;
|
||||
|
@ -8029,13 +8099,23 @@ int pour(lifeform_t *lf, object_t *o) {
|
|||
dst->blessknown = B_TRUE;
|
||||
// remove bonuses
|
||||
killflagsofid(dst->flags, F_BONUS);
|
||||
// remove temporary flags
|
||||
// remove temporary flags and modify some others
|
||||
for (f = dst->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if (f->lifetime > 0) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_FROZEN) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_ONFIRE) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_POISONED) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_OBHP) {
|
||||
f->val[0] = f->val[1];
|
||||
}
|
||||
}
|
||||
// restore hp
|
||||
|
||||
|
||||
if (!isknown(dst)) makeknown(dst->type->id);
|
||||
} else if (o->type->id == OT_POT_ACID) {
|
||||
|
@ -8706,8 +8786,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
char obname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
getobname(oo, obname,oo->amt);
|
||||
msg("%s%s %s %s softly.",lfname,getpossessive(lfname),noprefix(obname),
|
||||
(oo->amt == 1) ? "glows" : "glow");
|
||||
msg("A black aura breaks away from %s%s %s.",lfname,getpossessive(lfname),noprefix(obname));
|
||||
seen = B_TRUE;
|
||||
}
|
||||
// uncurse it
|
||||
|
@ -9159,6 +9238,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
int acc;
|
||||
int youhit;
|
||||
object_t *newob;
|
||||
cell_t *newloc;
|
||||
int db = B_TRUE;
|
||||
|
||||
reason = E_OK;
|
||||
|
@ -9303,6 +9383,22 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
msg("%s", throwstring);
|
||||
}
|
||||
|
||||
|
||||
// adjust destination location in case something is in the way.
|
||||
haslof(thrower, where, LOF_NEED, &newloc);
|
||||
if (newloc) {
|
||||
where = newloc;
|
||||
target = where->lf;
|
||||
if (target && isdead(target)) {
|
||||
target = NULL;
|
||||
}
|
||||
if (target) {
|
||||
getlfname(target, targetname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//taketime(thrower, SPEED_THROW);
|
||||
|
||||
// some obejcts will die when thrown.
|
||||
|
@ -9406,7 +9502,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
msg("%s", buf2);
|
||||
} else {
|
||||
if (willshatter(o->material->id)) {
|
||||
youhear(where, "shattering glass.");
|
||||
noise(where, NULL, "shattering glass.", NULL);
|
||||
}
|
||||
}
|
||||
sprintf(damstring, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
|
@ -9455,7 +9551,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
msg("%s shatters!",obcaps);
|
||||
free(obcaps);
|
||||
} else {
|
||||
youhear(where, "shattering glass.");
|
||||
noise(where, NULL, "shattering glass.", NULL);
|
||||
}
|
||||
shattered = B_TRUE;
|
||||
}
|
||||
|
@ -9593,7 +9689,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (youhit && target) {
|
||||
if (getobweight(o) >= getlfweight(target, B_NOOBS)) {
|
||||
int dir;
|
||||
dir = getdirtowards(srcloc, target->cell, target, B_FALSE);
|
||||
dir = getdirtowards(srcloc, target->cell, target, B_FALSE, DT_COMPASS);
|
||||
knockback(target, dir, 1, thrower);
|
||||
}
|
||||
}
|
||||
|
@ -10233,7 +10329,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
}
|
||||
|
||||
// penalty for throwing non-missiles
|
||||
if (missile && !firearm && !ismissile(missile)) {
|
||||
if (missile && !firearm && !isthrowmissile(missile)) {
|
||||
acc -= 20;
|
||||
}
|
||||
return acc;
|
||||
|
|
|
@ -31,6 +31,7 @@ int countnames(char **list);
|
|||
int countobs(obpile_t *op);
|
||||
int curseob(object_t *o);
|
||||
void damageallobs(object_t *exception, obpile_t *op, int howmuch, int damtype);
|
||||
void dumprandomobs(int amt);
|
||||
void explodeob(object_t *o, flag_t *f, int bigness);
|
||||
void extinguish(object_t *o);
|
||||
material_t *findmaterial(int id);
|
||||
|
@ -127,7 +128,7 @@ int isknownot(objecttype_t *ot);
|
|||
int isidentified(object_t *o);
|
||||
int isimpassableob(object_t *o, lifeform_t *lf);
|
||||
int ismetal(enum MATERIAL mat);
|
||||
int ismissile(object_t *o);
|
||||
int isthrowmissile(object_t *o);
|
||||
int isoperable(object_t *o);
|
||||
int isplainob(object_t *o);
|
||||
int ispourable(object_t *o);
|
||||
|
|
2
save.c
2
save.c
|
@ -277,6 +277,7 @@ map_t *loadmap(char *basefile) {
|
|||
fscanf(f, "%d\n",&m->nextmap[i]); // map dimensons
|
||||
}
|
||||
if (db) dblog("--> Finished map info. name='%s', dims=%d x %d\n",m->name, m->w, m->h);
|
||||
fscanf(f, "beingcreated:%d\n",&m->beingcreated);
|
||||
fscanf(f, "id:%d\n",&m->id); // map id
|
||||
|
||||
// load lifeforms
|
||||
|
@ -710,6 +711,7 @@ int savemap(map_t *m) {
|
|||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
fprintf(f, "%d\n",m->nextmap[i] ); // map dimensons
|
||||
}
|
||||
fprintf(f, "beingcreated:%d\n",m->beingcreated);
|
||||
|
||||
// save all non-player lifeforms (includes their objects)
|
||||
fprintf(f, "lifeforms:\n");
|
||||
|
|
333
spell.c
333
spell.c
|
@ -400,6 +400,36 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else {
|
||||
msg("There is nobody there!");
|
||||
}
|
||||
} else if (abilid == OT_A_ENHANCE) {
|
||||
cell_t *where;
|
||||
where = askcoords("Enhance stats of who?", TT_MONSTER);
|
||||
if (where && where->lf) {
|
||||
char ch;
|
||||
enum ATTRIB att;
|
||||
ch = askchar("Enhance which stat (n for none)?", "sdcin",NULL, B_TRUE);
|
||||
switch (ch) {
|
||||
case 's': att = A_STR; break;
|
||||
case 'd': att = A_DEX; break;
|
||||
case 'c': att = A_CON; break;
|
||||
case 'i': att = A_IQ; break;
|
||||
default: att = A_NONE; break;
|
||||
}
|
||||
if (att != A_NONE) {
|
||||
char buf[BUFLEN];
|
||||
int val;
|
||||
askstring("Set stat to what", '?', buf, BUFLEN, NULL);
|
||||
val = atoi(buf);
|
||||
if ((val <= 0) || (val > 18)) {
|
||||
msg("Invalid value.");
|
||||
} else {
|
||||
setattr(where->lf, att, val);
|
||||
getlfname(where->lf, buf);
|
||||
msg("%s%s %s set to %d.", buf, getpossessive(buf), getattrname(att), val);
|
||||
}
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
} else if (abilid == OT_A_HEAVYBLOW) {
|
||||
object_t *wep;
|
||||
char dirch;
|
||||
|
@ -672,7 +702,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_AIRBLAST) {
|
||||
int dir;
|
||||
object_t *o,*nexto;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
|
||||
if (cansee(player, caster)) {
|
||||
|
@ -680,7 +710,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("%s emit%s a powerful blast of air!", castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
dir = getdirtowards(caster->cell, targcell, target, B_FALSE);
|
||||
dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS);
|
||||
// lfs
|
||||
if (target) {
|
||||
knockback(target, dir, power, caster);
|
||||
|
@ -704,7 +734,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
newlf = makezombie(o);
|
||||
if (newlf) {
|
||||
if (isplayer(caster) && skillcheck(caster, A_IQ, 20, power)) {
|
||||
makefriendly(newlf);
|
||||
makefriendly(newlf, PERMENANT);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
|
@ -813,21 +843,23 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
teleportto(caster, targcell, B_TRUE);
|
||||
}
|
||||
} else if (spellid == OT_S_BURNINGWAVE) {
|
||||
cell_t *c;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, spellid, power)) return B_TRUE;
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell;
|
||||
int i;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_WALLSTOP, spellid, power)) return B_TRUE;
|
||||
|
||||
if (cansee(player, caster)) {
|
||||
msg("%s shoots a wave of fire!",castername);
|
||||
msg("%s shoot%s a wave of fire!",castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
// create a line of fire towards the target cell
|
||||
c = caster->cell;
|
||||
while (c != targcell) {
|
||||
int dir;
|
||||
dir = getdirtowards(c, targcell, NULL, B_FALSE);
|
||||
c = getcellindir(c, dir);
|
||||
if (!c) break;
|
||||
if (c->type->solid) break;
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcell);
|
||||
|
||||
// don't set caster's cell on fire!
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
cell_t *c;
|
||||
c = retcell[i];
|
||||
|
||||
// set on fire
|
||||
addob(c->obpile, "medium fire");
|
||||
if (c->lf) {
|
||||
|
@ -841,7 +873,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
} else if (spellid == OT_S_CLOUDKILL) {
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
|
||||
if (targcell->type->solid) {
|
||||
fizzle(caster);
|
||||
|
@ -854,10 +886,48 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("A cloud of poison gas appears!");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_CHARM) {
|
||||
char targetname[BUFLEN];
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
if (getallegiance(caster) == AL_PEACEFUL) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
if (getallegiance(target) == getallegiance(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s is already allied with you!",targetname);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (skillcheck(targcell->lf, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
msg("%s resists.",targetname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
int howlong;
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
howlong = getspellduration(20,30,blessed) + (power*10);
|
||||
|
||||
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
|
||||
}
|
||||
} else if (spellid == OT_S_CONECOLD) {
|
||||
char lfname[BUFLEN];
|
||||
int acc;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}');
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
|
@ -1042,8 +1112,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_DETECTLIFE) {
|
||||
target = caster;
|
||||
if (isplayer(caster)) {
|
||||
int howlong;
|
||||
int howlong,radius;
|
||||
howlong = getspellduration(10,20,blessed) + (power*2);
|
||||
radius = power * 10;
|
||||
addtempflag(target->flags, F_DETECTLIFE, 10, NA, NA, NULL, howlong);
|
||||
} else {
|
||||
// monsters can't use this
|
||||
|
@ -1068,9 +1139,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// monsters can't use this
|
||||
}
|
||||
*/
|
||||
} else if (spellid == OT_S_DETECTOBS) {
|
||||
target = caster;
|
||||
if (isplayer(caster)) {
|
||||
int howlong,radius;
|
||||
howlong = getspellduration(25,35,blessed) + (power*10);
|
||||
radius = power*10;
|
||||
addtempflag(target->flags, F_DETECTOBS, radius, NA, NA, NULL, howlong);
|
||||
} else {
|
||||
// monsters can't use this
|
||||
}
|
||||
} else if (spellid == OT_S_DETONATE) {
|
||||
// don't need line of fire!
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_DOOR, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_DOOR, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
explodecells(targcell, 20, B_TRUE, NULL, power / 4, B_TRUE);
|
||||
|
||||
|
@ -1081,7 +1162,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
float totalmass = 0;
|
||||
object_t *o, *nexto;
|
||||
|
||||
if (!validatespellcell(caster, &targcell, TT_OBJECT, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_OBJECT, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
// how much metal is there?
|
||||
for (o = targcell->obpile->first ; o ; o = nexto) {
|
||||
|
@ -1194,7 +1275,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (x = caster->cell->x - range ; x <= caster->cell->x + range; x++) {
|
||||
targcell = getcellat(caster->cell->map, x,y);
|
||||
if (targcell && (getcelldist(caster->cell, targcell) <= range)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster, targcell)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster, targcell, B_FALSE, NULL)) {
|
||||
char lfname[BUFLEN];
|
||||
// automatic hit
|
||||
getlfname(targcell->lf, lfname);
|
||||
|
@ -1216,7 +1297,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char numbuf[BUFLEN];
|
||||
|
||||
numtotext(power, numbuf);
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}');
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
|
@ -1245,7 +1326,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_FIREBALL) {
|
||||
int failed = B_FALSE;
|
||||
// ask for a target cell
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
if (targcell) {
|
||||
if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) {
|
||||
int dir;
|
||||
|
@ -1312,7 +1393,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_FIREDART) {
|
||||
char lfname[BUFLEN];
|
||||
int acc;
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}');
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
|
@ -1363,7 +1444,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (x = caster->cell->x - range ; x <= caster->cell->x + range; x++) {
|
||||
targcell = getcellat(caster->cell->map, x,y);
|
||||
if (targcell && (getcelldistorth(caster->cell, targcell) <= range)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster, targcell)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster, targcell, B_FALSE, NULL)) {
|
||||
char lfname[BUFLEN];
|
||||
// automatic hit
|
||||
getlfname(targcell->lf, lfname);
|
||||
|
@ -1378,7 +1459,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_FLAMEPILLAR) {
|
||||
int failed = B_FALSE;
|
||||
// ask for a target cell
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_WALLSTOP, spellid, power)) return B_TRUE;
|
||||
if (targcell && haslos(caster, targcell)) {
|
||||
if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) {
|
||||
flag_t *f;
|
||||
|
@ -1565,7 +1646,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_HASTE) {
|
||||
int howlong = 15;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
|
@ -1747,7 +1828,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char numbuf[BUFLEN];
|
||||
|
||||
numtotext(power, numbuf);
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}');
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
|
@ -1950,7 +2031,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, LOF_WALLSTOP, spellid, power)) return B_TRUE;
|
||||
|
||||
// 4 is the same as ST_TITANIC strength
|
||||
// 10 = gun speed
|
||||
|
@ -2062,9 +2143,40 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_ARBOOST, power*3, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_PULL) {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_TRUE, LOF_WALLSTOP, spellid, power)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
if (target) {
|
||||
int failed = B_FALSE;
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
failed = B_TRUE;
|
||||
} else {
|
||||
// they get pulled towards caster
|
||||
failed = pullnextto(target, caster->cell);
|
||||
}
|
||||
|
||||
if (isplayer(target) || cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
if (isplayer(target) || cansee(player, target)) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(target, buf);
|
||||
msg("%s %s pulled forward slightly.", buf, isplayer(target) ? "are" : "is");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_PULLMETAL) {
|
||||
int donesomething = B_FALSE;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT, B_TRUE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT, B_TRUE, LOF_WALLSTOP, spellid, power)) return B_TRUE;
|
||||
|
||||
if (targcell->lf) {
|
||||
object_t *o;
|
||||
|
@ -2282,7 +2394,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int willannounce = B_FALSE;
|
||||
char targname[BUFLEN];
|
||||
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target) {
|
||||
|
@ -2305,7 +2417,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_KNOCK) {
|
||||
object_t *o;
|
||||
if (!validatespellcell(caster, &targcell,TT_DOOR, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_DOOR, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
o = hasobwithflag(targcell->obpile, F_DOOR);
|
||||
if (o) {
|
||||
int dooropen;
|
||||
|
@ -2337,7 +2449,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// at power 3, you can control where the light appears
|
||||
// at power 8, the light is permenant
|
||||
if (power >= 3) {
|
||||
if (!validatespellcell(caster, &targcell,TT_NONE, B_FALSE, spellid, power)) return B_TRUE;
|
||||
// TODO: this actually means we can cast it through walls!!!
|
||||
if (!validatespellcell(caster, &targcell,TT_NONE, B_FALSE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
} else {
|
||||
targcell = caster->cell;
|
||||
}
|
||||
|
@ -2431,6 +2544,49 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_PACIFY) {
|
||||
char targetname[BUFLEN];
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
|
||||
if (skillcheck(targcell->lf, SC_RESISTMAG, 30 + power, 0)) {
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
msg("%s resists.",targetname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
int donesomething = B_FALSE;
|
||||
|
||||
// stop targetting anybody
|
||||
if (killflagsofid(target->flags, F_TARGET)) {
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
if (killflagsofid(target->flags, F_TARGETCELL)) {
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
if (killflagsofid(target->flags, F_HOSTILE)) {
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
|
||||
if (donesomething) {
|
||||
if (cansee(player, target)) {
|
||||
msg("%s calms down.",targetname);
|
||||
}
|
||||
} else {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s already seems calm enough.",targetname);
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
} else if (spellid == OT_S_PASSWALL) {
|
||||
int howlong = 7;
|
||||
target = caster;
|
||||
|
@ -2578,7 +2734,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_SPARK) {
|
||||
object_t *o,*nexto;
|
||||
int donesomething = B_FALSE;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, B_FALSE, spellid, power)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
if (haslos(player, targcell)) {
|
||||
msg("A small spark of flame appears.");
|
||||
|
@ -2837,9 +2993,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
o = relinkob(o, newloc->obpile);
|
||||
}
|
||||
if (o) {
|
||||
if (isblind(caster)) {
|
||||
youhear(caster->cell, "something hitting the ground.");
|
||||
} else {
|
||||
noise(caster->cell, NULL, "something hitting the ground.", NULL);
|
||||
if (!isblind(caster)) {
|
||||
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
} else {
|
||||
|
@ -3111,7 +3266,7 @@ void pullobto(object_t *o, lifeform_t *lf) {
|
|||
}
|
||||
// where does it end up?
|
||||
obloc = getoblocation(o);
|
||||
dir = getdirtowards(lf->cell, obloc, NULL, B_FALSE);
|
||||
dir = getdirtowards(lf->cell, obloc, NULL, B_FALSE, DT_COMPASS);
|
||||
newcell = getcellindir(lf->cell, dir);
|
||||
if (newcell) {
|
||||
// move next to player
|
||||
|
@ -3205,19 +3360,68 @@ lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **targe
|
|||
return *target;
|
||||
}
|
||||
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlof, enum OBTYPE spellid, int power) {
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlos, enum LOFTYPE needlof, enum OBTYPE spellid, int power) {
|
||||
int maxrange = UNLIMITED;
|
||||
int done = B_FALSE;
|
||||
cell_t *where = NULL;
|
||||
|
||||
maxrange = getspellrange(spellid, power);
|
||||
|
||||
while (!done) {
|
||||
if (*targcell) {
|
||||
done = B_TRUE;
|
||||
if (where) {
|
||||
cell_t *newwhere = NULL;
|
||||
// validate it
|
||||
if (where && needlos && !haslos(caster, where)) {
|
||||
msg("You cannot see there!"); more();
|
||||
where = NULL;
|
||||
}
|
||||
|
||||
if (where && needlof && !haslof(caster, where, needlof, &newwhere)) {
|
||||
if (newwhere) {
|
||||
// warn!
|
||||
int ch;
|
||||
ch = askchar("Your have no clear line of fire - really target here?","yn","n", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
where = newwhere;
|
||||
} else {
|
||||
where = NULL;
|
||||
}
|
||||
} else {
|
||||
where = NULL;
|
||||
}
|
||||
}
|
||||
if (where && (maxrange != UNLIMITED) && (getcelldist(caster->cell, where) > maxrange)) {
|
||||
// out of range
|
||||
msg("Too far away - max range is %d.",maxrange); more();
|
||||
where = NULL;
|
||||
}
|
||||
|
||||
if (where && isplayer(caster) && (where == caster->cell)) {
|
||||
// warn before targetting yourself!
|
||||
if (getiqname(getattr(caster, A_IQ), NULL) >= IQ_AVERAGE) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(spellid);
|
||||
if (sp) {
|
||||
if (hasflagval(sp->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL) ||
|
||||
hasflagval(sp->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL)) {
|
||||
int ch;
|
||||
ch = askchar("Really target yourself","yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
where = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// still got a target?
|
||||
if (where) {
|
||||
*targcell = where;
|
||||
done = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
// ask for a target cell
|
||||
if (isplayer(caster)) {
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
if (maxrange == UNLIMITED) {
|
||||
objecttype_t *ot;
|
||||
|
@ -3227,51 +3431,12 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, i
|
|||
sprintf(buf, "Where will you target your spell [max range %d]?",maxrange);
|
||||
}
|
||||
where = askcoords(buf, targtype);
|
||||
|
||||
if (where) {
|
||||
//if (haslos(caster, where) || (where == caster->cell)) {
|
||||
if (needlof && !haslof(caster, where)) {
|
||||
// no line of sight
|
||||
fizzle(caster);
|
||||
return NULL;
|
||||
} else if ((maxrange != UNLIMITED) && (getcelldist(caster->cell, where) > maxrange)) {
|
||||
// out of range
|
||||
fizzle(caster);
|
||||
return NULL;
|
||||
} else {
|
||||
*targcell = where;
|
||||
done = B_TRUE;
|
||||
// warn before targetting yourself!
|
||||
if (isplayer(caster) && (where == caster->cell)) {
|
||||
if (getiqname(getattr(caster, A_IQ), NULL) >= IQ_AVERAGE) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(spellid);
|
||||
if (sp) {
|
||||
if (hasflagval(sp->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL) ||
|
||||
hasflagval(sp->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL)) {
|
||||
int ch;
|
||||
ch = askchar("Really target yourself","yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
*targcell = NULL;
|
||||
done = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
} else {
|
||||
msg("You can't see there!");
|
||||
more();
|
||||
*targcell = NULL;
|
||||
done = B_FALSE;
|
||||
if (!where) {
|
||||
int ch;
|
||||
ch = askchar("Abandon your spell?","yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
where = NULL;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
// no line of sight or invalid cell
|
||||
fizzle(caster);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// TODO: fill in monster code?
|
||||
|
|
2
spell.h
2
spell.h
|
@ -19,7 +19,7 @@ void pullobto(object_t *o, lifeform_t *lf);
|
|||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target);
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlof, enum OBTYPE spellid, int power);
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlos, enum LOFTYPE needlof, enum OBTYPE spellid, int power);
|
||||
lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
|
||||
#endif
|
||||
|
||||
|
|
23
text.c
23
text.c
|
@ -32,16 +32,18 @@ char *capitaliseall(char *text) {
|
|||
|
||||
char *getattrname(enum ATTRIB att) {
|
||||
switch (att) {
|
||||
case A_NONE:
|
||||
return "?attrib_none?";
|
||||
case A_STR:
|
||||
return "strength";
|
||||
case A_IQ:
|
||||
return "intelligence";
|
||||
case A_DEX:
|
||||
return "dexterity";
|
||||
default:
|
||||
break;
|
||||
case A_CON:
|
||||
return "constitution";
|
||||
}
|
||||
return "?unknown?";
|
||||
return "?badattrib?";
|
||||
}
|
||||
|
||||
char *getpossessive(char *text) {
|
||||
|
@ -219,6 +221,21 @@ char *makeplural(char *text) {
|
|||
return newtext;
|
||||
}
|
||||
|
||||
int needses(char *text) {
|
||||
if (text[strlen(text)-1] == 's') {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (strlen(text) >= 2) {
|
||||
if ((text[strlen(text)-2] == 'c') &&
|
||||
(text[strlen(text)-1] == 'h')) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
char *noprefix(char *obname) {
|
||||
char *p;
|
||||
p = strchr(obname, ' ');
|
||||
|
|
Loading…
Reference in New Issue