* [+] bug: secret doors revealed when we walk away from them.
- [+] make lamps last heaps longer * [+] web spell * [+] spider monstrer * [+] funnelweb: * [+] redback: - [+] if you are wracked with pain, don't clear msg - [+] check rarity for spiders * [+] attack/defense mod if there is stickiness in your square - [+] replace "sticky" with "restrictive" * [+] make some mosnters start hidden - [+] adjust spot checks basd on distance - [+] ensure that attacking stops you hiding - [+] casting spells stops you from being hidden - [+] hidden mosnters shouldn't move unless their victim is ADJACENT. - [+] hidden mosnters shouldn't cast spells, throw missiles, etc unless their victim is ADJACENT. - [-] XP CALC - [+] funnelweb and redback are the same. - [+] check this is right...... i want funnel web to be worse. - [+] make hitconfer check in calcxpval take lifetime into account - [+] ALSO assign an xp rating to each hitconferred flag. - [+] hardcode this. * [+] entangle spell - [+] reveal secret doors if you see them get damaged. * [+] make askcoords list restrivitce objects - [+] ACTUALLY make vines not damaged by struggling * [+] object descriptions, a/an needs to change if showing condition: "a battered entangling vine" - [+] wizard levelled up and was prompted for "WISH, GIFT"! shouldn't happen! - [+] The human diety reads a blessed scroll of create monster! -- but nothing happens?? * [+] throw code - [+] wizard: ask for school specialty at start, from: fire, ice, xxx ? You get this + WILD. - [+] describe varpower spells - [+] fix mp cost for varpower spells - [+] we're not stopping running at staircases anymore for some reason. - [+] CHARGE ability (like swoop but don't return to original positino) - [+] need to honor f_canlearn when displaying new skills to learn! - [+] ai: if we are going to player's last known loc (via targetcell), abandon if we can SEE the player! - [+] make shatter() into a function - [+] oil potion makes oil puddle whan smashed - [+] make flammable objects be able to convert to others - [+] replace 'magic item usage' with 'channeling' - [+] a cloud of darkness descends. this is a *cursed* wand of light. - [+] spiders shouldn't be able to be stuck in a web! * [+] spells should be able to have MULTIPLE schools. - [+] don't bleed into walls - [+] in @M, use colours to show which spells are too hard so far (ie cost > maxmp) * [+] in @M, use schools that you know * [+] after loading game, barbarian is getting an extra attack? You miss the eyebat. You punch the eyebat. - [+] show objects on top of stairs - [+] stuck mosnters must pass a saving throw to follow you up/down stairs - [+] genericise: trytomove(lf) * [+] add more snakes - [+] undead can't eat or drink? or MOST undead can't. * [+] why can MONSTERS shoot webs through things? (but I can't) - [+] barkskin - doesn't reduce max mp enough? - [+] The skeleton touches a fuming aqua potion [tried] then recoils in pain! The skeleton drops a blessed fuming aqua potion [tried]. The skeleton drinks a fuming aqua potion! - [+] why can't i use abilites anymore? - [+] infinite loop bug due to ai only having one ignorecell. - [+] make sleet storms rust all armour - [+] make a kind of walkdam that hits armour - [+] add this as well as walkdam for: acid, fire, water - [+] Takeoff isn't prompting properly. only showing weapons! * [+] waterproof obs (ie cloak) * [+] walkdambp doesn't hurt body if you have a cloak NATURE SPELLS: - [+] mending, heals 1d6 damage - [+] spark - [+] purify food - [+] sticks to snakes - [+] calm animals (power_d4 hd) * [+] charm animal (works on one animal up to power hit dice, temporary) - [+] airblast - [+] barkskin (power +2 AR, firevuln, ongoing) - [+] soften earth (makes ground into mud) - [+] warp wood (damages wooden objects) - [+] repel insects - [+] reduce poison - [+] web - [+] windshield - [+] call lightning, air - [+] resist elements, ongoing - [+] passwall - [+] poisonbolt - [+] quench (puts out a fire) - [+] sleet storm (lowers movement, vision) - [+] healing - [+] cure poison * [+] calming scent - [+] dig - [+] entangle - [+] levitate - [+] flamepillar - [+] hailstorm. like sleetstorm but hurts more. power d 6. - [+] burning wave - [+] gaseous form * [+] knowledge skills: * [+] force makespellchoicelist() to show spells in level order. * [+] druid - [+] check OBJECT rarity list (dumplev) - [+] fix bug where heaps of books suddently appear from dlev 3 onwards - [+] gain skills on level up for some jobs - [+] f_levspellschool, v0=lev, v1 = school or ANY - select one from that school
This commit is contained in:
parent
4f54fc0ef9
commit
b18dea83a3
92
ai.c
92
ai.c
|
@ -19,6 +19,12 @@ extern enum ERROR reason;
|
|||
|
||||
int wantdb = B_TRUE;
|
||||
|
||||
void addignorecell(lifeform_t *lf, cell_t *c) {
|
||||
if (c) {
|
||||
addflag(lf->flags, F_IGNORECELL, c->x, c->y, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||
int db = B_FALSE;
|
||||
flag_t *f;
|
||||
|
@ -251,8 +257,10 @@ object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void aigoto(lifeform_t *lf, cell_t *c, int timelimit) {
|
||||
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit) {
|
||||
int db = B_FALSE;
|
||||
char whybuf[BUFLEN];
|
||||
flag_t *f = NULL;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
|
@ -267,12 +275,22 @@ void aigoto(lifeform_t *lf, cell_t *c, int timelimit) {
|
|||
killflagsofid(lf->flags, F_TARGET);
|
||||
killflagsofid(lf->flags, F_TARGETCELL);
|
||||
|
||||
if (why == MR_LF) {
|
||||
sprintf(whybuf, "%d", ((lifeform_t *)data)->id);
|
||||
} else if (why == MR_OB) {
|
||||
sprintf(whybuf, "%ld", ((object_t *)data)->id);
|
||||
} else {
|
||||
strcpy(whybuf, "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) {
|
||||
addflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL);
|
||||
f = addflag(lf->flags, F_TARGETCELL, c->x, c->y, why, whybuf);
|
||||
} else {
|
||||
addtempflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL,timelimit);
|
||||
f = addtempflag(lf->flags, F_TARGETCELL, c->x, c->y, why, whybuf,timelimit);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
||||
|
@ -296,7 +314,7 @@ void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
if (db) dblog(".oO { couldn't walk towards f_targetcell. abandoning it. }");
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
addignorecell(lf, c);
|
||||
} else {
|
||||
if (db) dblog(".oO { successfully walked towards f_targetcell. arrived at %d,%d }",lf->cell->x, lf->cell->y);
|
||||
// moved towards it.
|
||||
|
@ -314,7 +332,7 @@ void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
// destination doesn't exist!
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
addignorecell(lf, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,11 +526,13 @@ 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 (db) dblog(".oO { looking for covetted objects... }");
|
||||
if (lookforobs(lf, B_COVETS)) {
|
||||
if (db) dblog(".oO { found covetted object. returning. }");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// attacks
|
||||
|
@ -552,6 +572,7 @@ void aiturn(lifeform_t *lf) {
|
|||
if (goingtomove && (getcelldist(lf->cell, target->cell) == 1)) {
|
||||
}
|
||||
|
||||
if (!lfhasflag(lf, F_HIDING)) {
|
||||
// can we attack with spells (ie. ones which target the victim)?
|
||||
// if target is adjacent, we will normally just attack rather than try a spell.
|
||||
spell = aigetattackspell(lf, target);
|
||||
|
@ -700,6 +721,7 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} // end if !hiding
|
||||
|
||||
// do we have a valid melee attack?
|
||||
if (!icanattack) {
|
||||
|
@ -707,6 +729,12 @@ void aiturn(lifeform_t *lf) {
|
|||
goingtomove = B_FALSE;
|
||||
}
|
||||
|
||||
// if we are hiding, only attack when adjacent to maximise damage
|
||||
if (lfhasflag(lf, F_HIDING) &&
|
||||
(getcelldist(lf->cell, target->cell) != 1)) {
|
||||
goingtomove = B_FALSE;
|
||||
}
|
||||
|
||||
if (goingtomove) {
|
||||
if (!movetowards(lf, target->cell, DT_ORTH)) {
|
||||
// success
|
||||
|
@ -723,7 +751,7 @@ void aiturn(lifeform_t *lf) {
|
|||
// move towards their last known location instead
|
||||
targcell = getcellat(lf->cell->map, lastx, lasty);
|
||||
if (targcell) {
|
||||
aigoto(lf, targcell, PERMENANT);
|
||||
aigoto(lf, targcell, MR_LF, target, PERMENANT);
|
||||
} else {
|
||||
if (db) dblog(".oO { go to target's last known loc failed! }");
|
||||
}
|
||||
|
@ -747,7 +775,38 @@ void aiturn(lifeform_t *lf) {
|
|||
// do we have a target cell?
|
||||
f = hasflag(lf->flags, F_TARGETCELL);
|
||||
if (f) {
|
||||
int valid = B_TRUE;
|
||||
cell_t *c;
|
||||
// is it still valid?
|
||||
c = getcellat(lf->cell->map, f->val[0], f->val[1]);
|
||||
if (!c) {
|
||||
valid = B_FALSE;
|
||||
} else if (f->val[2] == MR_LF) {
|
||||
lifeform_t *who;
|
||||
who = findlf(lf->cell->map, atoi(f->text));
|
||||
// lf doesn't exist?
|
||||
if (!who) {
|
||||
valid = B_FALSE;
|
||||
} else if (cansee(lf, who) && (lf->cell != c)) {
|
||||
// can see them and they're not where we are going?
|
||||
valid = B_FALSE;
|
||||
}
|
||||
} else if (f->val[2] == MR_OB) {
|
||||
object_t *what;
|
||||
what = findobidinmap(lf->cell->map, atol(f->text));
|
||||
if (!what) {
|
||||
valid = B_FALSE;
|
||||
} else if (haslos(lf, c) && (what->pile->where != c)) {
|
||||
// if you can see the cell and object isn't there anymore
|
||||
valid = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
aimovetotargetcell(lf, f);
|
||||
} else {
|
||||
killflag(f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -870,8 +929,11 @@ void aiturn(lifeform_t *lf) {
|
|||
} else {
|
||||
// try to move towards master's last known loc
|
||||
if (mf->val[1] != NA) {
|
||||
cell_t *newcell;
|
||||
newcell = getcellat(lf->cell->map, mf->val[1], mf->val[2]);
|
||||
|
||||
if (db) dblog(".oO { cannot see my master - adding F_TARGETCELL for last known loc }");
|
||||
f = addflag(lf->flags, F_TARGETCELL, mf->val[1], mf->val[2], NA, NULL);
|
||||
f = aigoto(lf, newcell, MR_LF, master, PERMENANT);
|
||||
aimovetotargetcell(lf, f);
|
||||
} else {
|
||||
if (db) dblog(".oO { cannot see my master and dont have a last known location. randommove. }");
|
||||
|
@ -1105,6 +1167,18 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_WARPWOOD)) {
|
||||
specificcheckok = B_FALSE;
|
||||
if (victim) {
|
||||
object_t *oo;
|
||||
for (oo = victim->pack->first ; oo ; oo = oo->next) {
|
||||
if ((oo->type->material->id == MT_WOOD) && isequipped(oo)) {
|
||||
specificcheckok = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_S_WEAKEN)) {
|
||||
flag_t *lff;
|
||||
for (lff = lf->flags->first; lff ; lff = lff->next) {
|
||||
|
@ -1254,7 +1328,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
|
|||
int gothere = B_FALSE;
|
||||
|
||||
c = lf->los[i];
|
||||
if (!c->lf && (c != lf->ignorecell)) {
|
||||
if (!c->lf && !lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) {
|
||||
o = hasobmulti(c->obpile, oid, noids);
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf,o)) ) {
|
||||
if (db) dblog(".oO { remote cell has ob i want (%s). setting f_targetcell. }",o->type->name);
|
||||
|
@ -1306,7 +1380,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
|
|||
|
||||
if (gothere) {
|
||||
// start walking towards target cell
|
||||
aigoto(lf, c, AI_FOLLOWTIME);
|
||||
aigoto(lf, c, MR_OB, o, AI_FOLLOWTIME);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
3
ai.h
3
ai.h
|
@ -1,11 +1,12 @@
|
|||
#include "defs.h"
|
||||
|
||||
void addignorecell(lifeform_t *lf, cell_t *c);
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
|
||||
enum OBTYPE aigetfleespell(lifeform_t *lf);
|
||||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
||||
object_t * aigetwand(lifeform_t *lf, enum FLAG purpose);
|
||||
void aigoto(lifeform_t *lf, cell_t *c, int timelimit);
|
||||
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
|
||||
void aimovetotargetcell(lifeform_t *lf, flag_t *f);
|
||||
int aipickup(lifeform_t *lf, object_t *o);
|
||||
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target);
|
||||
|
|
81
attack.c
81
attack.c
|
@ -183,6 +183,12 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
}
|
||||
}
|
||||
|
||||
// stop sprinting
|
||||
f = lfhasflag(lf, F_SPRINTING);
|
||||
if (f && f->val[0]) {
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
// take time
|
||||
attacktime = getattackspeed(lf);
|
||||
taketime(lf, attacktime);
|
||||
|
@ -266,6 +272,9 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
if (op) {
|
||||
killobpile(op);
|
||||
}
|
||||
|
||||
// now stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -324,6 +333,18 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
if (aidb) dblog(".oO { my weapon is %s }", wepname);
|
||||
|
||||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
if (hasactivespell(victim, OT_S_REPELINSECTS)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Something prevents you from attacking %s!", victimname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("Something prevents %s from attacking %s!", attackername, victimname);
|
||||
}
|
||||
taketime(lf, getattackspeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// did you hit?
|
||||
ndam = 0;
|
||||
if (rolltohit(lf, victim, wep, &critical)) {
|
||||
|
@ -406,6 +427,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
dam[0] += pctof(pctextra, dam[0]);
|
||||
}
|
||||
}
|
||||
// bonus for knowledge about the other lf's race? applied LAST.
|
||||
if (getlorelevel(lf, victim->race->raceclass->id) >= PR_MASTER) {
|
||||
dam[0] = (int) ( (float)dam[0] * 1.5 );
|
||||
} else if (getlorelevel(lf, victim->race->raceclass->id) >= PR_SKILLED) {
|
||||
dam[0] = (int) ( (float)dam[0] * 1.25 );
|
||||
}
|
||||
}
|
||||
|
||||
if (aidb) dblog(".oO { dealing %d %s damage }", dam[0], getdamname(damtype[0]));
|
||||
|
@ -690,7 +717,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (adj) {
|
||||
flag_t *f;
|
||||
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
||||
moveto(victim, adj, B_FALSE);
|
||||
moveto(victim, adj, B_FALSE, B_FALSE);
|
||||
msg("%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
|
||||
killflag(f);
|
||||
}
|
||||
|
@ -1629,7 +1656,9 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
// only works if we did damage
|
||||
if (dam) {
|
||||
enum FLAG fid;
|
||||
int min,max,howlong;
|
||||
int howlong;
|
||||
flag_t *valflag = NULL;
|
||||
|
||||
fid = f->val[0];
|
||||
// the f_poisoned flag stacks, others don't.
|
||||
if (!lfhasflag(victim, fid) || (fid == F_POISONED)) {
|
||||
|
@ -1648,31 +1677,15 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
}
|
||||
|
||||
if (!passedcheck) {
|
||||
if (f->text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,f->text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
min = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (word) {
|
||||
max = atoi(word);
|
||||
howlong = rnd(min,max);
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
|
||||
howlong = gethitconferlifetime(f->text, NULL, NULL);
|
||||
|
||||
// get conferred flag values
|
||||
valflag = hasflag(f->pile, F_HITCONFERVALS);
|
||||
|
||||
if (fid == F_POISONED) {
|
||||
// need to fill in the name of what poisoned us
|
||||
char frombuf[BUFLEN];
|
||||
flag_t *typeflag;
|
||||
enum POISONTYPE ptype;
|
||||
int ppower;
|
||||
if (wep) {
|
||||
|
@ -1692,13 +1705,14 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
} else {
|
||||
strcpy(frombuf, "something unknown");
|
||||
}
|
||||
typeflag = hasflag(f->pile, F_HITPOISONTYPE);
|
||||
if (typeflag) {
|
||||
ptype = typeflag->val[0];
|
||||
if (typeflag->val[1] == NA) {
|
||||
|
||||
|
||||
if (valflag) {
|
||||
ptype = valflag->val[0];
|
||||
if (valflag->val[1] == NA) {
|
||||
ppower = 1;
|
||||
} else {
|
||||
ppower = typeflag->val[1];
|
||||
ppower = valflag->val[1];
|
||||
}
|
||||
} else {
|
||||
// should never happen.
|
||||
|
@ -1708,7 +1722,16 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
|
||||
poison(victim, howlong, ptype, ppower, frombuf);
|
||||
} else {
|
||||
addtempflag(victim->flags, fid, NA, NA, NA, NULL, howlong);
|
||||
flag_t *conferredflag;
|
||||
conferredflag = addtempflag(victim->flags, fid, NA, NA, NA, NULL, howlong);
|
||||
// flag values
|
||||
if (valflag) {
|
||||
conferredflag->val[0] = valflag->val[0];
|
||||
conferredflag->val[1] = valflag->val[1];
|
||||
conferredflag->val[2] = valflag->val[2];
|
||||
free(conferredflag->text);
|
||||
conferredflag->text = strdup(valflag->text);
|
||||
}
|
||||
}
|
||||
} // end if passedcheck
|
||||
} // end (if victim doesn't already have the flag)
|
||||
|
|
248
defs.h
248
defs.h
|
@ -34,6 +34,64 @@ enum COLOUR {
|
|||
C_BOLDGREEN = 14,
|
||||
};
|
||||
|
||||
enum SKILL {
|
||||
SK_NONE = 0,
|
||||
SK_ARMOUR = 1,
|
||||
SK_ATHLETICS,
|
||||
SK_BACKSTAB,
|
||||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_CHANNELING,
|
||||
SK_SHIELDS,
|
||||
SK_SPELLCASTING,
|
||||
SK_SPOTHIDDEN,
|
||||
SK_STEALTH,
|
||||
SK_TECHUSAGE,
|
||||
// knowledge
|
||||
SK_LORE_ARCANA,
|
||||
SK_LORE_DEMONS,
|
||||
SK_LORE_HUMANOID,
|
||||
SK_LORE_NATURE,
|
||||
SK_LORE_UNDEAD,
|
||||
// weaponry
|
||||
SK_AXES,
|
||||
SK_CLUBS,
|
||||
SK_LONGBLADES,
|
||||
SK_POLEARMS,
|
||||
SK_SHORTBLADES,
|
||||
SK_STAVES,
|
||||
SK_UNARMED,
|
||||
// spell schools
|
||||
SK_SS_ALLOMANCY,
|
||||
SK_SS_AIR,
|
||||
SK_SS_DEATH,
|
||||
SK_SS_DIVINATION,
|
||||
SK_SS_FIRE,
|
||||
SK_SS_ICE,
|
||||
SK_SS_GRAVITY,
|
||||
SK_SS_LIFE,
|
||||
SK_SS_MODIFICATION,
|
||||
SK_SS_MENTAL,
|
||||
SK_SS_NATURE,
|
||||
SK_SS_SUMMONING,
|
||||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 39
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
PR_INEPT = 0,
|
||||
PR_NOVICE = 1,
|
||||
PR_BEGINNER = 2,
|
||||
PR_ADEPT = 3,
|
||||
PR_SKILLED = 4,
|
||||
PR_EXPERT = 5,
|
||||
PR_MASTER = 6,
|
||||
};
|
||||
|
||||
|
||||
// save/load
|
||||
#define MAPDIR "data/maps"
|
||||
#define SAVEDIR "data/save"
|
||||
|
@ -161,6 +219,8 @@ enum LFCONDITION {
|
|||
|
||||
#define MAXPILEOBS 52
|
||||
|
||||
#define MAXSPELLLEV 9
|
||||
|
||||
#define MAXRETCELLS 80
|
||||
|
||||
#define MAXCHOICES 150
|
||||
|
@ -217,12 +277,14 @@ enum LFCONDITION {
|
|||
#define AO_WEARABLE 16
|
||||
#define AO_OPERABLE 32
|
||||
#define AO_POURABLE 64
|
||||
#define AO_EQUIPPEDARMOUR 128
|
||||
#define AO_EQUIPPEDNONWEAPON 128
|
||||
#define AO_WEILDABLE 256
|
||||
#define AO_SPECIFIED 512
|
||||
#define AO_READABLE 1024
|
||||
#define AO_ARMOUR 2048
|
||||
#define AO_NOTKNOWN 4096
|
||||
#define AO_DAMAGED 8192
|
||||
#define AO_DRINKABLE 16384
|
||||
|
||||
// askcoords target types
|
||||
#define TT_NONE 0
|
||||
|
@ -230,6 +292,7 @@ enum LFCONDITION {
|
|||
#define TT_OBJECT 2
|
||||
#define TT_DOOR 4
|
||||
#define TT_PLAYER 8
|
||||
#define TT_ALLY 16
|
||||
|
||||
// target requirements
|
||||
#define TR_NONE 0
|
||||
|
@ -326,13 +389,13 @@ enum SPELLSCHOOL {
|
|||
SS_AIR,
|
||||
SS_DEATH,
|
||||
SS_DIVINATION,
|
||||
SS_EARTH,
|
||||
SS_FIRE,
|
||||
SS_ICE,
|
||||
SS_GRAVITY,
|
||||
SS_LIFE,
|
||||
SS_MODIFICATION,
|
||||
SS_MENTAL,
|
||||
SS_NATURE,
|
||||
SS_SUMMONING,
|
||||
SS_TRANSLOCATION,
|
||||
SS_WILD,
|
||||
|
@ -460,7 +523,8 @@ enum HABITAT {
|
|||
H_ALL = 999
|
||||
};
|
||||
|
||||
#define RARITYVARIANCE (25)
|
||||
#define RARITYVARIANCELF (5)
|
||||
#define RARITYVARIANCEOB (10)
|
||||
|
||||
/*
|
||||
enum RARITY {
|
||||
|
@ -474,6 +538,16 @@ enum RARITY {
|
|||
};
|
||||
*/
|
||||
|
||||
enum RACECLASS {
|
||||
RC_ANIMAL,
|
||||
RC_DEMON,
|
||||
RC_HUMANOID,
|
||||
RC_INSECT,
|
||||
RC_SLIME,
|
||||
RC_MAGIC,
|
||||
RC_OTHER,
|
||||
RC_UNDEAD,
|
||||
};
|
||||
|
||||
enum RACE {
|
||||
R_NONE, R_RANDOM,
|
||||
|
@ -524,7 +598,12 @@ enum RACE {
|
|||
R_NEWT,
|
||||
R_RAT,
|
||||
R_SNAKE,
|
||||
R_SNAKECARPET,
|
||||
R_SPIDER,
|
||||
R_SPIDERFUNNELWEB,
|
||||
R_SPIDERREDBACK,
|
||||
R_WOLF,
|
||||
R_WOLFYOUNG,
|
||||
// insects
|
||||
R_BUTTERFLY,
|
||||
R_CENTIPEDE,
|
||||
|
@ -549,6 +628,7 @@ enum JOB {
|
|||
J_ALLOMANCER,
|
||||
J_BARBARIAN,
|
||||
J_COMMANDO,
|
||||
J_DRUID,
|
||||
J_PIRATE,
|
||||
J_PLUMBER,
|
||||
J_PRINCE,
|
||||
|
@ -589,6 +669,8 @@ enum MATERIAL {
|
|||
MT_SLIME = 21,
|
||||
MT_WAX = 22,
|
||||
MT_ACID = 23,
|
||||
MT_SILK = 24,
|
||||
MT_OIL = 25,
|
||||
};
|
||||
|
||||
// Object Types
|
||||
|
@ -681,6 +763,7 @@ enum OBTYPE {
|
|||
OT_SCR_KNOCK,
|
||||
OT_SCR_LIGHT,
|
||||
OT_SCR_MAPPING,
|
||||
OT_SCR_MENDING,
|
||||
OT_SCR_MINDSCAN,
|
||||
OT_SCR_PERMENANCE,
|
||||
OT_SCR_ENCHANT,
|
||||
|
@ -697,12 +780,17 @@ enum OBTYPE {
|
|||
OT_MAN_LISTEN,
|
||||
OT_MAN_LOCKPICKING,
|
||||
OT_MAN_MAGITEMUSAGE,
|
||||
OT_MAN_RESEARCH,
|
||||
OT_MAN_SHIELDS,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_SPOTHIDDEN,
|
||||
OT_MAN_STEALTH,
|
||||
OT_MAN_TECHUSAGE,
|
||||
// manuals of knowledge
|
||||
OT_MAN_LORE_ARCANA,
|
||||
OT_MAN_LORE_DEMONS,
|
||||
OT_MAN_LORE_HUMANOID,
|
||||
OT_MAN_LORE_NATURE,
|
||||
OT_MAN_LORE_UNDEAD,
|
||||
// manuals of weaponry
|
||||
OT_MAN_AXES,
|
||||
OT_MAN_CLUBS,
|
||||
|
@ -716,7 +804,7 @@ enum OBTYPE {
|
|||
OT_MAN_SS_AIR,
|
||||
OT_MAN_SS_DEATH,
|
||||
OT_MAN_SS_DIVINATION,
|
||||
OT_MAN_SS_EARTH,
|
||||
OT_MAN_SS_NATURE,
|
||||
OT_MAN_SS_FIRE,
|
||||
OT_MAN_SS_ICE,
|
||||
OT_MAN_SS_GRAVITY,
|
||||
|
@ -747,6 +835,7 @@ enum OBTYPE {
|
|||
OT_SB_MAPPING,
|
||||
// -- elemental - air
|
||||
OT_SB_AIRBLAST,
|
||||
OT_SB_CALLLIGHTNING,
|
||||
OT_SB_CLOUDKILL,
|
||||
// -- elemental - fire
|
||||
OT_SB_SPARK,
|
||||
|
@ -786,9 +875,11 @@ enum OBTYPE {
|
|||
OT_SB_INVISIBILITY,
|
||||
OT_SB_LIGHT,
|
||||
OT_SB_DARKNESS,
|
||||
OT_SB_MENDING,
|
||||
OT_SB_PASSWALL,
|
||||
OT_SB_PETRIFY,
|
||||
OT_SB_POLYMORPH,
|
||||
OT_SB_STICKTOSNAKE,
|
||||
// -- summoning
|
||||
OT_SB_CREATEMONSTER,
|
||||
// -- translocation
|
||||
|
@ -840,8 +931,6 @@ enum OBTYPE {
|
|||
OT_S_COLDBURST,
|
||||
OT_S_CONECOLD,
|
||||
OT_S_FREEZEOB,
|
||||
// -- elemental - earth
|
||||
OT_S_DIG,
|
||||
// -- gravity
|
||||
OT_S_GRAVLOWER,
|
||||
OT_S_GRAVBOOST,
|
||||
|
@ -861,17 +950,39 @@ enum OBTYPE {
|
|||
OT_S_PSYARMOUR,
|
||||
OT_S_CHARM,
|
||||
// -- modification
|
||||
OT_S_DARKNESS,
|
||||
OT_S_ENCHANT,
|
||||
OT_S_GASEOUSFORM,
|
||||
OT_S_INSCRIBE,
|
||||
OT_S_INVISIBILITY,
|
||||
OT_S_KNOCK,
|
||||
OT_S_LIGHT,
|
||||
OT_S_DARKNESS,
|
||||
OT_S_MENDING,
|
||||
OT_S_PASSWALL,
|
||||
OT_S_PETRIFY,
|
||||
OT_S_POLYMORPH,
|
||||
OT_S_POLYMORPHRND,
|
||||
// nature
|
||||
OT_S_BARKSKIN,
|
||||
OT_S_CALLLIGHTNING,
|
||||
OT_S_CALMANIMALS,
|
||||
OT_S_CALMINGSCENT,
|
||||
OT_S_CHARMANIMAL,
|
||||
OT_S_CUREPOISON,
|
||||
OT_S_DETECTPOISON,
|
||||
OT_S_DIG,
|
||||
OT_S_WEB,
|
||||
OT_S_ENDUREELEMENTS,
|
||||
OT_S_ENTANGLE,
|
||||
OT_S_HAILSTORM,
|
||||
OT_S_PURIFYFOOD,
|
||||
OT_S_QUENCH,
|
||||
OT_S_LESSENPOISON,
|
||||
OT_S_REPELINSECTS,
|
||||
OT_S_SLEETSTORM,
|
||||
OT_S_SOFTENEARTH,
|
||||
OT_S_STICKTOSNAKE,
|
||||
OT_S_WARPWOOD,
|
||||
// -- summoning
|
||||
OT_S_CREATEMONSTER,
|
||||
// -- translocation
|
||||
|
@ -895,9 +1006,11 @@ enum OBTYPE {
|
|||
OT_A_LEVELUP,
|
||||
// abilities
|
||||
OT_A_GRAB,
|
||||
OT_A_CHARGE,
|
||||
OT_A_CRUSH,
|
||||
OT_A_JUMP,
|
||||
OT_A_SPRINT,
|
||||
OT_A_STINGACID, // need to define dam in f_canwill
|
||||
OT_A_SWOOP,
|
||||
OT_A_EMPLOY,
|
||||
OT_A_HEAVYBLOW,
|
||||
|
@ -905,7 +1018,6 @@ enum OBTYPE {
|
|||
OT_A_INSPECT,
|
||||
OT_A_HURRICANESTRIKE,
|
||||
OT_A_POLYREVERT,
|
||||
OT_A_STINGACID, // need to define dam in f_canwill
|
||||
OT_A_WARCRY, // uses F_NOISETEXT -> N_WARCRY if it is there.
|
||||
// otherwise 'shouts a blood-curdling war cry'
|
||||
// wands
|
||||
|
@ -959,6 +1071,8 @@ enum OBTYPE {
|
|||
OT_BROKENGLASS,
|
||||
OT_ICECHUNK,
|
||||
OT_ICESHEET,
|
||||
OT_MUDPOOL,
|
||||
OT_PUDDLEOIL,
|
||||
OT_SPLASHWATER,
|
||||
OT_PUDDLEWATER,
|
||||
OT_PUDDLEWATERL,
|
||||
|
@ -977,13 +1091,17 @@ enum OBTYPE {
|
|||
OT_FIRELARGE,
|
||||
OT_FIREMED,
|
||||
OT_FIRESMALL,
|
||||
OT_HAILSTORM,
|
||||
OT_MAGICBARRIER,
|
||||
OT_STEAMCLOUD,
|
||||
OT_STEAMPUFF,
|
||||
OT_SLEETSTORM,
|
||||
OT_SMOKECLOUD,
|
||||
OT_SMOKEPUFF,
|
||||
OT_POISONCLOUD,
|
||||
OT_POISONPUFF,
|
||||
OT_VINE,
|
||||
OT_WEB,
|
||||
// armour - body
|
||||
OT_ARMOURLEATHER,
|
||||
OT_ARMOURRING,
|
||||
|
@ -1039,6 +1157,7 @@ enum OBTYPE {
|
|||
OT_RING_CONTROL,
|
||||
OT_RING_CON,
|
||||
OT_RING_DEX,
|
||||
OT_RING_HUNGER,
|
||||
OT_RING_IQ,
|
||||
OT_RING_STR,
|
||||
OT_RING_MANA,
|
||||
|
@ -1151,6 +1270,7 @@ enum BODYPART {
|
|||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
#define WE_PORTAL 3
|
||||
#define WE_NOTWALL 4
|
||||
|
||||
enum NOISETYPE {
|
||||
N_GETANGRY,
|
||||
|
@ -1196,6 +1316,7 @@ enum FLAG {
|
|||
F_CONTAINSOB, // for vending machiens. v0 is ob letter
|
||||
// text is an object it contains.
|
||||
F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc
|
||||
F_STARTBLESSED, // v0 = b_blessed or b_cursed
|
||||
// for items in shops
|
||||
F_SHOPITEM, // causes shops to show this item as identified
|
||||
F_VALUE, // how much an item is worth (over its base weight+material)
|
||||
|
@ -1213,7 +1334,9 @@ enum FLAG {
|
|||
F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it
|
||||
F_BLOCKSVIEW, // cannot see past this
|
||||
F_BLOCKSTHROW, // cannot throw past this
|
||||
F_DIETEXT, // text when the object dies
|
||||
F_THEREISHERE, // announce "there is xx here!", not "you see xx here"
|
||||
// text[0] is punctuation to use.
|
||||
F_OBDIETEXT, // text when the object dies
|
||||
F_DIECONVERTTEXT, // text when the object converts. eg. "melts"
|
||||
F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt"
|
||||
F_DIECONVERT, // val0 = what this turns into when dying
|
||||
|
@ -1241,9 +1364,7 @@ enum FLAG {
|
|||
F_HITCONFER, // hitting with this gives flagid=v0
|
||||
// unless you pass a val1 skillcheck, diff val2
|
||||
// with timeleft = text ("min-max")
|
||||
F_HITPOISONTYPE, // used when you have f_hitconfer->f_poisoned.
|
||||
// v0 is type of poison.
|
||||
// v1 is power (NA means 1)
|
||||
F_HITCONFERVALS,// specifies values for conferred flag.
|
||||
F_ACTIVATED, // val0 = is this object turned on?
|
||||
F_GRENADE, // this obkejct will drain charge when activated, then die
|
||||
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
|
||||
|
@ -1299,14 +1420,25 @@ enum FLAG {
|
|||
|
||||
// ob interaction flags
|
||||
F_HARD, // object is hard (ie. punching it will hurt!)
|
||||
F_REDUCEMOVEMENT, // time to move off here is multiplied by v0.
|
||||
F_RESTRICTMOVEMENT, // must pass a diff=v0 STR check to move off it.
|
||||
// if v1 is B_TRUE, then it takes 1 damage if you fail.
|
||||
//
|
||||
// for multiple objects, each one adds half its difficulty
|
||||
|
||||
F_RODSHAPED, // for sticks-to-snakes
|
||||
F_SHARP, // does damage when you step on it. v0/1 are min/max dam
|
||||
F_SCARY, // gives other lfs a penalty to morale checks against you,
|
||||
// v0 = penalty amt.
|
||||
F_SLIPPERY, // you might slip when stepping on it. v0 is amt
|
||||
F_SLIPMOVE, // if someone slips on this, it will move to an adj cell
|
||||
F_FLAMMABLE, // object will catch alight if burnt (ie fire damage)
|
||||
// v0 = how long it will burn for
|
||||
// text (optional) = what it will convert to
|
||||
// instead of just being set alight
|
||||
F_CANGETWET, // object will get F_WET if hit by water
|
||||
// v0 = enum WETNESS. v1 = how long
|
||||
F_WATERPROOF, // object doesn't get wet. note: overrides CANGETWET!
|
||||
F_WET, // object is wet
|
||||
F_RUSTED, // object is rusty
|
||||
// v0 = enum RUSTINESS.
|
||||
|
@ -1378,6 +1510,9 @@ enum FLAG {
|
|||
F_IDENTIFIED, // whether this object is fully identified
|
||||
// bad flags
|
||||
F_WALKDAM, // val0 = damtype, text = dam per sec
|
||||
F_WALKDAMBP, // v0 = bodypart, v1 = damtype, text = dam per sec
|
||||
// if v2 == FALLTHRU, damage falls through to lf if
|
||||
// no armour is there.
|
||||
// abilities
|
||||
F_NEEDSGRAB, // this ability needs to to grab someone first.
|
||||
F_NOANNOUNCE, // don't announce when you gain/lose this ability
|
||||
|
@ -1409,6 +1544,7 @@ enum FLAG {
|
|||
// lifeform flags / lf flags
|
||||
F_DEBUG, // debugging enabled
|
||||
F_ACCURACYMOD, // modify your accuracy by val0
|
||||
F_VEGETARIAN, // this lf will not eat meat.
|
||||
F_SHIELDPENALTY, // lower your accuracy by val0 due to a cumbersome
|
||||
// shield
|
||||
F_LEVRACE, // at level v0, this race is promoted to race v1
|
||||
|
@ -1430,6 +1566,8 @@ enum FLAG {
|
|||
F_STARTOBCLASS, // val0 = %chance of starting with obclass val1
|
||||
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
|
||||
F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS)
|
||||
F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will
|
||||
// start off hidden
|
||||
F_CORPSETYPE, // text field specifies what corpse obtype to leave
|
||||
F_MYCORPSE, // text field contains obid of my corpse.
|
||||
// (for ghosts)
|
||||
|
@ -1444,7 +1582,7 @@ enum FLAG {
|
|||
// (text is a long)
|
||||
// ABILITY/SPELL FLAGS / ability flags / spell flags
|
||||
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
|
||||
F_BOOSTSPELL, // v0 is active boost spell
|
||||
F_BOOSTSPELL, // v0 is active boost spell, v1 is ongoing mpcost, v2 is power
|
||||
F_SWOOPRANGE, // v0 = how far a flying creature can swoop
|
||||
// MONSTER AI FLAGS
|
||||
F_XPVAL, // force xp val for killing this lf to v0
|
||||
|
@ -1466,7 +1604,10 @@ enum FLAG {
|
|||
F_FLEEONHPPCT, // lf will run away if its hp drop to v0% or lower
|
||||
F_NOFLEE, // lf will not run away
|
||||
F_TARGET, // lf will attack lfid v0. lastknown x/y is v1/v2
|
||||
F_IGNORECELL, // won't accept targetcells of v0=x v1=y
|
||||
// this is cleared at start of turn.
|
||||
F_TARGETCELL, // lf will go towards this place. val0=x,val1=y
|
||||
// optional: v2 = mr_lf or mr_ob. text=lf or ob id.
|
||||
F_STABBEDBY, // lf has been stabbed by lfid v0. can't be stabbed
|
||||
// by them again until they go out of sight.
|
||||
F_FLEEFROM, // lf will run away from this lf id
|
||||
|
@ -1479,6 +1620,8 @@ enum FLAG {
|
|||
// text is "verb^noun"
|
||||
// eg. "shouts^a shout"
|
||||
F_SPELLCASTTEXT, // text is announcement for spellcast
|
||||
// if text is empty, then don't announce
|
||||
// this lf's spell casting at all.
|
||||
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
||||
F_BEHEADED, // use special corpse drop code
|
||||
F_SILENTMOVE, // lf makes no noise when walking/flying
|
||||
|
@ -1523,6 +1666,7 @@ enum FLAG {
|
|||
// INTRINSICS
|
||||
F_MAGICARMOUR,// armour is magically boosted. f->text is the description
|
||||
// ie 'magic armour', 'force field'
|
||||
// v0 is power left.
|
||||
F_ASLEEP, // is asleep
|
||||
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
|
||||
F_BLIND, // cannot see anything
|
||||
|
@ -1557,6 +1701,8 @@ enum FLAG {
|
|||
F_EXTRAMP, // lf has +v0 % extra maxmp
|
||||
F_FLYING, // lf is flying
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMETAB, // hunger counter increases faster, poison cures faster.
|
||||
// v0 is multiplier.
|
||||
F_FASTMOVE, // modifier for move speed
|
||||
F_FASTACTMOVE, // modifier for action and move speed
|
||||
F_POISONED, // has poisoning. v0 = poison type,
|
||||
|
@ -1573,6 +1719,7 @@ enum FLAG {
|
|||
// (bypasses armour)
|
||||
F_GRAVBOOSTED,// cannot walk or throw stuff
|
||||
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
|
||||
// if text not set, default dam is 1d2
|
||||
F_PARALYZED,// cannot do anything
|
||||
F_FROZEN, // made of ice
|
||||
F_LEVITATING, // like flying but uncontrolled
|
||||
|
@ -1655,6 +1802,13 @@ enum FLAG {
|
|||
F_NULL = -1
|
||||
};
|
||||
|
||||
// move reasons
|
||||
enum MOVEREASON {
|
||||
MR_OTHER,
|
||||
MR_LF,
|
||||
MR_OB,
|
||||
};
|
||||
|
||||
|
||||
// hunger levels
|
||||
enum HUNGER {
|
||||
|
@ -1678,6 +1832,8 @@ enum HUNGER {
|
|||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
|
||||
#define FALLTHRU (-8765)
|
||||
|
||||
//#define B_TEMP (-1)
|
||||
//#define B_PERM (-2)
|
||||
//#define B_NOT (-3)
|
||||
|
@ -1797,6 +1953,7 @@ enum ERROR {
|
|||
E_DRUNK = 47,
|
||||
//
|
||||
E_NOBP = 48,
|
||||
E_VEGETARIAN = 49,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1908,9 +2065,18 @@ typedef struct celltype_s {
|
|||
|
||||
} celltype_t;
|
||||
|
||||
typedef struct raceclass_s {
|
||||
enum RACECLASS id;
|
||||
char *name;
|
||||
char *pluralname;
|
||||
enum SKILL skill;
|
||||
struct raceclass_s *next, *prev;
|
||||
} raceclass_t;
|
||||
|
||||
typedef struct race_s {
|
||||
enum RACE id;
|
||||
enum RACE baseid;
|
||||
struct raceclass_s *raceclass;
|
||||
struct material_s *material;
|
||||
char *name;
|
||||
struct glyph_s glyph;
|
||||
|
@ -1962,7 +2128,6 @@ typedef struct lifeform_s {
|
|||
int born;
|
||||
|
||||
// for ai movement - don't need to save.
|
||||
struct cell_s *ignorecell;
|
||||
|
||||
struct cell_s *cell;
|
||||
struct lifeform_s *next, *prev;
|
||||
|
@ -2010,59 +2175,6 @@ typedef struct material_s {
|
|||
} material_t;
|
||||
|
||||
|
||||
enum SKILL {
|
||||
SK_NONE = 0,
|
||||
SK_ARMOUR = 1,
|
||||
SK_ATHLETICS,
|
||||
SK_BACKSTAB,
|
||||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_MAGITEMUSAGE,
|
||||
SK_RESEARCH,
|
||||
SK_SHIELDS,
|
||||
SK_SPELLCASTING,
|
||||
SK_SPOTHIDDEN,
|
||||
SK_STEALTH,
|
||||
SK_TECHUSAGE,
|
||||
// weaponry
|
||||
SK_AXES,
|
||||
SK_CLUBS,
|
||||
SK_LONGBLADES,
|
||||
SK_POLEARMS,
|
||||
SK_SHORTBLADES,
|
||||
SK_STAVES,
|
||||
SK_UNARMED,
|
||||
// spell schools
|
||||
SK_SS_ALLOMANCY,
|
||||
SK_SS_AIR,
|
||||
SK_SS_DEATH,
|
||||
SK_SS_DIVINATION,
|
||||
SK_SS_EARTH,
|
||||
SK_SS_FIRE,
|
||||
SK_SS_ICE,
|
||||
SK_SS_GRAVITY,
|
||||
SK_SS_LIFE,
|
||||
SK_SS_MODIFICATION,
|
||||
SK_SS_MENTAL,
|
||||
SK_SS_SUMMONING,
|
||||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 35
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
PR_INEPT = 0,
|
||||
PR_NOVICE = 1,
|
||||
PR_BEGINNER = 2,
|
||||
PR_ADEPT = 3,
|
||||
PR_SKILLED = 4,
|
||||
PR_EXPERT = 5,
|
||||
PR_MASTER = 6,
|
||||
};
|
||||
|
||||
|
||||
typedef struct skill_s {
|
||||
enum SKILL id;
|
||||
char *name;
|
||||
|
|
|
@ -9,3 +9,5 @@ objects.c:
|
|||
lf.c:
|
||||
add addskill()
|
||||
|
||||
|
||||
if it is a lroe skill, update isloreskill()
|
||||
|
|
10
flag.c
10
flag.c
|
@ -395,7 +395,17 @@ void killflagpile(flagpile_t *fp) {
|
|||
|
||||
void timeeffectsflag(flag_t *f, int howlong) {
|
||||
if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) {
|
||||
// special case - fast metabolism speeds up poison too.
|
||||
if (f->id == F_POISONED) {
|
||||
int multiplier;
|
||||
sumflags(f->pile, F_FASTMETAB, &multiplier, NULL, NULL);
|
||||
if (multiplier > 0) {
|
||||
howlong *= multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
f->lifetime -= howlong;
|
||||
|
||||
if (f->lifetime <= 0) {
|
||||
killflag(f);
|
||||
return;
|
||||
|
|
442
io.c
442
io.c
|
@ -382,6 +382,8 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
int valid = B_FALSE;
|
||||
if ((targettype & TT_MONSTER) && haslf(c) && cansee(player, c->lf) && (c->lf->controller != C_PLAYER)) {
|
||||
valid = B_TRUE;
|
||||
} else if ((targettype & TT_ALLY) && haslf(c) && cansee(player, c->lf) && areallies(c->lf, player)) {
|
||||
valid = B_TRUE;
|
||||
} else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) {
|
||||
valid = B_TRUE;
|
||||
} else if ((targettype & TT_OBJECT) && hasobject(c)) {
|
||||
|
@ -443,7 +445,7 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
if (c->lf) {
|
||||
if (cansee(player, c->lf)) {
|
||||
flag_t *f;
|
||||
object_t *wep;
|
||||
object_t *wep,*o;
|
||||
char extrainfo[BUFLEN];
|
||||
strcpy(extrainfo, "");
|
||||
getlfnamea(c->lf, buf);
|
||||
|
@ -488,8 +490,47 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "asleep");
|
||||
}
|
||||
|
||||
if ((getallegiance(c->lf) == AL_HOSTILE) &&
|
||||
(getlorelevel(player, c->lf->race->raceclass->id) >= PR_ADEPT)) {
|
||||
char dangerbuf[BUFLEN];
|
||||
float rating;
|
||||
rating = comparelfs(player, c->lf);
|
||||
if (rating >= 4) {
|
||||
sprintf(dangerbuf, "trivial");
|
||||
} else if (rating >= 3) {
|
||||
sprintf(dangerbuf, "very easy");
|
||||
} else if (rating >= 2) {
|
||||
sprintf(dangerbuf, "easy");
|
||||
} else if (rating >= 1) {
|
||||
sprintf(dangerbuf, "average");
|
||||
} else if (rating >= 0.5) {
|
||||
sprintf(dangerbuf, "challenging");
|
||||
} else if (rating >= 0.25) {
|
||||
sprintf(dangerbuf, "formidable");
|
||||
} else if (rating >= 0.125) {
|
||||
sprintf(dangerbuf, "dangerous");
|
||||
} else {
|
||||
sprintf(dangerbuf, "very dangerous");
|
||||
}
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, dangerbuf);
|
||||
}
|
||||
|
||||
o = hasobwithflag(c->obpile, F_RESTRICTMOVEMENT);
|
||||
if (o) {
|
||||
char buf2[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
getobname(o, obname, o->amt);
|
||||
sprintf(buf2, "stuck in %s", obname);
|
||||
strcat(extrainfo, buf2);
|
||||
}
|
||||
// hp
|
||||
if (isgenius(player) || (getseenlfconditioncutoff(player) == C_HEALTHY) ) {
|
||||
if (isgenius(player) || (getseenlfconditioncutoff(player) == C_HEALTHY) ||
|
||||
(getlorelevel(player, c->lf->race->raceclass->id) >= PR_ADEPT)
|
||||
) {
|
||||
char buf2[BUFLEN];
|
||||
// show actual hp
|
||||
sprintf(buf2, "hp %d/%d",c->lf->hp, c->lf->maxhp);
|
||||
|
@ -505,6 +546,7 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
wep = getweapon(c->lf);
|
||||
if (wep && (c->lf->race->id != R_DANCINGWEAPON)) {
|
||||
object_t *secwep;
|
||||
|
@ -957,6 +999,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s",lfname, isplayer(lf) ? "feel accelerated!" : "looks accelerated!");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FASTMETAB:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel ravenous!");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_FASTMOVE:
|
||||
msg("%s %s faster.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1240,6 +1288,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
char buf[BUFLEN];
|
||||
getlfname(lf2, buf);
|
||||
msg("%s break%s free of %s%s control!",lfname, isplayer(lf) ? "" : "s", buf,getpossessive(buf));
|
||||
if (isplayer(lf2)) {
|
||||
more();
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -1299,6 +1350,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s",lfname, isplayer(lf) ? "are no longer accelerated." : "is no longer accelerated.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FASTMETAB:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("Your metabolic rate has returned to normal.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_FASTMOVE:
|
||||
msg("%s %s slower.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1581,6 +1638,7 @@ int announceobflaggain(object_t *o, flag_t *f) {
|
|||
int donesomething = B_FALSE;
|
||||
char obname[BUFLEN];
|
||||
char prefix[BUFLEN];
|
||||
int wantpremods = B_TRUE;
|
||||
cell_t *loc;
|
||||
|
||||
loc = getoblocation(o);
|
||||
|
@ -1590,7 +1648,14 @@ int announceobflaggain(object_t *o, flag_t *f) {
|
|||
if (!haslos(player, loc)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE);
|
||||
|
||||
|
||||
if (f->id == F_ONFIRE) {
|
||||
// don't want "the flaming sword catches on fire"
|
||||
wantpremods = B_FALSE;
|
||||
}
|
||||
|
||||
real_getobname(o, obname, o->amt, wantpremods, B_FALSE, B_TRUE, B_TRUE);
|
||||
|
||||
if (o->pile->owner) {
|
||||
if (isplayer(o->pile->owner)) {
|
||||
|
@ -1608,8 +1673,6 @@ int announceobflaggain(object_t *o, flag_t *f) {
|
|||
switch (f->id) {
|
||||
case F_ONFIRE:
|
||||
donesomething = B_TRUE;
|
||||
// don't want "the flaming sword catches on fire"
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_TRUE);
|
||||
if (o->birthtime != curtime) msg("%s catch%s on fire.",prefix, (o->amt == 1) ? "es" : "");
|
||||
break;
|
||||
case F_PRODUCESLIGHT:
|
||||
|
@ -1626,6 +1689,7 @@ void announceobflagloss(object_t *o, flag_t *f) {
|
|||
char obname[BUFLEN];
|
||||
char prefix[BUFLEN];
|
||||
char isare[BUFLEN];
|
||||
char *temp;
|
||||
cell_t *loc;
|
||||
|
||||
loc = getoblocation(o);
|
||||
|
@ -1657,7 +1721,12 @@ void announceobflagloss(object_t *o, flag_t *f) {
|
|||
|
||||
switch (f->id) {
|
||||
case F_ONFIRE:
|
||||
msg("%s %s no longer on fire.",prefix,isare);
|
||||
// replace "the flaming xxx is no longer on fire"
|
||||
// with "the xxx is no longer on fire"
|
||||
temp = strdup(prefix);
|
||||
temp = strrep(temp, "flaming ","",NULL);
|
||||
msg("%s %s no longer on fire.",temp,isare);
|
||||
free(temp);
|
||||
break;
|
||||
case F_PRODUCESLIGHT:
|
||||
msg("%s %s no longer glowing.",prefix,isare);
|
||||
|
@ -2544,9 +2613,11 @@ void describeob(object_t *o) {
|
|||
}
|
||||
|
||||
|
||||
// now special flags...
|
||||
// skip line
|
||||
y++;
|
||||
|
||||
|
||||
// physical properties
|
||||
f = hasflag(o->flags, F_MASTERWORK);
|
||||
if (f && f->known) {
|
||||
mvwprintw(mainwin, y, 0, "It is extremely well crafted.");
|
||||
|
@ -2569,17 +2640,22 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_WET);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It is wet.");
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_RUSTED);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It is rusty.");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_WATERPROOF);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It is waterproof.");
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_WET);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It is wet.");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_ACTIVATED);
|
||||
if (f) {
|
||||
|
@ -2650,6 +2726,9 @@ void describeob(object_t *o) {
|
|||
case F_FASTACT:
|
||||
mvwprintw(mainwin, y, 0, "%s will speed up your actions.", buf); y++;
|
||||
break;
|
||||
case F_FASTMETAB:
|
||||
mvwprintw(mainwin, y, 0, "%s will increase your metabolic rate.", buf); y++;
|
||||
break;
|
||||
case F_FASTMOVE:
|
||||
mvwprintw(mainwin, y, 0, "%s will speed up your movement.", buf); y++;
|
||||
break;
|
||||
|
@ -2796,13 +2875,39 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
|
||||
// requirements
|
||||
i = B_FALSE;
|
||||
for (f = o->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_ATTREQ) {
|
||||
int usable = B_TRUE;
|
||||
if (!meetsattreq(player, f, o)) {
|
||||
usable = B_FALSE;
|
||||
}
|
||||
if (!usable) setcol(mainwin, C_RED);
|
||||
mvwprintw(mainwin, y, 0, "It requires at least %d %s to use.", f->val[1], getattrname(f->val[0]));
|
||||
y++;
|
||||
if (!usable) unsetcol(mainwin, C_RED);
|
||||
i = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// blank line
|
||||
y++;
|
||||
|
||||
|
||||
// skill type?
|
||||
f = hasflag(o->flags, F_USESSKILL);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It falls into the '%s' category (your skill: %s).",getskillname(f->val[0]),
|
||||
getskilllevelname(getskill(player, f->val[0])) );
|
||||
enum SKILLLEVEL slev;
|
||||
enum COLOUR col;
|
||||
slev = getskill(player, f->val[0]);
|
||||
mvwprintw(mainwin, y, 0, "It falls into the '%s' category (your skill: ",getskillname(f->val[0]));
|
||||
col = getskilllevelcolour(slev);
|
||||
setcol(mainwin, col);
|
||||
wprintw(mainwin, "%s", getskilllevelname(getskill(player, f->val[0])) );
|
||||
unsetcol(mainwin, col);
|
||||
wprintw(mainwin, ")");
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -2839,7 +2944,6 @@ void describeob(object_t *o) {
|
|||
|
||||
void describespell(objecttype_t *ot) {
|
||||
char buf[BUFLEN];
|
||||
int y;
|
||||
flag_t *f;
|
||||
int i;
|
||||
int power;
|
||||
|
@ -2851,36 +2955,31 @@ void describespell(objecttype_t *ot) {
|
|||
capitalise(buf);
|
||||
mvwprintw(mainwin, 0, 0, buf);
|
||||
|
||||
sprintf(buf, "%s",ot->desc);
|
||||
mvwprintw(mainwin, 2, 0, buf);
|
||||
mvwprintw(mainwin, 2, 0,"%s\n\n", ot->desc);
|
||||
|
||||
|
||||
// properties
|
||||
y = 5;
|
||||
f = hasflag(ot->flags, F_SPELLLEVEL);
|
||||
if (f) {
|
||||
flag_t *sf;
|
||||
sf = hasflag(ot->flags, F_SPELLSCHOOL);
|
||||
assert(sf);
|
||||
mvwprintw(mainwin, y, 0, "It is a level %d %s spell.",f->val[0], getschoolname(sf->val[0]));
|
||||
y++;
|
||||
wprintw(mainwin, "It is a level %d %s spell.\n",f->val[0], getschoolname(sf->val[0]));
|
||||
}
|
||||
|
||||
i = getmpcost(NULL, ot->id);
|
||||
if (i > 0) {
|
||||
if (hasflag(ot->flags, F_ONGOING)) {
|
||||
mvwprintw(mainwin, y, 0, "It takes %d MP to keep active - this is an ongoing cost.",i);
|
||||
wprintw(mainwin, "It takes %d MP to keep active - this is an ongoing cost.\n",i);
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, "It costs %d MP to cast.",i);
|
||||
wprintw(mainwin, "It costs %d MP to cast.\n",i);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
y++;
|
||||
wprintw(mainwin, "\n");
|
||||
|
||||
power = getspellpower(player, ot->id);
|
||||
mvwprintw(mainwin, y, 0, "You can cast it at power level %d (maximum %d).",power, getspellmaxpower(ot->id));
|
||||
y++;
|
||||
wprintw(mainwin, "You can cast it at power level %d (maximum %d).\n",power, getspellmaxpower(ot->id));
|
||||
|
||||
wrefresh(mainwin);
|
||||
|
||||
|
@ -3044,7 +3143,7 @@ void docomms(void) {
|
|||
// find adjacent cell
|
||||
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
aigoto(lf, c, AI_FOLLOWTIME);
|
||||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
|
@ -3227,7 +3326,7 @@ void doeat(obpile_t *op) {
|
|||
|
||||
// edible objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
if (isedible(o)) {
|
||||
if (caneat(player, o)) {
|
||||
getobname(o, obname, o->amt);
|
||||
sprintf(buf, "There %s %s here. Eat %s",
|
||||
(o->amt == 1) ? "is" : "are",
|
||||
|
@ -3491,6 +3590,24 @@ void dolook(cell_t *where) {
|
|||
char buf[BUFLEN];
|
||||
char seeverb[BUFLEN];
|
||||
int seensomething = B_FALSE;
|
||||
object_t *o,*firstob = NULL;
|
||||
flag_t *f;
|
||||
|
||||
// first announce "there is xxx" objects
|
||||
// (also count objects without this flag)
|
||||
numobs = 0;
|
||||
for (o = where->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_THEREISHERE);
|
||||
if (f) {
|
||||
// doens't matter if you're blind
|
||||
getobname(o, buf, o->amt);
|
||||
msg("There is %s here%c", buf, f->text[0]);
|
||||
seensomething = B_TRUE;
|
||||
} else {
|
||||
if (!numobs) firstob = o;
|
||||
numobs++;
|
||||
}
|
||||
}
|
||||
|
||||
//if (isblind(player)) {
|
||||
if (!haslos(player, player->cell)) {
|
||||
|
@ -3499,11 +3616,12 @@ void dolook(cell_t *where) {
|
|||
strcpy(seeverb, "see");
|
||||
}
|
||||
|
||||
numobs = countobs(where->obpile);
|
||||
if (numobs > 0) {
|
||||
if (numobs == 1) {
|
||||
getobname(where->obpile->first, buf, where->obpile->first->amt);
|
||||
if (!hasflag(firstob->flags, F_THEREISHERE)) {
|
||||
getobname(firstob, buf, firstob->amt);
|
||||
msg("You %s %s here.", seeverb, buf);
|
||||
}
|
||||
} else if ((numobs > 1) && (numobs <= 3)) {
|
||||
msg("You %s a few objects here.", seeverb);
|
||||
} else if ((numobs > 3) && (numobs <= 6)) {
|
||||
|
@ -3514,8 +3632,6 @@ void dolook(cell_t *where) {
|
|||
seensomething = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// writing here?
|
||||
if (where->writing && !isblind(player)) {
|
||||
msg("There is a magical inscription here:");
|
||||
|
@ -3523,7 +3639,6 @@ void dolook(cell_t *where) {
|
|||
seensomething = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (!seensomething) {
|
||||
// just clear the message buffer
|
||||
//clearmsg();
|
||||
|
@ -3549,7 +3664,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
|||
int validspell[MAXCANDIDATES];
|
||||
int deactspell[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
int i,n;
|
||||
int i,n,lev;
|
||||
enum SPELLSCHOOL lastschool;
|
||||
objecttype_t *ot;
|
||||
|
||||
|
@ -3559,15 +3674,22 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
|||
if ((wantschool != SS_NONE) && (i != wantschool)) {
|
||||
continue;
|
||||
}
|
||||
// only god gets divine ones
|
||||
if ((i == SS_DIVINE) && !hasjob(lf, J_GOD)) {
|
||||
continue;
|
||||
}
|
||||
// we can't cast spells from this school?
|
||||
if (getschoolskill(i) != SK_NONE) {
|
||||
if (!getskill(lf, getschoolskill(i))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (lev = 0; lev <= MAXSPELLLEV; lev++) {
|
||||
// get list of spells/abilities we can cast at will
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if ((ot->obclass->id == OC_SPELL) || (ot->obclass->id == OC_ABILITY)) {
|
||||
// doesn't match the current level?
|
||||
if (getspelllevel(ot->id) == lev) {
|
||||
f = lfhasflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
|
||||
if (!wantunknown && f) {
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) {
|
||||
|
@ -3590,14 +3712,14 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
|||
nposs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end if level ok
|
||||
} // end if spell/ability
|
||||
} // end foreach objecttype
|
||||
|
||||
if (!lfhasflag(lf, F_NOSPELLS)) {
|
||||
// get list of spells we can cast using mp
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if (ot->obclass->id == OC_SPELL) { // is it a spell?
|
||||
if ((ot->obclass->id == OC_SPELL) && (getspelllevel(ot->id) == lev)) { // is it a spell?
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) { // from the current school?
|
||||
// not using 'cancast' here because we want to list spells
|
||||
// even if we don't have enough mp
|
||||
|
@ -3644,6 +3766,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
|||
}
|
||||
}
|
||||
}
|
||||
} // end foreach spell level
|
||||
} // end foreach spell school
|
||||
|
||||
|
||||
|
@ -3661,16 +3784,16 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
|||
lastschool = SS_LAST;
|
||||
for (i = 0; i < nposs; i++) {
|
||||
int power;
|
||||
enum SPELLSCHOOL thisschool = SS_NONE;
|
||||
ot = findot(poss[i]);
|
||||
assert(ot);
|
||||
|
||||
power = getspellpower(lf, poss[i]);
|
||||
|
||||
// heading
|
||||
f = hasflag(ot->flags, F_SPELLSCHOOL);
|
||||
assert(f);
|
||||
if (f->val[0] != lastschool) {
|
||||
lastschool = f->val[0];
|
||||
thisschool = getspellschoolknown(lf, poss[i]);
|
||||
if (thisschool != lastschool) {
|
||||
lastschool = thisschool;
|
||||
addheading(pr, getschoolname(lastschool));
|
||||
}
|
||||
|
||||
|
@ -4322,7 +4445,7 @@ int dotakeoff(obpile_t *op) {
|
|||
int rv = B_TRUE;
|
||||
|
||||
// ask which object to read
|
||||
o = askobject(op, "Take off what", NULL, AO_EQUIPPEDARMOUR );
|
||||
o = askobject(op, "Take off what", NULL, AO_EQUIPPEDNONWEAPON );
|
||||
if (o) {
|
||||
if (isarmour(o)) {
|
||||
f = hasflag(o->flags, F_EQUIPPED);
|
||||
|
@ -5086,6 +5209,24 @@ int getkey(void) {
|
|||
return keycodetokey(key_code);
|
||||
}
|
||||
|
||||
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev) {
|
||||
switch (slev) {
|
||||
case PR_INEPT:
|
||||
return C_RED;
|
||||
case PR_BEGINNER:
|
||||
case PR_NOVICE:
|
||||
return C_BROWN;
|
||||
case PR_ADEPT:
|
||||
return C_GREEN;
|
||||
case PR_SKILLED:
|
||||
case PR_EXPERT:
|
||||
return C_BOLDGREEN;
|
||||
case PR_MASTER:
|
||||
return C_BOLDCYAN;
|
||||
}
|
||||
return C_GREY;
|
||||
}
|
||||
|
||||
void handleinput(void) {
|
||||
int ch;
|
||||
//char buf[BUFLEN];
|
||||
|
@ -5103,8 +5244,10 @@ void handleinput(void) {
|
|||
object_t *o;
|
||||
|
||||
|
||||
// certain objects will stop us from running.
|
||||
for (o = player->cell->obpile->first ; o ; o = o->next) {
|
||||
if (!hasflag(o->flags, F_NOPICKUP)) {
|
||||
if (!hasflag(o->flags, F_NOPICKUP) ||
|
||||
hasflag(o->flags, F_CLIMBABLE) ) {
|
||||
hasgettableobs = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -5504,7 +5647,6 @@ void warn(char *format, ... ) {
|
|||
// like msg, but interrupts rest ect
|
||||
interrupt(player);
|
||||
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf( buf, format, args );
|
||||
va_end(args);
|
||||
|
@ -6012,16 +6154,26 @@ void showlfarmour(lifeform_t *lf) {
|
|||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
||||
char rhs[BUFLEN];
|
||||
// default
|
||||
sprintf(rhs, "-");
|
||||
strcpy(rhs, "");
|
||||
|
||||
if (!lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
||||
object_t *outerob;
|
||||
sprintf(buf, "%15s:%3s",getbodypartname(bp), " ");
|
||||
o = hasobwithflagval(lf->pack, F_EQUIPPED, bp, NA, NA, NULL);
|
||||
o = getequippedob(lf->pack, bp);
|
||||
outerob = getouterequippedob(lf, bp);
|
||||
if (o) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
strcpy(rhs, obname);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (outerob && (outerob != o)) {
|
||||
char outerobname[BUFLEN];
|
||||
getobname(outerob, outerobname, outerob->amt);
|
||||
if (strlen(rhs)) strcat(rhs, " ");
|
||||
strcat(rhs, "(covered) ");
|
||||
}
|
||||
if (!strlen(rhs)) {
|
||||
strcpy(rhs, "-");
|
||||
}
|
||||
|
||||
|
@ -6088,18 +6240,34 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char prompt[BUFLEN];
|
||||
char cmdchars[BUFLEN];
|
||||
int done = B_FALSE;
|
||||
enum SKILLLEVEL lorelev;
|
||||
enum COLOUR lorecol;
|
||||
|
||||
h = getmaxy(mainwin);
|
||||
|
||||
|
||||
// determine knowledge about this monster
|
||||
lorelev = getlorelevel(player, lf->race->raceclass->id);
|
||||
if (isplayer(lf)) {
|
||||
lorecol = C_GREY; // ie. no colour
|
||||
} else if (lorelev == PR_MASTER) {
|
||||
lorecol = C_GREY; // ie. no colour
|
||||
} else {
|
||||
lorecol = C_BROWN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// override showall sometimes...
|
||||
// need 'player == lf' to cope with mind scans
|
||||
// where we update the player pointer, but don't
|
||||
// change the target's '->controller' setting (meaning
|
||||
// that isplayer(target) still returns false).
|
||||
if (isplayer(lf) || isgenius(player) || (player == lf)) {
|
||||
if (isplayer(lf) || isgenius(player) || (player == lf) || (lorelev >= PR_MASTER)) {
|
||||
showall = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (showall) {
|
||||
sprintf(prompt, "[@=stats S=skills/abilities M=magic E=effects %sESC=quit]", isplayer(lf) ? "" : "I=items " );
|
||||
sprintf(cmdchars, "@asme%s",isplayer(lf) ? "" : "i");
|
||||
|
@ -6140,7 +6308,8 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
j = getjob(lf);
|
||||
if (j) {
|
||||
mvwprintw(mainwin, y, 0, ftext, "Job");
|
||||
wprintw(mainwin, "%-20s", j->name); y++;
|
||||
sprintf(buf, "Level %d %s", lf->level, j->name);
|
||||
wprintw(mainwin, "%-20s", buf); y++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -6159,9 +6328,13 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
|
||||
|
||||
if (showall || (getseenlfconditioncutoff(player) == C_HEALTHY)) {
|
||||
if (showall ||
|
||||
(getseenlfconditioncutoff(player) == C_HEALTHY) ||
|
||||
(lorelev >= PR_ADEPT)) {
|
||||
if (lorelev >= PR_ADEPT) setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, ftext, "Hit Points");
|
||||
wprintw(mainwin, "%d / %d", lf->hp , lf->maxhp); y++;
|
||||
if (lorelev >= PR_ADEPT) unsetcol(mainwin, lorecol);
|
||||
} else {
|
||||
char hpinfo[BUFLEN];
|
||||
sprintf(hpinfo, "%s",getseenlfconditionname(lf, player));
|
||||
|
@ -6222,14 +6395,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (str != lf->baseatt[A_STR]) strcat(buf, "*");
|
||||
mvwprintw(mainwin, y, 0, ftext, "STR");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
} else if (!isplayer(lf)) {
|
||||
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
|
||||
int str;
|
||||
// just show name
|
||||
str = getattr(lf, A_STR);
|
||||
getstrname(str, buf);
|
||||
if (str != lf->baseatt[A_STR]) strcat(buf, "*");
|
||||
setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, ftext, "STR");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
if (showall) {
|
||||
|
@ -6249,14 +6424,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (dex != lf->baseatt[A_DEX]) strcat(buf, "*");
|
||||
mvwprintw(mainwin, y, 0, ftext, "DEX");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
} else if (!isplayer(lf)) {
|
||||
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
|
||||
int dex;
|
||||
// just show name
|
||||
dex = getattr(lf, A_DEX);
|
||||
getdexname(dex, buf);
|
||||
if (dex != lf->baseatt[A_DEX]) strcat(buf, "*");
|
||||
setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, ftext, "DEX");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
if (showall) {
|
||||
|
@ -6268,14 +6445,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (iq != lf->baseatt[A_IQ]) strcat(buf, "*");
|
||||
mvwprintw(mainwin, y, 0, ftext, "IQ");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
} else if (!isplayer(lf)) {
|
||||
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
|
||||
int iq;
|
||||
// just show name
|
||||
iq = getattr(lf, A_IQ);
|
||||
getiqname(iq, buf);
|
||||
if (iq != lf->baseatt[A_IQ]) strcat(buf, "*");
|
||||
setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, ftext, "IQ");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
if (showall) {
|
||||
|
@ -6287,14 +6466,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (con != lf->baseatt[A_CON]) strcat(buf, "*");
|
||||
mvwprintw(mainwin, y, 0, ftext, "CON");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
} else if (!isplayer(lf)) {
|
||||
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
|
||||
int con;
|
||||
// just show name
|
||||
con = getattr(lf, A_CON);
|
||||
getconname(con, buf);
|
||||
if (con != lf->baseatt[A_CON]) strcat(buf, "*");
|
||||
setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, ftext, "CON");
|
||||
wprintw(mainwin, "%s", buf); y++;
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
//mvwprintw(mainwin, y, 0, ftext, "XP");
|
||||
|
@ -6357,6 +6538,14 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
acc = getlfaccuracy(lf, w);
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Wep.Accuracy");
|
||||
wprintw(mainwin, "%d%%", acc); y2++;
|
||||
|
||||
// attack speed
|
||||
speed = getattackspeed(lf);
|
||||
getspeedname(speed, buf);
|
||||
capitalise(buf);
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Attack Speed");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
}
|
||||
} else {
|
||||
// no damage
|
||||
|
@ -6386,10 +6575,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
ot = findot(f->val[0]);
|
||||
o = addob(op, ot->name);
|
||||
if (o) {
|
||||
char dambuf[BUFLEN];
|
||||
strcpy(dambuf, "");
|
||||
sprintf(buf, "%s", o->type->name);
|
||||
// damage
|
||||
if (showall) {
|
||||
char dambuf[BUFLEN];
|
||||
if (showall || (lorelev >= PR_BEGINNER)) {
|
||||
int mindam,maxdam;
|
||||
|
||||
getdamrange(f, &mindam, &maxdam);
|
||||
|
@ -6403,11 +6593,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (maxdam < 0) maxdam = 0;
|
||||
|
||||
sprintf(dambuf, " (%d-%d dmg)",(int)mindam,(int)maxdam);
|
||||
strcat(buf, dambuf);
|
||||
}
|
||||
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Innate Attack");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
wprintw(mainwin, "%s", buf);
|
||||
if (strlen(dambuf)) {
|
||||
if (lorelev >= PR_BEGINNER) setcol(mainwin, lorecol);
|
||||
wprintw(mainwin, "%s", dambuf);
|
||||
if (lorelev >= PR_BEGINNER) unsetcol(mainwin, lorecol);
|
||||
}
|
||||
y2++;
|
||||
|
||||
} // end if o
|
||||
} // end if fid == hasattack
|
||||
|
@ -6424,28 +6619,24 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
// skip line
|
||||
y2++;
|
||||
|
||||
// attack speed
|
||||
if (w || op->first) {
|
||||
speed = getattackspeed(lf);
|
||||
getspeedname(speed, buf);
|
||||
capitalise(buf);
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Attack Speed");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
}
|
||||
|
||||
killobpile(op);
|
||||
|
||||
y2++; // skip line
|
||||
|
||||
// ARMOUR STUFF
|
||||
if (showall) {
|
||||
if (showall || (lorelev >= PR_NOVICE)) {
|
||||
arating = getarmourrating(lf);
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Armour");
|
||||
|
||||
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
|
||||
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Armour Rating");
|
||||
if (arating > 0) {
|
||||
wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++;
|
||||
} else {
|
||||
wprintw(mainwin, "%d", arating); y2++;
|
||||
}
|
||||
if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
if (showall) {
|
||||
evasion = getevasion(lf);
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Evasion");
|
||||
wprintw(mainwin, "%d%%", evasion); y2++;
|
||||
|
@ -6488,8 +6679,77 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
|
||||
// back to first column
|
||||
// now show bottom information.
|
||||
if (y2 > y) {
|
||||
y = y2 + 1;
|
||||
} else {
|
||||
y++;
|
||||
}
|
||||
|
||||
// knowledge?
|
||||
if (lf != player) {
|
||||
char knowstring[BUFLEN];
|
||||
switch (lorelev ){
|
||||
case PR_NOVICE:
|
||||
strcpy(knowstring, "You have heard of this creature.");
|
||||
break;
|
||||
case PR_BEGINNER:
|
||||
strcpy(knowstring, "You know a little about this creature.");
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
strcpy(knowstring, "You are fairly knowledgable about this creature.");
|
||||
break;
|
||||
case PR_SKILLED:
|
||||
strcpy(knowstring, "You have studied this creature in depth.");
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
strcpy(knowstring, "You are an expert on this creature.");
|
||||
break;
|
||||
case PR_MASTER:
|
||||
strcpy(knowstring, "You are an absolute authority on this creature.");
|
||||
break;
|
||||
default:
|
||||
strcpy(knowstring, "");
|
||||
break;
|
||||
}
|
||||
|
||||
if (strlen(knowstring)) {
|
||||
setcol(mainwin, lorecol);
|
||||
mvwprintw(mainwin, y, 0, "%s", knowstring);
|
||||
unsetcol(mainwin, lorecol);
|
||||
y++;
|
||||
}
|
||||
|
||||
// extra info from lore?
|
||||
if (lorelev >= PR_ADEPT) {
|
||||
float rating;
|
||||
// get threat rating
|
||||
rating = comparelfs(player, lf);
|
||||
setcol(mainwin, lorecol);
|
||||
if (rating >= 4) {
|
||||
sprintf(buf, "It is not a threat.");
|
||||
} else if (rating >= 3) {
|
||||
sprintf(buf, "You could defeat it very easily.");
|
||||
} else if (rating >= 2) {
|
||||
sprintf(buf, "You could defeat it quite easily.");
|
||||
} else if (rating >= 1) {
|
||||
sprintf(buf, "It would present an average challenge.");
|
||||
} else if (rating >= 0.5) {
|
||||
sprintf(buf, "It would be challenging to defeat.");
|
||||
} else if (rating >= 0.25) {
|
||||
sprintf(buf, "It would present a formidable opponent.");
|
||||
} else if (rating >= 0.125) {
|
||||
sprintf(buf, "It is very dangerous to you.");
|
||||
} else {
|
||||
sprintf(buf, "It is EXTREMELY dangerous to you.");
|
||||
}
|
||||
//mvwprintw(mainwin, y, 0, "Threat rating: %0.1f",comparelfs(player, lf));
|
||||
mvwprintw(mainwin, y, 0, "%s", buf);
|
||||
unsetcol(mainwin, lorecol);
|
||||
y++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// obvious physical effects here.
|
||||
f = lfhasknownflag(lf, F_ASLEEP);
|
||||
|
@ -6875,6 +7135,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char powerbuf[BUFLEN];
|
||||
int power;
|
||||
int mpcost;
|
||||
int castable = B_TRUE;
|
||||
|
||||
// power
|
||||
power = getspellpower(lf, ot->id);
|
||||
|
@ -6907,10 +7168,15 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((mpcost > getmaxmp(lf)) || (power <= 0)) {
|
||||
castable = B_FALSE;
|
||||
}
|
||||
|
||||
getspellname(ot->id, lf, spellname);
|
||||
sprintf(buf, " %-4d%-26s%-15s%-13s%s",thislev, spellname, getschoolnameshort(getspellschool(ot->id)), powerbuf, mpbuf);
|
||||
if (!castable) setcol(mainwin, C_RED);
|
||||
sprintf(buf, " %-4d%-26s%-15s%-13s%s",thislev, spellname, getschoolnameshort(getspellschoolknown(lf, ot->id)), powerbuf, mpbuf);
|
||||
mvwprintw(mainwin, y, 0, "%s\n", buf);
|
||||
if (!castable) unsetcol(mainwin, C_RED);
|
||||
anyfound = B_TRUE;
|
||||
if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
|
@ -6925,6 +7191,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s cannot cast any spells.", you(lf));
|
||||
}
|
||||
} else if (mode == 'e') {
|
||||
int nfound = 0;
|
||||
x = 0; // override
|
||||
// down a line.
|
||||
centre(mainwin, y, "EFFECTS");
|
||||
|
@ -6945,6 +7212,26 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
// spells
|
||||
nfound = 0;
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_BOOSTSPELL) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(f->val[0]);
|
||||
if (sp) {
|
||||
if (nfound == 0) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s the following spells active:", you(lf),
|
||||
isplayer(lf) ? "have" : "has");
|
||||
y++;
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, " - %s", sp->name);
|
||||
y++;
|
||||
nfound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nfound) y++;
|
||||
|
||||
// obvious physical effects first.
|
||||
f = lfhasknownflag(lf, F_BEINGSTONED);
|
||||
if (f) {
|
||||
|
@ -6966,6 +7253,13 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
// flags which aren't really intrinsics
|
||||
if (lfhasflag(lf, F_VEGETARIAN)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s a vegetarian.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
|
||||
|
||||
// show intrinsics
|
||||
f = lfhasknownflag(lf, F_ATTRSET);
|
||||
if (f && (f->known)) {
|
||||
|
|
1
io.h
1
io.h
|
@ -74,6 +74,7 @@ int drop(object_t *o, int count);
|
|||
char getchoice(prompt_t *prompt);
|
||||
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
|
||||
int getkey(void);
|
||||
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev);
|
||||
void handleinput(void);
|
||||
void doheading(WINDOW *win, int *y, int x, char *what);
|
||||
void initgfx(void);
|
||||
|
|
16
lf.h
16
lf.h
|
@ -3,9 +3,11 @@
|
|||
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
|
||||
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
|
||||
job_t *addjob(enum JOB id, char *name);
|
||||
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat);
|
||||
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass);
|
||||
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
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);
|
||||
void autoskill(lifeform_t *lf);
|
||||
|
@ -30,10 +32,12 @@ int canweild(lifeform_t *lf, object_t *o);
|
|||
int cantakeoff(lifeform_t *lf, object_t *o);
|
||||
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell);
|
||||
void checkxp(enum RACE rid);
|
||||
float comparelfs(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int countmoney(lifeform_t *lf);
|
||||
int countnearbyallies(lifeform_t *lf);
|
||||
void debug(lifeform_t *lf);
|
||||
void die(lifeform_t *lf);
|
||||
void dumplev(void);
|
||||
void dumplf(void);
|
||||
void dumpxp(void);
|
||||
int eat(lifeform_t *lf, object_t *o);
|
||||
|
@ -46,6 +50,7 @@ job_t *findjobbyname(char *name);
|
|||
lifeform_t *findlf(map_t *m, int lfid);
|
||||
race_t *findrace(enum RACE id);
|
||||
race_t *findracebyname(char *name);
|
||||
raceclass_t *findraceclass(enum RACECLASS id);
|
||||
skill_t *findskill(enum SKILL id);
|
||||
skill_t *findskillbyname(char *name);
|
||||
enum SKILLLEVEL findskilllevbyname(char *name);
|
||||
|
@ -65,6 +70,7 @@ int getattackspeed(lifeform_t *lf);
|
|||
int getattpoints(lifeform_t *lf);
|
||||
int getattr(lifeform_t *lf, enum ATTRIB attr);
|
||||
int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
|
||||
int getavgdam(lifeform_t *lf, int forxp);
|
||||
int getevasion(lifeform_t *lf);
|
||||
object_t *getbestthrowmissile(lifeform_t *lf);
|
||||
object_t *getbestweapon(lifeform_t *lf);
|
||||
|
@ -78,6 +84,8 @@ lifeform_t *getguntarget(lifeform_t *lf);
|
|||
int getguntargetid(lifeform_t *lf);
|
||||
//int gethealtime(lifeform_t *lf);
|
||||
int gethearingrange(lifeform_t *lf);
|
||||
int gethidemodifier(lifeform_t *lf);
|
||||
int gethitdice(lifeform_t *lf);
|
||||
int gethppct(lifeform_t *lf);
|
||||
enum HUNGER gethungerlevel(int hunger);
|
||||
char * gethungername(enum HUNGER hunger, char *buf);
|
||||
|
@ -87,10 +95,12 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep);
|
|||
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
char *getlfconditionname(enum LFCONDITION cond);
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||
enum LFCONDITION getseenlfconditioncutoff(lifeform_t *lf);
|
||||
char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer);
|
||||
glyph_t *getlfglyph(lifeform_t *lf);
|
||||
enum MATERIAL getlfmaterial(lifeform_t *lf);
|
||||
enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid);
|
||||
float getmaxcarryweight(lifeform_t *lf);
|
||||
float getmaxliftweight(lifeform_t *lf);
|
||||
int getmaxmp(lifeform_t *lf);
|
||||
|
@ -113,6 +123,7 @@ char *getplayernamefull(char *buf);
|
|||
int getpoisondamchance(enum POISONTYPE ptype);
|
||||
char *getpoisondamverb(enum POISONTYPE ptype);
|
||||
char *getpoisonname(enum POISONTYPE ptype);
|
||||
int getraceclass(lifeform_t *lf);
|
||||
int getracerarity(enum RACE rid);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
//int getrandommonlevel(int depth);
|
||||
|
@ -169,6 +180,7 @@ int isgenius(lifeform_t *lf);
|
|||
int isimmobile(lifeform_t *lf);
|
||||
flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
|
||||
int isingunrange(lifeform_t *lf, cell_t *where);
|
||||
int isloreskill(enum SKILL skid);
|
||||
int ismaxedskill(lifeform_t *lf, enum SKILL skid);
|
||||
int ispeaceful(lifeform_t *lf);
|
||||
int ispetof(lifeform_t *lf, lifeform_t *owner);
|
||||
|
@ -188,8 +200,10 @@ void losemp(lifeform_t *lf, int amt);
|
|||
void makefriendly(lifeform_t *lf, int howlong);
|
||||
void makenauseated(lifeform_t *lf, int amt, int howlong);
|
||||
void makenoise(lifeform_t *lf, enum NOISETYPE nid);
|
||||
void makepeaceful(lifeform_t *lf);
|
||||
lifeform_t *makezombie(object_t *o);
|
||||
void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how);
|
||||
int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o);
|
||||
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
||||
void modhunger(lifeform_t *lf, int amt);
|
||||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
|
|
73
map.c
73
map.c
|
@ -22,6 +22,8 @@ extern glyph_t tempglyph;
|
|||
|
||||
extern enum OBCLASS sortorder[];
|
||||
|
||||
extern enum ERROR reason;
|
||||
|
||||
cell_t *addcell(map_t *m, int x, int y) {
|
||||
cell_t *cell;
|
||||
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
|
||||
|
@ -80,7 +82,8 @@ map_t *addmap(void) {
|
|||
}
|
||||
|
||||
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
||||
// when monsters are made during level generation, autogen will be true. otherwise false;
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen) {
|
||||
lifeform_t *lf = NULL;
|
||||
race_t *r;
|
||||
int db = B_FALSE;
|
||||
|
@ -116,7 +119,8 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
}
|
||||
}
|
||||
|
||||
if (lf->cell->map->beingcreated) {
|
||||
//if (lf->cell->map->beingcreated) {
|
||||
if (autogen) {
|
||||
// sometimes start off asleep in new maps
|
||||
if (!lfhasflag(lf, F_DEAF)) {
|
||||
// TODO: base this on the time, and whether monster is nocturnal
|
||||
|
@ -124,9 +128,19 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
f = lfhasflag(lf, F_STARTHIDDENPCT);
|
||||
if (f) {
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
// note: if we start off hidden, we have no hide penalty.
|
||||
// this is so we can have monsters which start hidden, but
|
||||
// don't have the 'hide' skill.
|
||||
addflag(lf->flags, F_HIDING, 0, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// appears in groups?
|
||||
if (autogen) {
|
||||
f = hasflag(lf->flags, F_NUMAPPEAR);
|
||||
if (f) {
|
||||
// override amount
|
||||
|
@ -155,8 +169,10 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// minons?
|
||||
if (autogen) {
|
||||
f = hasflag(lf->flags, F_MINIONS);
|
||||
if (f) {
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
|
@ -185,6 +201,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sometimes give the lf random objects (extra monsters through
|
||||
|
@ -228,7 +245,7 @@ void addrandomthing(cell_t *c, int obchance) {
|
|||
addrandomob(c);
|
||||
} else {
|
||||
// monster
|
||||
addmonster(c, R_RANDOM, B_TRUE, 1);
|
||||
addmonster(c, R_RANDOM, B_TRUE, 1, B_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,11 +471,14 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
|||
*g = *(getglyph(o));
|
||||
}
|
||||
// show dungeon features
|
||||
o = hasobofclass(c->obpile, OC_DFEATURE);
|
||||
if (o) {
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (o->type->obclass->id == OC_DFEATURE) {
|
||||
if (!issecretdoor(o)) {
|
||||
*g = *(getglyph(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1938,6 +1958,10 @@ int getobchance(int habitat) {
|
|||
}
|
||||
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) {
|
||||
return real_getrandomadjcell(c, wantempty, allowexpand, NULL);
|
||||
}
|
||||
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum OBTYPE *dontwantob) {
|
||||
int radius = 1;
|
||||
int x,y;
|
||||
cell_t *poss[MAXCANDIDATES];
|
||||
|
@ -1951,24 +1975,44 @@ cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) {
|
|||
for (x = c->x - radius ; x <= c->x + radius ; x++) {
|
||||
new = getcellat(c->map, x, y);
|
||||
if (new && (getcelldist(c,new) == radius) && haslof(c, new, LOF_WALLSTOP, NULL)) {
|
||||
enum OBTYPE *badoid;
|
||||
int ok = B_FALSE;
|
||||
numwithlof++;
|
||||
if (wantempty == WE_EMPTY) {
|
||||
// make sure it's empty
|
||||
if (isempty(new)) {
|
||||
poss[nposs++] = new;
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wantempty == WE_WALKABLE) {
|
||||
if (cellwalkable(NULL, new, NULL)) {
|
||||
poss[nposs++] = new;
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wantempty == WE_PORTAL) {
|
||||
if (cellwalkable(NULL, new, NULL) && !hasenterableobject(new) ) {
|
||||
if (!hasobwithflag(new->obpile, F_DOOR)) {
|
||||
poss[nposs++] = new;
|
||||
ok = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (wantempty == WE_NOTWALL) {
|
||||
if (!new->type->solid){
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
// always ok
|
||||
ok = B_TRUE;
|
||||
}
|
||||
|
||||
// obs we dont want?
|
||||
if (dontwantob) {
|
||||
for (badoid = dontwantob; (*badoid != OT_NONE) ; badoid++) {
|
||||
if (hasob(new->obpile, *badoid)) {
|
||||
ok = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
poss[nposs++] = new;
|
||||
}
|
||||
}
|
||||
|
@ -2079,16 +2123,19 @@ void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells) {
|
|||
}
|
||||
|
||||
// returns how slippery this cell is
|
||||
// if slipob is set, return the most slippery object in it.
|
||||
int getslipperyness(cell_t *c, object_t **slipob) {
|
||||
object_t *o;
|
||||
object_t *o,*bestob = NULL;
|
||||
int bestslip = 0;
|
||||
int totalslip = 0;
|
||||
if (slipob) *slipob = NULL;
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
int thisslip;
|
||||
sumflags(o->flags, F_SLIPPERY, &thisslip, NULL, NULL);
|
||||
if (thisslip > 0) {
|
||||
if (slipob && (*slipob == NULL)) {
|
||||
*slipob = o;
|
||||
if (thisslip > bestslip) {
|
||||
bestob = o;
|
||||
bestslip = thisslip;
|
||||
}
|
||||
}
|
||||
thisslip *= o->amt;
|
||||
|
@ -2097,6 +2144,10 @@ int getslipperyness(cell_t *c, object_t **slipob) {
|
|||
|
||||
totalslip *= 2;
|
||||
|
||||
if (slipob) {
|
||||
*slipob = bestob;
|
||||
}
|
||||
|
||||
return totalslip;
|
||||
}
|
||||
|
||||
|
|
3
map.h
3
map.h
|
@ -2,7 +2,7 @@
|
|||
|
||||
cell_t *addcell(map_t *map, int x, int y);
|
||||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen);
|
||||
void addrandomob(cell_t *c);
|
||||
void addrandomthing(cell_t *c, int obchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
|
@ -35,6 +35,7 @@ cell_t *getcellindir(cell_t *cell, int dir);
|
|||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||
int getobchance(int habitat);
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum OBTYPE *dontwantob);
|
||||
cell_t *getrandomcell(map_t *map);
|
||||
cell_t *getrandomcelloftype(map_t *map, int id);
|
||||
int getrandomdir(int dirtype);
|
||||
|
|
253
move.c
253
move.c
|
@ -550,8 +550,11 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype ) {
|
|||
|
||||
// IMPORTANT: don't modify lf's flagpile during this code!
|
||||
// particularly don't remove flags...
|
||||
void moveeffects(lifeform_t *lf) {
|
||||
|
||||
// returns TRUE if we displayed a message
|
||||
int moveeffects(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
int didmsg = B_FALSE;
|
||||
|
||||
if (isbleeding(lf)) {
|
||||
if (rnd(1,2) == 1) {
|
||||
|
@ -562,18 +565,29 @@ void moveeffects(lifeform_t *lf) {
|
|||
f = lfhasflag(lf, F_PAIN);
|
||||
if (f) {
|
||||
if (!isdrunk(lf)) {
|
||||
int dam;
|
||||
if (isplayer(lf)) {
|
||||
msg("Your body is wracked with pain!");
|
||||
didmsg = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s convulses in pain!",lfname);
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
losehp(lf, roll(f->text), f->val[0], NULL, "extreme pain");
|
||||
|
||||
if (strlen(f->text)) {
|
||||
dam = roll(f->text);
|
||||
} else {
|
||||
dam = roll("1d2");
|
||||
}
|
||||
losehp(lf, dam, f->val[0], NULL, "extreme pain");
|
||||
if (isdead(lf)) return didmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (isdead(lf)) return;
|
||||
|
||||
return didmsg;
|
||||
}
|
||||
|
||||
|
||||
|
@ -586,6 +600,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
flag_t *f;
|
||||
int changedlev = B_FALSE;
|
||||
int preroom = -1, postroom = -1;
|
||||
int prespeed = B_FALSE, postspeed = B_FALSE;
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
|
@ -594,8 +609,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
|
||||
// update current cell + room id
|
||||
lf->cell->lf = NULL;
|
||||
prespeed = getmovespeed(lf);
|
||||
preroom = lf->cell->roomid;
|
||||
lf->cell->lf = NULL;
|
||||
|
||||
|
||||
// if required, relink lifeform to new map
|
||||
if (newcell->map != lf->cell->map) {
|
||||
|
@ -613,6 +630,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
|
||||
// remember new room...
|
||||
postroom = lf->cell->roomid;
|
||||
postspeed = getmovespeed(lf);
|
||||
|
||||
// update new cell
|
||||
newcell->lf = lf;
|
||||
|
@ -622,7 +640,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
calclight(lf->cell->map);
|
||||
}
|
||||
|
||||
moveeffects(lf);
|
||||
didmsg = moveeffects(lf);
|
||||
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
|
@ -770,16 +788,20 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
}
|
||||
|
||||
// status bar
|
||||
if ((prespeed != postspeed) && isplayer(lf)) {
|
||||
statdirty = B_TRUE;
|
||||
}
|
||||
|
||||
return didmsg;
|
||||
}
|
||||
|
||||
// basically this is a warpper for 'movelf' which
|
||||
// does other game things like telling the player
|
||||
// what is here.
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
||||
char lfname[BUFLEN];
|
||||
int didmsg;
|
||||
int dontclearmsg = B_FALSE;
|
||||
int predark = B_FALSE,postdark = B_FALSE;
|
||||
|
||||
if (!onpurpose || !isplayer(lf)) {
|
||||
|
@ -1176,6 +1198,145 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// do pre-move checks like slipping on stuff in your current cell,
|
||||
// webs, etc.
|
||||
// cell can be null if you're using stairs.
|
||||
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
||||
object_t *o, *nexto;
|
||||
char buf[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
// check for cursed objects in new cell + animals
|
||||
// do this AFTER checking if we will move, so that
|
||||
// they will actually try the move and fail (this lets
|
||||
// the player find out about the cursed object).
|
||||
//
|
||||
// note however that if a monster is chasing a player (ie
|
||||
// has F_TARGET,player) then they will simply avoid the cursed
|
||||
// object rather than failing the movement.
|
||||
if (cell) {
|
||||
for (o = cell->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (!isplayer(lf)) {
|
||||
if ((o->blessed == B_CURSED) && lfhasflag(lf, F_ANIMAL) && !isairborne(lf)) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf,lfname);
|
||||
getobname(o, buf, o->amt);
|
||||
msg("%s %s away from %s!", lfname, isplayer(lf) ? "shy" : "shies", buf);
|
||||
o->blessknown = B_TRUE;
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
}
|
||||
taketime(lf, getmovespeed(lf));
|
||||
reason = E_OK;
|
||||
// avoid this object in future
|
||||
sprintf(buf, "%ld",o->id);
|
||||
addflag(lf->flags, F_AVOIDCURSEDOB, NA, NA, NA, buf);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gravboosted
|
||||
if (lfhasflag(lf, F_GRAVBOOSTED)) {
|
||||
// make a saving throw to move
|
||||
if (!skillcheck(lf, SC_STR, 25, 0)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You try to move but are unable to lift your feet!");
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s tries to move but is unable to lift its feet!",lfname);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
}
|
||||
reason = E_OK;
|
||||
taketime(lf, getmovespeed(lf));
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sticky objects in current cell?
|
||||
for (o = lf->cell->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
|
||||
if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_RESTRICTMOVEMENT);
|
||||
if (f) {
|
||||
char lfname[BUFLEN];
|
||||
int diff;
|
||||
int getsweaker;
|
||||
getlfname(lf,lfname);
|
||||
getobname(o, buf, o->amt);
|
||||
|
||||
// for stacks of sticky objects, each one after the first adds
|
||||
// quarter its difficuly. ie:
|
||||
// 1 x object with f_sticky:20, difficult is 20
|
||||
// 2 x object with f_sticky:20, difficult is 25
|
||||
// 3 x object with f_sticky:20, difficult is 30
|
||||
// etc
|
||||
// can you break free?
|
||||
diff = f->val[0];
|
||||
if (o->amt > 1) {
|
||||
diff = (o->amt - 1) * ((float)f->val[0] / 4.0);
|
||||
}
|
||||
getsweaker = f->val[1];
|
||||
if (skillcheck(lf, SC_STR, diff, 0)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You tear free from %s!", buf);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s tears free from %s!", lfname, buf);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
}
|
||||
killob(o);
|
||||
continue;
|
||||
} else {
|
||||
// failed - object gets a little less sticky
|
||||
if (isplayer(lf)) {
|
||||
msg("You struggle in %s!", buf);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s struggles in %s!", lfname, buf);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
}
|
||||
|
||||
if (getsweaker) {
|
||||
takedamage(o, 1, DT_DIRECT);
|
||||
}
|
||||
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
reason = E_OK;
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// slipping on something before moving?
|
||||
if (!isairborne(lf)) {
|
||||
int slip;
|
||||
object_t *slipob;
|
||||
slip = getslipperyness(lf->cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
if (didmsg) *didmsg = B_TRUE;
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// teleport somewhere, along with puffs of smoke etc
|
||||
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
|
||||
char buf[BUFLEN];
|
||||
|
@ -1226,6 +1387,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
cell_t *cell;
|
||||
enum ERROR errcode;
|
||||
char buf[BUFLEN];
|
||||
int dontclearmsg = B_FALSE;
|
||||
flag_t *f;
|
||||
|
||||
f = isdrunk(lf);
|
||||
|
@ -1240,73 +1402,13 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
if (canandwillmove(lf, dir, &errcode)) {
|
||||
object_t *o,*slipob;
|
||||
int slip;
|
||||
|
||||
// check for cursed objects + animals
|
||||
// do this AFTER checking if we will move, so that
|
||||
// they will actually try the move and fail (this lets
|
||||
// the player find out about the cursed object).
|
||||
//
|
||||
// note however that if a monster is chasing a player (ie
|
||||
// has F_TARGET,player) then they will simply avoid the cursed
|
||||
// object rather than failing the movement.
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (!isplayer(lf)) {
|
||||
if (o->blessed == B_CURSED) {
|
||||
if (lfhasflag(lf, F_ANIMAL)) {
|
||||
if (!isairborne(lf)) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf,lfname);
|
||||
getobname(o, buf, o->amt);
|
||||
msg("%s %s away from %s!", lfname, isplayer(lf) ? "shy" : "shies", buf);
|
||||
o->blessknown = B_TRUE;
|
||||
}
|
||||
taketime(lf, getmovespeed(lf));
|
||||
reason = E_OK;
|
||||
// avoid this object in future
|
||||
sprintf(buf, "%ld",o->id);
|
||||
addflag(lf->flags, F_AVOIDCURSEDOB, NA, NA, NA, buf);
|
||||
if (initiatemove(lf, cell, &dontclearmsg)) {
|
||||
// failed?
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// slipping on blood before moving?
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(lf->cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// gravboosted
|
||||
if (lfhasflag(lf, F_GRAVBOOSTED)) {
|
||||
// make a saving throw to move
|
||||
if (!skillcheck(lf, SC_STR, 25, 0)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You try to move but are unable to lift your feet!");
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s tries to move but is unable to lift its feet!",lfname);
|
||||
}
|
||||
reason = E_OK;
|
||||
taketime(lf, getmovespeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// move to new cell
|
||||
reason = E_OK;
|
||||
moveto(lf, cell, onpurpose);
|
||||
moveto(lf, cell, onpurpose, dontclearmsg);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
} else {
|
||||
object_t *inway = NULL;
|
||||
|
@ -1428,7 +1530,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
oldcell = lf->cell;
|
||||
|
||||
// move you..
|
||||
moveto(lf, cell, onpurpose);
|
||||
moveto(lf, cell, onpurpose, B_FALSE);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// move them...
|
||||
|
@ -1463,7 +1565,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
killflagsofid(lf->flags, F_GRABBEDBY);
|
||||
killflagsofid(grabbedby->flags, F_GRABBING);
|
||||
// move - don't clear the 'you break free from' msg
|
||||
moveto(lf, cell, B_TRUE);
|
||||
moveto(lf, cell, B_TRUE, B_TRUE);
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You cannot get away from %s!",gbname);
|
||||
|
@ -1523,6 +1625,13 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
|
||||
// don't attack other monsters
|
||||
if (cell->lf) { // if someone is in the way
|
||||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
if (hasactivespell(cell->lf, OT_S_REPELINSECTS)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isplayer(lf)) { // if we are a monster
|
||||
// if the person in the way isn't our enemy...
|
||||
if (!areenemies(lf, cell->lf)) {
|
||||
|
|
5
move.h
5
move.h
|
@ -13,13 +13,14 @@ int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int d
|
|||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
|
||||
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher);
|
||||
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype);
|
||||
void moveeffects(lifeform_t *lf);
|
||||
int moveeffects(lifeform_t *lf);
|
||||
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose);
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg);
|
||||
int movetowards(lifeform_t *lf, cell_t *dst, int dirtype);
|
||||
int opendoorat(lifeform_t *lf, cell_t *c);
|
||||
int opendoor(lifeform_t *lf, object_t *o);
|
||||
int pullnextto(lifeform_t *lf, cell_t *c);
|
||||
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg);
|
||||
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke);
|
||||
int trymove(lifeform_t *lf, int dir, int onpurpose);
|
||||
int tryrun(lifeform_t *lf, int dir);
|
||||
|
|
16
nexus.c
16
nexus.c
|
@ -25,6 +25,7 @@ obmod_t *firstobmod = NULL,*lastobmod = NULL;
|
|||
celltype_t *firstcelltype = NULL,*lastcelltype = NULL;
|
||||
command_t *firstcommand = NULL,*lastcommand = NULL;
|
||||
race_t *firstrace = NULL,*lastrace = NULL;
|
||||
raceclass_t *firstraceclass = NULL,*lastraceclass = NULL;
|
||||
job_t *firstjob = NULL,*lastjob = NULL;
|
||||
skill_t *firstskill = NULL,*lastskill = NULL;
|
||||
map_t *firstmap = NULL,*lastmap = NULL;
|
||||
|
@ -160,6 +161,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// find staircase
|
||||
where = findobinmap(firstmap, OT_STAIRSUP);
|
||||
assert(where);
|
||||
|
@ -177,14 +179,26 @@ int main(int argc, char **argv) {
|
|||
addflag(player->flags, F_NAME, NA, NA, NA, "Anonymous");
|
||||
}
|
||||
givejob(player, j->id);
|
||||
// special case:
|
||||
// special cases for jobs:
|
||||
if (j->id == J_PIRATE) {
|
||||
flag_t *f;
|
||||
f = lfhasflagval(player, F_HASATTACK, OT_FISTS, NA, NA, NULL);
|
||||
assert(f);
|
||||
f->val[0] = OT_HOOKHAND;
|
||||
sprintf(f->text, "1d4");
|
||||
} else if (j->id == J_WIZARD) {
|
||||
skill_t *sk;
|
||||
initprompt(&prompt, "Select your spell specialty:");
|
||||
addchoice(&prompt, 'a', getskillname(SK_SS_AIR), NULL, findskill(SK_SS_AIR));
|
||||
addchoice(&prompt, 'i', getskillname(SK_SS_ICE), NULL, findskill(SK_SS_ICE));
|
||||
addchoice(&prompt, 'f', getskillname(SK_SS_FIRE), NULL, findskill(SK_SS_FIRE));
|
||||
getchoice(&prompt);
|
||||
sk = (skill_t *) prompt.result;
|
||||
giveskill(player, sk->id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// read cheat info from player file
|
||||
if (playerfile) {
|
||||
if (parseplayerfile(playerfile, player)) {
|
||||
|
|
|
@ -125,6 +125,7 @@ int isblessknown(object_t *o);
|
|||
int iscorpse(object_t *o);
|
||||
int iscursed(object_t *o);
|
||||
int isdangerousob(object_t *o, lifeform_t *lf, int onlyifknown);
|
||||
int isdeadob(object_t *o);
|
||||
int isdrinkable(object_t *o);
|
||||
int isedible(object_t *o);
|
||||
flag_t *isequipped(object_t *o);
|
||||
|
@ -188,6 +189,7 @@ object_t *relinkob(object_t *src, obpile_t *dst);
|
|||
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
||||
void setinscription(object_t *o, char *text);
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||
void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
void shufflehiddennames(void);
|
||||
object_t *splitob(object_t *o);
|
||||
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||
|
|
6
save.c
6
save.c
|
@ -199,7 +199,11 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
|
||||
if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading flags.",l->hp,l->maxhp,l->timespent,l->sorted);
|
||||
|
||||
// lf flags
|
||||
// clear existing flags from addlf
|
||||
while (l->flags->first) {
|
||||
killflag(l->flags->first);
|
||||
}
|
||||
// load lf flags
|
||||
loadflagpile(f, l->flags);
|
||||
|
||||
if (db) dblog("--> now loading objects");
|
||||
|
|
2
spell.h
2
spell.h
|
@ -15,7 +15,9 @@ int getspellmaxpower(enum OBTYPE spellid);
|
|||
char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf);
|
||||
int getspellpower(lifeform_t *lf, enum OBTYPE spellid);
|
||||
enum SPELLSCHOOL getspellschool(enum OBTYPE spellid);
|
||||
enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid);
|
||||
int getspellrange(enum OBTYPE spellid, int power);
|
||||
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
|
||||
void pullobto(object_t *o, lifeform_t *lf);
|
||||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
|
|
37
text.c
37
text.c
|
@ -4,6 +4,7 @@
|
|||
#include <string.h>
|
||||
#include "defs.h"
|
||||
#include "lf.h"
|
||||
#include "nexus.h"
|
||||
#include "objects.h"
|
||||
#include "text.h"
|
||||
|
||||
|
@ -113,6 +114,38 @@ char *getattrname(enum ATTRIB att) {
|
|||
return "?badattrib?";
|
||||
}
|
||||
|
||||
int gethitconferlifetime(char *text, int *min, int *max) {
|
||||
int howlong;
|
||||
int localmin,localmax;
|
||||
if (text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
localmin = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (word) {
|
||||
localmax = atoi(word);
|
||||
howlong = rnd(localmin,localmax);
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
localmin = -1;
|
||||
localmax = -1;
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
localmin = -1;
|
||||
localmax = -1;
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
if (min) *min = localmin;
|
||||
if (max) *max = localmax;
|
||||
return howlong;
|
||||
}
|
||||
|
||||
char *getpossessive(char *text) {
|
||||
char lastchar;
|
||||
// you -> your
|
||||
|
@ -406,6 +439,10 @@ char *roman(int num) {
|
|||
return "";
|
||||
}
|
||||
|
||||
int speedtokph(int speed) {
|
||||
return speed * speed * speed;
|
||||
}
|
||||
|
||||
void splittime(int *hours, int *mins, int *secs) {
|
||||
long left;
|
||||
left = curtime;
|
||||
|
|
2
text.h
2
text.h
|
@ -6,6 +6,7 @@ char *capitaliseall(char *text);
|
|||
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf);
|
||||
char *getattrabbrev(enum ATTRIB att);
|
||||
char *getattrname(enum ATTRIB att);
|
||||
int gethitconferlifetime(char *text, int *min, int *max);
|
||||
char *getpossessive(char *text);
|
||||
char *getdrunktext(flag_t *drunkflag);
|
||||
char *getsizetext(enum LFSIZE sz);
|
||||
|
@ -19,6 +20,7 @@ int needses(char *text);
|
|||
char *noprefix(char *obname);
|
||||
char *numtotext(int num, char *buf);
|
||||
char *roman(int num);
|
||||
int speedtokph(int speed);
|
||||
void splittime(int *hours, int *mins, int *secs);
|
||||
char *strrep(char *text, char *oldtok, char *newtok, int *rv);
|
||||
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
|
||||
|
|
Loading…
Reference in New Issue