* [+] make vending machines use this container code instead.
- [+] don't say "you see a few things" if one of them is footsteps * [+] IFMONSTER code failing....because flags are now SORTED!!! - [+] tumble - askcoords is letting us pick a cell we don't have lof to. * [+] assign a name to lfs once you hire them * [+] coloured msgtext - [+] make min dam reduction from AR be AR/5. - [+] safebox - [+] if intelligent, prompt before walking into RESTRICTMOVEMENT with no getsweaker (val1) * [+] make fire / ice damage mor elike netheck - [+] towns should have gates on EVERY side - [+] forest cells outside town gates need to be CLEARED. (maybe turn to dirt) - [+] fix up knock targetting to include magical barriers - [+] say "open a bag?" not "operate a bag?" * [+] implement immunetodisease - [+] sort known skills in @s. - [+] better damage bonus when attacking someone who is asleep - [+] practive firearms/throwing * [+] need objecttype->size * [+] containers * [+] change guns so you have to reload them. ("operate") - [+] crash when loading map with water - [+] SAVE OBJECT CONTENTSk - [+] monsters with jobs aren't getting start items - [+] shopkeeper has shotgun - [+] bug: monster keeps swapping between shotgun and flail - [+] when hiring, remember failure. * [+] Inn - [+] bug: pets fighting!!! then they all turn on you. never make allies get angry unless the attacker is the player * [+] hiring npcs - [+] chat to pet: "stay close" or "keep your distance" - [+] new 'furniture' obclass - [+] allow for 'randomshop' regiontype * [+] add enchantment school - [+] cast a scroll of mending on itself. CRASH. * [+] lessengravity should make you jump better and get knocked back further - [+] boostgrav/lessengrav cancel out each other. * [+] CRASH when you fall down a hole and die. - [+] problem: master gravitation doesn't let us cast levitat. getspellschoolknown() should return the HIGHEST known skill, not the first. * [+] bug: dregion is null?!??! * [+] dig a pit, if you cleared out land below, you just stay down there. - [+] potion of leveitation - [+] warning msg when levitate is about to expire * [+] if you fall upwards to the surface... * [+] if you are ever on the surface while levitating.... - [+] BUG: cna't go up stairs to surface anymore!!!!! - [+] get hungry LOTS more quickly when you start sprinting * [+] monk slow metabolism psionic pell. - [+] fix buf with lore giving LESS accuracy instead of more. - [+] food shop - [+] wand of digging not identified if you dig upwards * [+] when you make ah ole in the roof, objects above should fall through right away * [+] all towns should have: - [+] give monks more psionics spells. - [+] sk_throwing skill - [+] make calm animals use spellpower * [+] add wisdom * [+] need to save region data along with maps * [+] COMBINE armour evasion and accuracy penalty!!! * [+] make armour reduce accuracy as well (unless you have 'armour' skill) - [+] landmine trap * [+] make friendly monsters of same raceclass swap ammo - [+] rename 'pull' to 'suck' to avoid confusion with pull metal * [+] food to fix blindness - [+] potion of coffee * [+] genericise statbrackets * [+] tumble ability * [+] simplify spell power * [+] shopkeeprs should be allowed to pursue targets outside of the shop. - [+] give shopkeepers a shotgun * [+] make F_RNDHOSTILE be able to ahve a random chance. * [+] if you randomly generate food in a shop, still give it a price. - [+] if peaceful humanoid walks into you, "sorry!" - [+] sayphrase(lf, SP_SORRY, vol) - [+] only let you recruit jobs with j_recruitable - [+] CRASH - summon "monk" - [+] dogs, - [+] chickens, - [+] drunks, * [+] village objects - [+] change armourrating AGAIN. instead of a percentage, make it a number. - [+] rename inn to "pub", since you can't sleep there. * [+] random speech code * [+] genericise sayphrase text based on lf's job * [+] monks - add rest of abliities - [+] add fiengdeath ability to some monsters
This commit is contained in:
parent
14eb81566c
commit
7c86e87f4a
234
ai.c
234
ai.c
|
@ -25,7 +25,8 @@ void addignorecell(lifeform_t *lf, cell_t *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||
// returns true on failure
|
||||
int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||
int db = B_FALSE;
|
||||
flag_t *f;
|
||||
|
||||
|
@ -34,9 +35,9 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
}
|
||||
|
||||
// mindless?
|
||||
if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) {
|
||||
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) {
|
||||
if (!isundead(lf)) {
|
||||
return;
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,19 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
if ((f->lifetime > 0) && (f->lifetime < timelimit)) {
|
||||
f->lifetime = timelimit;
|
||||
}
|
||||
return;
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// feigning death?
|
||||
if (lfhasflag(victim, F_FEIGNINGDEATH)) {
|
||||
int penalty;
|
||||
penalty = (getcelldist(lf->cell, victim->cell)-1);
|
||||
if (penalty < 0) penalty = 0;
|
||||
penalty *= 3;
|
||||
if (!skillcheckvs(lf, SC_WILL, -penalty, victim, SC_WILL, 0)) {
|
||||
dblog(".oO { attempted target fooled me with feign death. ignoring. }");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (db) {
|
||||
|
@ -84,6 +97,7 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
// no longer a pet
|
||||
f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
|
||||
|
@ -225,7 +239,7 @@ object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra) {
|
|||
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
||||
|
||||
o = getfirearm(lf);
|
||||
if (o && getammo(lf)) {
|
||||
if (o && getammo(o)) {
|
||||
if (db) {
|
||||
char gunname[BUFLEN];
|
||||
getobname(o, gunname, o->amt);
|
||||
|
@ -423,6 +437,14 @@ flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int t
|
|||
return f;
|
||||
}
|
||||
|
||||
flag_t *aihastarget(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
f = lfhasflag(lf, F_TARGETLF);
|
||||
if (f) return f;
|
||||
f = lfhasflag(lf, F_TARGETCELL);
|
||||
if (f) return f;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// returns B_FALSE if we did something.
|
||||
// returns B_TRUE if we failed (ie. did nothing)
|
||||
|
@ -486,6 +508,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
attackok = B_TRUE;
|
||||
} else if (!lfhasflag(lf, F_HIDING)) {
|
||||
attackok = B_TRUE;
|
||||
} else if (!lfhasflag(lf, F_FEIGNINGDEATH)) {
|
||||
attackok = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,8 +633,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// if we got here, we're either at the correct distance or couldn't
|
||||
// move.
|
||||
if (attackok) {
|
||||
enum IQBRACKET iqb;
|
||||
iqb = getiqname(getattr(lf, A_IQ), NULL);
|
||||
enum ATTRBRACKET iqb;
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
|
||||
// if not adjacent, check for guns, wands, throwing
|
||||
if ( (rangedattack != RA_NONE) &&
|
||||
|
@ -774,7 +798,6 @@ int aipickupok(lifeform_t *lf, object_t *o) {
|
|||
int ok = B_FALSE;
|
||||
|
||||
if (hasflag(o->flags, F_SHOPITEM)) {
|
||||
// && (getiqname(getattr(lf, A_IQ), NULL) > IQ_ANIMAL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -819,8 +842,8 @@ void aiturn(lifeform_t *lf) {
|
|||
enum BODYPART bp;
|
||||
//cell_t *c;
|
||||
lifeform_t *master = NULL;
|
||||
enum IQBRACKET iqb;
|
||||
int n;
|
||||
enum ATTRBRACKET iqb;
|
||||
int n,i;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -857,8 +880,7 @@ void aiturn(lifeform_t *lf) {
|
|||
// info gathering
|
||||
///////////////////////////////////////////
|
||||
// remember our intelligence
|
||||
iqb = getiqname(getattr(lf, A_IQ), NULL);
|
||||
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
|
||||
// are we a pet?
|
||||
f = lfhasflagval(lf, F_PETOF, NA, NA, NA, NULL);
|
||||
|
@ -869,7 +891,7 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
// emergencies
|
||||
///////////////////////////////////////////////
|
||||
if (iqb >= IQ_AVERAGE) {
|
||||
if (iqb >= AT_AVERAGE) {
|
||||
if (celldangerous(lf, lf->cell, B_TRUE, NULL)) {
|
||||
// if our cell is dangerous, move away!
|
||||
if (!dorandommove(lf, B_NOBADMOVES, B_FALSE)) {
|
||||
|
@ -881,9 +903,29 @@ void aiturn(lifeform_t *lf) {
|
|||
|
||||
///////////////////////////////////////////////
|
||||
// housekeeping - weapon changes, drop/pickup,
|
||||
// use items, etc
|
||||
// use items, talk,etc
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// talking
|
||||
f = lfhasflag(lf, F_RANDOMTALKPCT);
|
||||
if (f) {
|
||||
if (pctchance(f->val[0])) {
|
||||
flag_t *poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
for (f = lf->flags->first ;f ; f = f->next) {
|
||||
if (f->id == F_RANDOMTALK) {
|
||||
poss[nposs++] = f;
|
||||
}
|
||||
}
|
||||
if (nposs) {
|
||||
int vol;
|
||||
f = poss[rnd(0,nposs-1)];
|
||||
vol = rnd(f->val[1], f->val[2]);
|
||||
sayphrase(lf, f->val[0], vol, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// healing
|
||||
///////////////////////////////////////////////
|
||||
|
@ -894,13 +936,26 @@ void aiturn(lifeform_t *lf) {
|
|||
int sleepval = 18;
|
||||
|
||||
if (modcounter(lf->flags, 1) >= sleepval) {
|
||||
taketime(lf, getactspeed(lf));
|
||||
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
||||
return;
|
||||
// we say that this ISNT on purpose, because otherwise
|
||||
// we'll wake up as soon as we're healed. in this case
|
||||
// we actually want to sleep forever (or until woken).
|
||||
if (!gotosleep(lf, B_FALSE)) {
|
||||
// force this since when not on purpose, gotosleep wont
|
||||
// take time.
|
||||
taketime(lf, getactspeed(lf));
|
||||
return; // success
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// feigning death with enemies in sight?
|
||||
if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) {
|
||||
// just wait...
|
||||
taketime(lf, getactspeed(lf));
|
||||
return;
|
||||
}
|
||||
|
||||
// need to heal?
|
||||
if (lf->hp < (lf->maxhp/2)) {
|
||||
if (!useitemwithflag(lf, F_AIHEALITEM)) {
|
||||
|
@ -944,16 +999,18 @@ void aiturn(lifeform_t *lf) {
|
|||
curwep = getweapon(lf);
|
||||
bestwep = getbestweapon(lf);
|
||||
|
||||
if (curwep != bestwep) {
|
||||
if ((curwep != bestwep) && !isfirearm(curwep)) {
|
||||
if (db) dblog(".oO { i have a better weapon than my current one (%s > %s) }",bestwep->type->name, curwep ? curwep->type->name : "nothing");
|
||||
// weild better one
|
||||
if (!weild(lf, bestwep)) return;
|
||||
}
|
||||
|
||||
// do we have a better firearm ?
|
||||
curgun = getfirearm(lf);
|
||||
if (curwep && hasflag(curwep->flags, F_TWOHANDED)) {
|
||||
// we are using a two handed weapon. don't
|
||||
// check for guns.
|
||||
} else {
|
||||
curgun = getfirearm(lf);
|
||||
bestgun = getbestfirearm(lf);
|
||||
|
||||
if (curgun != bestgun) {
|
||||
|
@ -963,14 +1020,15 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// do we have better ammo?
|
||||
// do we have ammo for an empty gun?
|
||||
if (curgun) {
|
||||
object_t *curammo;
|
||||
curammo = getammo(lf);
|
||||
curammo = getammo(curgun);
|
||||
if (!curammo) {
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
testammo(lf, o); // doesn't take any time.
|
||||
if (getammo(lf)) break;
|
||||
o = getrandomammo(lf);
|
||||
if (o && !loadfirearm(lf, curgun, o)) {
|
||||
// success
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -998,7 +1056,7 @@ void aiturn(lifeform_t *lf) {
|
|||
// look for any object which we _covet_.
|
||||
// ie. if we covet something, we will pick it up
|
||||
// instead of attacking our target.
|
||||
if (!lfhasflag(lf, F_HIDING)) {
|
||||
if (!lfhasflag(lf, F_HIDING) && !lfhasflag(lf, F_FEIGNINGDEATH)) {
|
||||
if (db) dblog(".oO { looking for covetted objects... }");
|
||||
if (lookforobs(lf)) {
|
||||
if (db) dblog(".oO { found covetted object. returning. }");
|
||||
|
@ -1034,6 +1092,7 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
// generic pre-movement actions.
|
||||
///////////////////////////////////////////////
|
||||
// need light?
|
||||
if (!haslos(lf, lf->cell)) {
|
||||
object_t *lamp;
|
||||
lamp = hasobwithflagval(lf->pack, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL);
|
||||
|
@ -1047,6 +1106,29 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// ally needs ammo?
|
||||
for (i = 0; i < lf->nlos; i++) {
|
||||
cell_t *c;
|
||||
c = lf->los[i];
|
||||
if (c->lf && (c->lf != lf) && areallies(lf, c->lf)) {
|
||||
object_t *gun;
|
||||
gun = getfirearm(c->lf);
|
||||
if (gun && !getammo(gun)) {
|
||||
object_t *o;
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (isammofor(o->type, gun) ) {
|
||||
if (getcelldist(lf->cell, c) <= getmaxthrowrange(lf, o)) {
|
||||
// throw it to them!
|
||||
if (!throwat(lf, o, c)) {
|
||||
// success
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// movement
|
||||
|
@ -1111,6 +1193,26 @@ void aiturn(lifeform_t *lf) {
|
|||
// not attacking anyone in particular
|
||||
if (db) dblog(".oO { i do not have a target or can't move towards it. looking for one. }");
|
||||
|
||||
// shopkeepers will return to their shops
|
||||
if (hasjob(lf, J_SHOPKEEPER)) {
|
||||
f = lfhasflag(lf, F_OWNSSHOP);
|
||||
if (f) {
|
||||
int myshop;
|
||||
cell_t *where;
|
||||
myshop = f->val[0];
|
||||
// find the closest cell of my shop
|
||||
where = getclosestroomcell(lf, myshop);
|
||||
// move towards my shop. note that if the player leaves then
|
||||
// re-enters this map, they will find that we have instantly
|
||||
// teleported there (see mapentereffects).
|
||||
if (aigoto(lf, where, MR_OTHER, NULL, PERMENANT)) {
|
||||
// success
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// look for any race which we hate
|
||||
newtarget = NULL;
|
||||
for (n = 0; n < lf->nlos; n++) {
|
||||
|
@ -1141,77 +1243,21 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
if (newtarget) {
|
||||
aiattack(lf, newtarget, AI_FOLLOWTIME);
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
|
||||
if (icanattack) {
|
||||
if (!movetowards(lf, newtarget->cell, DT_ORTH)) return;
|
||||
if (aiattack(lf, newtarget, AI_FOLLOWTIME)) {
|
||||
// failed for some reason. maybe target was feigning
|
||||
// death?
|
||||
} else {
|
||||
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||
}
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
|
||||
if (icanattack) {
|
||||
if (!movetowards(lf, newtarget->cell, DT_ORTH)) return;
|
||||
} else {
|
||||
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// look for a target to attack based on our allegiance
|
||||
switch (getallegiance(lf)) {
|
||||
int i;
|
||||
int x,y;
|
||||
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);
|
||||
|
||||
aiattack(lf, c->lf, AI_FOLLOWTIME);
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
|
||||
if (icanattack) {
|
||||
if (!movetowards(lf, c, DT_ORTH)) 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) && !ispeaceful(c->lf)) {
|
||||
if (areenemies(lf, 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, DT_ORTH)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// training
|
||||
///////////////////////////////////////////////
|
||||
|
@ -1484,6 +1530,8 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if (ot->id == OT_A_HIDE) {
|
||||
if (lfhasflag(victim, F_HIDING)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (lfhasflag(victim, F_FEIGNINGDEATH)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (!safetorest(victim)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
|
|
3
ai.h
3
ai.h
|
@ -1,7 +1,7 @@
|
|||
#include "defs.h"
|
||||
|
||||
void addignorecell(lifeform_t *lf, cell_t *c);
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
|
||||
int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
|
||||
enum OBTYPE aigetfleespell(lifeform_t *lf);
|
||||
cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir);
|
||||
|
@ -9,6 +9,7 @@ object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra);
|
|||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
||||
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
|
||||
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
|
||||
flag_t *aihastarget(lifeform_t *lf);
|
||||
int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack);
|
||||
void aimovetotargetcell(lifeform_t *lf, flag_t *f);
|
||||
int aipickup(lifeform_t *lf, object_t *o);
|
||||
|
|
354
attack.c
354
attack.c
|
@ -61,10 +61,10 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
|||
// SOME of the damage reduction goes towards the armour
|
||||
// damage taken by armour is reduced by half its armour rating
|
||||
if (ar) {
|
||||
int max;
|
||||
max = ar/2;
|
||||
if (max >= 1) {
|
||||
actualdam -= rnd(0,max);
|
||||
int maxreduction;
|
||||
maxreduction = ar/2;
|
||||
if (maxreduction >= 1) {
|
||||
actualdam -= rnd(0,maxreduction);
|
||||
limit(&actualdam, 0, NA);
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
int attacksdone = 0;
|
||||
int lastweaponidx = -1;
|
||||
flag_t *sf;
|
||||
int saysorry = B_FALSE;
|
||||
|
||||
// anyone there? if so just attack.
|
||||
if (c->lf) {
|
||||
|
@ -172,7 +173,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
priwep = getweapon(lf);
|
||||
|
||||
// confirm ?
|
||||
if (!force && isplayer(lf) && wepdullable(priwep) && (getiqname(getattr(player, A_IQ), NULL) >= IQ_SMART) ) {
|
||||
if (!force && isplayer(lf) && wepdullable(priwep) && (getattrbracket(getattr(player, A_IQ), A_IQ, NULL) >= AT_GTAVERAGE) ) {
|
||||
char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN];
|
||||
char ch;
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
||||
|
@ -244,7 +245,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
objecttype_t *ot;
|
||||
|
||||
if (!op) {
|
||||
op = addobpile(NULL, NULL);
|
||||
op = addobpile(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
ot = findot(f->val[0]);
|
||||
|
@ -330,7 +331,14 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
if (validwep[i]) {
|
||||
if (attacktype == AT_LF) {
|
||||
if (!isdead((lifeform_t *)attacktarget)) {
|
||||
if (attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i])) break;
|
||||
lifeform_t *victim;
|
||||
victim = (lifeform_t *)attacktarget;
|
||||
// did we just attack someone by accident?
|
||||
if (!isplayer(lf) && !areenemies(lf, victim) && (lf->race->raceclass->id == RC_HUMANOID) &&
|
||||
(getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= A_LOW) ) {
|
||||
saysorry = B_TRUE;
|
||||
}
|
||||
if (attacklf(lf, victim, wep[i], damflag[i])) break;
|
||||
}
|
||||
} else if (attacktype == AT_OB) {
|
||||
if (attackob(lf, (object_t *)attacktarget, wep[i], damflag[i])) break;
|
||||
|
@ -356,6 +364,11 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
|
||||
// now stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
if (saysorry) {
|
||||
sayphrase(lf, SP_SORRY, -1, NA, NULL);
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -367,6 +380,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
char attackername[BUFLEN];
|
||||
char victimname[BUFLEN];
|
||||
int fatal = B_FALSE;
|
||||
int feigneddeath = B_FALSE;
|
||||
int deflected = B_FALSE;
|
||||
int weppassthrough = B_FALSE;
|
||||
int firstisbackstab = B_FALSE;
|
||||
|
@ -424,9 +438,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
if (hasactivespell(victim, OT_S_REPELINSECTS)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Something prevents you from attacking %s!", victimname);
|
||||
msg("^wSomething prevents you from attacking %s!", victimname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("Something prevents %s from attacking %s!", attackername, victimname);
|
||||
msg("^wSomething prevents %s from attacking %s!", attackername, victimname);
|
||||
}
|
||||
taketime(lf, getattackspeed(lf));
|
||||
return B_FALSE;
|
||||
|
@ -438,9 +452,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// ie. you have been made noncorporeal
|
||||
if ((f->id == F_NONCORPOREAL) && (f->lifetime != FROMRACE)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Your attack passes straight through %s.", victimname);
|
||||
msg("^wYour attack passes straight through %s.", victimname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
msg("^w%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
}
|
||||
taketime(lf, getattackspeed(lf));
|
||||
return B_FALSE;
|
||||
|
@ -450,8 +464,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// did you hit?
|
||||
ndam = 0;
|
||||
|
||||
|
||||
|
||||
hit = rolltohit(lf, victim, wep, &critical);
|
||||
|
||||
// weapon passing through ghosts etc?
|
||||
|
@ -563,6 +575,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
}
|
||||
|
||||
// target asleep?
|
||||
if (lfhasflag(victim, F_ASLEEP)) {
|
||||
dam[0] *= 2;
|
||||
}
|
||||
|
||||
|
||||
// bonus for knowledge about the other lf's race? applied LAST.
|
||||
slev = getlorelevel(lf, victim->race->raceclass->id);
|
||||
if (slev == PR_INEPT) {
|
||||
|
@ -598,6 +616,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (firstisbackstab && (i == 0)) backstab = B_TRUE;
|
||||
//dblog("initial dam[%d] = %d",i,dam[i]);
|
||||
|
||||
// slightly more damage for heavy blows
|
||||
if (lfhasflag(lf, F_HEAVYBLOW) || hasflag(wep->flags, F_HEAVYBLOW)) {
|
||||
dam[i] = (int)pctof(110,dam[i]);
|
||||
//dblog("heavy blow makes dam[%d] = %d",i,dam[i]);
|
||||
|
@ -635,105 +654,134 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
//dblog("reduced by armour to dam[%d] = %d",i,dam[i]);
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_QUIVERINGPALM)) {
|
||||
// make sure damage isn't fatal
|
||||
if (dam[i] >= victim->hp) {
|
||||
dam[i] = victim->hp - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// will this hit be fatal?
|
||||
if (dam[i] >= victim->hp) {
|
||||
fatal = B_TRUE;
|
||||
}
|
||||
|
||||
// monsters feigning death?
|
||||
if (lfhasflag(victim, F_FEIGNINGDEATH)) {
|
||||
killflagsofid(victim->flags, F_FEIGNINGDEATH);
|
||||
} else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) {
|
||||
if (onein(6) || isbleeding(victim)) {
|
||||
// do it!
|
||||
useability(victim, OT_A_FEIGNDEATH, lf, lf->cell);
|
||||
feigneddeath = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// announce it
|
||||
if (isplayer(lf)) {
|
||||
char extradambuf[BUFLEN];
|
||||
char withwep[BUFLEN];
|
||||
char *verb;
|
||||
int needfree = B_FALSE;
|
||||
|
||||
strcpy(extradambuf, "");
|
||||
|
||||
if (wep && !ismeleeweapon(wep)) {
|
||||
sprintf(withwep, " with %s", wepname);
|
||||
} else {
|
||||
strcpy(withwep, "");
|
||||
}
|
||||
|
||||
strcpy(extradambuf, "");
|
||||
if (dam[i] == 0) {
|
||||
if (getlorelevel(lf, victim->race->raceclass->id) >= PR_ADEPT) {
|
||||
strcpy(extradambuf, " but do no damage");
|
||||
}
|
||||
} else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) {
|
||||
sprintf(extradambuf, " [%d dmg]",dam[i]);
|
||||
}
|
||||
|
||||
if (backstab && (i == 0)) {
|
||||
verb = strdup("backstab");
|
||||
needfree = B_TRUE;
|
||||
} else if (fatal) {
|
||||
verb = getkillverb(victim, wep, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
if ((getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) ||
|
||||
!ismeleedam(damtype[i])) {
|
||||
verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
// always use verb for 10%
|
||||
verb = getattackverb(lf, wep, damtype[i], pctof(10, victim->maxhp), victim->maxhp);
|
||||
}
|
||||
}
|
||||
warn("You %s %s%s%s%s",
|
||||
verb,
|
||||
victimname, withwep,extradambuf,
|
||||
(fatal || backstab) ? "!" : ".");
|
||||
|
||||
if (fatal && strstr(verb, "behead")) {
|
||||
addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
if (fatal && !hasflag(victim->flags, F_NODEATHANNOUNCE)) {
|
||||
// don't also say "the xx dies"
|
||||
addflag(victim->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
if (needfree) {
|
||||
free(verb);
|
||||
}
|
||||
} else {
|
||||
if (cansee(player, lf) || isplayer(victim)) {
|
||||
if (!feigneddeath) {
|
||||
if (isplayer(lf)) {
|
||||
char extradambuf[BUFLEN];
|
||||
char withwep[BUFLEN];
|
||||
char attackverb[BUFLEN];
|
||||
char nodamstr[BUFLEN];
|
||||
char *verb;
|
||||
int needfree = B_FALSE;
|
||||
|
||||
// capitalise first letter
|
||||
strcpy(buf, attackername);
|
||||
capitalise(buf);
|
||||
|
||||
if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
|
||||
strcpy(extradambuf, "");
|
||||
|
||||
if (wep && !ismeleeweapon(wep)) {
|
||||
sprintf(withwep, " with %s", wepname);
|
||||
} else {
|
||||
strcpy(withwep, "");
|
||||
}
|
||||
|
||||
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
|
||||
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
|
||||
strcpy(nodamstr, " but does no damage");
|
||||
} else {
|
||||
strcpy(nodamstr, "");
|
||||
}
|
||||
warn("%s %s%s %s%s%s.", buf, attackverb,
|
||||
needses(attackverb) ? "es" : "s",
|
||||
victimname,withwep, nodamstr);
|
||||
}
|
||||
noise(lf->cell, lf, NC_OTHER, 3, "sounds of fighting.", NULL);
|
||||
|
||||
strcpy(extradambuf, "");
|
||||
if (dam[i] == 0) {
|
||||
if (getlorelevel(lf, victim->race->raceclass->id) >= PR_ADEPT) {
|
||||
strcpy(extradambuf, " but do no damage");
|
||||
}
|
||||
} else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) {
|
||||
sprintf(extradambuf, " [%d dmg]",dam[i]);
|
||||
}
|
||||
|
||||
if (backstab && (i == 0)) {
|
||||
verb = strdup("backstab");
|
||||
needfree = B_TRUE;
|
||||
} else if (fatal) {
|
||||
verb = getkillverb(victim, wep, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
if ((getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) ||
|
||||
!ismeleedam(damtype[i])) {
|
||||
verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
// always use verb for 10%
|
||||
verb = getattackverb(lf, wep, damtype[i], pctof(10, victim->maxhp), victim->maxhp);
|
||||
}
|
||||
}
|
||||
warn("^%cYou %s %s%s%s%s", fatal ? 'g' : 'n',
|
||||
verb,
|
||||
victimname, withwep,extradambuf,
|
||||
(fatal || backstab) ? "!" : ".");
|
||||
|
||||
if (fatal && strstr(verb, "behead")) {
|
||||
addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
if (fatal && !hasflag(victim->flags, F_NODEATHANNOUNCE)) {
|
||||
// don't also say "the xx dies"
|
||||
addflag(victim->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
if (needfree) {
|
||||
free(verb);
|
||||
}
|
||||
} else {
|
||||
if (cansee(player, lf) || isplayer(victim)) {
|
||||
char withwep[BUFLEN];
|
||||
char attackverb[BUFLEN];
|
||||
char nodamstr[BUFLEN];
|
||||
int nodam = B_FALSE;
|
||||
|
||||
// capitalise first letter
|
||||
strcpy(buf, attackername);
|
||||
capitalise(buf);
|
||||
|
||||
if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
|
||||
sprintf(withwep, " with %s", wepname);
|
||||
} else {
|
||||
strcpy(withwep, "");
|
||||
}
|
||||
|
||||
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
|
||||
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
|
||||
nodam = B_TRUE;
|
||||
strcpy(nodamstr, " but does no damage");
|
||||
} else {
|
||||
strcpy(nodamstr, "");
|
||||
}
|
||||
warn("^%c%s %s%s %s%s%s.", (isplayer(victim) && !nodam) ? 'b' : 'n', buf, attackverb,
|
||||
needses(attackverb) ? "es" : "s",
|
||||
victimname,withwep, nodamstr);
|
||||
}
|
||||
noise(lf->cell, lf, NC_OTHER, 3, "sounds of fighting.", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (willheal) {
|
||||
if (cansee(player, victim)) {
|
||||
flag_t *f;
|
||||
msg("%s %s healed!",victimname, isplayer(victim) ? "are" : "is");
|
||||
if (areallies(player, victim)) {
|
||||
msg("^g%s %s healed!",victimname, isplayer(victim) ? "are" : "is");
|
||||
} else {
|
||||
msg("^w%s %s healed!",victimname, isplayer(victim) ? "are" : "is");
|
||||
}
|
||||
f = hasflag(wep->flags, F_BALANCE);
|
||||
if (f) {
|
||||
f->known = B_TRUE;
|
||||
}
|
||||
gainhp(victim, dam[i]);
|
||||
}
|
||||
} else if (lfhasflag(lf, F_QUIVERINGPALM)) {
|
||||
// victim explodes!
|
||||
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE);
|
||||
} else {
|
||||
char attackername2[BUFLEN];
|
||||
real_getlfname(lf, attackername2, B_FALSE);
|
||||
|
@ -796,7 +844,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
real_getlfname(lf, lfname, B_FALSE);
|
||||
losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE);
|
||||
if (isplayer(victim) || cansee(player, victim)) {
|
||||
msg("%s bites %s!", lfname, victimname);
|
||||
msg("^%c%s bites %s!", isplayer(victim) ? 'b' : 'n', lfname, victimname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -822,7 +870,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
sprintf(damstring, "%s pack", lfname);
|
||||
losehp(victim, f->val[0], f->val[1], lf, damstring);
|
||||
if (isplayer(victim) || cansee(player, victim)) {
|
||||
msg("%s pack attacks %s!", lfname, victimname);
|
||||
msg("%c%s pack attacks %s!", isplayer(victim) ? 'b' : 'c', lfname, victimname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -870,7 +918,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
char damstring[BUFLEN];
|
||||
rdam = rolldie(f->val[0], f->val[1]);
|
||||
if (cansee(player, victim)) {
|
||||
msg("%s%s %s %s %s!", victimname, getpossessive(victimname),
|
||||
msg("^%c%s%s %s %s %s!", isplayer(victim) ? 'b' : 'n', victimname, getpossessive(victimname),
|
||||
noprefix(f->text),
|
||||
getattackverb(victim, NULL, f->val[2], rdam, lf->maxhp),
|
||||
attackername);
|
||||
|
@ -885,17 +933,17 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// announce it
|
||||
if (weppassthrough) {
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
msg("^w%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
}
|
||||
} else if (deflected) {
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s deflect%s %s%s attack.", victimname, isplayer(victim) ? "" : "s",attackername, getpossessive(attackername));
|
||||
msg("^w%s deflect%s %s%s attack.", victimname, isplayer(victim) ? "" : "s",attackername, getpossessive(attackername));
|
||||
}
|
||||
} else if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) {
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
sprintf(buf, "%s",attackername);
|
||||
|
||||
msg("%s%s magnetic shield repels %s%s attack.", victimname, getpossessive(victimname),
|
||||
msg("^w%s%s magnetic shield repels %s%s attack.", victimname, getpossessive(victimname),
|
||||
buf, getpossessive(buf));
|
||||
}
|
||||
} else {
|
||||
|
@ -921,7 +969,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
flag_t *f;
|
||||
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
||||
moveto(victim, adj, B_FALSE, B_FALSE);
|
||||
msg("%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
|
||||
msg("^w%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1102,6 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
} else {
|
||||
strcpy(withwep, "");
|
||||
}
|
||||
|
||||
msg("%s %ss %s%s.", attackername,
|
||||
getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep);
|
||||
} else {
|
||||
|
@ -1066,7 +1113,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
sprintf(buf, "punching %s", obname);
|
||||
if ( losehp(lf, 1, DT_BASH, lf, buf)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Ow!");
|
||||
msg("^bOw!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1118,21 +1165,21 @@ int damtypecausesbleed(enum DAMTYPE dt) {
|
|||
// returns the amount of damage the armour blocked...
|
||||
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
|
||||
int reduceamt = 0;
|
||||
int ar;
|
||||
int pctrange;
|
||||
int ar,min;
|
||||
//int pctrange;
|
||||
object_t *o;
|
||||
|
||||
ar = getarmourrating(lf, NULL, NULL, NULL);
|
||||
|
||||
//reducepct = getdamreducepct(ar);
|
||||
//reduceamt = (int) ceil((reducepct / 100.0) * (float)dam);
|
||||
|
||||
//reduceamt = ar/2;
|
||||
|
||||
// between 25% and 75% of AR.
|
||||
// ie. with AR of 20, all damage is reduced by 5-15.
|
||||
pctrange = rnd(25,75);
|
||||
reduceamt = pctof(pctrange, ar);
|
||||
//pctrange = rnd(25,75);
|
||||
//reduceamt = pctof(pctrange, ar);
|
||||
|
||||
// between ar/5 and AR
|
||||
min = ar/5;
|
||||
reduceamt = rnd(min, ar);
|
||||
|
||||
|
||||
// special case
|
||||
if (damtype == DT_PROJECTILE) {
|
||||
|
@ -1486,46 +1533,6 @@ void getdamrange(flag_t *f, int *min, int *max) {
|
|||
if (max) *max = maxdam;
|
||||
}
|
||||
|
||||
/*
|
||||
void getdamrangeunarmed(flag_t *f, int *min, int *max) {
|
||||
obpile_t *op = NULL;
|
||||
object_t *o = NULL;
|
||||
flag_t *damflag = NULL;
|
||||
|
||||
if (strlen(f->text)) {
|
||||
damflag = f;
|
||||
} else {
|
||||
objecttype_t *ot;
|
||||
ot = findot(f->val[0]);
|
||||
op = addobpile(NULL, NULL);
|
||||
// create the fake weapon
|
||||
o = addob(op, ot->name);
|
||||
if (o) {
|
||||
damflag = hasflag(o->flags, F_DAM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (damflag) {
|
||||
int ndice,nsides,mod;
|
||||
texttodice(damflag->text, &ndice, &nsides, &mod);
|
||||
|
||||
if (min) *min = (ndice * 1) + mod;
|
||||
if (max) *max = (ndice * nsides) + mod;
|
||||
} else {
|
||||
if (min) *min = 0;
|
||||
if (max) *max = 0;
|
||||
}
|
||||
|
||||
if (o) {
|
||||
killob(o);
|
||||
}
|
||||
if (op) {
|
||||
free(op);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// roll for damage
|
||||
int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
|
||||
|
@ -1660,44 +1667,6 @@ float getstrdammod(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
|
||||
// determine attack type for lifeform.
|
||||
// allocate a pile and add weapon to it.
|
||||
// return the pile. remember to free it!
|
||||
/*
|
||||
obpile_t *getunarmedweapon(lifeform_t *lf,flag_t **uflag) {
|
||||
int nposs;
|
||||
flag_t *f;
|
||||
int sel;
|
||||
char poss[MAXPILEOBS][BUFLEN];
|
||||
obpile_t *op;
|
||||
flag_t *possflag[MAXPILEOBS];
|
||||
|
||||
op = addobpile(NULL, NULL);
|
||||
|
||||
// pick a random attack type.
|
||||
nposs = 0;
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_HASATTACK) {
|
||||
strcpy(poss[nposs],f->text);
|
||||
possflag[nposs] = f;
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
if (nposs > 0) {
|
||||
object_t *uob;
|
||||
sel = rnd(0,nposs-1);
|
||||
uob = addob(op, poss[sel]);
|
||||
assert(uob);
|
||||
if (uflag) *uflag = possflag[sel];
|
||||
}
|
||||
|
||||
if (!op->first) {
|
||||
if (uflag) *uflag = NULL;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
*/
|
||||
|
||||
// ie. caused by hitting something with a melee weapon
|
||||
int ismeleedam(enum DAMTYPE damtype) {
|
||||
switch (damtype) {
|
||||
|
@ -1848,15 +1817,16 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
acc += 50;
|
||||
}
|
||||
|
||||
// modify for lore level
|
||||
if (slev != PR_INEPT) {
|
||||
acc += (slev*10);
|
||||
}
|
||||
|
||||
limit(&acc, 0, 100);
|
||||
|
||||
//if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc);
|
||||
|
||||
myroll = rnd(1,100);
|
||||
if (slev != PR_INEPT) {
|
||||
myroll += (slev*10);
|
||||
}
|
||||
|
||||
// modify for lore
|
||||
if (myroll <= acc) {
|
||||
|
@ -1894,7 +1864,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
addob(where->obpile, "small fire");
|
||||
// announce
|
||||
if (haslos(player, where)) {
|
||||
msg("A column of fire erupts from the ground!");
|
||||
msg("^wA column of fire erupts from the ground!");
|
||||
f->known = B_KNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -1927,10 +1897,10 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
|
||||
// announce
|
||||
if (isplayer(owner)) {
|
||||
msg("Your %s blasts %s!",noprefix(obname),victimname);
|
||||
msg("^wYour %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);
|
||||
msg("^w%s%s %s blasts %s!",buf, getpossessive(buf),noprefix(obname),victimname);
|
||||
f->known = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1961,7 +1931,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
getlfname(owner,lfname);
|
||||
getlfname(victim, victimname);
|
||||
if (cansee(player, owner)) {
|
||||
msg("%s disarm%s %s!",lfname, isplayer(owner) ? "" : "s", victimname);
|
||||
msg("^w%s disarm%s %s!",lfname, isplayer(owner) ? "" : "s", victimname);
|
||||
}
|
||||
drop(victimwep, ALL);
|
||||
}
|
||||
|
@ -1983,7 +1953,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
getlfname(owner,lfname);
|
||||
getlfname(victim, victimname);
|
||||
if (cansee(player, owner)) {
|
||||
msg("%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname);
|
||||
msg("^w%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname);
|
||||
}
|
||||
fall(victim, NULL, B_TRUE);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
james
|
||||
john
|
||||
robert
|
||||
michael
|
||||
william
|
||||
david
|
||||
richard
|
||||
charles
|
||||
joseph
|
||||
thomas
|
||||
christopher
|
||||
daniel
|
||||
paul
|
||||
mark
|
||||
donald
|
||||
george
|
||||
kenneth
|
||||
steven
|
||||
edward
|
||||
brian
|
||||
ronald
|
||||
anthony
|
||||
kevin
|
||||
jason
|
||||
matthew
|
||||
gary
|
||||
timothy
|
||||
jose
|
||||
larry
|
||||
jeffrey
|
||||
frank
|
||||
scott
|
||||
eric
|
||||
stephen
|
||||
andrew
|
||||
raymond
|
||||
gregory
|
||||
joshua
|
||||
jerry
|
||||
dennis
|
||||
walter
|
||||
patrick
|
||||
peter
|
||||
harold
|
||||
douglas
|
||||
henry
|
||||
carl
|
||||
arthur
|
||||
ryan
|
||||
roger
|
||||
joe
|
||||
juan
|
||||
jack
|
||||
albert
|
||||
jonathan
|
||||
justin
|
||||
terry
|
||||
gerald
|
||||
keith
|
||||
samuel
|
||||
willie
|
||||
ralph
|
||||
lawrence
|
||||
nicholas
|
||||
roy
|
||||
benjamin
|
||||
bruce
|
||||
brandon
|
||||
adam
|
||||
harry
|
||||
fred
|
||||
wayne
|
||||
billy
|
||||
steve
|
||||
louis
|
||||
jeremy
|
||||
aaron
|
||||
randy
|
||||
howard
|
||||
eugene
|
||||
carlos
|
||||
russell
|
||||
bobby
|
||||
victor
|
||||
martin
|
||||
ernest
|
||||
phillip
|
||||
todd
|
||||
jesse
|
||||
craig
|
||||
alan
|
||||
shawn
|
||||
clarence
|
||||
sean
|
||||
philip
|
||||
chris
|
||||
johnny
|
||||
earl
|
||||
jimmy
|
||||
antonio
|
||||
danny
|
||||
bryan
|
||||
tony
|
||||
luis
|
||||
mike
|
||||
stanley
|
||||
leonard
|
||||
nathan
|
||||
dale
|
||||
manuel
|
||||
rodney
|
||||
curtis
|
||||
norman
|
||||
allen
|
||||
marvin
|
||||
vincent
|
||||
glenn
|
||||
jeffery
|
||||
travis
|
||||
jeff
|
||||
chad
|
||||
jacob
|
||||
lee
|
||||
melvin
|
||||
alfred
|
||||
kyle
|
||||
francis
|
||||
bradley
|
||||
jesus
|
||||
herbert
|
||||
frederick
|
||||
ray
|
||||
joel
|
||||
edwin
|
||||
don
|
||||
eddie
|
||||
ricky
|
||||
troy
|
||||
randall
|
||||
barry
|
||||
alexander
|
||||
bernard
|
||||
mario
|
||||
leroy
|
||||
francisco
|
||||
marcus
|
||||
micheal
|
||||
theodore
|
||||
clifford
|
||||
miguel
|
||||
oscar
|
||||
jay
|
||||
jim
|
||||
tom
|
||||
calvin
|
||||
alex
|
||||
jon
|
||||
ronnie
|
||||
bill
|
||||
lloyd
|
||||
tommy
|
||||
leon
|
||||
derek
|
||||
warren
|
||||
darrell
|
||||
jerome
|
||||
floyd
|
||||
leo
|
||||
alvin
|
||||
tim
|
||||
wesley
|
||||
gordon
|
||||
dean
|
||||
greg
|
||||
jorge
|
||||
dustin
|
||||
pedro
|
||||
derrick
|
||||
dan
|
||||
lewis
|
||||
zachary
|
||||
corey
|
||||
herman
|
||||
maurice
|
||||
vernon
|
||||
roberto
|
||||
clyde
|
||||
glen
|
||||
hector
|
||||
shane
|
||||
ricardo
|
||||
sam
|
||||
rick
|
||||
lester
|
||||
brent
|
||||
ramon
|
||||
charlie
|
||||
tyler
|
||||
gilbert
|
||||
gene
|
||||
marc
|
||||
reginald
|
||||
ruben
|
||||
brett
|
||||
angel
|
||||
nathaniel
|
||||
rafael
|
||||
leslie
|
||||
edgar
|
||||
milton
|
||||
raul
|
||||
ben
|
||||
chester
|
||||
cecil
|
||||
duane
|
||||
franklin
|
||||
andre
|
||||
elmer
|
||||
brad
|
||||
gabriel
|
||||
ron
|
||||
mitchell
|
||||
roland
|
||||
arnold
|
||||
harvey
|
||||
jared
|
||||
adrian
|
||||
karl
|
||||
cory
|
||||
claude
|
||||
erik
|
||||
darryl
|
||||
jamie
|
||||
neil
|
||||
jessie
|
||||
christian
|
||||
javier
|
||||
fernando
|
||||
clinton
|
||||
ted
|
||||
mathew
|
||||
tyrone
|
||||
darren
|
||||
lonnie
|
||||
lance
|
||||
cody
|
||||
julio
|
||||
kelly
|
||||
kurt
|
||||
allan
|
||||
nelson
|
||||
guy
|
||||
clayton
|
||||
hugh
|
||||
max
|
||||
dwayne
|
||||
dwight
|
||||
armando
|
||||
felix
|
||||
jimmie
|
||||
everett
|
||||
jordan
|
||||
ian
|
||||
wallace
|
||||
ken
|
||||
bob
|
||||
jaime
|
||||
casey
|
||||
alfredo
|
||||
alberto
|
||||
dave
|
||||
ivan
|
||||
johnnie
|
||||
sidney
|
||||
byron
|
||||
julian
|
||||
isaac
|
||||
morris
|
||||
clifton
|
||||
willard
|
||||
daryl
|
||||
ross
|
||||
virgil
|
||||
andy
|
||||
marshall
|
||||
salvador
|
||||
perry
|
||||
kirk
|
||||
sergio
|
||||
marion
|
||||
tracy
|
||||
seth
|
||||
kent
|
||||
terrance
|
||||
rene
|
||||
eduardo
|
||||
terrence
|
||||
enrique
|
||||
freddie
|
||||
wade
|
||||
|
277
defs.h
277
defs.h
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
// ncurses colours
|
||||
#define C_NONE -1
|
||||
#define C_NONE (-1)
|
||||
enum COLOUR {
|
||||
C_BLACK = 0,
|
||||
C_RED = 1,
|
||||
|
@ -45,6 +45,18 @@ enum NOISECLASS {
|
|||
NC_OTHER = 2,
|
||||
};
|
||||
|
||||
enum SAYPHRASE {
|
||||
SP_DRUNK,
|
||||
SP_PAYWARN,
|
||||
SP_PAYTHREAT,
|
||||
SP_RECRUIT_ACCEPT,
|
||||
SP_RECRUIT_ASKPRICE,
|
||||
SP_RECRUIT_DECLINE,
|
||||
SP_RECRUIT_DECLINE_CANTPAY,
|
||||
SP_RECRUIT_DECLINE_WONTPAY,
|
||||
SP_SORRY
|
||||
};
|
||||
|
||||
enum SPEECHVOL {
|
||||
SV_SILENT = 0,
|
||||
SV_WHISPER = 1,
|
||||
|
@ -78,6 +90,7 @@ enum SKILL {
|
|||
SK_SWIMMING,
|
||||
SK_TECHUSAGE,
|
||||
SK_THIEVERY,
|
||||
SK_THROWING,
|
||||
SK_TRACKING,
|
||||
SK_TRAPS,
|
||||
SK_TWOWEAPON,
|
||||
|
@ -100,6 +113,7 @@ enum SKILL {
|
|||
SK_SS_AIR,
|
||||
SK_SS_DEATH,
|
||||
SK_SS_DIVINATION,
|
||||
SK_SS_ENCHANTMENT,
|
||||
SK_SS_FIRE,
|
||||
SK_SS_COLD,
|
||||
SK_SS_GRAVITY,
|
||||
|
@ -111,7 +125,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 52
|
||||
#define MAXSKILLS 54
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -138,6 +152,7 @@ enum SKILLLEVEL {
|
|||
#define NOBODY (-1)
|
||||
#define ALLCONFERRED (-9873)
|
||||
#define PCT (65432) // must be POSITIVE
|
||||
#define RANDOM (-2610)
|
||||
|
||||
#define AUTO (-7654)
|
||||
|
||||
|
@ -155,11 +170,12 @@ enum ATTRIB {
|
|||
A_NONE = -1,
|
||||
A_STR = 0,
|
||||
A_DEX = 1,
|
||||
A_IQ = 2,
|
||||
A_CON = 3,
|
||||
A_CHA = 4,
|
||||
A_WIS = 2,
|
||||
A_IQ = 3,
|
||||
A_CON = 4,
|
||||
A_CHA = 5,
|
||||
};
|
||||
#define MAXATTS 5
|
||||
#define MAXATTS 6
|
||||
|
||||
enum CHECKTYPE {
|
||||
SC_STR,
|
||||
|
@ -167,6 +183,7 @@ enum CHECKTYPE {
|
|||
SC_IQ,
|
||||
SC_CON,
|
||||
SC_CHA,
|
||||
SC_WIS,
|
||||
//////////
|
||||
SC_CLIMB,
|
||||
SC_DISARM,
|
||||
|
@ -182,6 +199,7 @@ enum CHECKTYPE {
|
|||
SC_SEARCH,
|
||||
SC_STEAL,
|
||||
SC_STEALTH,
|
||||
SC_TUMBLE,
|
||||
SC_WILL,
|
||||
};
|
||||
|
||||
|
@ -213,7 +231,7 @@ enum SENSE {
|
|||
// AI defs
|
||||
|
||||
// if target lf is out of view for this many turns, abandon chase
|
||||
#define AI_FOLLOWTIME (10)
|
||||
#define AI_FOLLOWTIME (30)
|
||||
|
||||
#define DEFAULTRESTHEALTIME (3)
|
||||
|
||||
|
@ -222,29 +240,40 @@ enum SENSE {
|
|||
#define RO_NONE 0
|
||||
#define RO_DAMTYPE 1
|
||||
#define RO_OBCLASS 2
|
||||
#define RO_HOLDABLE 3
|
||||
|
||||
// for flags
|
||||
// flag lifetimes
|
||||
#define PERMENANT (-9873)
|
||||
#define FROMRACE (-9872)
|
||||
#define FROMJOB (-9871)
|
||||
#define FROMOBEQUIP (-9870)
|
||||
#define FROMOBHOLD (-9869)
|
||||
#define FROMOBACTIVATE (-9868)
|
||||
#define FROMMAT (-9867)
|
||||
#define FROMBLESSING (-9866)
|
||||
#define FROMBRAND (-9865)
|
||||
#define FROMOBMOD (-9864)
|
||||
#define FROMSPELL (-9863)
|
||||
#define FROMPOISON (-9862)
|
||||
|
||||
// external sources (ie. don't kill them)
|
||||
#define FROMEXTERNAL_HIGH (-7000)
|
||||
#define FROMRACE (-7872)
|
||||
#define FROMJOB (-7871)
|
||||
#define FROMOBEQUIP (-7870)
|
||||
#define FROMOBHOLD (-7869)
|
||||
#define FROMOBACTIVATE (-7868)
|
||||
#define FROMMAT (-7867)
|
||||
#define FROMBLESSING (-9866)
|
||||
#define FROMBRAND (-7865)
|
||||
#define FROMOBMOD (-7864)
|
||||
#define FROMEXTERNAL_LOW (-7999)
|
||||
|
||||
|
||||
#define LEVABILITYDONE (-8000)
|
||||
|
||||
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known.
|
||||
#define IFACTIVE (-9771) // used by f_prodeuceslight. only does so if object is activated
|
||||
|
||||
#define NOCONDITION (0)
|
||||
#define IFMONSTER (-9769) // used in v2 of f_ifpct job flags
|
||||
#define IFPLAYER (-9768) // used in v2 of f_ifpct job flags
|
||||
enum FLAGCONDITION {
|
||||
FC_NOCONDITION = 0,
|
||||
FC_IFPLAYER,
|
||||
FC_IFMONSTER,
|
||||
};
|
||||
//#define NOCONDITION (0)
|
||||
//#define IFMONSTER (-9769) // used in v2 of f_ifpct job flags
|
||||
//#define IFPLAYER (-9768) // used in v2 of f_ifpct job flags
|
||||
|
||||
#define ANYROOM (-9770)
|
||||
|
||||
|
@ -262,8 +291,17 @@ enum SENSE {
|
|||
|
||||
|
||||
#define MORESTRING "--More--"
|
||||
#define MSGMORESTRING "^n--More--"
|
||||
#define SOLDOUTSTRING "--SOLD OUT--"
|
||||
|
||||
enum MSGCHARCOL {
|
||||
CC_VBAD,
|
||||
CC_BAD,
|
||||
CC_NORMAL,
|
||||
CC_GOOD,
|
||||
CC_VGOOD,
|
||||
};
|
||||
|
||||
// hunger constant - this is how many turns
|
||||
// it will take to go from 'normal' to 'hungry' etc
|
||||
#define HUNGERCONST 200
|
||||
|
@ -361,6 +399,7 @@ enum MODTYPE {
|
|||
#define TT_DOOR 4
|
||||
#define TT_PLAYER 8
|
||||
#define TT_ALLY 16
|
||||
#define TT_IMPASSABLE 32
|
||||
|
||||
// target requirements
|
||||
#define TR_NONE 0
|
||||
|
@ -473,6 +512,7 @@ enum SPELLSCHOOL {
|
|||
SS_AIR,
|
||||
SS_DEATH,
|
||||
SS_DIVINATION,
|
||||
SS_ENCHANTMENT,
|
||||
SS_FIRE,
|
||||
SS_COLD,
|
||||
SS_GRAVITY,
|
||||
|
@ -486,70 +526,21 @@ enum SPELLSCHOOL {
|
|||
SS_LAST,
|
||||
};
|
||||
|
||||
enum CHABRACKET {
|
||||
CH_RANDOM = -1,
|
||||
CH_HIDEOUS = 0,
|
||||
CH_REPULSIVE,
|
||||
CH_UGLY,
|
||||
CH_UNATTRACTIVE,
|
||||
CH_AVERAGE,
|
||||
CH_ATTRACTIVE,
|
||||
CH_ALLURING,
|
||||
CH_BEAUTIFUL,
|
||||
enum ATTRBRACKET {
|
||||
AT_RANDOM = -99,
|
||||
AT_EXLOW = -4,
|
||||
AT_VLOW = -3,
|
||||
AT_LOW = -2,
|
||||
AT_LTAVERAGE = -1,
|
||||
AT_AVERAGE = 0,
|
||||
AT_GTAVERAGE = 1,
|
||||
AT_HIGH = 2,
|
||||
AT_VHIGH = 3,
|
||||
AT_EXHIGH = 4,
|
||||
};
|
||||
|
||||
enum STRBRACKET {
|
||||
ST_RANDOM = -1,
|
||||
ST_HELPLESS = 0,
|
||||
ST_FEEBLE = 1,
|
||||
ST_VWEAK = 2,
|
||||
ST_WEAK = 3,
|
||||
ST_AVERAGE = 4,
|
||||
ST_STRONG = 5,
|
||||
ST_MIGHTY = 6,
|
||||
ST_TITANIC = 7,
|
||||
};
|
||||
|
||||
enum DEXBRACKET {
|
||||
DX_RANDOM = -1,
|
||||
DX_INCOMPETENT = 0,
|
||||
DX_OAFISH = 1,
|
||||
DX_INEPT = 2,
|
||||
DX_CLUMSY = 3,
|
||||
DX_AWKWARD = 4,
|
||||
DX_AVERAGE = 5,
|
||||
DX_DEXTROUS = 6,
|
||||
DX_NIMBLE = 7,
|
||||
DX_AGILE = 8,
|
||||
DX_SWIFT = 9,
|
||||
DX_SUPERSONIC = 10,
|
||||
};
|
||||
|
||||
enum IQBRACKET {
|
||||
IQ_RANDOM = -1,
|
||||
IQ_MINDLESS = 0,
|
||||
IQ_VEGETABLE = 1,
|
||||
IQ_ANIMAL = 2,
|
||||
IQ_STUPID = 3,
|
||||
IQ_DIMWITTED = 4,
|
||||
IQ_DOPEY = 5,
|
||||
IQ_AVERAGE = 6,
|
||||
IQ_SMART = 7,
|
||||
IQ_ENLIGHTENED = 8,
|
||||
IQ_GENIUS = 9,
|
||||
};
|
||||
|
||||
enum CONBRACKET {
|
||||
CN_RANDOM = -1,
|
||||
CN_FRAIL = 0,
|
||||
CN_SICKLY = 1,
|
||||
CN_UNHEALTHY = 2,
|
||||
CN_UNFIT = 3,
|
||||
CN_AVERAGE = 4,
|
||||
CN_HEALTHY = 5,
|
||||
CN_FIT = 6,
|
||||
CN_HARDY = 7,
|
||||
};
|
||||
#define IQ_MINDLESS AT_EXLOW
|
||||
#define IQ_ANIMAL AT_VLOW
|
||||
|
||||
// damage type
|
||||
enum DAMTYPE {
|
||||
|
@ -594,6 +585,7 @@ enum OBCLASS {
|
|||
OC_EFFECT,
|
||||
OC_FLORA,
|
||||
OC_FOOD,
|
||||
OC_FURNITURE,
|
||||
OC_MISC,
|
||||
OC_MISSILE,
|
||||
OC_MONEY,
|
||||
|
@ -660,6 +652,7 @@ enum RACE {
|
|||
// human monsters
|
||||
R_HUMAN,
|
||||
R_BANDIT,
|
||||
R_DRUNK,
|
||||
R_TOWNGUARD,
|
||||
// monsters
|
||||
R_BEHOLDER,
|
||||
|
@ -717,6 +710,8 @@ enum RACE {
|
|||
R_BAT,
|
||||
R_BEAR,
|
||||
R_BEARGRIZZLY,
|
||||
R_CHICKEN,
|
||||
R_DOG,
|
||||
R_DOGBLINK,
|
||||
R_DOGDEATH,
|
||||
R_DOGWAR,
|
||||
|
@ -774,6 +769,7 @@ enum JOB {
|
|||
J_SHOPKEEPER,
|
||||
J_WIZARD,
|
||||
};
|
||||
#define J_RANDOM J_NONE
|
||||
|
||||
enum MATSTATE {
|
||||
MS_SOLID,
|
||||
|
@ -822,13 +818,11 @@ enum OBTYPE {
|
|||
OT_STATUE,
|
||||
OT_DOORWOOD,
|
||||
OT_DOORIRON,
|
||||
OT_FENCEWOOD,
|
||||
OT_FOUNTAIN,
|
||||
OT_GATEIRON,
|
||||
OT_GATEWOOD,
|
||||
OT_FENCEWOOD,
|
||||
OT_SIGN,
|
||||
OT_WOODENTABLE,
|
||||
OT_WOODENBARREL,
|
||||
OT_WOODENSTOOL,
|
||||
OT_HOLYCIRCLE,
|
||||
OT_PENTAGRAM,
|
||||
OT_HOLEINGROUND,
|
||||
|
@ -876,6 +870,7 @@ enum OBTYPE {
|
|||
OT_JERKY,
|
||||
OT_ROASTMEAT,
|
||||
OT_BREADFRESH,
|
||||
OT_CARROT,
|
||||
OT_CHOCOLATE,
|
||||
OT_CLOVER,
|
||||
// corpses
|
||||
|
@ -887,6 +882,7 @@ enum OBTYPE {
|
|||
OT_POT_AMBROSIA,
|
||||
OT_POT_BLOOD,
|
||||
OT_POT_BLOODC,
|
||||
OT_POT_COFFEE,
|
||||
OT_POT_COMPETENCE,
|
||||
OT_POT_ELEMENTIMMUNE,
|
||||
OT_POT_ETHEREALNESS,
|
||||
|
@ -897,6 +893,7 @@ enum OBTYPE {
|
|||
OT_POT_HEALINGMAJ,
|
||||
OT_POT_INVIS,
|
||||
OT_POT_INVULN,
|
||||
OT_POT_LEVITATION,
|
||||
OT_POT_MAGIC,
|
||||
OT_POT_OIL,
|
||||
OT_POT_POISON,
|
||||
|
@ -1009,6 +1006,7 @@ enum OBTYPE {
|
|||
OT_S_HEALINGMAJ,
|
||||
OT_S_TURNUNDEAD,
|
||||
// -- mental / psionic
|
||||
OT_S_BODYCONTROL,
|
||||
OT_S_MINDSCAN,
|
||||
OT_S_SLEEP,
|
||||
OT_S_TELEKINESIS,
|
||||
|
@ -1068,9 +1066,9 @@ enum OBTYPE {
|
|||
OT_S_SUMMONWEAPON,
|
||||
// -- translocation
|
||||
OT_S_BLINK,
|
||||
OT_S_PULL,
|
||||
OT_S_DISPERSAL,
|
||||
OT_S_GATE,
|
||||
OT_S_SUCK,
|
||||
OT_S_TELEPORT,
|
||||
OT_S_TWIDDLE,
|
||||
// -- wild
|
||||
|
@ -1093,6 +1091,7 @@ enum OBTYPE {
|
|||
OT_A_COOK,
|
||||
OT_A_DARKWALK,
|
||||
OT_A_DISARM,
|
||||
OT_A_FEIGNDEATH,
|
||||
OT_A_FLURRY,
|
||||
OT_A_GRAB,
|
||||
OT_A_CHARGE,
|
||||
|
@ -1110,7 +1109,9 @@ enum OBTYPE {
|
|||
OT_A_INSPECT,
|
||||
OT_A_HURRICANESTRIKE,
|
||||
OT_A_POLYREVERT,
|
||||
OT_A_QUIVERINGPALM,
|
||||
OT_A_STEAL,
|
||||
OT_A_TUMBLE,
|
||||
OT_A_WARCRY, // uses F_NOISETEXT -> N_WARCRY if it is there.
|
||||
// otherwise 'shouts a blood-curdling war cry'
|
||||
// wands
|
||||
|
@ -1135,7 +1136,6 @@ enum OBTYPE {
|
|||
OT_BLANKET,
|
||||
OT_BLINDFOLD,
|
||||
OT_BUGLAMP,
|
||||
OT_CANDELABRUM,
|
||||
OT_CANDLE,
|
||||
OT_GUNPOWDER,
|
||||
OT_LAMPOIL,
|
||||
|
@ -1144,6 +1144,8 @@ enum OBTYPE {
|
|||
OT_PANPIPES,
|
||||
OT_PICKAXE,
|
||||
OT_ROPE,
|
||||
OT_SACK,
|
||||
OT_SAFEBOX,
|
||||
OT_TORCH,
|
||||
OT_TOWEL,
|
||||
// tech
|
||||
|
@ -1166,8 +1168,16 @@ enum OBTYPE {
|
|||
OT_TELEPAD,
|
||||
OT_TENT,
|
||||
OT_XRAYGOGGLES,
|
||||
// furniture
|
||||
OT_CANDELABRUM,
|
||||
OT_FIREPLACE,
|
||||
OT_WEAPONRACK,
|
||||
OT_WOODENTABLE,
|
||||
OT_WOODENBARREL,
|
||||
OT_WOODENSTOOL,
|
||||
// misc objects
|
||||
OT_BONE,
|
||||
OT_CHEST,
|
||||
OT_EMPTYFLASK,
|
||||
OT_EMPTYVIAL,
|
||||
OT_CALTROP,
|
||||
|
@ -1356,6 +1366,7 @@ enum OBTYPE {
|
|||
OT_CROSSBOWHAND,
|
||||
OT_LONGBOW,
|
||||
OT_REVOLVER,
|
||||
OT_SHOTGUN,
|
||||
OT_SLING,
|
||||
// special weapons
|
||||
OT_ENERGYBLADE,
|
||||
|
@ -1447,6 +1458,11 @@ enum ALLEGIENCE {
|
|||
AL_FRIENDLY, // will help you fight
|
||||
};
|
||||
|
||||
enum POISONSEVERITY {
|
||||
PS_DISEASE,
|
||||
PS_POISON,
|
||||
};
|
||||
|
||||
enum POISONTYPE {
|
||||
P_COLD,
|
||||
P_FOOD,
|
||||
|
@ -1455,6 +1471,7 @@ enum POISONTYPE {
|
|||
P_WEAKNESS,
|
||||
};
|
||||
|
||||
|
||||
enum RANGEATTACK {
|
||||
RA_NONE = 0,
|
||||
RA_GUN,
|
||||
|
@ -1505,7 +1522,6 @@ enum FLAG {
|
|||
F_VALUE, // how much an item is worth (over its base weight+material)
|
||||
// weapon/armour flags
|
||||
F_EQUIPPED, // val0 = where it is equipped. CLEAR WHEN OB MOVED!
|
||||
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_THROWMISSILE, // weapon would make a good thrown missle - used by AI
|
||||
|
@ -1684,10 +1700,15 @@ enum FLAG {
|
|||
F_TWOHANDED, // weapon uses two hands to weild
|
||||
F_TRIPATTACK, // weapon can trip the victim
|
||||
F_DISARMATTACK, // weapon can disarm the victim
|
||||
// gun flags
|
||||
F_FIREARM, // this weapon is equipped in bp_secweapon, not _weapon.
|
||||
F_FIRESPEED, // how fast this weapon shoots projectiles
|
||||
F_AMMOOB, // what object this weapon fires
|
||||
F_AMMOOB, // v0 = what object this weapon fires. can have multiple types.
|
||||
F_AMMOCAPACITY, // v0 = max ammo that can be loaded
|
||||
F_RANGE, // range of projectile firing weapon
|
||||
F_FIRETURNS, // # actions it takes to fire this gun
|
||||
F_RELOADTURNS, // # actions it takes to reload this gun
|
||||
// end gun flags
|
||||
F_FLAMESTRIKE, // causes fires where you hit
|
||||
F_BALANCE, // heals target if their maxhp < your maxhp
|
||||
F_REVENGE, // causes damage based on your hp
|
||||
|
@ -1718,6 +1739,7 @@ enum FLAG {
|
|||
F_NODIECONVERTTEXT, // don't anounce when this object changes
|
||||
// misc flags
|
||||
F_LINKOB, // val0 = linked object id
|
||||
// for fountains: v2 = ifknown
|
||||
F_LINKRACE, // val0 = linked race id
|
||||
// scroll flags
|
||||
F_LINKSPELL, // val0 = spell this scroll will cast when read
|
||||
|
@ -1770,13 +1792,22 @@ enum FLAG {
|
|||
F_VEGETARIAN, // this lf will not eat meat.
|
||||
F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry'
|
||||
F_CARNIVORE, // this lf will only eat meat.
|
||||
F_SHIELDPENALTY, // lower your accuracy by val0 due to a cumbersome
|
||||
// shield
|
||||
F_SHIELDPENALTY, // lower your acc/ev by val0 due to a cumbersome
|
||||
// shield. lowered by sk_shield skill.
|
||||
// v0 is accuracy penalty, v1 is evasion penalty.
|
||||
F_ARMOURPENALTY, // lower your acc/ev by val0 due to cumbersome
|
||||
// armour. lowered by sk_armour skill.
|
||||
// v0 is accuracy penalty, v1 is evasion penalty.
|
||||
F_LEVRACE, // at level v0, this race is promoted to race v1
|
||||
// must apply this to the BASE race.
|
||||
F_ATTRMOD, // modify attribute val0 by val1. ie. 0=A_STR,1=-3
|
||||
F_ATTRSET, // forces attribute val0 to be val1. ie. 0=A_STR,1=18
|
||||
F_SIZE, // val0 = lf size (enum LFSIZE)
|
||||
F_RANDOMTALKPCT, // v0 = chance of randomly saying something each turn
|
||||
F_RANDOMTALK, // v0 = sp_xxx for what to say when we randomly talk.
|
||||
// v1/v2 are min/max volume
|
||||
// can have multiple of these flags, if so then
|
||||
// randomly eslect one each time.
|
||||
F_RESTCOUNT, // val0 = how long you've been resting for
|
||||
F_RESTHEALTIME, // val0 = how long to rest before healing hp
|
||||
F_RESTHEALAMT, // val0 = how many hp to gain after resting x turns
|
||||
|
@ -1793,12 +1824,16 @@ enum FLAG {
|
|||
F_CANLEARN, // lf is able to learn skill val0
|
||||
F_STARTOB, // val0 = %chance of starting with it, text = ob name
|
||||
// val1,2 = min/max amounts. if NA, min=max=1.
|
||||
F_STARTSKILL, // val0 = skill id
|
||||
F_STARTOBDT, // val0 = %chance of starting with damtype val1
|
||||
F_STARTOBCLASS, // val0 = %chance of starting with obclass val1
|
||||
// option val2 = addition to map depth for rarity
|
||||
// calculation
|
||||
F_STARTOBRND, // val0 = %chance of starting with a random ob
|
||||
// v1 = depth modifier. can use 'RANDOM'
|
||||
F_CONTAINER, // this object is a container - you can use 'o'
|
||||
// to take stuff out or put it in.
|
||||
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
|
||||
F_STARTSKILL, // val0 = skill id
|
||||
F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS)
|
||||
// if text is set, it overrides val0.
|
||||
// text can be:
|
||||
|
@ -1830,6 +1865,7 @@ enum FLAG {
|
|||
// (text is a long)
|
||||
F_STAYINHABITAT, // lf will not walk onto a cell of a different
|
||||
// habitat
|
||||
F_STAYINROOM, // lf will not walk out of roomid v0
|
||||
F_FALLDISTANCE, // how many floors this lf has fallen through.
|
||||
// ABILITY/SPELL FLAGS / ability flags / spell flags
|
||||
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
|
||||
|
@ -1850,6 +1886,9 @@ enum FLAG {
|
|||
// monsters with this abil/spell are worth
|
||||
// v0 more xp.
|
||||
F_XPMULTIPLY, // multiply xp val for killing this lf by v0
|
||||
F_HIRABLE, // this job/lf can be recruited
|
||||
F_HIREPRICE, // how much it costs to hire this lf.
|
||||
F_NOHIRE, // this lf will not be hired.
|
||||
F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc
|
||||
F_LASTDIR, // this is the last direction we moved.
|
||||
//F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
|
||||
|
@ -1866,6 +1905,7 @@ enum FLAG {
|
|||
F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on
|
||||
// sight
|
||||
F_HARMLESS, // it is safe to rest around this lf
|
||||
F_RNDHOSTILE, // v0% chance of being hostile.
|
||||
F_HOSTILE, // lf will attack the player if in sight
|
||||
F_FRIENDLY, // lf will attack all non-players if in sight
|
||||
F_WANTS, // lf will try to pick up object type val0. if
|
||||
|
@ -1916,7 +1956,7 @@ enum FLAG {
|
|||
F_HITDICE, // val0: # d4 to roll for maxhp per level. val1: +xx
|
||||
F_MPDICE, // val0: # d4 to roll for maxmp per level. val1: +xx
|
||||
F_JOB, // val0 = player's class/job
|
||||
F_NAME, // text = player's name
|
||||
F_NAME, // text = lf's name
|
||||
F_XPMOD, // add/subtract this much from calculated xpval
|
||||
F_BLOODOB, // text = type of object to drop for blood
|
||||
F_DIESPLATTER, // this lf will splatter objcets of type 'text'
|
||||
|
@ -1952,6 +1992,8 @@ enum FLAG {
|
|||
F_MORALE, // gain +v0 in morale checks.
|
||||
F_SPOTTED, // you have spotted hiding lf id v0. you lsoe this if they
|
||||
// go out of sight.
|
||||
F_HEAVYBLOW, // next attack is a heavy blow
|
||||
F_QUIVERINGPALM, // your next strike will be a quivpalm attack
|
||||
// INTRINSICS
|
||||
F_MAGICARMOUR,// armour is magically boosted. f->text is the description
|
||||
// ie 'magic armour', 'force field'
|
||||
|
@ -1963,6 +2005,7 @@ enum FLAG {
|
|||
F_BLIND, // cannot see anything
|
||||
F_DEAF, // cannot hear
|
||||
F_NEEDOBFORSPELLS, // lf can only cast spells if it has object v0
|
||||
F_CAFFEINATED, // can't sleep.
|
||||
F_CANCAST, // can cast the spell val0 (need MP)
|
||||
F_CANHEARLF, // you can hear lifeform id v0 (show their glyph)
|
||||
// this flag does not get announced.
|
||||
|
@ -1987,6 +2030,7 @@ enum FLAG {
|
|||
F_DETECTMAGIC, // autodetect magic/special objects
|
||||
F_DETECTMETAL, // autodetect nearby metal
|
||||
F_DETECTOBS, // autodetect nearby obs in orthog dist v0
|
||||
F_DISEASEIMMUNE, // lf can't be diseased
|
||||
F_DRUNK, // v1 is drunknness - 1-5.
|
||||
F_ENHANCESEARCH, // gives v0 bonus on search checks.
|
||||
F_ENHANCESMELL, // can 'see' scents.
|
||||
|
@ -1996,6 +2040,7 @@ enum FLAG {
|
|||
F_EXTRAINFO, // knows extra info
|
||||
F_EXTRALUCK, // lf gets +v0 to all skill checks!
|
||||
F_EXTRAMP, // lf has +v0 % extra maxmp
|
||||
F_FEIGNINGDEATH, // lf is pretending to be dead
|
||||
F_FLYING, // lf is flying
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMETAB, // hunger counter increases faster, poison cures faster.
|
||||
|
@ -2009,7 +2054,6 @@ enum FLAG {
|
|||
// v2 is save difficulty
|
||||
F_GRABBEDBY,// you've been grabbed by lf id v0
|
||||
F_GRABBING, // you are grabbing lf id v0
|
||||
F_HEAVYBLOW, // next attack is a heavy blow
|
||||
F_HURRICANESTRIKE, // lf is performing a hurricane strike
|
||||
F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks.
|
||||
F_INVISIBLE, // lifeform is invisible
|
||||
|
@ -2018,6 +2062,7 @@ enum FLAG {
|
|||
F_QUICKBITE, // deals v0 d d1 + d2 damage when you hit a bleeding victim
|
||||
// (bypasses armour)
|
||||
F_GRAVBOOSTED,// cannot walk or throw stuff
|
||||
F_GRAVLESSENED,// knockback maeks you go further, can jump further
|
||||
F_NEEDSWATER, // cannot survive out of deep water
|
||||
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
|
||||
// if text not set, default dam is 1d2
|
||||
|
@ -2052,6 +2097,7 @@ enum FLAG {
|
|||
// if val2 is true, will only make light if ob
|
||||
// is activated!
|
||||
F_SLOWACT, // modifier for action speed
|
||||
F_SLOWMETAB, // hunger counter increases slower, poison cures slower.
|
||||
F_SLOWMOVE, // modifier for move speed
|
||||
F_SLOWACTMOVE, // modifier for move and action speed
|
||||
F_XRAYVIS, //val0=num of walls we can see through
|
||||
|
@ -2096,12 +2142,12 @@ enum FLAG {
|
|||
F_SELECTWEAPON, // this job gets to pick their starting weapon
|
||||
F_NOPLAYER, // players can't pick this job
|
||||
F_HASPET, // this job starts with a pet of race f->text
|
||||
F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0.
|
||||
F_ELSE,
|
||||
F_IFPLAYER,
|
||||
F_IFMONSTER,
|
||||
F_ENDIFPLAYER,
|
||||
F_ENDIFMONSTER,
|
||||
//F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0.
|
||||
//F_ELSE,
|
||||
//F_IFPLAYER,
|
||||
//F_IFMONSTER,
|
||||
//F_ENDIFPLAYER,
|
||||
//F_ENDIFMONSTER,
|
||||
F_LEVSKILL, // at level v0, this job gains 1 point in skill v1
|
||||
F_LEVABIL, // at level v0, this job gains f_canwill v1.
|
||||
// v2 = how often you can do it (or NA for unlimited)
|
||||
|
@ -2230,6 +2276,7 @@ enum SPELLTARGET {
|
|||
|
||||
#define NOOWNER (NULL)
|
||||
#define NOLOC (NULL)
|
||||
#define NOOB (NULL)
|
||||
|
||||
#define B_NOTSOLID (0)
|
||||
#define B_EMPTY (0)
|
||||
|
@ -2293,6 +2340,7 @@ enum ERROR {
|
|||
E_LOWIQ,
|
||||
E_LOWSTR,
|
||||
E_LOWCHA,
|
||||
E_LOWWIS,
|
||||
E_WONT,
|
||||
E_OFFMAP,
|
||||
// charm failure reasons
|
||||
|
@ -2352,6 +2400,11 @@ enum COMMAND {
|
|||
};
|
||||
|
||||
|
||||
typedef struct npcname_s {
|
||||
char *name;
|
||||
int valid;
|
||||
} npcname_t;
|
||||
|
||||
typedef struct coord_s {
|
||||
int x,y;
|
||||
} coord_t;
|
||||
|
@ -2393,6 +2446,7 @@ enum REGIONTHING {
|
|||
RT_REGIONLINK, // val is enum regiontype to link to.
|
||||
// what is stair object type
|
||||
RT_VAULT, // what is vaultname
|
||||
RT_RNDVAULTWITHFLAG, // val is wantedflag
|
||||
};
|
||||
|
||||
typedef struct regionthing_s {
|
||||
|
@ -2405,6 +2459,7 @@ typedef struct regionthing_s {
|
|||
|
||||
#define MAXOUTLINETHINGS 20
|
||||
typedef struct regionoutline_s {
|
||||
int id;
|
||||
regiontype_t *rtype;
|
||||
regionthing_t thing[MAXOUTLINETHINGS];
|
||||
int nthings;
|
||||
|
@ -2416,7 +2471,7 @@ typedef struct region_s {
|
|||
regiontype_t *rtype;
|
||||
regionoutline_t *outline;
|
||||
struct region_s *parentregion;
|
||||
int nthings;
|
||||
int nthings; // is this used???
|
||||
struct region_s *next, *prev;
|
||||
} region_t;
|
||||
|
||||
|
@ -2623,8 +2678,9 @@ typedef struct lifeform_s {
|
|||
|
||||
|
||||
typedef struct obpile_s {
|
||||
lifeform_t *owner;// } Only one of these
|
||||
cell_t *where; // } should be filled in
|
||||
lifeform_t *owner;// } Only one of
|
||||
cell_t *where; // } these should be
|
||||
struct object_s *parentob; // } filled in
|
||||
struct object_s *first,*last;
|
||||
|
||||
// for loading
|
||||
|
@ -2641,11 +2697,20 @@ typedef struct flagpile_s {
|
|||
int nitems;
|
||||
} flagpile_t;
|
||||
|
||||
typedef struct altflagval_s {
|
||||
enum FLAG id;
|
||||
int val[3];
|
||||
char *text;
|
||||
} altflagval_t;
|
||||
|
||||
typedef struct flag_s {
|
||||
enum FLAG id;
|
||||
int nvals;
|
||||
int val[3];
|
||||
char *text;
|
||||
struct altflagval_s *altval; // don't need to save this.
|
||||
enum FLAGCONDITION condition;
|
||||
int chance;
|
||||
|
||||
long obfrom; // for conferred flags, link to object->id. -1 if not conferred.
|
||||
|
||||
|
@ -2657,6 +2722,7 @@ typedef struct flag_s {
|
|||
struct flag_s *next, *prev;
|
||||
} flag_t;
|
||||
|
||||
|
||||
typedef struct material_s {
|
||||
enum MATERIAL id;
|
||||
char *name;
|
||||
|
@ -2714,6 +2780,7 @@ typedef struct objecttype_s {
|
|||
char *desc;
|
||||
struct objectclass_s *obclass;
|
||||
material_t *material;
|
||||
enum LFSIZE size;
|
||||
float weight; // in kilograms
|
||||
struct flagpile_s *flags;
|
||||
struct objecttype_s *next, *prev;
|
||||
|
@ -2737,6 +2804,8 @@ typedef struct object_s {
|
|||
long birthtime;
|
||||
flagpile_t *flags;
|
||||
|
||||
struct obpile_s *contents;
|
||||
|
||||
struct object_s *next, *prev;
|
||||
} object_t;
|
||||
|
||||
|
|
|
@ -2,20 +2,24 @@ defs.h:
|
|||
add A_xxx
|
||||
inc MAXATTS
|
||||
|
||||
add E_LOWxxx
|
||||
|
||||
add CHECKTYPE (SC_xxx)
|
||||
add xxxBRACKET
|
||||
|
||||
|
||||
lf.c:
|
||||
add getxxxname()
|
||||
update rollstat()
|
||||
add rollxxx()
|
||||
update getattrbracket()
|
||||
update skillcheck()
|
||||
update enhanceskills() question if you can up this at levelup
|
||||
update modattr()
|
||||
|
||||
update meetsattreq()
|
||||
|
||||
update weild() E_xxx error message
|
||||
|
||||
update jobs
|
||||
io.c:
|
||||
update announceflaggain() and loss() for this stat
|
||||
text.c:
|
||||
add getattrabbrev()
|
||||
add getattrname()
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
{ = water
|
||||
} = gas
|
||||
^ = trap / dangerous thing
|
||||
) = dancing weapon
|
||||
) = weapon
|
||||
ooo
|
||||
A = avian / bird
|
||||
a = ant
|
||||
B = bat
|
||||
|
@ -46,5 +47,5 @@ hybrid human animal?
|
|||
} = gas
|
||||
, = small puddle
|
||||
{ = large puddle/pool
|
||||
( = barrel
|
||||
( = barrel/container
|
||||
\ = furniture
|
||||
|
|
90
flag.c
90
flag.c
|
@ -16,6 +16,25 @@ extern int statdirty;
|
|||
|
||||
extern lifeform_t *player;
|
||||
|
||||
altflagval_t *addaltval(flag_t *f, enum FLAG id, int val1, int val2, int val3, char *text) {
|
||||
f->altval = malloc(sizeof(altflagval_t));
|
||||
f->altval->id = id;
|
||||
f->altval->val[0] = val1;
|
||||
f->altval->val[1] = val2;
|
||||
f->altval->val[2] = val3;
|
||||
if (text) {
|
||||
f->altval->text = strdup(text);
|
||||
} else {
|
||||
f->altval->text = strdup("");
|
||||
}
|
||||
return f->altval;
|
||||
}
|
||||
|
||||
void addcondition(flag_t *f, enum FLAGCONDITION fc, int chance) {
|
||||
f->condition = fc;
|
||||
f->chance = chance;
|
||||
}
|
||||
|
||||
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text) {
|
||||
return addflag_real(fp, id, val1, val2, val3, text, PERMENANT, B_KNOWN, -1);
|
||||
}
|
||||
|
@ -148,6 +167,10 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
f->known = known;
|
||||
f->obfrom = obfromid;
|
||||
|
||||
f->altval = NULL;
|
||||
f->condition = FC_NOCONDITION;
|
||||
f->chance = 100;
|
||||
|
||||
// first blank values
|
||||
for (i = 0; i < 3; i++) {
|
||||
f->val[i] = NA;
|
||||
|
@ -357,9 +380,11 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
|
|||
case F_BLIND:
|
||||
case F_EATING:
|
||||
case F_FASTMOVE:
|
||||
case F_FLYING:
|
||||
case F_HASNEWLEVEL:
|
||||
case F_HIDING:
|
||||
case F_INVISIBLE:
|
||||
case F_LEVITATING:
|
||||
case F_PARALYZED:
|
||||
case F_POISONED:
|
||||
case F_PRODUCESLIGHT:
|
||||
|
@ -601,6 +626,15 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch
|
|||
*/
|
||||
}
|
||||
|
||||
int istransitoryflag(flag_t *f) {
|
||||
if ((f->lifetime >= FROMEXTERNAL_LOW) && (f->lifetime <= FROMEXTERNAL_HIGH)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// returns true if we did something
|
||||
int killflagsofid(flagpile_t *fp, enum FLAG fid) {
|
||||
flag_t *f,*nextf;
|
||||
|
@ -705,6 +739,11 @@ void killflag(flag_t *f) {
|
|||
}
|
||||
|
||||
// free mem
|
||||
if (f->text) free(f->text);
|
||||
if (f->altval) {
|
||||
if (f->altval->text) free(f->altval->text);
|
||||
free(f->altval);
|
||||
}
|
||||
|
||||
// remove from list
|
||||
nextone = f->next;
|
||||
|
@ -751,6 +790,45 @@ void killflagpile(flagpile_t *fp) {
|
|||
free(fp);
|
||||
}
|
||||
|
||||
int killtransitoryflags(flagpile_t *fp, enum FLAG fid) {
|
||||
flag_t *f,*nextf;
|
||||
int nkilled = 0;
|
||||
for (f = fp->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > fid) break;
|
||||
|
||||
if (istransitoryflag(f) && (f->id == fid)) {
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
}
|
||||
}
|
||||
return nkilled;
|
||||
}
|
||||
|
||||
int killtransitoryflagvals(flagpile_t *fp, enum FLAG fid, int val1, int val2, int val3, char *text) {
|
||||
flag_t *f, *nextf;
|
||||
int nkilled = 0;
|
||||
for (f = fp->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > fid) break;
|
||||
|
||||
if (istransitoryflag(f) && (f->id == fid)) {
|
||||
if ( ((val1 == NA) || (f->val[0] == val1)) &&
|
||||
((val2 == NA) || (f->val[1] == val2)) &&
|
||||
((val3 == NA) || (f->val[2] == val3)) &&
|
||||
((text == NULL) || strstr(f->text, text))) {
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nkilled;
|
||||
}
|
||||
|
||||
void timeeffectsflag(flag_t *f, int howlong) {
|
||||
// special case:
|
||||
if (f->id == F_TRAIL) {
|
||||
|
@ -800,6 +878,12 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
case F_POLYMORPHED:
|
||||
warn("You are starting to revert to your original form...");
|
||||
break;
|
||||
case F_LEVITATING:
|
||||
warn("Your levitation is starting to expire...");
|
||||
break;
|
||||
case F_FLYING:
|
||||
warn("Your ability to fly is starting to expire...");
|
||||
break;
|
||||
default: // no message
|
||||
break;
|
||||
}
|
||||
|
@ -851,9 +935,15 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
case F_MAGSHIELD:
|
||||
warn("Your magnetic shield is about to expire!");
|
||||
break;
|
||||
case F_LEVITATING:
|
||||
warn("Your levitation is about to expire!");
|
||||
break;
|
||||
case F_POLYMORPHED:
|
||||
warn("You are about to revert to your original form!");
|
||||
break;
|
||||
case F_FLYING:
|
||||
warn("Your ability to fly is about to expire!");
|
||||
break;
|
||||
default: // no message
|
||||
break;
|
||||
}
|
||||
|
|
5
flag.h
5
flag.h
|
@ -2,6 +2,8 @@
|
|||
|
||||
|
||||
// functions
|
||||
altflagval_t *addaltval(flag_t *f, enum FLAG id, int val1, int val2, int val3, char *text);
|
||||
void addcondition(flag_t *f, enum FLAGCONDITION fc, int chance);
|
||||
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text);
|
||||
flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft);
|
||||
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid);
|
||||
|
@ -19,9 +21,12 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception);
|
|||
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||
flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown);
|
||||
int istransitoryflag(flag_t *f);
|
||||
int killflagsofid(flagpile_t *fp, enum FLAG fid);
|
||||
void killflag(flag_t *f);
|
||||
void killflagpile(flagpile_t *fp);
|
||||
int killtransitoryflags(flagpile_t *fp, enum FLAG fid);
|
||||
int killtransitoryflagvals(flagpile_t *fp, enum FLAG fid, int val1, int val2, int val3, char *text);
|
||||
void makeflagknown(flagpile_t *fp);
|
||||
int modcounter(flagpile_t *fp, int amt);
|
||||
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2);
|
||||
|
|
6
io.h
6
io.h
|
@ -52,7 +52,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly);
|
|||
void domemmagic(void);
|
||||
void domsghist(void);
|
||||
void dooperate(obpile_t *op);
|
||||
int dopickup(obpile_t *op);
|
||||
int dopickup(obpile_t *op, int forceask);
|
||||
void dolockpick(obpile_t *op);
|
||||
void donextguntarget(void);
|
||||
void dopour(obpile_t *op);
|
||||
|
@ -60,7 +60,7 @@ void doquit(void);
|
|||
void doquaff(obpile_t *op);
|
||||
void doread(obpile_t *op);
|
||||
void dorest(void);
|
||||
void doselguntarget(void);
|
||||
int doselguntarget(void);
|
||||
void dostairs(int dir);
|
||||
int dotakeoff(obpile_t *op);
|
||||
void dothrow(obpile_t *op);
|
||||
|
@ -78,6 +78,7 @@ void drawscreen(void);
|
|||
void drawstatus(void);
|
||||
int drop(object_t *o, int count);
|
||||
void dumpspells(void);
|
||||
enum COLOUR getattrcolour(enum ATTRBRACKET brack);
|
||||
char getchoice(prompt_t *prompt);
|
||||
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
|
||||
int getkey(void);
|
||||
|
@ -108,6 +109,7 @@ void unsetcol(WINDOW *win, enum COLOUR col);
|
|||
void setobcolour(WINDOW *win, object_t *o, int set);
|
||||
void showlfarmour(lifeform_t *lf);
|
||||
void showlfstats(lifeform_t *lf, int showall);
|
||||
void textwithcol(WINDOW *win, char *buf);
|
||||
void tombstone(lifeform_t *lf);
|
||||
void updatestatus(void);
|
||||
int updateviewfor(cell_t *cell);
|
||||
|
|
33
lf.h
33
lf.h
|
@ -13,6 +13,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o);
|
|||
int areallies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int askforpayment(lifeform_t *shk, lifeform_t *lf);
|
||||
char *assignnpcname(lifeform_t *lf);
|
||||
void autoskill(lifeform_t *lf);
|
||||
void autotarget(lifeform_t *lf);
|
||||
void autoweild(lifeform_t *lf);
|
||||
|
@ -91,6 +92,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms
|
|||
int getattackspeed(lifeform_t *lf);
|
||||
int getattpoints(lifeform_t *lf);
|
||||
int getattr(lifeform_t *lf, enum ATTRIB attr);
|
||||
enum ATTRBRACKET getattrbracket(int attrval, enum ATTRIB whichatt, char *buf);
|
||||
int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
|
||||
int getavgdam(lifeform_t *lf, int forxp);
|
||||
float getequippedweight(lifeform_t *lf);
|
||||
|
@ -102,6 +104,7 @@ int getbodyparthitchance(enum BODYPART bp);
|
|||
char *getbodypartname(enum BODYPART bp);
|
||||
char *getbodypartequipname(enum BODYPART bp);
|
||||
object_t *getequippedob(obpile_t *op, enum BODYPART bp);
|
||||
int getexposedlimbs(lifeform_t *lf);
|
||||
object_t *getfirearm(lifeform_t *lf);
|
||||
int getfootprinttime(lifeform_t *lf);
|
||||
lifeform_t *getguntarget(lifeform_t *lf);
|
||||
|
@ -117,6 +120,7 @@ int gethungerval(lifeform_t *lf);
|
|||
job_t *getjob(lifeform_t *lf);
|
||||
int getlastdir(lifeform_t *lf);
|
||||
int getlfaccuracy(lifeform_t *lf, object_t *wep);
|
||||
char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc);
|
||||
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||
int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
|
@ -155,9 +159,11 @@ int getpoisondamchance(enum POISONTYPE ptype);
|
|||
char *getpoisondamverb(enum POISONTYPE ptype);
|
||||
char *getpoisondesc(enum POISONTYPE ptype);
|
||||
char *getpoisonname(enum POISONTYPE ptype);
|
||||
enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
|
||||
int getraceclass(lifeform_t *lf);
|
||||
int getracerarity(map_t *map, enum RACE rid);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
job_t *getrandomjob(int onlyplayerjobs);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
race_t *getrandomrace(cell_t *c, int forcedepth);
|
||||
race_t *getreallyrandomrace(enum RACECLASS wantrc);
|
||||
|
@ -168,11 +174,6 @@ int getsounddist(int volume);
|
|||
char *getspeedname(int speed, char *buf);
|
||||
char *getspeednameshort(int speed, char *buf);
|
||||
float getstatmod(lifeform_t *lf, enum ATTRIB att);
|
||||
enum CHABRACKET getchaname(int cha, char *buf);
|
||||
enum CONBRACKET getconname(int con, char *buf);
|
||||
enum STRBRACKET getstrname(int str, char *buf);
|
||||
enum DEXBRACKET getdexname(int dex, char *buf);
|
||||
enum IQBRACKET getiqname(int iq, char *buf);
|
||||
char *getskilldesc(enum SKILL id );
|
||||
char *getskillname(enum SKILL id );
|
||||
char *getskilllevelname(enum SKILLLEVEL sl);
|
||||
|
@ -185,9 +186,10 @@ int givemoney(lifeform_t *from, lifeform_t *to, int amt);
|
|||
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 givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp);
|
||||
void givestartskills(lifeform_t *lf, flagpile_t *fp);
|
||||
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
|
||||
int gotosleep(lifeform_t *lf, int onpurpose);
|
||||
int hasfreeaction(lifeform_t *lf);
|
||||
job_t *hasjob(lifeform_t *lf, enum JOB job);
|
||||
int lfcanbestoned(lifeform_t *lf);
|
||||
|
@ -219,6 +221,7 @@ int isfleeing(lifeform_t *lf);
|
|||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||
int isfriendly(lifeform_t *lf);
|
||||
int isgenius(lifeform_t *lf);
|
||||
int ishirable(lifeform_t *lf);
|
||||
int isimmobile(lifeform_t *lf);
|
||||
flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
|
||||
int isinbattle(lifeform_t *lf);
|
||||
|
@ -244,6 +247,8 @@ void killjob(job_t *job);
|
|||
void killlf(lifeform_t *lf);
|
||||
void killrace(race_t *race);
|
||||
flag_t *levelabilityready(lifeform_t *lf);
|
||||
int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo);
|
||||
int loadfirearmfast(lifeform_t *lf);
|
||||
void loseconcentration(lifeform_t *lf);
|
||||
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);
|
||||
|
@ -261,6 +266,7 @@ float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
|||
int needstorest(lifeform_t *lf, char *validchars);
|
||||
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
||||
void outfitlf(lifeform_t *lf);
|
||||
void petify(lifeform_t *lf, lifeform_t *owner);
|
||||
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
|
||||
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat);
|
||||
int poisoncausesvomit(enum POISONTYPE ptype);
|
||||
|
@ -269,21 +275,20 @@ void practice(lifeform_t *lf, enum SKILL skid, int amt);
|
|||
void precalclos(lifeform_t *lf);
|
||||
int push(lifeform_t *lf, object_t *o, int dir);
|
||||
int readytotrain(lifeform_t *lf);
|
||||
int recruit(lifeform_t *lf);
|
||||
void refreshlevelabilities(lifeform_t *lf);
|
||||
void relinklf(lifeform_t *src, map_t *dst);
|
||||
int rest(lifeform_t *lf, int onpurpose);
|
||||
void startresting(lifeform_t *lf, int willtrain);
|
||||
int rollcha(enum CHABRACKET bracket);
|
||||
int rollcon(enum CONBRACKET bracket);
|
||||
int rolldex(enum DEXBRACKET bracket);
|
||||
int rolliq(enum IQBRACKET bracket);
|
||||
int rollstr(enum STRBRACKET bracket);
|
||||
int startresting(lifeform_t *lf, int willtrain);
|
||||
int rollattr(enum ATTRBRACKET bracket);
|
||||
int rollstat(lifeform_t *lf, enum ATTRIB attr);
|
||||
int safetorest(lifeform_t *lf);
|
||||
int say(lifeform_t *lf, char *text, int volume);
|
||||
int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text);
|
||||
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
|
||||
int setammo(lifeform_t *lf, object_t *o);
|
||||
//int setammo(lifeform_t *lf, object_t *o);
|
||||
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
||||
void setfollowdistance(lifeform_t *lf, int min, int max);
|
||||
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
||||
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph);
|
||||
void setlastdam(lifeform_t *lf, char *buf);
|
||||
|
@ -302,7 +307,7 @@ void stopresting(lifeform_t *lf);
|
|||
void stoprunning(lifeform_t *lf);
|
||||
void stopsprinting(lifeform_t *lf);
|
||||
lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, int randomjobsok, job_t *forcejob, int lifetime, int wantfriendly);
|
||||
int testammo(lifeform_t *lf, object_t *o);
|
||||
//int testammo(lifeform_t *lf, object_t *o);
|
||||
int takeoff(lifeform_t *lf, object_t *o);
|
||||
void taketime(lifeform_t *lf, long howlong);
|
||||
int throwat(lifeform_t *thrower, object_t *o, cell_t *where);
|
||||
|
|
339
map.c
339
map.c
|
@ -44,7 +44,7 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell->habitat = m->habitat;
|
||||
setcelltype(cell, cell->habitat->solidcelltype);
|
||||
cell->visited = B_FALSE;
|
||||
cell->obpile = addobpile(NOOWNER, cell);
|
||||
cell->obpile = addobpile(NOOWNER, cell, NOOB);
|
||||
cell->lf = NULL;
|
||||
cell->roomid = -1;
|
||||
cell->vault = NULL;
|
||||
|
@ -196,7 +196,15 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
// has a job?
|
||||
if (f->id == F_STARTJOB) {
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
givejob(lf, f->val[1]);
|
||||
enum JOB wantjob;
|
||||
if (f->val[1] == J_RANDOM) {
|
||||
job_t *j;
|
||||
j = getrandomjob(B_TRUE);
|
||||
wantjob = j->id;
|
||||
} else {
|
||||
wantjob = f->val[1];
|
||||
}
|
||||
givejob(lf, wantjob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +375,7 @@ object_t *addrandomob(cell_t *c) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (real_getrandomob(c->map, buf, RO_NONE, NA, NA, c->habitat->id)) {
|
||||
if (real_getrandomob(c->map, buf, RO_NONE, NA, NA, c->habitat->id, SZ_MAX)) {
|
||||
if (db) dblog("adding rand obj %s to cell %d,%d",buf,c->x,c->y);
|
||||
o = addob(c->obpile, buf);
|
||||
}
|
||||
|
@ -483,7 +491,8 @@ void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy,
|
|||
}
|
||||
}
|
||||
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent) {
|
||||
// if outlineid is -1, it's automatically assigned
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid) {
|
||||
region_t *a;
|
||||
regionoutline_t *ro,*poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
@ -515,17 +524,22 @@ region_t *addregion(enum REGIONTYPE rtype, region_t *parent) {
|
|||
a->rtype = findregiontype(rtype);
|
||||
a->parentregion = parent;
|
||||
|
||||
// randomly assign a regionoutline
|
||||
for (ro = firstregionoutline; ro ; ro = ro->next) {
|
||||
if (ro->rtype->id == rtype) {
|
||||
poss[nposs++] = ro;
|
||||
if (outlineid == -1) {
|
||||
// randomly assign a regionoutline
|
||||
for (ro = firstregionoutline; ro ; ro = ro->next) {
|
||||
if (ro->rtype->id == rtype) {
|
||||
poss[nposs++] = ro;
|
||||
}
|
||||
}
|
||||
// make sure we got one...
|
||||
if (nposs) {
|
||||
a->outline = poss[rnd(0,nposs-1)];
|
||||
} else {
|
||||
a->outline = NULL;
|
||||
}
|
||||
}
|
||||
// make sure we got one...
|
||||
if (nposs) {
|
||||
a->outline = poss[rnd(0,nposs-1)];
|
||||
} else {
|
||||
a->outline = NULL;
|
||||
a->outline = findoutline(outlineid);
|
||||
assert(a->outline);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
@ -549,6 +563,11 @@ regionoutline_t *addregionoutline(enum REGIONTYPE rtype) {
|
|||
a->next = NULL;
|
||||
|
||||
// props
|
||||
if (a == firstregionoutline) {
|
||||
a->id = 0;
|
||||
} else {
|
||||
a->id = lastregionoutline->id + 1;
|
||||
}
|
||||
a->rtype = findregiontype(rtype);
|
||||
a->nthings = 0;
|
||||
return a;
|
||||
|
@ -838,7 +857,7 @@ int cellhaslos(cell_t *c1, cell_t *dest) {
|
|||
}
|
||||
|
||||
void clearcell(cell_t *c) {
|
||||
// kill everything there
|
||||
// kill everything there - (lifeforms && objects)
|
||||
if (c->lf && !isplayer(c->lf)) {
|
||||
killlf(c->lf);
|
||||
}
|
||||
|
@ -1898,11 +1917,12 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
lifeform_t *lf;
|
||||
map_t *m;
|
||||
char buf[BUFLEN];
|
||||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
int i,x,y;
|
||||
enum HABITAT habitat;
|
||||
regionthing_t *thing[MAXOUTLINETHINGS];
|
||||
int nthings = 0;
|
||||
int db = B_TRUE;
|
||||
|
||||
// determine habitat based on region
|
||||
// note: we might override this later based on our region outline
|
||||
|
@ -1918,8 +1938,10 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
map->depth = depth;
|
||||
map->region = region;
|
||||
|
||||
sprintf(buf, "RegionID %d (#%d)",map->region->id, map->id);
|
||||
map->name = strdup(buf);
|
||||
if (db) {
|
||||
getregionname(buf, map, B_FALSE);
|
||||
dblog("Creating new map of region '%s'",buf);
|
||||
}
|
||||
map->habitat = findhabitat(habitat);
|
||||
|
||||
map->nrooms = 0;
|
||||
|
@ -1934,6 +1956,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
|
||||
// look for adjacent maps above/below this one
|
||||
if (db) dblog(" look for adjacent maps above/below this one");
|
||||
for (i = depth-1; i <= depth+1; i += 2) {
|
||||
map_t *othermap;
|
||||
othermap = findregionmap(map->region->id, i);
|
||||
|
@ -1941,8 +1964,10 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (othermap) {
|
||||
if (i == (depth-1)) {
|
||||
map->nextmap[D_UP] = othermap->id;
|
||||
if (db) dblog(" found mapin dir d_up: %s", othermap->name);
|
||||
} else {
|
||||
map->nextmap[D_DOWN] = othermap->id;
|
||||
if (db) dblog(" found mapin dir d_down: %s", othermap->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1952,6 +1977,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (parentmap) {
|
||||
if ((parentmap->region->id == map->region->id) ||
|
||||
(map->region->rtype->majorbranch)) {
|
||||
if (db) dblog(" linking to parentmap %s in dir %s", parentmap->name, getdirname(diropposite(exitdir)));
|
||||
parentmap->nextmap[exitdir] = map->id;
|
||||
map->nextmap[diropposite(exitdir)] = parentmap->id;
|
||||
}
|
||||
|
@ -1985,12 +2011,16 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
// set map coords
|
||||
// first world map??
|
||||
if (map == firstmap) {
|
||||
if (db) dblog(" map is the first world map. setting coords to 0,0.");
|
||||
addflag(map->flags, F_MAPCOORDS, 0, 0, NA, NULL);
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
// set mapcoords if not already done.
|
||||
if (!hasflag(map->flags, F_MAPCOORDS)) {
|
||||
x = -999;
|
||||
y = -999;
|
||||
// set mapcoords based on parent map
|
||||
if (parentmap) {
|
||||
getmapcoords(parentmap, &x, &y);
|
||||
assert((x != -999) && (y != -999));
|
||||
|
@ -2011,16 +2041,18 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
// no change
|
||||
break;
|
||||
}
|
||||
addflag(map->flags, F_MAPCOORDS, x, y, NA, NULL);
|
||||
if (db) dblog(" setting map coords to %d,%d (based on parent map)",x,y);
|
||||
} else {
|
||||
// set it based on something else...
|
||||
if (region->rtype->id == RG_WORLDMAP) {
|
||||
// TODO: is this right???????????
|
||||
// find another map of this region and set it.
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
if ((m != map) && (m->region == region)) {
|
||||
flag_t *ff;
|
||||
ff = hasflag(m->flags, F_MAPCOORDS);
|
||||
if (ff) {
|
||||
if (db) dblog(" setting map coords to %d,%d (based on other region map)",x,y);
|
||||
x = ff->val[0];
|
||||
y = ff->val[1];
|
||||
break;
|
||||
|
@ -2038,10 +2070,15 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
}
|
||||
|
||||
// we now have the map name!
|
||||
getregionname(buf2, map, B_TRUE);
|
||||
sprintf(buf, "%s (id #%d)",buf2, map->id);
|
||||
map->name = strdup(buf);
|
||||
|
||||
// get a list of what things are here based on the region's outline
|
||||
nthings = 0;
|
||||
if (region->outline) {
|
||||
if (db) dblog(" checking region outline for things...");
|
||||
for (i = 0; i < region->outline->nthings; i++) {
|
||||
int matched = B_FALSE;
|
||||
if ((region->rtype->id == RG_WORLDMAP) &&
|
||||
|
@ -2058,27 +2095,36 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (matched) {
|
||||
// override region
|
||||
if (region->outline->thing[i].whatkind == RT_HABITAT) {
|
||||
map->habitat = findhabitat(region->outline->thing[i].value);
|
||||
habitat_t *h;
|
||||
h = findhabitat(region->outline->thing[i].value);
|
||||
if (db) dblog(" setting map habitat to %s based on outlinething.",h->name);
|
||||
map->habitat = h;
|
||||
} else {
|
||||
if (db) dblog(" remembering region thing for later.");
|
||||
// remember this thing
|
||||
thing[nthings] = ®ion->outline->thing[i];
|
||||
nthings++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(" region has no outline.");
|
||||
}
|
||||
|
||||
|
||||
// build it...
|
||||
if (db) dblog(" creating map habitat.");
|
||||
createhabitat(map, depth, parentmap, exitdir, entryob);
|
||||
|
||||
// add home objects
|
||||
if (db) dblog(" adding home objects.");
|
||||
for (lf = map->lf ; lf ; lf = lf->next) {
|
||||
addhomeobs(lf);
|
||||
}
|
||||
|
||||
|
||||
// add outline things
|
||||
if (db) dblog(" adding remembered region outline things...");
|
||||
for (i = 0; i < nthings ;i++) {
|
||||
vault_t *v;
|
||||
// add this thing
|
||||
|
@ -2086,26 +2132,38 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
case RT_HABITAT: // already handled above
|
||||
break;
|
||||
case RT_REGIONLINK:
|
||||
if (db) dblog(" adding regionlink");
|
||||
createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region);
|
||||
// ... don't need to do this since we know there won't be anywhere to link to.
|
||||
//linkstairs(o);
|
||||
break;
|
||||
case RT_VAULT:
|
||||
if (db) dblog(" adding vault");
|
||||
v = findvault(thing[i]->what);
|
||||
assert(v);
|
||||
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
|
||||
dblog("ERROR - couldn't create vault %s on map %s", v->id, map->name);
|
||||
}
|
||||
break;
|
||||
case RT_RNDVAULTWITHFLAG:
|
||||
if (db) dblog(" adding rndvaultwithflag");
|
||||
v = findvaultwithflag(thing[i]->value);
|
||||
assert(v);
|
||||
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
|
||||
dblog("ERROR - couldn't create rndvaultwithflag %s on map %s", v->id, map->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// special cases
|
||||
// village - add town walls and clear it out
|
||||
if (db) dblog(" finalising village creation...");
|
||||
if (map->habitat->id == H_VILLAGE) {
|
||||
int x1 = 999,y1 = 999,x2 = -1,y2 = -1,x,y;
|
||||
int gx,gy;
|
||||
int guardx[2], guardy[2];
|
||||
int gx[MAXDIR_ORTH],gy[MAXDIR_ORTH];
|
||||
int guardx[MAXDIR_ORTH][2], guardy[MAXDIR_ORTH][2];
|
||||
int dir;
|
||||
cell_t *c;
|
||||
// find outermost dimensions of shops
|
||||
for (y = 0; y < map->h; y++) {
|
||||
|
@ -2131,39 +2189,41 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
limit(&y2, 0, map->h-1);
|
||||
|
||||
// decide where the gate will be (not the corner)
|
||||
switch (rnd(D_N, D_W)) {
|
||||
case D_N:
|
||||
gx = rnd(x1+2,x2-2);
|
||||
gy = y1;
|
||||
guardx[0] = gx-1;
|
||||
guardy[0] = gy+1;
|
||||
guardx[1] = gx+1;
|
||||
guardy[1] = gy+1;
|
||||
break;
|
||||
case D_E:
|
||||
gx = x2;
|
||||
gy = rnd(y1+2,y2-2);
|
||||
guardx[0] = gx-1;
|
||||
guardy[0] = gy-1;
|
||||
guardx[1] = gx-1;
|
||||
guardy[1] = gy+1;
|
||||
break;
|
||||
case D_S:
|
||||
gx = rnd(x1+2,x2-2);
|
||||
gy = y2;
|
||||
guardx[0] = gx-1;
|
||||
guardy[0] = gy-1;
|
||||
guardx[1] = gx+1;
|
||||
guardy[1] = gy-1;
|
||||
break;
|
||||
case D_W:
|
||||
gx = x1;
|
||||
gy = rnd(y1+2,y2-2);
|
||||
guardx[0] = gx+1;
|
||||
guardy[0] = gy-1;
|
||||
guardx[1] = gx+1;
|
||||
guardy[1] = gy+1;
|
||||
break;
|
||||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
switch (dir) {
|
||||
case D_N:
|
||||
gx[dir] = rnd(x1+2,x2-2);
|
||||
gy[dir] = y1;
|
||||
guardx[dir][0] = gx[dir]-1;
|
||||
guardy[dir][0] = gy[dir]+1;
|
||||
guardx[dir][1] = gx[dir]+1;
|
||||
guardy[dir][1] = gy[dir]+1;
|
||||
break;
|
||||
case D_E:
|
||||
gx[dir] = x2;
|
||||
gy[dir] = rnd(y1+2,y2-2);
|
||||
guardx[dir][0] = gx[dir]-1;
|
||||
guardy[dir][0] = gy[dir]-1;
|
||||
guardx[dir][1] = gx[dir]-1;
|
||||
guardy[dir][1] = gy[dir]+1;
|
||||
break;
|
||||
case D_S:
|
||||
gx[dir] = rnd(x1+2,x2-2);
|
||||
gy[dir] = y2;
|
||||
guardx[dir][0] = gx[dir]-1;
|
||||
guardy[dir][0] = gy[dir]-1;
|
||||
guardx[dir][1] = gx[dir]+1;
|
||||
guardy[dir][1] = gy[dir]-1;
|
||||
break;
|
||||
case D_W:
|
||||
gx[dir] = x1;
|
||||
gy[dir] = rnd(y1+2,y2-2);
|
||||
guardx[dir][0] = gx[dir]+1;
|
||||
guardy[dir][0] = gy[dir]-1;
|
||||
guardx[dir][1] = gx[dir]+1;
|
||||
guardy[dir][1] = gy[dir]+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// fill in town walls and clearing
|
||||
|
@ -2179,13 +2239,14 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
// mark as different habitat to outside
|
||||
c->habitat = findhabitat(H_VILLAGE);
|
||||
|
||||
if ((c->x == gx) && (c->y == gy)) {
|
||||
// town gate location
|
||||
clearcell(c);
|
||||
if (!isroom(c)) {
|
||||
// get rid of objects (ie. trees) here
|
||||
killallobs(c->obpile);
|
||||
// make the ground dirt
|
||||
setcelltype(c, CT_DIRT);
|
||||
addob(c->obpile, "wooden gate");
|
||||
} else if ((c->x == x1) || (c->y == y1) ||
|
||||
}
|
||||
|
||||
if ((c->x == x1) || (c->y == y1) ||
|
||||
(c->x == x2) || (c->y == y2)) {
|
||||
// town perimeter (walls)
|
||||
if (!isroom(c)) {
|
||||
|
@ -2193,18 +2254,30 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
setcelltype(c, CT_DIRT);
|
||||
addob(c->obpile, "wooden fence");
|
||||
}
|
||||
} else { // elsewhere within the town grounds
|
||||
if (!isroom(c)) {
|
||||
// get rid of objects (ie. trees) here
|
||||
killallobs(c->obpile);
|
||||
// make the ground dirt
|
||||
}
|
||||
|
||||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
// town gate location
|
||||
if ((c->x == gx[dir]) && (c->y == gy[dir])) {
|
||||
int d2;
|
||||
cell_t *c2;
|
||||
clearcell(c);
|
||||
setcelltype(c, CT_DIRT);
|
||||
addob(c->obpile, "wooden gate");
|
||||
// also make surrounding forest cells be dirt and no trees,
|
||||
for (d2 = DC_N; d2 <= DC_NW; d2++) {
|
||||
c2 = getcellindir(c, d2);
|
||||
if (c2 && (c2->habitat->id != H_VILLAGE)) {
|
||||
clearcell(c2);
|
||||
setcelltype(c2, CT_DIRT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// village guards
|
||||
for (i = 0; i < 1; i++) {
|
||||
if ((c->x == guardx[i]) && (c->y == guardy[i])) {
|
||||
addmonster(c, R_TOWNGUARD, B_FALSE, 1, B_TRUE, NULL);
|
||||
// village guards
|
||||
for (i = 0; i < 1; i++) {
|
||||
if ((c->x == guardx[dir][i]) && (c->y == guardy[dir][i])) {
|
||||
addmonster(c, R_TOWNGUARD, B_FALSE, 1, B_TRUE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2218,6 +2291,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
|
||||
// try to join up any unlinked staircases in this map.
|
||||
if (db) dblog(" joining unlinked stairs...");
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
cell_t *c;
|
||||
|
@ -2227,7 +2301,18 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (o && !getstairdestination(o)) {
|
||||
// this will join these stairs to existing ones on
|
||||
// existing adjacent maps
|
||||
linkstairs(o, NULL);
|
||||
if (!linkstairs(o, NULL)) {
|
||||
if (db) {
|
||||
cell_t *dst;
|
||||
dst = getstairdestination(o);
|
||||
dblog(" linked '%s' to map %s",o->type->name, dst->map->name);
|
||||
}
|
||||
} else {
|
||||
if (db) {
|
||||
dblog(" FAILED to link stiars: '%s'",o->type->name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2235,9 +2320,13 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
// link up holes - this will create NEW holes in THIS map connecting to
|
||||
// EXISTING unlinked holes in adjacent maps
|
||||
linkholes(map);
|
||||
i = linkholes(map);
|
||||
if (db) {
|
||||
if (db) dblog(" autolinked to %d holes in adjacent maps.",i);
|
||||
}
|
||||
|
||||
// add random objects and monsters
|
||||
if (db) dblog(" adding random objects+monsters");
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
cell_t *c;
|
||||
|
@ -2252,6 +2341,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
|
||||
// look for adjacent maps
|
||||
if (db) dblog(" linking to adjacent maps");
|
||||
getmapcoords(map, &x, &y);
|
||||
assert(x != -999);
|
||||
assert(y != -999);
|
||||
|
@ -2260,21 +2350,34 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
int thisx,thisy;
|
||||
getmapcoords(m, &thisx, &thisy);
|
||||
if (map->nextmap[D_N] == -1) {
|
||||
if (thisy == (y - 1)) map->nextmap[D_N] = m->id;
|
||||
if (thisy == (y - 1)) {
|
||||
map->nextmap[D_N] = m->id;
|
||||
if (db) dblog(" linked to map %d (dir N)",m->id);
|
||||
}
|
||||
}
|
||||
if (map->nextmap[D_E] == -1) {
|
||||
if (thisx == (x + 1)) map->nextmap[D_E] = m->id;
|
||||
if (thisx == (x + 1)) {
|
||||
map->nextmap[D_E] = m->id;
|
||||
if (db) dblog(" linked to map %d (dir E)",m->id);
|
||||
}
|
||||
}
|
||||
if (map->nextmap[D_S] == -1) {
|
||||
if (thisy == (y + 1)) map->nextmap[D_S] = m->id;
|
||||
if (thisy == (y + 1)) {
|
||||
map->nextmap[D_S] = m->id;
|
||||
if (db) dblog(" linked to map %d (dir S)",m->id);
|
||||
}
|
||||
}
|
||||
if (map->nextmap[D_W] == -1) {
|
||||
if (thisx == (x - 1)) map->nextmap[D_W] = m->id;
|
||||
if (thisx == (x - 1)) {
|
||||
map->nextmap[D_W] = m->id;
|
||||
if (db) dblog(" linked to map %d (dir W)",m->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map->beingcreated = B_FALSE;
|
||||
if (db) dblog(" Map creation finished.");
|
||||
}
|
||||
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety) {
|
||||
|
@ -2496,7 +2599,7 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO
|
|||
flag_t *f;
|
||||
region_t *r;
|
||||
// create a new region
|
||||
r = addregion(newregiontype, m->region);
|
||||
r = addregion(newregiontype, m->region, -1);
|
||||
// add stairs to new region
|
||||
if (!c) {
|
||||
c = NULL;
|
||||
|
@ -2887,6 +2990,14 @@ cell_t *findobinmap(map_t *m, enum OBTYPE oid) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
regionoutline_t *findoutline(int id) {
|
||||
regionoutline_t *ro;
|
||||
for (ro = firstregionoutline ;ro ; ro = ro->next) {
|
||||
if (ro->id == id) return ro;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
region_t *findregion(int regionid) {
|
||||
region_t *r;
|
||||
for (r = firstregion ; r ; r = r->next) {
|
||||
|
@ -3015,6 +3126,21 @@ cell_t *getcellindir(cell_t *cell, int dir) {
|
|||
return newcell;
|
||||
}
|
||||
|
||||
cell_t *getclosestroomcell(lifeform_t *lf, int roomid) {
|
||||
int i;
|
||||
cell_t *c,*best = NULL;
|
||||
int closest = 9999;
|
||||
for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
|
||||
c = lf->cell->map->cell[i];
|
||||
if ((c->roomid == roomid) & cellwalkable(lf, c, NULL)) {
|
||||
if (getcelldist(lf->cell, c) < closest) {
|
||||
best = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
// select a new direction (random chance of turnung)
|
||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
|
||||
int foundvaliddir = B_FALSE;
|
||||
|
@ -3495,7 +3621,7 @@ void initmap(void) {
|
|||
addregiontype(RG_WORLDMAP, H_FOREST, 10, 0, D_NONE, B_TRUE);
|
||||
addregiontype(RG_FIRSTDUNGEON, H_DUNGEON, 30, 3, D_DOWN, B_TRUE);
|
||||
addregiontype(RG_PIT, H_PIT, 1, 1, D_DOWN, B_FALSE);
|
||||
// region outlines
|
||||
// region definitions (outlines)
|
||||
addregionoutline(RG_WORLDMAP);
|
||||
// link to first dungeon
|
||||
addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_FIRSTDUNGEON, "staircase going down");
|
||||
|
@ -3509,9 +3635,11 @@ void initmap(void) {
|
|||
*/
|
||||
vx = 0; vy = -1;
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_HABITAT, H_VILLAGE, NULL);
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "potion_shop");
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "weapon_shop");
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "armour_shop");
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "food_shop");
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "pub");
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL);
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL);
|
||||
addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL);
|
||||
addregionoutline(RG_FIRSTDUNGEON);
|
||||
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");
|
||||
}
|
||||
|
@ -3754,12 +3882,14 @@ int iswallindir(cell_t *cell, int dir) {
|
|||
|
||||
// search for unlinked pits/holes in roof in ADJACENT maps
|
||||
// if we find any, add a matching end as close as we can in THIS map.
|
||||
void linkholes(map_t *map) {
|
||||
// returns then umber of holes linked.
|
||||
int linkholes(map_t *map) {
|
||||
map_t *adjmap;
|
||||
cell_t *c;
|
||||
object_t *o, *newob;
|
||||
int x,y;
|
||||
int dir;
|
||||
int nlinked = 0;
|
||||
|
||||
for (dir = D_UP ; dir <= D_DOWN; dir++) {
|
||||
adjmap = getmapindir(map, dir);
|
||||
|
@ -3792,6 +3922,14 @@ void linkholes(map_t *map) {
|
|||
newob = addobject(c2->obpile, ot->name, B_FALSE, B_FALSE);
|
||||
// link holes manually now.
|
||||
linkstairs(newob, o);
|
||||
|
||||
// objects above fall down
|
||||
if (dir == D_UP) {
|
||||
obsfallthrough(c, o);
|
||||
} else {
|
||||
obsfallthrough(c2, newob);
|
||||
}
|
||||
nlinked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3799,6 +3937,7 @@ void linkholes(map_t *map) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return nlinked;
|
||||
}
|
||||
|
||||
// link the staircase 'o' to a free one in adjacent maps.
|
||||
|
@ -3990,6 +4129,36 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {
|
|||
}
|
||||
}
|
||||
|
||||
void mapentereffects(map_t *m) {
|
||||
int i;
|
||||
cell_t *c;
|
||||
flag_t *f;
|
||||
for (i = 0; i < m->w * m->h; i++) {
|
||||
// teleport shopkeepers back to their shops
|
||||
c = m->cell[i];
|
||||
if (c->lf && hasjob(c->lf, J_SHOPKEEPER) && !isplayer(c->lf)) {
|
||||
f = lfhasflag(c->lf, F_OWNSSHOP);
|
||||
if (f) {
|
||||
cell_t *where;
|
||||
int myshop;
|
||||
myshop = f->val[0];
|
||||
// find the closest cell of my shop
|
||||
where = getclosestroomcell(c->lf, myshop);
|
||||
if (where) {
|
||||
movelf(c->lf, where);
|
||||
}
|
||||
}
|
||||
}
|
||||
// replace people in the Inn
|
||||
if (c->vault && streq(c->vault->id, "inn") && c->lf && (c->lf->race->id == R_HUMAN)) {
|
||||
lifeform_t *lf;
|
||||
killlf(c->lf);
|
||||
lf = addmonster(c, R_HUMAN, B_TRUE, 1, B_FALSE, NULL);
|
||||
addflag(lf->flags, F_STAYINROOM, c->roomid, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setcellknown(cell_t *cell, int forcelev) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
|
@ -4188,6 +4357,12 @@ int validateregionthing(regionthing_t *thing) {
|
|||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
case RT_RNDVAULTWITHFLAG:
|
||||
if (!findvaultwithflag(thing->value)) {
|
||||
dblog("Invalid rt_rndvaultwithflag specified in regionthing.");
|
||||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
7
map.h
7
map.h
|
@ -7,7 +7,7 @@ map_t *addmap(void);
|
|||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded);
|
||||
object_t *addrandomob(cell_t *c);
|
||||
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent);
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid);
|
||||
regionoutline_t *addregionoutline(enum REGIONTYPE rtype);
|
||||
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major);
|
||||
|
@ -58,6 +58,7 @@ map_t *findmapofdepth(int depth);
|
|||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
||||
object_t *findobidinmap(map_t *m, long id);
|
||||
cell_t *findobinmap(map_t *m, enum OBTYPE oid);
|
||||
regionoutline_t *findoutline(int id);
|
||||
region_t *findregion(int regionid);
|
||||
region_t *findregionbytype(enum REGIONTYPE rtid);
|
||||
map_t *findregionmap(int regionid, int depth);
|
||||
|
@ -65,6 +66,7 @@ regiontype_t *findregiontype(enum REGIONTYPE rtype);
|
|||
map_t *findsurfaceexitmap(map_t *m);
|
||||
void forgetcells(map_t *map, int amt);
|
||||
cell_t *getcellindir(cell_t *cell, int dir);
|
||||
cell_t *getclosestroomcell(lifeform_t *lf, int roomid);
|
||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||
int getobchance(int habitat);
|
||||
char *getregionname(char *buf, map_t *m, int withlevel);
|
||||
|
@ -99,11 +101,12 @@ int isoutdoors(map_t *m);
|
|||
int isroom(cell_t *c);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||
void linkholes(map_t *map);
|
||||
int linkholes(map_t *map);
|
||||
int linkstairs(object_t *o, object_t *o2);
|
||||
void makedoor(cell_t *cell, int openchance);
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||
void mapentereffects(map_t *m);
|
||||
void setcellknown(cell_t *cell, int forcelev);
|
||||
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
|
||||
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
||||
|
|
104
move.c
104
move.c
|
@ -138,7 +138,7 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
|
|||
// onlyifknown = true means "check for _known_ dangerous objects"
|
||||
// onlyifknown = false means "check for _any dangerous objects, doesn't matter if we know about them"
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *error) {
|
||||
enum IQBRACKET iq;
|
||||
enum ATTRBRACKET iq;
|
||||
int include_nonobvious = B_FALSE;
|
||||
flag_t *f;
|
||||
object_t *o;
|
||||
|
@ -200,6 +200,15 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
}
|
||||
}
|
||||
}
|
||||
f = obrestrictsmovement(o, lf);
|
||||
if (f) {
|
||||
// always avoid if possible
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
if ((f->val[0] != DT_WATER) || isvulnto(lf->flags, DT_WATER)) {
|
||||
|
@ -220,8 +229,8 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
if (!onlyifknown) {
|
||||
include_nonobvious = B_TRUE;
|
||||
} else {
|
||||
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||
if ((iq >= IQ_AVERAGE) && haslos(lf, cell)) {
|
||||
iq = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
if ((iq >= AT_AVERAGE) && haslos(lf, cell)) {
|
||||
if (!lfhasflag(lf, F_UNDEAD)) {
|
||||
include_nonobvious = B_TRUE;
|
||||
}
|
||||
|
@ -644,6 +653,13 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
int mightfall = B_TRUE;
|
||||
lifeform_t *newlf;
|
||||
|
||||
if (lfhasflag(lf, F_GRAVLESSENED)) {
|
||||
howfar *= 2;
|
||||
} else if (lfhasflag(lf, F_GRAVBOOSTED)) {
|
||||
howfar /= 2;
|
||||
if (howfar < 0) howfar = 0;
|
||||
}
|
||||
|
||||
// calculate chance of falling
|
||||
if (fallcheckdiff == 0) {
|
||||
// chance based on distance
|
||||
|
@ -962,6 +978,11 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
// special effects when the player moves to a new map
|
||||
if (changedlev && isplayer(lf)) {
|
||||
mapentereffects(newcell->map);
|
||||
}
|
||||
|
||||
didmsg = moveeffects(lf);
|
||||
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
@ -1193,18 +1214,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
shk = findshopkeeper(lf->cell->map, preshop);
|
||||
// do you have any unpaid items from that shop?
|
||||
if (shk && getowing(lf, preshop, &nitems)) {
|
||||
char saybuf[BUFLEN];
|
||||
// warning...
|
||||
switch (rnd(1,3)) {
|
||||
case 1: sprintf(saybuf, "Hey! Where do you think you're going?");
|
||||
break;
|
||||
case 2: sprintf(saybuf, "AHEM!");
|
||||
break;
|
||||
case 3: sprintf(saybuf, "I hope you are going to pay for %s!",
|
||||
(nitems == 1) ? "that" : "those" );
|
||||
break;
|
||||
}
|
||||
say(shk, saybuf, SV_SHOUT);
|
||||
sayphrase(shk, SP_PAYWARN, SV_SHOUT, NA, (nitems == 1) ? "that" : "those" );
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
} else if (lf->cell->roomid != preshop) {
|
||||
|
@ -1212,17 +1223,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
lifeform_t *shk;
|
||||
shk = findshopkeeper(lf->cell->map, preshop);
|
||||
if (shk && getowing(lf, preshop, NULL)) {
|
||||
char saybuf[BUFLEN];
|
||||
// call the guards
|
||||
switch (rnd(1,3)) {
|
||||
case 1: sprintf(saybuf, "Stop thief!");
|
||||
break;
|
||||
case 2: sprintf(saybuf, "GUARDS!");
|
||||
break;
|
||||
case 3: sprintf(saybuf, "I've been robbed!");
|
||||
break;
|
||||
}
|
||||
say(shk, saybuf, SV_ROAR);
|
||||
sayphrase(shk, SP_PAYTHREAT, SV_ROAR, NA, NULL);
|
||||
didmsg = B_TRUE;
|
||||
fightback(shk, lf); // shopkeeper attacks
|
||||
callguards(shk, lf); // guards come running
|
||||
|
@ -1369,19 +1371,13 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
msg("%s trigger%s %s!", lfname, isplayer(lf) ? "" : "s", trapname);
|
||||
if (isplayer(lf)) more();
|
||||
}
|
||||
trapeffects(o, o->type->id, lf);
|
||||
interrupt(lf);
|
||||
if (haslos(player, newcell)) {
|
||||
// no longer hidden
|
||||
killflagsofid(o->flags, F_SECRET);
|
||||
}
|
||||
switch (o->type->id) {
|
||||
case OT_TRAPGAS:
|
||||
removeob(o, o->amt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// NOTE: after trapeffects(), o might be killed.
|
||||
trapeffects(o, o->type->id, lf);
|
||||
interrupt(lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1775,30 +1771,17 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
|||
nexto = o->next;
|
||||
|
||||
|
||||
if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) {
|
||||
continue;
|
||||
}
|
||||
if ((o->type->id == OT_VINE) && hasjob(lf, J_DRUID)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_RESTRICTMOVEMENT);
|
||||
f = obrestrictsmovement(o, lf);
|
||||
if (f) {
|
||||
char lfname[BUFLEN];
|
||||
int diff;
|
||||
int checkmod = 0;
|
||||
int getsweaker;
|
||||
|
||||
if (isairborne(lf) && (f->val[2] != B_TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ((o->type->id == OT_WEB) && isairborne(lf)) {
|
||||
checkmod -= 5;
|
||||
}
|
||||
|
||||
|
||||
getlfname(lf,lfname);
|
||||
getobname(o, buf, o->amt);
|
||||
|
||||
|
@ -1859,6 +1842,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
|||
msg("%s stands up.",lfname);
|
||||
}
|
||||
killflagsofid(lf->flags, F_PRONE);
|
||||
killflagsofid(lf->flags, F_FEIGNINGDEATH);
|
||||
// time to get up depends on armour
|
||||
// 1*movespeed for every 1/4 of maxcarryweight being worn.
|
||||
quartermax = getmaxcarryweight(lf) / 4;
|
||||
|
@ -2440,12 +2424,13 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
|
||||
int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||
cell_t *cell;
|
||||
enum IQBRACKET iq;
|
||||
enum ATTRBRACKET iq;
|
||||
object_t *o;
|
||||
char buf[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
//object_t *o;
|
||||
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||
iq = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
|
||||
// default
|
||||
if (error) {
|
||||
|
@ -2468,9 +2453,18 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (!isroom(cell) && hasjob(lf, J_SHOPKEEPER)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
// shopkeepers will only leave their shops if they have a target
|
||||
f = lfhasflag(lf, F_STAYINROOM);
|
||||
if (f) {
|
||||
int roomid;
|
||||
roomid = f->val[0];
|
||||
// if moving out of my room..
|
||||
if ((lf->cell->roomid == roomid) && (lf->cell->roomid != cell->roomid)) {
|
||||
if (!aihastarget(lf)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_STAYINHABITAT) && (cell->habitat->id != lf->cell->habitat->id)) {
|
||||
|
@ -2501,7 +2495,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
// for at least average iq things...
|
||||
if (iq >= IQ_AVERAGE) {
|
||||
if (iq >= AT_AVERAGE) {
|
||||
// don't move if in pain
|
||||
if (lfhasflag(lf, F_PAIN)) {
|
||||
if (error) *error = E_WONT;
|
||||
|
@ -2528,13 +2522,13 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
if (hasflag(o->flags, F_TRAP)) {
|
||||
if (hasflag(o->flags, F_SECRET)) {
|
||||
// hidden traps?
|
||||
if (iq >= IQ_SMART) {
|
||||
if (iq >= AT_GTAVERAGE) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
// non-hidden traps?
|
||||
if (iq >= IQ_AVERAGE) {
|
||||
if (iq >= AT_AVERAGE) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
87
nexus.c
87
nexus.c
|
@ -38,6 +38,8 @@ regionoutline_t *firstregionoutline = NULL,*lastregionoutline = NULL;
|
|||
regiontype_t *firstregiontype = NULL,*lastregiontype = NULL;
|
||||
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
||||
hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
||||
npcname_t *npcname;
|
||||
int numnpcnames;
|
||||
|
||||
extern vault_t *firstvault;
|
||||
|
||||
|
@ -177,7 +179,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
j = NULL;
|
||||
while (!j) {
|
||||
getchoice(&prompt);
|
||||
getchoicestr(&prompt, B_FALSE, B_TRUE);
|
||||
j = prompt.result;
|
||||
}
|
||||
}
|
||||
|
@ -188,12 +190,14 @@ int main(int argc, char **argv) {
|
|||
region_t *wregion, *dregion;
|
||||
newworld = B_TRUE;
|
||||
// create world map.
|
||||
wregion = addregion(RG_WORLDMAP, NULL);
|
||||
wregion = addregion(RG_WORLDMAP, NULL, -1);
|
||||
assert(wregion);
|
||||
addmap();
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE, NULL);
|
||||
//createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
||||
// create first dungeon
|
||||
dregion = findregionbytype(RG_FIRSTDUNGEON);
|
||||
assert(dregion);
|
||||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL);
|
||||
}
|
||||
|
@ -278,9 +282,8 @@ int main(int argc, char **argv) {
|
|||
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
assert(c);
|
||||
pet = addlf(c, r->id, 1);
|
||||
makefriendly(pet, PERMENANT);
|
||||
// mark us as its master
|
||||
addflag(pet->flags, F_PETOF, player->id, player->cell->x, player->cell->y, NULL);
|
||||
petify(pet, player);
|
||||
}
|
||||
|
||||
getplayernamefull(pname);
|
||||
|
@ -533,6 +536,9 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in
|
|||
void donextturn(map_t *map) {
|
||||
lifeform_t *who;
|
||||
int db = B_FALSE;
|
||||
map_t *oldpmap;
|
||||
|
||||
oldpmap = player->cell->map;
|
||||
|
||||
who = map->lf;
|
||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||
|
@ -738,8 +744,19 @@ void donextturn(map_t *map) {
|
|||
//////////////////////////////////
|
||||
|
||||
// note: can't use 'who->' below since 'who' might have died
|
||||
// and been de-alloced during checkdeath() above.
|
||||
timeeffectsworld(player->cell->map); // in case the player changed levels!
|
||||
// and been de-alloced during checkdeath() above if they
|
||||
// died.
|
||||
timeeffectsworld(player->cell->map);
|
||||
|
||||
// the previous call to timeeffectsworld might cause the player to
|
||||
// change levels (ie. falling down through one or more pits).
|
||||
//
|
||||
// if this happens, we need to call it again to make sure that ->timespent
|
||||
// values don't get out of whack.
|
||||
while (player->cell->map != oldpmap) {
|
||||
oldpmap = player->cell->map;
|
||||
timeeffectsworld(player->cell->map);
|
||||
}
|
||||
}
|
||||
|
||||
char *getdirname(int dir) {
|
||||
|
@ -833,6 +850,9 @@ int init(void) {
|
|||
playerglyph.colour = C_GREY;
|
||||
tempglyph.ch = '@';
|
||||
tempglyph.colour = C_GREY;
|
||||
|
||||
// load npc names
|
||||
loadnpcnames();
|
||||
|
||||
initcommands();
|
||||
initobjects();
|
||||
|
@ -1010,6 +1030,45 @@ int limitf(float *what, float min, float max) {
|
|||
return limited;
|
||||
}
|
||||
|
||||
int loadnpcnames(void) {
|
||||
FILE *f;
|
||||
char buf[BUFLEN];
|
||||
int i = 0;
|
||||
f = fopen("data/npcnames.txt", "rt");
|
||||
if (!f) return B_TRUE;
|
||||
|
||||
// count lines...
|
||||
fgets(buf, BUFLEN, f);
|
||||
numnpcnames = 0;
|
||||
while (!feof(f)) {
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
if (strlen(buf)) {
|
||||
numnpcnames++;
|
||||
}
|
||||
fgets(buf, BUFLEN, f);
|
||||
}
|
||||
|
||||
// alloc mem
|
||||
npcname = malloc(numnpcnames * sizeof(npcname_t));
|
||||
|
||||
// back to start
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
// now read in names
|
||||
fgets(buf, BUFLEN, f);
|
||||
while (!feof(f)) {
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
if (strlen(buf)) {
|
||||
capitalise(buf);
|
||||
npcname[i].name = strdup(buf);
|
||||
npcname[i].valid = B_TRUE;
|
||||
i++;
|
||||
}
|
||||
fgets(buf, BUFLEN, f);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int onein(int howmany) {
|
||||
if (howmany <= 0) return B_FALSE;
|
||||
if (rnd(1,howmany) == 1) return B_TRUE;
|
||||
|
@ -1067,6 +1126,13 @@ int parseplayerfile(FILE *f, lifeform_t *lf) {
|
|||
return goterror;
|
||||
}
|
||||
|
||||
int pctchance(int pct) {
|
||||
if (rnd(1,100) <= pct) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
float pctof(float pct, float num) {
|
||||
return ((pct / 100.0) * num);
|
||||
}
|
||||
|
@ -1371,7 +1437,14 @@ void timeeffectsworld(map_t *map) {
|
|||
for (x = 0; x < map->w; x++) {
|
||||
cell_t *c;
|
||||
c = getcellat(map, x, y);
|
||||
if (c) {
|
||||
if (c) {
|
||||
object_t *pit;
|
||||
pit = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
if (pit) {
|
||||
obsfallthrough(c, pit);
|
||||
}
|
||||
|
||||
|
||||
// go through each object in the cell...
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
|
|
2
nexus.h
2
nexus.h
|
@ -20,8 +20,10 @@ void initcommands(void);
|
|||
int isplayerturn(void);
|
||||
int limit(int *what, int min, int max);
|
||||
int limitf(float *what, float min, float max);
|
||||
int loadnpcnames(void);
|
||||
int onein(int howmany);
|
||||
int parseplayerfile(FILE *f, lifeform_t *lf);
|
||||
int pctchance(int pct);
|
||||
float pctof(float pct, float num);
|
||||
int rnd(int min, int max);
|
||||
int roll(char *string);
|
||||
|
|
14
objects.h
14
objects.h
|
@ -13,9 +13,9 @@ object_t *addob(obpile_t *where, char *name);
|
|||
object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes);
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof);
|
||||
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where, object_t *parentob);
|
||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
|
||||
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid);
|
||||
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size);
|
||||
void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype);
|
||||
|
@ -63,11 +63,14 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
int getobaccuracy(object_t *wep, lifeform_t *weilder);
|
||||
int getobbonus(object_t *o);
|
||||
skill_t *getobskill(object_t *o);
|
||||
enum LFSIZE getobsize(object_t *o);
|
||||
int getobspellpower(object_t *o, lifeform_t *lf);
|
||||
int getobvalue(object_t *o);
|
||||
char *getoperateverb(object_t *o);
|
||||
object_t *getoutercontainer(object_t *o);
|
||||
//int getobtypevalue(objecttype_t *ot);
|
||||
char *getaccuracyname(int accpct);
|
||||
object_t *getammo(lifeform_t *lf);
|
||||
object_t *getammo(object_t *gun);
|
||||
objecttype_t *getbasicweaponforskill(enum SKILL skid);
|
||||
object_t *getrandomammo(lifeform_t *lf);
|
||||
objecttype_t *getrandomammofor(object_t *o);
|
||||
|
@ -104,8 +107,9 @@ char *getobhurtname(object_t *o, enum DAMTYPE damtype);
|
|||
float getobweight(object_t *o);
|
||||
float getobunitweight(object_t *o);
|
||||
objecttype_t *getoppositestairs(objecttype_t *ot);
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat);
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat, enum LFSIZE maxsize);
|
||||
char *getrandomob(map_t *map, char *buf);
|
||||
char *getrandomobofsize(map_t *map, char *buf, enum LFSIZE maxsize);
|
||||
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf);
|
||||
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod);
|
||||
int getobrarity(object_t *o, enum RARITY *rr);
|
||||
|
@ -196,6 +200,8 @@ int obmatchescondition(object_t *o, long opts);
|
|||
int obproduceslight(object_t *o);
|
||||
int obpropsmatch(object_t *a, object_t *b);
|
||||
int obotpropsmatch(object_t *a, objecttype_t *b);
|
||||
flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf);
|
||||
int obsfallthrough(cell_t *c, object_t *pit);
|
||||
int operate(lifeform_t *lf, object_t *o, cell_t *where);
|
||||
int pilehasletter(obpile_t *op, char let);
|
||||
void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE potlessed, int *seen);
|
||||
|
|
203
save.c
203
save.c
|
@ -13,6 +13,7 @@
|
|||
#include "nexus.h"
|
||||
#include "objects.h"
|
||||
#include "save.h"
|
||||
#include "text.h"
|
||||
#include "vault.h"
|
||||
|
||||
extern long curtime;
|
||||
|
@ -20,6 +21,8 @@ extern long curtime;
|
|||
extern lifeform_t *player;
|
||||
extern map_t *firstmap;
|
||||
extern knowledge_t *knowledge;
|
||||
extern region_t *firstregion,*lastregion;
|
||||
extern regionoutline_t *firstregionoutline,*lastregionoutline;
|
||||
|
||||
extern enum GAMEMODE gamemode;
|
||||
|
||||
|
@ -34,6 +37,14 @@ int loadall(void) {
|
|||
dblog("Could not open map directory '%s'",MAPDIR);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// load region outlines first.
|
||||
if (loadregions()) {
|
||||
// this isn't an error - just means no savegames
|
||||
dblog("No region data found.");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// for each map file in directory
|
||||
while ((ent = readdir(dir)) != NULL) {
|
||||
char *p;
|
||||
|
@ -61,7 +72,7 @@ int loadflagpile(FILE *f, flagpile_t *fp) {
|
|||
flag_t *fl;
|
||||
char buf[BUFLEN];
|
||||
int rv;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
|
||||
rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n",
|
||||
&tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom);
|
||||
|
@ -265,6 +276,7 @@ map_t *loadmap(char *basefile) {
|
|||
object_t *o;
|
||||
map_t *m;
|
||||
cell_t *dummycell;
|
||||
int regionid;
|
||||
|
||||
if (db) dblog("Loading map from %s...",basefile);
|
||||
sprintf(filename, "%s/%s",MAPDIR,basefile);
|
||||
|
@ -273,7 +285,7 @@ map_t *loadmap(char *basefile) {
|
|||
// create map
|
||||
m = addmap();
|
||||
dummycell = malloc(sizeof(cell_t));
|
||||
dummycell->obpile = addobpile(NULL, dummycell);
|
||||
dummycell->obpile = addobpile(NULL, dummycell, NULL);
|
||||
dummycell->map = m;
|
||||
dummycell->type = (celltype_t *)DUMMYCELLTYPE; // for debugging
|
||||
|
||||
|
@ -285,11 +297,13 @@ map_t *loadmap(char *basefile) {
|
|||
// load map info
|
||||
if (db) dblog("--> Loading map info...\n");
|
||||
fscanf(f, "id:%d\n",&m->id); // map id
|
||||
fscanf(f, "region:%d\n",®ionid); // region id
|
||||
m->region = findregion(regionid);
|
||||
fscanf(f, "depth:%d\n",&m->depth); // map depth
|
||||
fgets(buf, BUFLEN, f); // map name
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
m->name = strdup(buf + 5); // after 'name:'
|
||||
fscanf(f, "habitat:%d\n",(int *)habitatid); // habitat
|
||||
fscanf(f, "habitat:%d\n",(int *)&habitatid); // habitat
|
||||
m->habitat = findhabitat(habitatid);
|
||||
fscanf(f, "seed:%d\n",&m->seed); // seed
|
||||
fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons
|
||||
|
@ -549,7 +563,105 @@ int loadob(FILE *f, obpile_t *op, long *id) {
|
|||
|
||||
dblog("About to start loading object flags...");
|
||||
loadflagpile(f, o->flags);
|
||||
fscanf(f, "endob\n");
|
||||
|
||||
fgets(buf, BUFLEN, f);// either 'obcontents:xx' or 'endob'
|
||||
if (strstarts(buf, "obcontents")) {
|
||||
// load this object's contents...
|
||||
char *p;
|
||||
char buf2[BUFLEN];
|
||||
int ncontents;
|
||||
int i;
|
||||
//dblog("got obcontents");
|
||||
// strip newline
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
p = readuntil(buf2, buf, ':'); // ignore bit before :
|
||||
p = readuntil(buf2, p, ')'); // ) will really be eol
|
||||
ncontents = atoi(buf2);
|
||||
for (i = 0 ; i < ncontents; i++) {
|
||||
loadob(f, o->contents, NULL);
|
||||
}
|
||||
fgets(buf, BUFLEN, f);// 'endobcontents'
|
||||
//dblog("want endobcontents, got: '%s'", buf);
|
||||
fgets(buf, BUFLEN, f);// 'endob'
|
||||
//dblog("want endob, got: '%s'", buf);
|
||||
}
|
||||
if (strstarts(buf, "endob")) {
|
||||
// we got 'endob'
|
||||
} else {
|
||||
dblog("ERROR loading objects - expecting 'endob' but got '%s'\n",buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//fscanf(f, "endob\n");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int loadregions(void) {
|
||||
FILE *f;
|
||||
char filename[BUFLEN];
|
||||
int rtid,nthings,i,n;
|
||||
int numoutlines,numregions;
|
||||
int db = B_FALSE;
|
||||
|
||||
// TODO: check that map dir exists
|
||||
sprintf(filename, "%s/regions.dat",MAPDIR);
|
||||
f = fopen(filename, "rt");
|
||||
if (!f) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
fscanf(f, "numoutlines:%d\n",&numoutlines);
|
||||
if (db) dblog("Found %d region outlines.\n",numoutlines);
|
||||
for (n = 0; n < numoutlines; n++) {
|
||||
fscanf(f, "startro\n");
|
||||
fscanf(f, "rtypeid:%d\n",&rtid); // region type id
|
||||
addregionoutline(rtid);
|
||||
|
||||
fscanf(f, "nthings:%d\n",&nthings);
|
||||
for (i = 0; i < nthings; i++) {
|
||||
int depth,x,y,val;
|
||||
enum REGIONTHING whatkind;
|
||||
char buf[BUFLEN],*p;
|
||||
fscanf(f, "startthing\n");
|
||||
fscanf(f, " thingdepth:%d,%d,%d\n",&depth, &x, &y);
|
||||
fscanf(f, " thingkind:%d\n",(int *)&whatkind);
|
||||
fscanf(f, " thingval:%d\n",&val);
|
||||
fscanf(f, " thingwhat:%s\n",buf);
|
||||
fscanf(f, "endthing\n");
|
||||
|
||||
// replace ^ with ' ' in thingwhat
|
||||
for (p = buf ; *p; p++) {
|
||||
if (*p == '^') *p = ' ';
|
||||
}
|
||||
addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf);
|
||||
}
|
||||
fscanf(f, "endro\n");
|
||||
if (db) dblog("Loaded regionoutline #%d / %d",n+1, numoutlines);
|
||||
}
|
||||
|
||||
// now save out the actual region->outline mappings
|
||||
fscanf(f, "numregions:%d\n",&numregions);
|
||||
if (db) dblog("Found %d regions.\n",numregions);
|
||||
for (n = 0; n < numregions; n++) {
|
||||
region_t *r;
|
||||
enum REGIONTYPE rtid;
|
||||
int outlineid,parentid,nthings;
|
||||
fscanf(f, "startregion\n");
|
||||
fscanf(f, " rtypeid:%d\n",(int *)&rtid);
|
||||
fscanf(f, " outline:%d\n",&outlineid);
|
||||
fscanf(f, " parentregion:%d\n",&parentid);
|
||||
fscanf(f, " nthings:%d\n",&nthings);
|
||||
fscanf(f, "endregion\n");
|
||||
r = addregion(rtid, (parentid == -1) ? NULL : findregion(parentid), outlineid);
|
||||
r->nthings = nthings;
|
||||
if (db) dblog("Loaded region #%d / %d",n+1, numregions);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// successful load - kill the file now
|
||||
unlink(filename);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -581,7 +693,7 @@ int loadsavegame(void) {
|
|||
exit(1);
|
||||
}
|
||||
if (!loadlf(f, NULL)) {
|
||||
printf("Error loading savegame from file '%s'",ent->d_name);
|
||||
printf("Error loading player from file '%s'",ent->d_name);
|
||||
exit(1);
|
||||
}
|
||||
if (loadknowledge(f)) {
|
||||
|
@ -699,6 +811,12 @@ int savegame(void) {
|
|||
FILE *f;
|
||||
char buf[BUFLEN];
|
||||
int rv;
|
||||
rv = saveregions();
|
||||
if (rv) {
|
||||
msg("Could not save region data.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
for (m = firstmap; m ; m = m->next) {
|
||||
// save world
|
||||
rv = savemap(m);
|
||||
|
@ -737,6 +855,7 @@ int savemap(map_t *m) {
|
|||
|
||||
// save map info
|
||||
fprintf(f, "id:%d\n",m->id); // map id
|
||||
fprintf(f, "region:%d\n",m->region->id); // map region id
|
||||
fprintf(f, "depth:%d\n",m->depth); // map depth
|
||||
fprintf(f, "name:%s\n",m->name); // map name
|
||||
fprintf(f, "habitat:%d\n",m->habitat->id); // habitat
|
||||
|
@ -797,6 +916,8 @@ int savemap(map_t *m) {
|
|||
|
||||
|
||||
int saveob(FILE *f, object_t *o) {
|
||||
object_t *oo;
|
||||
int ncontents;
|
||||
fprintf(f, "id:%ld\n",o->id);
|
||||
fprintf(f, "type:%d\n",o->type->id);
|
||||
fprintf(f, "material:%d\n",o->material->id);
|
||||
|
@ -808,6 +929,78 @@ int saveob(FILE *f, object_t *o) {
|
|||
fprintf(f, "amt:%d\n",o->amt);
|
||||
fprintf(f, "birthtime:%ld\n",o->birthtime);
|
||||
saveflagpile(f, o->flags);
|
||||
// object contents...
|
||||
ncontents = countobs(o->contents, B_FALSE);
|
||||
if (ncontents) {
|
||||
fprintf(f, "obcontents:%d\n",ncontents);
|
||||
for (oo = o->contents->first ; oo ; oo = oo->next) {
|
||||
saveob(f, oo);
|
||||
}
|
||||
fprintf(f, "endobcontents\n");
|
||||
}
|
||||
fprintf(f, "endob\n");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int saveregions(void) {
|
||||
FILE *f;
|
||||
char filename[BUFLEN];
|
||||
int i;
|
||||
regionoutline_t *ro;
|
||||
region_t *r;
|
||||
int numoutlines = 0,numregions = 0;
|
||||
|
||||
// TODO: check that map dir exists
|
||||
sprintf(filename, "%s/regions.dat",MAPDIR);
|
||||
f = fopen(filename, "wt");
|
||||
for (ro = firstregionoutline ; ro ; ro = ro->next) {
|
||||
numoutlines++;
|
||||
}
|
||||
fprintf(f, "numoutlines:%d\n",numoutlines);
|
||||
|
||||
for (ro = firstregionoutline ; ro ; ro = ro->next) {
|
||||
// save this outline
|
||||
fprintf(f, "startro\n");
|
||||
fprintf(f, "rtypeid:%d\n",ro->rtype->id); // region type id
|
||||
fprintf(f, "nthings:%d\n",ro->nthings);
|
||||
for (i = 0; i < ro->nthings; i++) {
|
||||
fprintf(f, "startthing\n");
|
||||
fprintf(f, " thingdepth:%d,%d,%d\n",ro->thing[i].depth, ro->thing[i].x, ro->thing[i].y);
|
||||
fprintf(f, " thingkind:%d\n",(int)ro->thing[i].whatkind);
|
||||
fprintf(f, " thingval:%d\n",(int)ro->thing[i].value);
|
||||
if (strlen(ro->thing[i].what)) {
|
||||
char localwhat[BUFLEN],*p;
|
||||
strcpy(localwhat,ro->thing[i].what);
|
||||
for (p = localwhat ; *p; p++) {
|
||||
if (*p == ' ') *p = '^';
|
||||
}
|
||||
fprintf(f, " thingwhat:%s\n",localwhat);
|
||||
} else {
|
||||
fprintf(f, " thingwhat:NULL\n");
|
||||
}
|
||||
fprintf(f, "endthing\n");
|
||||
}
|
||||
fprintf(f, "endro\n");
|
||||
}
|
||||
|
||||
|
||||
// now save out the actual region->outline mappings
|
||||
|
||||
numregions = 0;
|
||||
for (r = firstregion ; r; r = r->next) {
|
||||
numregions++;
|
||||
}
|
||||
|
||||
fprintf(f, "numregions:%d\n",numregions);
|
||||
for (r = firstregion ; r; r = r->next) {
|
||||
fprintf(f, "startregion\n");
|
||||
fprintf(f, " rtypeid:%d\n",r->rtype->id);
|
||||
fprintf(f, " outline:%d\n",r->outline ? r->outline->id : -1);
|
||||
fprintf(f, " parentregion:%d\n",r->parentregion ? r->parentregion->id : -1);
|
||||
fprintf(f, " nthings:%d\n",r->nthings);
|
||||
fprintf(f, "endregion\n");
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
2
save.h
2
save.h
|
@ -6,6 +6,7 @@ int loadknowledge(FILE *f);
|
|||
lifeform_t *loadlf(FILE *f, cell_t *where);
|
||||
map_t *loadmap(char *basefile);
|
||||
int loadob(FILE *f, obpile_t *op, long *id);
|
||||
int loadregions(void);
|
||||
int loadsavegame(void);
|
||||
int saveflagpile(FILE *f, flagpile_t *fp);
|
||||
int saveknowledge(FILE *f);
|
||||
|
@ -13,3 +14,4 @@ int savelf(FILE *f, lifeform_t *l);
|
|||
int savegame(void);
|
||||
int savemap(map_t *m);
|
||||
int saveob(FILE *f, object_t *o);
|
||||
int saveregions(void);
|
||||
|
|
567
spell.c
567
spell.c
|
@ -390,6 +390,41 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (abilid == OT_A_FEIGNDEATH) {
|
||||
lifeform_t *lf;
|
||||
if (hasflag(user->flags, F_FEIGNINGDEATH)) {
|
||||
if (isplayer(user)) msg("You are already feigning death!");
|
||||
return B_TRUE;
|
||||
}
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
if (isplayer(user)) {
|
||||
msg("You drop to the ground.");
|
||||
} else if (cansee(player, user)) {
|
||||
if (target) {
|
||||
char targname[BUFLEN];
|
||||
getlfname(target, targname);
|
||||
msg("%s kill%s %s.", targname, isplayer(target) ? "" : "s", username);
|
||||
} else {
|
||||
msg("%s dies.", username);
|
||||
}
|
||||
}
|
||||
addflag(user->flags, F_PRONE, B_TRUE, NA, NA, NULL);
|
||||
addflag(user->flags, F_FEIGNINGDEATH, B_TRUE, NA, NA, NULL);
|
||||
// anyone attacking you stops
|
||||
for (lf = user->cell->map->lf ; lf ; lf = lf->next) {
|
||||
flag_t *f;
|
||||
char buf[BUFLENTINY];
|
||||
f = hasflagval(lf->flags, F_TARGETLF, user->id, NA, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
f = hasflagval(lf->flags, F_TARGETCELL, user->cell->x, user->cell->y, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
sprintf(buf, "%d\n",user->id);
|
||||
f = hasflagval(lf->flags, F_TARGETCELL, NA, NA, MR_LF, buf);
|
||||
if (f) killflag(f);
|
||||
}
|
||||
needredraw = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
} else if (abilid == OT_A_FLURRY) {
|
||||
int dir;
|
||||
int dirch;
|
||||
|
@ -399,7 +434,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!isdualweilding(user)) {
|
||||
if (hasjob(user, J_MONK)) {
|
||||
if (getweapon(user)) {
|
||||
if (isplayer(user)) msg("You need be unarmed to perform an attack flurry!");
|
||||
}
|
||||
return B_TRUE;
|
||||
} else if (!isdualweilding(user)) {
|
||||
if (isplayer(user)) msg("You need two be dual-weilding to perform an attack flurry!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -561,28 +601,40 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char victimname[BUFLEN];
|
||||
int dodged = B_FALSE;
|
||||
cell_t *origcell;
|
||||
int maxrange = 2;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't jump while swimming!");
|
||||
return B_TRUE;
|
||||
} else if (isairborne(user)) {
|
||||
if (isplayer(user)) msg("You can't jump while airbourne!");
|
||||
return B_TRUE;
|
||||
} else if (hasflag(user->flags, F_GRAVBOOSTED)) {
|
||||
if (isplayer(user)) msg("You can't jump with gravity boosted around you!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (hasflag(user->flags, F_GRAVLESSENED)) {
|
||||
maxrange++;
|
||||
}
|
||||
|
||||
|
||||
if (!targcell) {
|
||||
sprintf(buf, "Jump where (max distance 2)?");
|
||||
sprintf(buf, "Jump where (max distance %d)?", maxrange);
|
||||
while (!targcell) {
|
||||
// ask where
|
||||
targcell = askcoords(buf, "Jump->", TT_NONE, user, 2, LOF_DONTNEED, B_TRUE);
|
||||
targcell = askcoords(buf, "Jump->", TT_NONE, user, maxrange, LOF_DONTNEED, B_TRUE);
|
||||
if (!targcell) {
|
||||
return B_TRUE;
|
||||
} else if (getcelldist(user->cell, targcell) > 2) {
|
||||
} else if (getcelldist(user->cell, targcell) > maxrange) {
|
||||
targcell = NULL;
|
||||
if (isplayer(user)) {
|
||||
sprintf(buf, "You can't jump that far! Jump where (max distance 2)?");
|
||||
sprintf(buf, "You can't jump that far! Jump where (max distance %d)?", maxrange);
|
||||
}
|
||||
} else if (!haslos(user, targcell)) {
|
||||
targcell = NULL;
|
||||
if (isplayer(user)) {
|
||||
sprintf(buf, "You can't see where to land! Jump where (max distance 2)?");
|
||||
sprintf(buf, "You can't see where to land! Jump where (max distance %d)?", maxrange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -707,10 +759,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
int cutoff;
|
||||
switch (slev) {
|
||||
case PR_NOVICE: cutoff = 33; break;
|
||||
case PR_BEGINNER: cutoff = 40; break;
|
||||
case PR_ADEPT: cutoff = 50; break;
|
||||
case PR_SKILLED: cutoff = 65; break;
|
||||
case PR_EXPERT: cutoff = 80; break;
|
||||
case PR_BEGINNER: cutoff = 50; break;
|
||||
case PR_ADEPT: cutoff = 60; break;
|
||||
case PR_SKILLED: cutoff = 70; break;
|
||||
case PR_EXPERT: cutoff = 85; break;
|
||||
case PR_MASTER: cutoff = 100; break;
|
||||
default: cutoff = 0; break;
|
||||
}
|
||||
|
@ -723,10 +775,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
int cutoff;
|
||||
switch (slev) {
|
||||
case PR_NOVICE: cutoff = 33; break;
|
||||
case PR_BEGINNER: cutoff = 40; break;
|
||||
case PR_ADEPT: cutoff = 50; break;
|
||||
case PR_SKILLED: cutoff = 65; break;
|
||||
case PR_EXPERT: cutoff = 80; break;
|
||||
case PR_BEGINNER: cutoff = 50; break;
|
||||
case PR_ADEPT: cutoff = 60; break;
|
||||
case PR_SKILLED: cutoff = 70; break;
|
||||
case PR_EXPERT: cutoff = 85; break;
|
||||
case PR_MASTER: cutoff = 100; break;
|
||||
default: cutoff = 0; break;
|
||||
}
|
||||
|
@ -868,6 +920,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
|
||||
addtempflag(user->flags, F_SPRINTING, B_TRUE, NA, NA, NULL, howlong);
|
||||
practice(user, SK_ATHLETICS, 1);
|
||||
// get hungry heaps!
|
||||
modhunger(user, 50);
|
||||
} else if (abilid == OT_A_STINGACID) {
|
||||
validateabillf(user, abilid, &target);
|
||||
if (!target) return B_TRUE;
|
||||
|
@ -1031,6 +1085,109 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (haslos(player, origcell)) {
|
||||
redraw();
|
||||
}
|
||||
} else if (abilid == OT_A_TUMBLE) {
|
||||
cell_t *origcell,*c;
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int i,nretcell = 0;
|
||||
object_t *stopob = NULL;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't tumble while swimming!");
|
||||
return B_TRUE;
|
||||
} else if (isairborne(user)) {
|
||||
if (isplayer(user)) msg("You can't tumble while airbourne!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!targcell) {
|
||||
sprintf(buf, "Tumble where (max distance 2)?");
|
||||
while (!targcell) {
|
||||
// ask where
|
||||
targcell = askcoords(buf, "Tumble->", TT_NONE, user, 2, LOF_NEED, B_TRUE);
|
||||
if (!targcell) {
|
||||
if (isplayer(user)) msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
} else if (!haslos(user, targcell)) {
|
||||
targcell = NULL;
|
||||
if (isplayer(user)) {
|
||||
sprintf(buf, "You can't see where to land! Tumble where (max distance 2)?");
|
||||
}
|
||||
} else if (!haslof(user->cell, targcell, LOF_NEED, NULL)) {
|
||||
targcell = NULL;
|
||||
if (isplayer(user)) {
|
||||
sprintf(buf, "You don't have a clear line of fire to there!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isburdened(user)) {
|
||||
if (isplayer(user)) {
|
||||
msg("Your load is too heavy to tumble with!");
|
||||
}
|
||||
return B_TRUE;
|
||||
} else if (lfhasflag(user, F_GRAVBOOSTED)) {
|
||||
if (isplayer(user)) {
|
||||
msg("Gravity around you is too strong to tumble!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
origcell = user->cell;
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
|
||||
// will you be interrupted on the way?
|
||||
calcbresnham(origcell->map, origcell->x, origcell->y, targcell->x, targcell->y, retcell, &nretcell);
|
||||
for (i = 0; i < nretcell; i++) {
|
||||
c = retcell[i];
|
||||
if (getcellwaterdepth(c, user)) {
|
||||
// stop here.
|
||||
targcell = c;
|
||||
stopob = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
break;
|
||||
} else if (hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL)) {
|
||||
// stop here.
|
||||
targcell = c;
|
||||
stopob = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// skillcheck...
|
||||
if (!skillcheck(user, SC_TUMBLE, 10, 0)) {
|
||||
// fail!
|
||||
if (isplayer(user)) {
|
||||
msg("You fumble and fall.");
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s fumbles and falls.", username);
|
||||
}
|
||||
fall(user, NULL, B_FALSE);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// go there!
|
||||
movelf(user, targcell);
|
||||
|
||||
// announce
|
||||
if (isplayer(user)) {
|
||||
msg("You tumble across the ground!");
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s tumbles across the ground!", username);
|
||||
}
|
||||
// pits/water?
|
||||
if (stopob) {
|
||||
char obname[BUFLEN];
|
||||
getobname(stopob, obname, 1);
|
||||
if (isplayer(user)) {
|
||||
msg("Your tumble is interrupted by %s!",obname);
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s%s tumble is interrupted by %s!",username,getpossessive(username), obname);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (abilid == OT_A_POLYREVERT) {
|
||||
flag_t *f;
|
||||
if (!target) target = user;
|
||||
|
@ -1170,6 +1327,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char targetname[BUFLEN];
|
||||
flag_t *f;
|
||||
int heavyamt = 8;
|
||||
int badweapon = B_FALSE;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You lack the stability for a heavy blow while swimming.");
|
||||
|
@ -1177,10 +1335,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
wep = getweapon(user);
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < heavyamt)) { // ie. 8 is weight of a mace
|
||||
if (!wep) {
|
||||
if (!hasjob(user, J_MONK)) {
|
||||
badweapon = B_TRUE;
|
||||
}
|
||||
} else if (!ismeleeweapon(wep) || (getobunitweight(wep) < heavyamt)) { // ie. 8 is weight of a mace
|
||||
badweapon = B_TRUE;
|
||||
}
|
||||
|
||||
if (badweapon) {
|
||||
if (isplayer(user)) msg("You need a heavy weapon (%dkg or more) to perform a heavy blow!", heavyamt);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// ask for direction
|
||||
if (!targcell) {
|
||||
|
@ -1207,7 +1373,52 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
f = addflag(wep->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL);
|
||||
f = addflag(user->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL);
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
killflag(f);
|
||||
} else if (abilid == OT_A_QUIVERINGPALM) {
|
||||
object_t *wep;
|
||||
char dirch;
|
||||
char targetname[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You lack the stability to use this ability while swimming.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
wep = getweapon(user);
|
||||
if (wep) {
|
||||
if (isplayer(user)) msg("You must be unarmed to make a quivering palm strike.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// ask for direction
|
||||
if (!targcell) {
|
||||
dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
|
||||
if (dirch == '.') {
|
||||
// yourself!
|
||||
targcell = user->cell;
|
||||
} else {
|
||||
int dir;
|
||||
dir = chartodir(dirch);
|
||||
if (dir == D_NONE) {
|
||||
if (isplayer(user)) msg("Cancelled.");
|
||||
return B_TRUE ;
|
||||
} else {
|
||||
targcell = getcellindir(user->cell, dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
if (isplayer(user)) msg("There is nobody there to attack!");
|
||||
return B_TRUE;
|
||||
}
|
||||
getlfname(target, targetname);
|
||||
|
||||
f = addflag(user->flags, F_QUIVERINGPALM, B_TRUE, NA, NA, NULL);
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
killflag(f);
|
||||
} else if (abilid == OT_A_STEAL) {
|
||||
|
@ -1895,6 +2106,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
teleportto(caster, targcell, B_TRUE);
|
||||
}
|
||||
} else if (spellid == OT_S_BODYCONTROL) {
|
||||
flag_t *f;
|
||||
// ie. 2 - 4
|
||||
f = addtempflag(caster->flags, F_SLOWMETAB, 2+(power/4), NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
// you move more slowly too.
|
||||
if (power < 3) {
|
||||
f = addtempflag(caster->flags, F_SLOWMOVE, 10, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (power < 5) {
|
||||
f = addtempflag(caster->flags, F_SLOWMOVE, 5, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
}
|
||||
} else if (spellid == OT_S_BURNINGWAVE) {
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell;
|
||||
|
@ -2037,7 +2261,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int powerleft;
|
||||
int donesomething = B_FALSE;
|
||||
cell_t *c;
|
||||
powerleft = rolldie(power+1, 4);
|
||||
//powerleft = rolldie(power+1, 4);
|
||||
powerleft = power;
|
||||
for (i = 0; i < caster->nlos; i++) {
|
||||
c = caster->los[i];
|
||||
if (c->lf && (c->lf->race->raceclass->id == RC_ANIMAL) && (gethitdice(c->lf) <= powerleft)) {
|
||||
|
@ -2328,13 +2553,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(target, lfname);
|
||||
|
||||
// how many body parts are impacted?
|
||||
exposedlimbs = 0;
|
||||
if (!getouterequippedob(target, BP_HEAD)) exposedlimbs += 1;
|
||||
if (!getouterequippedob(target, BP_SHOULDERS)) exposedlimbs += 1;
|
||||
if (!getouterequippedob(target, BP_BODY)) exposedlimbs += 2;
|
||||
if (!getouterequippedob(target, BP_HANDS)) exposedlimbs += 1;
|
||||
if (!getouterequippedob(target, BP_LEGS)) exposedlimbs += 2;
|
||||
if (!getouterequippedob(target, BP_FEET)) exposedlimbs += 1;
|
||||
exposedlimbs = getexposedlimbs(target);
|
||||
|
||||
dam = rolldie(exposedlimbs, 3);
|
||||
|
||||
|
@ -2358,9 +2577,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// always hit
|
||||
if (!isimmuneto(target->flags, DT_COLD)) {
|
||||
losehp(target, dam, DT_COLD, caster, "a chill spell");
|
||||
if (!skillcheck(target, SC_CON, 20+(exposedlimbs*3), 0)) {
|
||||
poison(target, 20+(power*3), P_COLD, 0, "a chill spell");
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_COLDBURST) {
|
||||
int range = 1;
|
||||
|
@ -2515,12 +2731,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
jobname[0] = tolower(jobname[0]);
|
||||
p = strstr(buf, jobname);
|
||||
if (p) {
|
||||
char newbuf[BUFLEN];
|
||||
strncpy(newbuf, buf, (p - buf) - 1);
|
||||
r = findracebyname(newbuf);
|
||||
if (r) {
|
||||
forcejob = j;
|
||||
if (p == buf) {
|
||||
// just asked for the job name
|
||||
// fail.
|
||||
break;
|
||||
} else {
|
||||
char newbuf[BUFLEN];
|
||||
strncpy(newbuf, buf, (p - buf) - 1);
|
||||
r = findracebyname(newbuf);
|
||||
if (r) {
|
||||
forcejob = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2691,8 +2913,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
} else if (ch == '<') {
|
||||
if (seenbyplayer && haslos(player, caster->cell)) *seenbyplayer = B_TRUE;
|
||||
return digup(caster, NULL);
|
||||
} else if (ch == '>') {
|
||||
if (seenbyplayer && haslos(player, caster->cell)) *seenbyplayer = B_TRUE;
|
||||
return digdown(caster, NULL);
|
||||
} else {
|
||||
dir = chartodir(ch);
|
||||
|
@ -3503,6 +3727,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
f = hasflag(o->flags, F_RESTRICTMOVEMENT);
|
||||
if (f) {
|
||||
f->val[0] = 30 + (power/2);
|
||||
f->val[1] = B_FALSE; // struggling doesn't damage the vine
|
||||
}
|
||||
/// remmeber creator. if they don't have los to us, spell
|
||||
// is broken and vines will vanish.
|
||||
|
@ -4261,7 +4486,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
|
||||
// 4 is the same as ST_TITANIC strength
|
||||
// 5 is the same as AT_VHIGH strength
|
||||
// 10 = gun speed
|
||||
fireat(caster, targob, 1, targcell, 8 + (power / 2) , NULL);
|
||||
} else if (spellid == OT_S_PARALYZE) {
|
||||
|
@ -4512,37 +4737,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_MAGICARMOUR, power*4, NA, NA, "psychic barrier", FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_PULL) {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) 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, is(target));
|
||||
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, spellid, power, frompot)) return B_TRUE;
|
||||
|
@ -4811,7 +5005,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, spellid, power, frompot)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_DOOR|TT_IMPASSABLE, spellid, power, frompot)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
||||
|
@ -5136,18 +5330,36 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_GRAVBOOST) {
|
||||
// ask for target
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
if (target) {
|
||||
int howlong = 15;
|
||||
flag_t *f;
|
||||
int i;
|
||||
|
||||
if (isplayer(target) || cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
f = hasactivespell(target, OT_S_GRAVLOWER);
|
||||
if (f) {
|
||||
stopspell(target, OT_S_GRAVLOWER);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
i += killtransitoryflags(target->flags, F_GRAVLESSENED);
|
||||
i += killtransitoryflagvals(target->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL);
|
||||
if (i) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (lfhasflag(target, F_GRAVBOOSTED) || skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily heavier.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (cansee(player, target)) {
|
||||
char targname[BUFLEN];
|
||||
getlfname(target, targname);
|
||||
msg("%s looks momentarily heavier.", targname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -5163,8 +5375,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = lfhasflag(target, F_GRAVBOOSTED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (isplayer(target) || cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
f = addtempflag(caster->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
f = addtempflag(caster->flags, F_GRAVLESSENED, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_GUSTOFWIND) {
|
||||
obpile_t *op;
|
||||
object_t *o, *nexto;
|
||||
|
@ -5263,15 +5486,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
flag_t *f;
|
||||
char fullobname[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
|
||||
if (isplayer(caster)) {
|
||||
sprintf(fullobname, "Your %s", noprefix(obname));
|
||||
} else if (cansee(player, caster)) {
|
||||
sprintf(fullobname, "%s%s %s", castername, getpossessive(castername), noprefix(obname));
|
||||
} else {
|
||||
strcpy(fullobname, "");
|
||||
}
|
||||
|
||||
if (targob) {
|
||||
o = targob;
|
||||
|
@ -5284,6 +5498,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
getobname(o, obname, o->amt);
|
||||
|
||||
if (isplayer(caster)) {
|
||||
sprintf(fullobname, "Your %s", noprefix(obname));
|
||||
} else if (cansee(player, caster)) {
|
||||
sprintf(fullobname, "%s%s %s", castername, getpossessive(castername), noprefix(obname));
|
||||
} else {
|
||||
strcpy(fullobname, "");
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (f && isdamaged(o)) {
|
||||
if (blessed == B_CURSED) {
|
||||
|
@ -6001,6 +6225,37 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_SUCK) {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) 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, is(target));
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_TELEPORT) {
|
||||
cell_t *c = NULL;
|
||||
lifeform_t *ally[8];
|
||||
|
@ -6860,6 +7115,8 @@ enum SKILL getschoolskill(enum SPELLSCHOOL ss) {
|
|||
return SK_SS_DEATH;
|
||||
case SS_DIVINATION:
|
||||
return SK_SS_DIVINATION;
|
||||
case SS_ENCHANTMENT:
|
||||
return SK_SS_ENCHANTMENT;
|
||||
case SS_NATURE:
|
||||
return SK_SS_NATURE;
|
||||
case SS_FIRE:
|
||||
|
@ -7013,6 +7270,118 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
||||
int power = 0;
|
||||
int spelllev;
|
||||
enum SKILLLEVEL spellcastskill,schoolskill;
|
||||
enum SPELLSCHOOL school;
|
||||
int db = B_FALSE;
|
||||
int usesorcery = B_FALSE;
|
||||
flag_t *f;
|
||||
|
||||
if (db) {
|
||||
objecttype_t *ot;
|
||||
ot = findot(spellid);
|
||||
if (db) dblog("getspellpower for lf %s, spell %s", lf->race->name, ot->name);
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// CAN WE CAST THIS AT ALL
|
||||
////////////////////////////////////
|
||||
// If we can _will_ this to occur then we might have a set
|
||||
// spellpower
|
||||
f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
|
||||
if (f && strlen(f->text)) {
|
||||
texttospellopts(f->text, &power, NULL, NULL, NULL);
|
||||
if (power > 0) {
|
||||
if (db) {
|
||||
dblog("-->power = %d (from canwill)", power);
|
||||
}
|
||||
return power;
|
||||
}
|
||||
}
|
||||
|
||||
// get spell details
|
||||
school = getspellschoolknown(lf, spellid);
|
||||
schoolskill = getskill(lf, getschoolskill(school));
|
||||
spellcastskill = getskill(lf, SK_SPELLCASTING);
|
||||
spelllev = getspelllevel(spellid);
|
||||
|
||||
// for most spell schools, your skill in the school determines which
|
||||
// spells you can cast.
|
||||
//
|
||||
// this check doesn't apply for monsters.
|
||||
if (isplayer(lf)) {
|
||||
if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) {
|
||||
// always okay
|
||||
} else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) {
|
||||
// dont need spellcasting skill for mental/allomancy
|
||||
} else {
|
||||
int maxspelllevel;
|
||||
usesorcery = B_TRUE;
|
||||
switch (schoolskill) {
|
||||
case PR_INEPT: maxspelllevel = 0; break;
|
||||
case PR_NOVICE: maxspelllevel = 1; break;
|
||||
case PR_BEGINNER: maxspelllevel = 2; break;
|
||||
case PR_ADEPT: maxspelllevel = 4; break;
|
||||
case PR_SKILLED: maxspelllevel = 6; break;
|
||||
case PR_EXPERT: maxspelllevel = 8; break;
|
||||
case PR_MASTER: maxspelllevel = 9; break;
|
||||
}
|
||||
|
||||
// player can only ever cast spells up to your level.
|
||||
if (!hasjob(lf, J_GOD)) {
|
||||
limit(&maxspelllevel, NA, lf->level);
|
||||
}
|
||||
|
||||
if (spelllev > maxspelllevel) {
|
||||
if (db) dblog("-->power = 0 (no skilled enough in spell school)");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////
|
||||
// HOW POWERFUL IS THIS SPELL?
|
||||
////////////////////////////////////
|
||||
if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) {
|
||||
// always okay
|
||||
usesorcery = B_FALSE;
|
||||
} else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) {
|
||||
// dont need spellcasting skill for mental/allomancy
|
||||
usesorcery = B_FALSE;
|
||||
} else {
|
||||
usesorcery = B_TRUE;
|
||||
}
|
||||
|
||||
power = 1; // base power of 1.
|
||||
// plus either your hitdice/3 OR your sorcery skill
|
||||
if (usesorcery) {
|
||||
power += spellcastskill;
|
||||
} else {
|
||||
power += (gethitdice(lf)/3);
|
||||
}
|
||||
|
||||
// plus intelligence modifier
|
||||
if (school == SS_MENTAL) {
|
||||
// +/- 2 for iq
|
||||
power += (getstatmod(lf, A_IQ) / 25);
|
||||
} else if (school == SS_NATURE) {
|
||||
// +/- 1 for wisdom
|
||||
power += (getstatmod(lf, A_WIS) / 50);
|
||||
// TODO: clerical +/- 2 for wisdom
|
||||
} else {
|
||||
// +/- 1 for iq
|
||||
power += (getstatmod(lf, A_IQ) / 50);
|
||||
}
|
||||
|
||||
limit(&power, 0, getspellmaxpower(spellid));
|
||||
return power;
|
||||
}
|
||||
|
||||
/*
|
||||
ooooooo old oooooooo
|
||||
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
||||
int power = 0;
|
||||
int statmod;
|
||||
|
@ -7134,6 +7503,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
|||
if (db) dblog("==> final power: %d", power);
|
||||
return power;
|
||||
}
|
||||
*/
|
||||
|
||||
enum SPELLSCHOOL getspellschool(enum OBTYPE spellid) {
|
||||
flag_t *f;
|
||||
|
@ -7152,10 +7522,15 @@ enum SPELLSCHOOL getspellschool(enum OBTYPE spellid) {
|
|||
return SS_NONE;
|
||||
}
|
||||
|
||||
// return the school which the given spell belongs to, HOWEVER if it
|
||||
// belongs to multiple ones, prefer ones which the given lifeform
|
||||
// is skilled in.
|
||||
enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
|
||||
flag_t *f;
|
||||
enum SPELLSCHOOL thisschool;
|
||||
objecttype_t *ot;
|
||||
enum SPELLSCHOOL poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
||||
ot = findot(spellid);
|
||||
if (!ot) {
|
||||
|
@ -7166,24 +7541,46 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
|
|||
return SS_ABILITY;
|
||||
}
|
||||
|
||||
|
||||
// find a school which we know about!
|
||||
// make a list of all schools which this spell belongs to, and which we know.
|
||||
thisschool = SS_NONE;
|
||||
for (f = ot->flags->first ; f ; f = f->next) {
|
||||
if ((f->id == F_SPELLSCHOOL) && getskill(lf, getschoolskill(f->val[0]))) {
|
||||
thisschool = f->val[0];
|
||||
break;
|
||||
poss[nposs++] = f->val[0];
|
||||
}
|
||||
}
|
||||
// if we don't know any of the schools...
|
||||
if (thisschool == SS_NONE) {
|
||||
if (nposs) {
|
||||
int i;
|
||||
enum SPELLSCHOOL poss2[MAXCANDIDATES];
|
||||
int nposs2 = 0;
|
||||
enum SKILLLEVEL highestskill = PR_INEPT;
|
||||
// find the school which we are most skilled in
|
||||
for (i = 0; i < nposs; i++) {
|
||||
enum SKILLLEVEL thisslev;
|
||||
thisslev = getskill(lf, getschoolskill(poss[i]));
|
||||
if (thisslev > highestskill) {
|
||||
highestskill = thisslev;
|
||||
}
|
||||
}
|
||||
|
||||
// now only select from these ones...
|
||||
for (i = 0; i < nposs; i++) {
|
||||
enum SKILLLEVEL thisslev;
|
||||
thisslev = getskill(lf, getschoolskill(poss[i]));
|
||||
if (thisslev == highestskill) {
|
||||
poss2[nposs2++] = poss[i];
|
||||
}
|
||||
}
|
||||
|
||||
// pick one randomly
|
||||
thisschool = poss2[rnd(0,nposs2-1)];
|
||||
} else {
|
||||
// if we don't know any of the schools...
|
||||
// just pick the first one.
|
||||
f = hasflag(ot->flags, F_SPELLSCHOOL);
|
||||
assert(f);
|
||||
thisschool = f->val[0];
|
||||
}
|
||||
|
||||
|
||||
return thisschool;
|
||||
}
|
||||
|
||||
|
@ -7599,7 +7996,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
|
|||
|
||||
if (!frompot && where && where->lf && haslos(caster, where) && isplayer(caster) && areallies(caster, where->lf)) {
|
||||
// warn before targetting yourself!
|
||||
if (getiqname(getattr(caster, A_IQ), NULL) >= IQ_AVERAGE) {
|
||||
if (getattrbracket(getattr(caster, A_IQ), A_IQ, NULL) >= AT_AVERAGE) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(spellid);
|
||||
if (sp) {
|
||||
|
|
50
text.c
50
text.c
|
@ -19,8 +19,16 @@ int needan(char *text) {
|
|||
}
|
||||
|
||||
char *capitalise(char *text) {
|
||||
if (strlen(text) > 0) {
|
||||
text[0] = toupper(text[0]);
|
||||
if (strlen(text)) {
|
||||
char *p;
|
||||
p = text;
|
||||
while (*p == '^') {
|
||||
p++; // go past the ^
|
||||
if (!(*p)) return text; // do nothing
|
||||
p++; // go past the colour char
|
||||
if (!(*p)) return text; // do nothing
|
||||
}
|
||||
*p = toupper(*p);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -40,6 +48,27 @@ char *capitaliseall(char *text) {
|
|||
return text;
|
||||
}
|
||||
|
||||
enum COLOUR chartocol(char ch) {
|
||||
switch (ch) {
|
||||
case 'w': // warning
|
||||
return C_YELLOW;
|
||||
case 'W': // extra warning
|
||||
return C_BOLDMAGENTA;
|
||||
case 'b': // bad
|
||||
return C_BROWN;
|
||||
case 'B': // v.bad
|
||||
return C_RED;
|
||||
case 'g': // good
|
||||
return C_GREEN;
|
||||
case 'G': // v.good
|
||||
return C_CYAN;
|
||||
case 'n': // normal
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return C_GREY;
|
||||
}
|
||||
|
||||
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf) {
|
||||
int localmin, localmax;
|
||||
|
||||
|
@ -122,13 +151,15 @@ char *getattrabbrev(enum ATTRIB att) {
|
|||
case A_CHA:
|
||||
return "Ch";
|
||||
case A_CON:
|
||||
return "Fi";
|
||||
return "Ft";
|
||||
case A_DEX:
|
||||
return "Dx";
|
||||
case A_IQ:
|
||||
return "Iq";
|
||||
case A_STR:
|
||||
return "St";
|
||||
case A_WIS:
|
||||
return "Wi";
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
@ -147,6 +178,8 @@ char *getattrname(enum ATTRIB att) {
|
|||
return "intelligence";
|
||||
case A_STR:
|
||||
return "strength";
|
||||
case A_WIS:
|
||||
return "wisdom";
|
||||
}
|
||||
return "?badattrib?";
|
||||
}
|
||||
|
@ -186,7 +219,7 @@ int gethitconferlifetime(char *text, int *min, int *max) {
|
|||
char *getpossessive(char *text) {
|
||||
char lastchar;
|
||||
// you -> your
|
||||
if (!strcmp(text, "you")) {
|
||||
if (!strcasecmp(text, "you")) {
|
||||
return "r";
|
||||
}
|
||||
|
||||
|
@ -235,14 +268,15 @@ char *getsizetext(enum LFSIZE sz) {
|
|||
case SZ_LARGE:
|
||||
return "large";
|
||||
case SZ_HUMAN:
|
||||
return "human-sized";
|
||||
return "human";
|
||||
case SZ_MEDIUM:
|
||||
return "medium";
|
||||
case SZ_SMALL:
|
||||
return "small";
|
||||
case SZ_MINI:
|
||||
case SZ_TINY:
|
||||
return "extremely small";
|
||||
return "tiny";
|
||||
case SZ_MINI:
|
||||
return "miniscule";
|
||||
default:
|
||||
return "unknown-sized";
|
||||
}
|
||||
|
@ -550,7 +584,7 @@ char *roman(int num) {
|
|||
}
|
||||
|
||||
int speedtokph(int speed) {
|
||||
return speed * speed * speed;
|
||||
return speed * speed;
|
||||
}
|
||||
|
||||
void splittime(int *hours, int *mins, int *secs) {
|
||||
|
|
1
text.h
1
text.h
|
@ -3,6 +3,7 @@
|
|||
int needan(char *text);
|
||||
char *capitalise(char *text);
|
||||
char *capitaliseall(char *text);
|
||||
enum COLOUR chartocol(char ch);
|
||||
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf);
|
||||
int flip(int ch);
|
||||
char *getattrabbrev(enum ATTRIB att);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/:ob:wooden table
|
||||
-:ob:wooden footstool
|
||||
c:ob:lit candelabrum
|
||||
@:mon:Jimbo
|
||||
@:mon:jailer
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
Loading…
Reference in New Issue