- [+] tweak armour damage -make natural armour hittable.

- [+] getdirtowards/away bug
- [+] metalwork or armour skills let you see armour hp!
* [+] allow players to select their weapon specialties at the start
- [+] make statbar easier to read
* [+] druids
- [+] spark on rum will blow it up!
* [+] evasion skill
- [+] add charisma
* [+] add speech skill 
- [+] bug: gate to level 1 took me to the outside!
* [+] bug: not hearing shopkeepers final yell - out of range??
- [+] special corpses:  i - a Jimbo corpse should be "Jimbo's corpse"
- [+] when autogenerating monsters, make sure they have ammo for ranged
      weapons.
* [+] map to town
- [+] randomly place the town now.
* [+] shopkeeper still doesn't talk to us if we can't see him when we
      pick up an object
- [+] i am STILL not hearing when the shopkeeper yells you "stop
      thief"!!
* [+] bug:  LOTS of dungeon rooms with no exit
- [+] town guards want money
- [+] announce "a xxx falls through a pit" 
* [+] make running go around corners
* [+] colourise known skills
- [+] rename constitution to fitness
* [+] scroll of mending - should this fix dulled weapons (by hitting
      doors etc)?
- [+] colourise @@ (boldwhite for titles)
* [+] colourise @s
* [+] colourise @m and @e
This commit is contained in:
Rob Pearce 2011-07-01 03:34:41 +00:00
parent 7dfeb42e5a
commit 95c6ab8396
16 changed files with 1605 additions and 428 deletions

11
ai.c
View File

@ -59,7 +59,6 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
killflagsofid(lf->flags, F_TARGETLF); killflagsofid(lf->flags, F_TARGETLF);
killflagsofid(lf->flags, F_TARGETCELL); killflagsofid(lf->flags, F_TARGETCELL);
if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) { if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) {
addflag(lf->flags, F_TARGETLF, victim->id, victim->cell->x, victim->cell->y, NULL); addflag(lf->flags, F_TARGETLF, victim->id, victim->cell->x, victim->cell->y, NULL);
} else { } else {
@ -70,12 +69,14 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
makenoise(lf, N_GETANGRY); makenoise(lf, N_GETANGRY);
} }
// become hostile?
if (!hasflag(lf->flags, F_HOSTILE)) {
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
}
// change allegience ? // change allegience ?
if (!areenemies(lf, victim)) { if (!areenemies(lf, victim)) {
if (getallegiance(victim) == AL_FRIENDLY) { if (getallegiance(victim) == AL_FRIENDLY) {
if (!hasflag(lf->flags, F_HOSTILE)) {
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
}
killflagsofid(lf->flags, F_FRIENDLY); killflagsofid(lf->flags, F_FRIENDLY);
} }
} }
@ -1685,7 +1686,7 @@ int lookforobs(lifeform_t *lf) {
// if we are in battle only go for it if we covet it // if we are in battle only go for it if we covet it
if (target && !wantflagcovet[n]) continue; if (target && !wantflagcovet[n]) continue;
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf,o)) ) { if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) && (canpickup(lf, o, 1) || caneat(lf,o)) ) {
if (db) dblog(".oO { current cell has ob with flag i want (%s) }",o->type->name); if (db) dblog(".oO { current cell has ob with flag i want (%s) }",o->type->name);
// try to pick it up // try to pick it up
if (!aipickup(lf, o)) return B_TRUE; if (!aipickup(lf, o)) return B_TRUE;

View File

@ -59,9 +59,14 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
// ALL of damage reduction goes towards armour // ALL of damage reduction goes towards armour
} else { } else {
// SOME of the damage reduction goes towards the armour // SOME of the damage reduction goes towards the armour
// damage taken by armour is reduced by half its armour rating
if (ar) { if (ar) {
actualdam -= rnd(0,ar); int max;
limit(&actualdam, 0, NA); max = ar/2;
if (max >= 1) {
actualdam -= rnd(0,max);
limit(&actualdam, 0, NA);
}
} }
} }
@ -124,6 +129,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
int attacktime; int attacktime;
int gotweapon = B_FALSE; int gotweapon = B_FALSE;
int maxattacks = ALL; int maxattacks = ALL;
int attacksdone = 0;
int lastweaponidx = -1; int lastweaponidx = -1;
flag_t *sf; flag_t *sf;
@ -180,7 +186,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
}; };
} else { } else {
// TODO: attack wall? // TODO: attack wall?
if (isplayer(lf)) { if (isplayer(lf) && !lfhasflag(lf, F_HURRICANESTRIKE)) {
msg("There is nothing there to attack!"); msg("There is nothing there to attack!");
} }
return B_TRUE; return B_TRUE;
@ -272,7 +278,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
//maxattacks = nweps; // ie. all //maxattacks = nweps; // ie. all
maxattacks = getmaxattacks(lf); maxattacks = getattacks(lf, NULL, NULL);
/* /*
// if we have a weapon, this takes the place of one of our // if we have a weapon, this takes the place of one of our
@ -317,22 +323,28 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
// remember initial cells // remember initial cells
for (i = 0; i < nweps; i++) {
if (validwep[i]) { attacksdone = 0;
if (attacktype == AT_LF) { while (attacksdone < maxattacks) {
if (!isdead((lifeform_t *)attacktarget)) { for (i = 0; (i < nweps) && (attacksdone < maxattacks); i++) {
if (attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i])) break; if (validwep[i]) {
if (attacktype == AT_LF) {
if (!isdead((lifeform_t *)attacktarget)) {
if (attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i])) break;
}
} else if (attacktype == AT_OB) {
if (attackob(lf, (object_t *)attacktarget, wep[i], damflag[i])) break;
} }
} else if (attacktype == AT_OB) {
if (attackob(lf, (object_t *)attacktarget, wep[i], damflag[i])) break;
} }
} attacksdone++;
// stop attacking if they somehow got out of range // stop attacking if they somehow got out of range
// (eg. dodging) // (eg. dodging)
if (attacktype == AT_LF) { if (attacktype == AT_LF) {
if (getcelldist(lf->cell, ((lifeform_t *)attacktarget)->cell) > 1) { if (getcelldist(lf->cell, ((lifeform_t *)attacktarget)->cell) > 1) {
break; attacksdone = maxattacks;
break;
}
} }
} }
} }
@ -662,8 +674,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
!ismeleedam(damtype[i])) { !ismeleedam(damtype[i])) {
verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp); verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp);
} else { } else {
verb = strdup("hit"); // always use verb for 10%
needfree = B_TRUE; verb = getattackverb(lf, wep, damtype[i], pctof(10, victim->maxhp), victim->maxhp);
} }
} }
warn("You %s %s%s%s%s", warn("You %s %s%s%s%s",
@ -708,7 +720,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
needses(attackverb) ? "es" : "s", needses(attackverb) ? "es" : "s",
victimname,withwep, nodamstr); victimname,withwep, nodamstr);
} }
noise(lf->cell, lf, 3, "sounds of fighting.", NULL); noise(lf->cell, lf, NC_OTHER, 3, "sounds of fighting.", NULL);
} }
@ -897,6 +909,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
msg("%s misses %s.", buf, victimname); msg("%s misses %s.", buf, victimname);
} }
} }
// train evasion
practice(victim, SK_EVASION, 1);
if (lfhasflag(victim, F_DODGES)) { if (lfhasflag(victim, F_DODGES)) {
cell_t *adj; cell_t *adj;
@ -1043,7 +1058,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
msg("%s %ss %s%s.", attackername, msg("%s %ss %s%s.", attackername,
getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep); getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep);
} else { } else {
noise(lf->cell, NULL, 3, "sounds of fighting.", NULL); noise(lf->cell, NULL, NC_OTHER, 3, "sounds of fighting.", NULL);
} }
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARDNESS)) { if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARDNESS)) {
@ -1107,7 +1122,7 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
int pctrange; int pctrange;
object_t *o; object_t *o;
ar = getarmourrating(lf); ar = getarmourrating(lf, NULL, NULL, NULL);
//reducepct = getdamreducepct(ar); //reducepct = getdamreducepct(ar);
//reduceamt = (int) ceil((reducepct / 100.0) * (float)dam); //reduceamt = (int) ceil((reducepct / 100.0) * (float)dam);
@ -1760,7 +1775,7 @@ void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, en
// returns true if we hit // returns true if we hit
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) { int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) {
int acc,ev; int acc,ev;
int gothit; int gothit = B_FALSE;
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
int myroll; int myroll;
flag_t *f; flag_t *f;
@ -1791,7 +1806,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
killflag(f); killflag(f);
} }
gothit = B_TRUE; gothit = B_TRUE;
} else if (critical) { } else if (critical && *critical) {
gothit = B_TRUE; gothit = B_TRUE;
} else { } else {
// actually roll... // actually roll...

162
defs.h
View File

@ -17,6 +17,7 @@
*/ */
// ncurses colours // ncurses colours
#define C_NONE -1
enum COLOUR { enum COLOUR {
C_BLACK = 0, C_BLACK = 0,
C_RED = 1, C_RED = 1,
@ -35,6 +36,14 @@ enum COLOUR {
C_ORANGE = 13, C_ORANGE = 13,
C_BOLDGREEN = 14, C_BOLDGREEN = 14,
}; };
#define BLUEBG 50
enum NOISECLASS {
NC_NONE = 0,
NC_SPEECH = 1,
NC_OTHER = 2,
};
enum SPEECHVOL { enum SPEECHVOL {
SV_SILENT = 0, SV_SILENT = 0,
@ -54,6 +63,7 @@ enum SKILL {
SK_CHANNELING, SK_CHANNELING,
SK_CLIMBING, SK_CLIMBING,
SK_COOKING, SK_COOKING,
SK_EVASION,
SK_FIRSTAID, SK_FIRSTAID,
SK_LISTEN, SK_LISTEN,
SK_LOCKPICKING, SK_LOCKPICKING,
@ -61,6 +71,7 @@ enum SKILL {
SK_RANGED, SK_RANGED,
SK_SEWING, SK_SEWING,
SK_SHIELDS, SK_SHIELDS,
SK_SPEECH,
SK_SPELLCASTING, SK_SPELLCASTING,
SK_SPOTHIDDEN, SK_SPOTHIDDEN,
SK_STEALTH, SK_STEALTH,
@ -100,7 +111,7 @@ enum SKILL {
SK_SS_TRANSLOCATION, SK_SS_TRANSLOCATION,
SK_SS_WILD, SK_SS_WILD,
}; };
#define MAXSKILLS 50 #define MAXSKILLS 52
// proficiency levels // proficiency levels
enum SKILLLEVEL { enum SKILLLEVEL {
@ -146,14 +157,16 @@ enum ATTRIB {
A_DEX = 1, A_DEX = 1,
A_IQ = 2, A_IQ = 2,
A_CON = 3, A_CON = 3,
A_CHA = 4,
}; };
#define MAXATTS 4 #define MAXATTS 5
enum CHECKTYPE { enum CHECKTYPE {
SC_STR, SC_STR,
SC_DEX, SC_DEX,
SC_IQ, SC_IQ,
SC_CON, SC_CON,
SC_CHA,
////////// //////////
SC_CLIMB, SC_CLIMB,
SC_DISARM, SC_DISARM,
@ -473,6 +486,18 @@ enum SPELLSCHOOL {
SS_LAST, SS_LAST,
}; };
enum CHABRACKET {
CH_RANDOM = -1,
CH_HIDEOUS = 0,
CH_REPULSIVE,
CH_UGLY,
CH_UNATTRACTIVE,
CH_AVERAGE,
CH_ATTRACTIVE,
CH_ALLURING,
CH_BEAUTIFUL,
};
enum STRBRACKET { enum STRBRACKET {
ST_RANDOM = -1, ST_RANDOM = -1,
ST_HELPLESS = 0, ST_HELPLESS = 0,
@ -741,6 +766,7 @@ enum JOB {
J_BARBARIAN, J_BARBARIAN,
J_COMMANDO, J_COMMANDO,
J_DRUID, J_DRUID,
J_MONK,
J_PIRATE, J_PIRATE,
J_PLUMBER, J_PLUMBER,
J_PRINCE, J_PRINCE,
@ -833,6 +859,7 @@ enum OBTYPE {
// flora // flora
OT_FLOWER, OT_FLOWER,
OT_LEAF, OT_LEAF,
OT_MISTLETOE,
OT_SHRUB, OT_SHRUB,
OT_STUMP, OT_STUMP,
OT_TREE, OT_TREE,
@ -883,6 +910,7 @@ enum OBTYPE {
OT_POT_JUICE, OT_POT_JUICE,
// scrolls // scrolls
OT_MAP, OT_MAP,
OT_GRAPHPAPER,
OT_SCR_NOTHING, OT_SCR_NOTHING,
OT_SCR_CREATEMONSTER, OT_SCR_CREATEMONSTER,
OT_SCR_DETECTAURA, OT_SCR_DETECTAURA,
@ -1451,6 +1479,9 @@ enum FLAG {
F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold) F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold)
F_CONTAINSOB, // for vending machiens. v0 is ob letter F_CONTAINSOB, // for vending machiens. v0 is ob letter
// text is an object it contains. // text is an object it contains.
F_MAPTO, // this object is a map to the world map at xy=v0/v1.
// optional v2 = obtypeid of target
// text = what this is a map to ie. "the nearest village"
F_SIGNTEXT, // for 'sign' objects. f->text is what is says. F_SIGNTEXT, // for 'sign' objects. f->text is what is says.
F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc
F_STARTBLESSED, // v0 = b_blessed or b_cursed F_STARTBLESSED, // v0 = b_blessed or b_cursed
@ -1535,6 +1566,8 @@ enum FLAG {
// val1 = BIG means hit surrounding cells // val1 = BIG means hit surrounding cells
// val2 = ifactivated, only explodes if activated. // val2 = ifactivated, only explodes if activated.
F_EXPLODEONDAM, // explodes when it is damaged, deals TEXT damage. F_EXPLODEONDAM, // explodes when it is damaged, deals TEXT damage.
// v0 = damage type which makes it explode.
// NA means 'any damage type'
// val1 = BIG means hit surrounding cells // val1 = BIG means hit surrounding cells
// val2 = ifactivated, only explodes if activated. // val2 = ifactivated, only explodes if activated.
F_FLASHONDEATH, // produce a bright flash when it dies,v0=range F_FLASHONDEATH, // produce a bright flash when it dies,v0=range
@ -1976,6 +2009,7 @@ enum FLAG {
F_GRABBEDBY,// you've been grabbed by lf id v0 F_GRABBEDBY,// you've been grabbed by lf id v0
F_GRABBING, // you are grabbing lf id v0 F_GRABBING, // you are grabbing lf id v0
F_HEAVYBLOW, // next attack is a heavy blow F_HEAVYBLOW, // next attack is a heavy blow
F_HURRICANESTRIKE, // lf is performing a hurricane strike
F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks. F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks.
F_INVISIBLE, // lifeform is invisible F_INVISIBLE, // lifeform is invisible
F_INVULNERABLE,// immune to most damage F_INVULNERABLE,// immune to most damage
@ -2032,7 +2066,8 @@ enum FLAG {
F_HASSKILL, // lf has skill v0 at level v1 F_HASSKILL, // lf has skill v0 at level v1
F_PRACTICINGSKILL, // lf is pract skill v0 F_PRACTICINGSKILL, // lf is pract skill v0
// COMBAT // COMBAT
F_MAXATTACKS, // v0 = max # attacks this lf can make per round F_MAXATTACKS, // v0 = min # attacks this lf can make per round
// v1 = max # attacks this lf can make per round
F_HASATTACK, // v0 = obid to use when attacking unarmed F_HASATTACK, // v0 = obid to use when attacking unarmed
// if text is set, it overrides the damage // if text is set, it overrides the damage
F_EVASION, // % chance of evading an attack F_EVASION, // % chance of evading an attack
@ -2050,11 +2085,14 @@ enum FLAG {
F_RESTUNTILMP, // resting until we have full mp F_RESTUNTILMP, // resting until we have full mp
F_RESTUNTILALLIES, // resting until allies have full hp F_RESTUNTILALLIES, // resting until allies have full hp
// //
F_RUNNING, // are we running? F_RUNNING, // are we running? (shift+dir)
// v0 is last dir moved.
// v1 is whether we have turned yet.
// nutrition // nutrition
F_HUNGER, // val0 = hunger, higher = hungrier F_HUNGER, // val0 = hunger, higher = hungrier
// for jobs (job flags) // for jobs (job flags)
F_SELECTWEAPON, // this job gets to pick their starting weapon
F_NOPLAYER, // players can't pick this job F_NOPLAYER, // players can't pick this job
F_HASPET, // this job starts with a pet of race f->text F_HASPET, // this job starts with a pet of race f->text
F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0. F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0.
@ -2211,65 +2249,66 @@ enum SPELLTARGET {
enum ERROR { enum ERROR {
E_OK = 0, E_OK = 0,
E_WALLINWAY = 1, E_WALLINWAY = 1,
E_LFINWAY = 2, E_LFINWAY,
E_NOSPACE = 3, E_NOSPACE,
E_SELNOTHING = 4, E_SELNOTHING,
E_ALREADYUSING = 5, E_ALREADYUSING,
E_WEARINGSOMETHINGELSE = 6, E_WEARINGSOMETHINGELSE,
E_NOUNARMEDATTACK = 7, E_NOUNARMEDATTACK,
E_NOTEQUIPPED = 8, E_NOTEQUIPPED,
E_NOPICKUP = 9, E_NOPICKUP,
E_MONSTERNEARBY = 10, E_MONSTERNEARBY,
E_NOEFFECT = 11, E_NOEFFECT,
E_FAILED = 12, E_FAILED,
E_WRONGCELLTYPE = 13, E_WRONGCELLTYPE,
E_OBINWAY = 14, E_OBINWAY,
E_TOOHEAVY = 15, E_TOOHEAVY,
E_NOHANDS = 16, E_NOHANDS,
E_NOPACK = 17, E_NOPACK,
E_INSUBSTANTIAL = 18, E_INSUBSTANTIAL,
E_WRONGOBTYPE = 19, E_WRONGOBTYPE,
E_CURSED = 20, E_CURSED,
E_NOLOS = 21, E_NOLOS,
E_NOLOF = 22, E_NOLOF,
E_IMPOSSIBLE = 23, E_IMPOSSIBLE,
E_NOTARGET = 24, E_NOTARGET,
E_NOAMMO = 25, E_NOAMMO,
E_GRAVBOOSTED = 26, E_GRAVBOOSTED,
E_NOMP = 27, E_NOMP,
E_AVOIDOB = 28, E_AVOIDOB,
E_FROZEN = 29, E_FROZEN,
E_TOOBIG = 30, E_TOOBIG,
E_NOTREADY = 31, E_NOTREADY,
E_BLIND = 32, E_BLIND,
E_GRABBEDBY = 33, E_GRABBEDBY,
E_CANTMOVE = 34, E_CANTMOVE,
E_NOTKNOWN = 35, E_NOTKNOWN,
E_TOOPOWERFUL = 36, E_TOOPOWERFUL,
E_NEEDGRAB = 37, E_NEEDGRAB,
E_DOORINWAY = 38, E_DOORINWAY,
E_NOCANNIBUL = 39, E_NOCANNIBUL,
E_LOWCON = 40, E_LOWCON,
E_LOWDEX = 41, E_LOWDEX,
E_LOWIQ = 42, E_LOWIQ,
E_LOWSTR = 43, E_LOWSTR,
E_WONT = 44, E_LOWCHA,
E_OFFMAP = 45, E_WONT,
E_OFFMAP,
// charm failure reasons // charm failure reasons
// LOWIQ = 42 // LOWIQ
E_UNDEAD = 46, E_UNDEAD,
E_DRUNK = 47, E_DRUNK,
// //
E_NOBP = 48, E_NOBP,
E_VEGETARIAN = 49, E_VEGETARIAN,
E_PARTVEGETARIAN = 50, E_PARTVEGETARIAN,
E_CARNIVORE = 51, E_CARNIVORE,
E_NOOB = 52, E_NOOB,
E_LEVITATING = 53, E_LEVITATING,
E_PRONE = 54, E_PRONE,
E_PENTAGRAM = 55, E_PENTAGRAM,
E_SWIMMING = 56, E_SWIMMING,
E_DANGEROUS = 57, E_DANGEROUS,
}; };
@ -2575,6 +2614,7 @@ typedef struct lifeform_s {
int born; int born;
// for ai movement - don't need to save. // for ai movement - don't need to save.
struct cell_s *prevcell[2];
struct cell_s *cell; struct cell_s *cell;
struct lifeform_s *next, *prev; struct lifeform_s *next, *prev;

View File

@ -11,9 +11,10 @@ lf.c:
update rollstat() update rollstat()
add rollxxx() add rollxxx()
update skillcheck() update skillcheck()
update gainlevel() question update enhanceskills() question if you can up this at levelup
update givejob()
update modattr() update modattr()
update jobs
io.c: io.c:
update announceflaggain() and loss() for this stat update announceflaggain() and loss() for this stat
text.c: text.c:

View File

@ -1,13 +1,11 @@
defs.h: defs.h:
add SK_xxx add SK_xxx
inc MAXSKILLS inc MAXSKILLS
add OT_MAN_xxx for this skill
objects.c:
add a manual for this skill
lf.c: lf.c:
add addskill() add addskill()
if it is a lore skill, update isloreskill()
if it is a weapon skill, update isweaponskill()
if it is a lroe skill, update isloreskill() assign to jobs

420
io.c
View File

@ -1040,6 +1040,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
case A_STR: case A_STR:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "weaker" : "stronger"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "weaker" : "stronger");
break; break;
case A_CHA:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "less attractive" : "more attractive");
break;
case A_IQ: case A_IQ:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "foolish" : "smarter"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "foolish" : "smarter");
break; break;
@ -1060,6 +1063,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
case A_STR: case A_STR:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "weak" : "strong"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "weak" : "strong");
break; break;
case A_CHA:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "ugly" : "attractive");
break;
case A_IQ: case A_IQ:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "foolish" : "smart"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "foolish" : "smart");
break; break;
@ -1557,6 +1563,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
case A_STR: case A_STR:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less strong" : "less weak"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less strong" : "less weak");
break; break;
case A_CHA:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less attractive" : "less ugly");
break;
case A_IQ: case A_IQ:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less smart" : "less foolish"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less smart" : "less foolish");
break; break;
@ -1577,6 +1586,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
case A_STR: case A_STR:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less strong" : "less weak"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less strong" : "less weak");
break; break;
case A_CHA:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less attractive" : "less ugly");
break;
case A_IQ: case A_IQ:
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less smart" : "less foolish"); msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less smart" : "less foolish");
break; break;
@ -2269,7 +2281,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
mvwprintw(mainwin, 2, 0, "There is nothing here."); mvwprintw(mainwin, 2, 0, "There is nothing here.");
} }
// wait for key // wait for key
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]"); centre(mainwin, C_WHITE, getmaxy(mainwin)-1, "[Press any key]");
getch(); getch();
restoregamewindows(); restoregamewindows();
@ -2465,7 +2477,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
cls(); cls();
mvwprintw(mainwin, 2, 0, "You have no possessions."); mvwprintw(mainwin, 2, 0, "You have no possessions.");
// wait for key // wait for key
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]"); centre(mainwin,C_WHITE, getmaxy(mainwin)-1, "[Press any key]");
getch(); getch();
restoregamewindows(); restoregamewindows();
@ -2683,7 +2695,7 @@ vault_t *askvault(char *prompttext) {
return v; return v;
} }
void centre(WINDOW *win, int y, char *format, ... ) { void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... ) {
int w; int w;
char buf[BUFLEN]; char buf[BUFLEN];
va_list args; va_list args;
@ -2696,16 +2708,18 @@ void centre(WINDOW *win, int y, char *format, ... ) {
w = getmaxx(win); w = getmaxx(win);
startx = (w/2) - (strlen(buf)/2); startx = (w/2) - (strlen(buf)/2);
if (startx < 0) startx = 0; if (startx < 0) startx = 0;
if (col != C_NONE) setcol(win, col);
mvwprintw(win, y, (w/2) - (strlen(buf)/2), buf); mvwprintw(win, y, (w/2) - (strlen(buf)/2), buf);
if (col != C_NONE) unsetcol(win, col);
} }
int chartodir(char c) { int chartodir(char c) {
switch (tolower(c)) { switch (tolower(c)) {
case 'h': return D_W; case 'h': return DC_W;
case 'j': return D_S; case 'j': return DC_S;
case 'k': return D_N; case 'k': return DC_N;
case 'l': return D_E; case 'l': return DC_E;
case 'y': return DC_NW; case 'y': return DC_NW;
case 'u': return DC_NE; case 'u': return DC_NE;
case 'b': return DC_SW; case 'b': return DC_SW;
@ -2939,7 +2953,7 @@ void describeob(object_t *o) {
// weapons? // weapons?
if (o->type->obclass->id == OC_WEAPON) { if (o->type->obclass->id == OC_WEAPON) {
int delay; int delay;
mvwprintw(mainwin, y, 0, "It is a weapon."); mvwprintw(mainwin, y, 0, "It is a %s weapon.", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed");
y++; y++;
if (hasflag(o->flags, F_DAM)) { if (hasflag(o->flags, F_DAM)) {
int bonus = 0; int bonus = 0;
@ -3055,6 +3069,8 @@ void describeob(object_t *o) {
evmod = adjustarmourpenalty(player, f->val[0]); evmod = adjustarmourpenalty(player, f->val[0]);
if (evmod != 0) { if (evmod != 0) {
sprintf(buf, " When worn, it %s your evasion chance by %d%%.", (evmod < 0) ? "reduces" : "increases", abs(evmod)); sprintf(buf, " When worn, it %s your evasion chance by %d%%.", (evmod < 0) ? "reduces" : "increases", abs(evmod));
mvwprintw(mainwin, y, 0, "%s",buf);
y++;
} }
} }
@ -3070,9 +3086,43 @@ void describeob(object_t *o) {
f = hasflag(o->flags, F_GOESON); f = hasflag(o->flags, F_GOESON);
if (f) { if (f) {
sprintf(buf, "It is worn %s your %s. ",getbodypartequipname(f->val[0]), getbodypartname(f->val[0])); sprintf(buf, "It is worn %s your %s. ",getbodypartequipname(f->val[0]), getbodypartname(f->val[0]));
mvwprintw(mainwin, y, 0, "%s",buf);
y++;
} }
} }
if (hasflag(o->flags, F_DAMAGABLE) && isarmour(o) ) {
int showfullhp = B_FALSE;
char hpbuf[BUFLEN];
f = hasflag(o->flags, F_OBHP);
if (isarmour(o) && getskill(player, SK_ARMOUR)) {
showfullhp = B_TRUE;
} else if ((o->type->material->id == MT_METAL) && getskill(player, SK_METALWORK)) {
showfullhp = B_TRUE;
} else if ( ((o->type->material->id == MT_LEATHER) || (o->type->material->id == MT_CLOTH)) &&
getskill(player, SK_SEWING)) {
showfullhp = B_TRUE;
}
if (isdamaged(o)) {
sprintf(buf, "It has been damaged.");
} else {
sprintf(buf, "It is in perfect condition.");
}
if (showfullhp) {
sprintf(hpbuf, " [%d/%d hp]", f->val[0], f->val[1]);
} else if (isdamaged(o)) {
int pct;
pct = (int)(((float)f->val[0] / (float)f->val[1]) * 100.0);
sprintf(hpbuf, " [%d%% hp]", pct);
} else {
strcpy(hpbuf, "");
}
strcat(buf, hpbuf);
mvwprintw(mainwin, y, 0, "%s", buf);
y++;
}
if (o->type->obclass->id == OC_WAND) { if (o->type->obclass->id == OC_WAND) {
if (isidentified(o)) { if (isidentified(o)) {
int charges; int charges;
@ -3862,7 +3912,7 @@ void docomms(lifeform_t *lf) {
break; break;
case 'y': case 'y':
msg("You shout at %s!", lfname); msg("You shout at %s!", lfname);
noise(where, player, 3, "someone shouting!", NULL); noise(where, player, NC_OTHER, 3, "someone shouting!", NULL);
break; break;
} }
taketime(player, getactspeed(player)); taketime(player, getactspeed(player));
@ -4059,7 +4109,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
cls(); cls();
mvwprintw(mainwin, 0, 0, toptext); mvwprintw(mainwin, 0, 0, toptext);
y = 2; y = 2;
centre(mainwin, y, "VENDING MACINE"); centre(mainwin,C_WHITE, y, "VENDING MACINE");
y += 2; y += 2;
// list objects for sale // list objects for sale
@ -4223,7 +4273,11 @@ void doknowledgelist(void) {
first = B_FALSE; first = B_FALSE;
} }
mvwprintw(mainwin, y, 0, " %-25s (%s)",ot->name, k->hiddenname); if (k->known == B_KNOWN) {
mvwprintw(mainwin, y, 0, " %-25s (%s)",ot->name, k->hiddenname);
} else { // ie. tried
mvwprintw(mainwin, y, 0, " %-25s (%s)","???", k->hiddenname);
}
y++; y++;
numfound++; numfound++;
@ -4621,11 +4675,7 @@ void dooperate(obpile_t *op) {
// ask which object to read // ask which object to read
o = askobject(op, "Operate what", NULL, AO_OPERABLE); o = askobject(op, "Operate what", NULL, AO_OPERABLE);
if (o) { if (o) {
if (isoperable(o)) { operate(player, o, NULL);
operate(player, o, NULL);
} else {
msg("You can't operate that!");
}
} }
} }
@ -4779,20 +4829,20 @@ void dohelp(void) {
h = getmaxy(mainwin); h = getmaxy(mainwin);
cls(); cls();
centre(mainwin, 0, "COMMAND REFERENCE"); centre(mainwin,C_WHITE, 0, "COMMAND REFERENCE");
y = 2; y = 2;
for (c = firstcommand ; c ; c = c->next) { for (c = firstcommand ; c ; c = c->next) {
mvwprintw(mainwin, y, 0, ftext, c->ch, c->desc); y++; mvwprintw(mainwin, y, 0, ftext, c->ch, c->desc); y++;
if (y >= (h-2)) { if (y >= (h-2)) {
centre(mainwin, h-1, "[Press any key]"); centre(mainwin,C_WHITE, h-1, "[Press any key]");
getch(); getch();
cls(); cls();
y = 2; y = 2;
} }
} }
centre(mainwin, h-1, "[Press any key]"); centre(mainwin,C_WHITE, h-1, "[Press any key]");
getch(); getch();
restoregamewindows(); restoregamewindows();
@ -5242,9 +5292,9 @@ int downline(int *y, int h, char *heading, char *subheading, char *bottomstring,
snprintf(headbuf, w-1, "%s (continued)", heading); snprintf(headbuf, w-1, "%s (continued)", heading);
(*y)++; (*y)++;
if (*y >= (h-3)) { if (*y >= (h-3)) {
centre(mainwin, h-2, MORESTRING); centre(mainwin,C_WHITE, h-2, MORESTRING);
if (bottomstring) { if (bottomstring) {
centre(mainwin, h-1, bottomstring); centre(mainwin, C_WHITE, h-1, bottomstring);
} }
ch = getch(); ch = getch();
if (cmdchars && strchr(cmdchars, ch)) { if (cmdchars && strchr(cmdchars, ch)) {
@ -5256,7 +5306,7 @@ int downline(int *y, int h, char *heading, char *subheading, char *bottomstring,
} }
cls(); *y = 0; cls(); *y = 0;
centre(mainwin, *y, headbuf); centre(mainwin, C_WHITE, *y, headbuf);
*y += 2; *y += 2;
wmove(mainwin, *y, 0); wmove(mainwin, *y, 0);
@ -5399,11 +5449,19 @@ void doheading(WINDOW *win, int *y, int x, char *what) {
buf = malloc(len * sizeof(char)); buf = malloc(len * sizeof(char));
memset(buf, '-', (size_t)(len-1)); memset(buf, '-', (size_t)(len-1));
buf[len] = '\0'; buf[len] = '\0';
setcol(win, C_WHITE);
mvwprintw(win, *y, x, what); (*y)++; mvwprintw(win, *y, x, what); (*y)++;
mvwprintw(win, *y, x, buf); (*y)++; mvwprintw(win, *y, x, buf); (*y)++;
unsetcol(win, C_WHITE);
free(buf); free(buf);
} }
void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading) {
setcol(win, C_WHITE);
mvwprintw(mainwin, y, x, format, heading);
unsetcol(win, C_WHITE);
}
void initgfx(void) { void initgfx(void) {
int msgwinh = 2; int msgwinh = 2;
int statwinh = 2; int statwinh = 2;
@ -5438,6 +5496,25 @@ void initgfx(void) {
init_pair(C_BOLDGREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_BOLDGREEN, COLOR_GREEN, COLOR_BLACK);
init_pair(C_ORANGE, COLOR_RED, COLOR_BLACK); init_pair(C_ORANGE, COLOR_RED, COLOR_BLACK);
init_pair(BLUEBG+C_BLACK, COLOR_BLACK, COLOR_BLUE);
init_pair(BLUEBG+C_RED, COLOR_RED, COLOR_BLUE);
init_pair(BLUEBG+C_GREEN, COLOR_GREEN, COLOR_BLUE);
init_pair(BLUEBG+C_BROWN, COLOR_YELLOW, COLOR_BLUE);
init_pair(BLUEBG+C_YELLOW, COLOR_YELLOW, COLOR_BLUE);
init_pair(BLUEBG+C_BLUE, COLOR_BLUE, COLOR_BLUE);
init_pair(BLUEBG+C_MAGENTA, COLOR_MAGENTA, COLOR_BLUE);
init_pair(BLUEBG+C_CYAN, COLOR_CYAN, COLOR_BLUE);
init_pair(BLUEBG+C_GREY, COLOR_WHITE, COLOR_BLUE);
init_pair(BLUEBG+C_YELLOW, COLOR_YELLOW, COLOR_BLUE);
init_pair(BLUEBG+C_WHITE, COLOR_WHITE, COLOR_BLUE);
init_pair(BLUEBG+C_BOLDCYAN, COLOR_CYAN, COLOR_BLUE);
init_pair(BLUEBG+C_BOLDBLUE, COLOR_BLUE, COLOR_BLUE);
init_pair(BLUEBG+C_BOLDMAGENTA, COLOR_MAGENTA, COLOR_BLUE);
init_pair(BLUEBG+C_BOLDGREEN, COLOR_GREEN, COLOR_BLUE);
init_pair(BLUEBG+C_ORANGE, COLOR_RED, COLOR_BLUE);
noecho(); noecho();
cbreak(); cbreak();
nodelay(mainwin, FALSE); nodelay(mainwin, FALSE);
@ -5481,22 +5558,29 @@ int drop(object_t *o, int count) {
getobname(o, obname, count); getobname(o, obname, count);
origid = o->type->id; origid = o->type->id;
// have to announce this before aclling drop, because
// drop might trigger 'the xx falls down a hole' etc
if (isplayer(op->owner)) {
msg("You drop %s.",obname);
} else if (cansee(player, op->owner)) {
char ownername[BUFLEN];
getlfname(op->owner, ownername);
msg("%s drops %s.",ownername, obname);
}
newob = moveob(o, op->owner->cell->obpile, count); newob = moveob(o, op->owner->cell->obpile, count);
if (newob) { // if drop was successful... if (newob) { // if drop was successful...
//taketime(op->owner, (SPEED_DROP * count)); //taketime(op->owner, (SPEED_DROP * count));
taketime(op->owner, SPEED_DROP); taketime(op->owner, SPEED_DROP);
// if object wasn't changed... // if object wasn't changed...
/*
if (newob->type->id == origid) { if (newob->type->id == origid) {
if (op->owner) { if (op->owner) {
if (isplayer(op->owner)) {
msg("You drop %s.",obname);
} else if (cansee(player, op->owner)) {
char ownername[BUFLEN];
getlfname(op->owner, ownername);
msg("%s drops %s.",ownername, obname);
}
} }
} }
*/
} else { } else {
// tell the player why! // tell the player why!
if (isplayer(op->owner)) { if (isplayer(op->owner)) {
@ -5927,16 +6011,18 @@ enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev) {
switch (slev) { switch (slev) {
case PR_INEPT: case PR_INEPT:
return C_RED; return C_RED;
case PR_BEGINNER:
case PR_NOVICE: case PR_NOVICE:
return C_BROWN; return C_BROWN;
case PR_BEGINNER:
return C_GREY;
case PR_ADEPT: case PR_ADEPT:
return C_GREEN; return C_GREEN;
case PR_SKILLED: case PR_SKILLED:
case PR_EXPERT:
return C_BOLDGREEN; return C_BOLDGREEN;
case PR_MASTER: case PR_EXPERT:
return C_BOLDCYAN; return C_BOLDCYAN;
case PR_MASTER:
return C_BOLDMAGENTA;
} }
return C_GREY; return C_GREY;
} }
@ -5952,32 +6038,78 @@ void handleinput(void) {
// if running, automatically do move // if running, automatically do move
f = hasflag(player->flags, F_RUNNING); f = hasflag(player->flags, F_RUNNING);
if (f) { if (f) {
int dir; int rundir = D_NONE;
int hasgettableobs = B_FALSE; int lastdir;
dir = f->val[0]; int ihaveturned;
int stopnow = B_FALSE;
lastdir = f->val[0];
ihaveturned = f->val[1];
object_t *o; object_t *o;
// certain objects will stop us from running. // certain objects will stop us from running.
for (o = player->cell->obpile->first ; o ; o = o->next) { 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) ) { hasflag(o->flags, F_CLIMBABLE) ) {
hasgettableobs = B_TRUE; stopnow = B_TRUE;
break; break;
} }
} }
if (countadjcellswithflag(player->cell, F_DOOR, DT_COMPASS)) {
stopnow = B_TRUE;
}
// stop if enter/exit a room
if (player->prevcell[0] && (player->cell->roomid != player->prevcell[0]->roomid)) {
stopnow = B_TRUE;
}
// something here? // something here?
if (hasgettableobs) { if (stopnow) {
stoprunning(player); } else if (!ihaveturned && moveclear(player, lastdir, NULL)) {
} else if (!moveclear(player, dir, NULL)) { // can't move anymore? // go the same dir if we can.
rundir = lastdir;
} else {
int dir;
int poss[MAXDIR_COMPASS],nposs;
// we have now turned
f->val[1] = B_TRUE;
// check how many possible moves we have.
nposs = 0;
for (dir = DC_N; dir <= DC_W; dir+= 2) { // ie. only go orthogonally from now on
// don't count the way we just came from
if (dir == diropposite(lastdir)) continue;
if (moveclear(player,dir, NULL)) {
cell_t *adjcell;
// if not in last two spots moved...
adjcell = getcellindir(player->cell, dir);
if ((adjcell != player->prevcell[0]) && (adjcell != player->prevcell[1])) {
poss[nposs++] = dir;
}
}
}
// only one possible direction?
if (nposs == 1) {
rundir = poss[0];
} else {
// stop running
stoprunning(player);
stopnow = B_TRUE;
}
}
if (rundir == D_NONE) {
stopnow = B_TRUE;
}
if (stopnow) {
stoprunning(player); stoprunning(player);
} else { } else {
if (trymove(player, dir, B_TRUE)) { if (trymove(player, rundir, B_TRUE)) {
// failed.
stoprunning(player); stoprunning(player);
} else { } else {
// moved ok - dont wait for input // moved ok. remember this dir.
f->val[0] = rundir;
// our turn ends
return; return;
} }
} }
@ -6478,18 +6610,25 @@ void drawstatus(void) {
curs_set(0); curs_set(0);
wclear(statwin); wclear(statwin);
xpleft = getxpforlev(player->level + 1) - player->xp; xpleft = getxpforlev(player->level + 1) - player->xp;
sprintf(buf, "[%-26s] Lv:%d", pname, wmove(statwin, 0, 0);
player->level); wattron(statwin, A_BOLD); wprintw(statwin, "["); wattroff(statwin, A_BOLD);
mvwprintw(statwin, 0, 0, buf); wprintw(statwin, "%-26s ", pname);
wattron(statwin, A_BOLD); wprintw(statwin, "] "); wattroff(statwin, A_BOLD);
wattron(statwin, A_BOLD); wprintw(statwin, "Lv:"); wattroff(statwin, A_BOLD);
sprintf(buf, "%d", player->level);
wprintw(statwin, buf);
if (lfhasflag(player, F_HASNEWLEVEL)) { if (lfhasflag(player, F_HASNEWLEVEL)) {
setcol(statwin, C_BOLDGREEN); setcol(statwin, C_BOLDGREEN);
wprintw(statwin, " LevUp",xpleft); wprintw(statwin, " LevUp",xpleft);
unsetcol(statwin, C_BOLDGREEN); unsetcol(statwin, C_BOLDGREEN);
} else { } else {
wprintw(statwin, " Next:%ld",xpleft); wattron(statwin, A_BOLD); wprintw(statwin, " Next:"); wattroff(statwin, A_BOLD);
wprintw(statwin, "%ld",xpleft);
} }
// blinded? // blinded?
if (isblind(player) && !lfhasflag(player, F_ASLEEP)) { if (isblind(player) && !lfhasflag(player, F_ASLEEP)) {
@ -6532,9 +6671,9 @@ void drawstatus(void) {
wprintw(statwin, " Resting"); wprintw(statwin, " Resting");
unsetcol(statwin, C_CYAN); unsetcol(statwin, C_CYAN);
} else if (lfhasflag(player, F_ASLEEP)) { } else if (lfhasflag(player, F_ASLEEP)) {
setcol(statwin, C_BLUE); setcol(statwin, C_MAGENTA);
wprintw(statwin, " Asleep"); wprintw(statwin, " Asleep");
unsetcol(statwin, C_BLUE); unsetcol(statwin, C_MAGENTA);
} else if (isprone(player)) { } else if (isprone(player)) {
setcol(statwin, C_YELLOW); setcol(statwin, C_YELLOW);
wprintw(statwin, " Prone"); wprintw(statwin, " Prone");
@ -6679,13 +6818,13 @@ void drawstatus(void) {
// good effects // good effects
f = lfhasflag(player, F_HIDING); f = lfhasflag(player, F_HIDING);
if (f) { if (f) {
setcol(statwin, C_BLUE); setcol(statwin, C_MAGENTA);
if (f->val[0] < 0) { if (f->val[0] < 0) {
wprintw(statwin, " Hiding--"); wprintw(statwin, " Hiding--");
} else { } else {
wprintw(statwin, " Hiding"); wprintw(statwin, " Hiding");
} }
unsetcol(statwin, C_BLUE); unsetcol(statwin, C_MAGENTA);
} }
// construct waiting string // construct waiting string
@ -6726,7 +6865,8 @@ void drawstatus(void) {
// HP // HP
mvwprintw(statwin, 1, 0, "HP:"); wmove(statwin, 1, 0);
wattron(statwin, A_BOLD); wprintw(statwin, "HP:"); wattroff(statwin, A_BOLD);
setcol(statwin, getpctcol(player->hp, player->maxhp)); setcol(statwin, getpctcol(player->hp, player->maxhp));
wprintw(statwin, "%d",player->hp); wprintw(statwin, "%d",player->hp);
unsetcol(statwin, getpctcol(player->hp, player->maxhp)); unsetcol(statwin, getpctcol(player->hp, player->maxhp));
@ -6734,21 +6874,28 @@ void drawstatus(void) {
// MP // MP
if (getmaxmp(player) > 0) { if (getmaxmp(player) > 0) {
wprintw(statwin, "MP:"); wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD);
setcol(statwin, getpctcol(player->mp, getmaxmp(player))); setcol(statwin, getpctcol(player->mp, getmaxmp(player)));
wprintw(statwin, "%d",player->mp); wprintw(statwin, "%d",player->mp);
unsetcol(statwin, getpctcol(player->mp, getmaxmp(player))); unsetcol(statwin, getpctcol(player->mp, getmaxmp(player)));
wprintw(statwin, "/%d%s ",getmaxmp(player),maxmpstr); wprintw(statwin, "/%d%s ",getmaxmp(player),maxmpstr);
} else { } else {
wprintw(statwin, "MP:- "); wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD);
wprintw(statwin, "- ");
} }
sprintf(buf, "$:%d AR:%d ", countmoney(player), getarmourrating(player)); wattron(statwin, A_BOLD); wprintw(statwin, "$:"); wattroff(statwin, A_BOLD);
sprintf(buf, "%d ", countmoney(player));
wprintw(statwin, buf);
wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD);
sprintf(buf, "%d ", getarmourrating(player, NULL, NULL, NULL));
wprintw(statwin, buf); wprintw(statwin, buf);
wattron(statwin, A_BOLD); wprintw(statwin, "EV:"); wattroff(statwin, A_BOLD);
wprintw(statwin, "%d ", getevasion(player));
for (a = 0; a < MAXATTS; a++) { for (a = 0; a < MAXATTS; a++) {
wprintw(statwin, "%s:", getattrabbrev(a)); wattron(statwin, A_BOLD); wprintw(statwin, "%s:",getattrabbrev(a)); wattroff(statwin, A_BOLD);
if (myatt[a] == player->baseatt[a]) { if (myatt[a] == player->baseatt[a]) {
wprintw(statwin, "%d ",myatt[a]); wprintw(statwin, "%d ",myatt[a]);
} else { } else {
@ -6864,7 +7011,7 @@ void setobcolour(WINDOW *win, object_t *o, int set) {
if (!o) return; if (!o) return;
// unpaid? // unpaid?
if (hasflag(o->flags, F_SHOPITEM)) { if (hasflag(o->flags, F_SHOPITEM) && o->pile->owner) {
funcptr(win, C_ORANGE); funcptr(win, C_ORANGE);
return; return;
} }
@ -6898,9 +7045,9 @@ void showlfarmour(lifeform_t *lf) {
cls(); cls();
if (isplayer(lf)) { if (isplayer(lf)) {
centre(mainwin, 0, "CHARACTER EQUIPMENT"); centre(mainwin, C_WHITE, 0, "CHARACTER EQUIPMENT");
} else{ } else{
centre(mainwin, 0, "MONSTER EQUIPMENT"); centre(mainwin, C_WHITE, 0, "MONSTER EQUIPMENT");
} }
y = 2; y = 2;
@ -6939,7 +7086,7 @@ void showlfarmour(lifeform_t *lf) {
} }
} }
y = getmaxy(mainwin); y = getmaxy(mainwin);
centre(mainwin, y-1, "[Press any key]"); centre(mainwin, C_WHITE, y-1, "[Press any key]");
/* /*
@ -6998,6 +7145,7 @@ void showlfstats(lifeform_t *lf, int showall) {
int done = B_FALSE; int done = B_FALSE;
enum SKILLLEVEL lorelev; enum SKILLLEVEL lorelev;
enum COLOUR lorecol; enum COLOUR lorecol;
int min,max;
h = getmaxy(mainwin); h = getmaxy(mainwin);
@ -7038,9 +7186,9 @@ void showlfstats(lifeform_t *lf, int showall) {
ch = '\0'; ch = '\0';
if (mode == '@') { if (mode == '@') {
if (isplayer(lf)) { if (isplayer(lf)) {
centre(mainwin, 0, "CHARACTER DETAILS"); centre(mainwin, C_WHITE, 0, "CHARACTER DETAILS");
} else{ } else{
centre(mainwin, 0, "MONSTER DETAILS"); centre(mainwin, C_WHITE, 0, "MONSTER DETAILS");
} }
y = 2; y = 2;
y2 = 2; y2 = 2;
@ -7053,34 +7201,34 @@ void showlfstats(lifeform_t *lf, int showall) {
} else { } else {
getlfnamea(lf, buf); getlfnamea(lf, buf);
} }
mvwprintw(mainwin, y, 0, ftext, "Name"); doheadingsmall(mainwin, y, 0, ftext, "Name");
wprintw(mainwin, "%-20s", buf); y++; wprintw(mainwin, "%-20s", buf); y++;
if (isplayer(lf)) { if (isplayer(lf)) {
mvwprintw(mainwin, y, 0, ftext, "Race"); doheadingsmall(mainwin, y, 0, ftext, "Race");
wprintw(mainwin, "%-20s", lf->race->name); y++; wprintw(mainwin, "%-20s", lf->race->name); y++;
} else { } else {
mvwprintw(mainwin, y, 0, ftext, "Type"); doheadingsmall(mainwin, y, 0, ftext, "Type");
wprintw(mainwin, "%-20s", lf->race->raceclass->name); y++; wprintw(mainwin, "%-20s", lf->race->raceclass->name); y++;
} }
j = getjob(lf); j = getjob(lf);
if (j) { if (j) {
mvwprintw(mainwin, y, 0, ftext, "Job"); doheadingsmall(mainwin, y, 0, ftext, "Job");
sprintf(buf, "Level %d %s", lf->level, j->name); sprintf(buf, "Level %d %s", lf->level, j->name);
wprintw(mainwin, "%-20s", buf); y++; wprintw(mainwin, "%-20s", buf); y++;
} }
// size // size
mvwprintw(mainwin, y, 0, ftext, "Size"); doheadingsmall(mainwin, y, 0, ftext, "Size");
wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++; wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++;
if (showall) { if (showall) {
float w; float w;
w = getlfweight(lf, B_NOOBS); w = getlfweight(lf, B_NOOBS);
mvwprintw(mainwin, y, 0, ftext, "Weight"); doheadingsmall(mainwin, y, 0, ftext, "Weight");
getweighttext(w, buf); getweighttext(w, buf);
wprintw(mainwin, buf, w); y++; wprintw(mainwin, buf, w); y++;
} }
@ -7090,15 +7238,15 @@ void showlfstats(lifeform_t *lf, int showall) {
if (showall || if (showall ||
(getseenlfconditioncutoff(player) == C_HEALTHY) || (getseenlfconditioncutoff(player) == C_HEALTHY) ||
(lorelev >= PR_ADEPT)) { (lorelev >= PR_ADEPT)) {
doheadingsmall(mainwin, y, 0, ftext, "Hit Points");
if (lorelev >= PR_ADEPT) setcol(mainwin, lorecol); if (lorelev >= PR_ADEPT) setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, ftext, "Hit Points");
wprintw(mainwin, "%d / %d", lf->hp , lf->maxhp); y++; wprintw(mainwin, "%d / %d", lf->hp , lf->maxhp); y++;
if (lorelev >= PR_ADEPT) unsetcol(mainwin, lorecol); if (lorelev >= PR_ADEPT) unsetcol(mainwin, lorecol);
} else { } else {
char hpinfo[BUFLEN]; char hpinfo[BUFLEN];
sprintf(hpinfo, "%s",getseenlfconditionname(lf, player)); sprintf(hpinfo, "%s",getseenlfconditionname(lf, player));
if (strlen(hpinfo) > 0) { if (strlen(hpinfo) > 0) {
mvwprintw(mainwin, y, 0, ftext, "Hit Points"); doheadingsmall(mainwin, y, 0, ftext, "Hit Points");
wprintw(mainwin, "%s", hpinfo); y++; wprintw(mainwin, "%s", hpinfo); y++;
} }
} }
@ -7111,11 +7259,11 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(maxmpstr, "(%d)",lf->maxmp); sprintf(maxmpstr, "(%d)",lf->maxmp);
} }
mvwprintw(mainwin, y, 0, ftext, "Mana"); doheadingsmall(mainwin, y, 0, ftext, "Mana");
wprintw(mainwin, "%d / %d%s", lf->mp , lf->maxmp,maxmpstr); y++; wprintw(mainwin, "%d / %d%s", lf->mp , lf->maxmp,maxmpstr); y++;
} }
if (showall) { if (showall) {
mvwprintw(mainwin, y, 0, ftext, "Exp Level"); doheadingsmall(mainwin, y, 0, ftext, "Exp Level");
if (isplayer(lf)) { if (isplayer(lf)) {
xpneeded = getxpforlev(lf->level + 1) - lf->xp; xpneeded = getxpforlev(lf->level + 1) - lf->xp;
wprintw(mainwin, "%d (%ld XP, %ld for next)", lf->level, lf->xp, xpneeded); y++; wprintw(mainwin, "%d (%ld XP, %ld for next)", lf->level, lf->xp, xpneeded); y++;
@ -7125,7 +7273,7 @@ void showlfstats(lifeform_t *lf, int showall) {
if (isplayer(lf)) { if (isplayer(lf)) {
int attpoints; int attpoints;
attpoints = getattpoints(lf); attpoints = getattpoints(lf);
mvwprintw(mainwin, y, 0, ftext, "Training"); doheadingsmall(mainwin, y, 0, ftext, "Training");
if ((lf->skillpoints == 0) && (attpoints == 0)) { if ((lf->skillpoints == 0) && (attpoints == 0)) {
wprintw(mainwin, "n/a"); wprintw(mainwin, "n/a");
} else { } else {
@ -7152,16 +7300,16 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(buf, "%d (%s, -%d%% dmg)",str, buf2, (int)(100 - (dammod * 100)) ); sprintf(buf, "%d (%s, -%d%% dmg)",str, buf2, (int)(100 - (dammod * 100)) );
} }
if (str != lf->baseatt[A_STR]) strcat(buf, "*"); if (str != lf->baseatt[A_STR]) strcat(buf, "*");
mvwprintw(mainwin, y, 0, ftext, "STR"); doheadingsmall(mainwin, y, 0, ftext, "Strength");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
int str; int str;
// just show name // just show name
str = getattr(lf, A_STR); str = getattr(lf, A_STR);
getstrname(str, buf); getstrname(str, buf);
doheadingsmall(mainwin, y, 0, ftext, "Strength");
if (str != lf->baseatt[A_STR]) strcat(buf, "*"); if (str != lf->baseatt[A_STR]) strcat(buf, "*");
setcol(mainwin, lorecol); setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, ftext, "STR");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
unsetcol(mainwin, lorecol); unsetcol(mainwin, lorecol);
} }
@ -7181,7 +7329,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
if (dex != lf->baseatt[A_DEX]) strcat(buf, "*"); if (dex != lf->baseatt[A_DEX]) strcat(buf, "*");
mvwprintw(mainwin, y, 0, ftext, "DEX"); doheadingsmall(mainwin, y, 0, ftext, "Dexterity");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
int dex; int dex;
@ -7189,8 +7337,8 @@ void showlfstats(lifeform_t *lf, int showall) {
dex = getattr(lf, A_DEX); dex = getattr(lf, A_DEX);
getdexname(dex, buf); getdexname(dex, buf);
if (dex != lf->baseatt[A_DEX]) strcat(buf, "*"); if (dex != lf->baseatt[A_DEX]) strcat(buf, "*");
doheadingsmall(mainwin, y, 0, ftext, "Dexterity");
setcol(mainwin, lorecol); setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, ftext, "DEX");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
unsetcol(mainwin, lorecol); unsetcol(mainwin, lorecol);
} }
@ -7202,7 +7350,7 @@ void showlfstats(lifeform_t *lf, int showall) {
getiqname(iq, buf2); getiqname(iq, buf2);
sprintf(buf, "%d (%s)",iq, buf2); sprintf(buf, "%d (%s)",iq, buf2);
if (iq != lf->baseatt[A_IQ]) strcat(buf, "*"); if (iq != lf->baseatt[A_IQ]) strcat(buf, "*");
mvwprintw(mainwin, y, 0, ftext, "IQ"); doheadingsmall(mainwin, y, 0, ftext, "Intelligence");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
int iq; int iq;
@ -7210,8 +7358,8 @@ void showlfstats(lifeform_t *lf, int showall) {
iq = getattr(lf, A_IQ); iq = getattr(lf, A_IQ);
getiqname(iq, buf); getiqname(iq, buf);
if (iq != lf->baseatt[A_IQ]) strcat(buf, "*"); if (iq != lf->baseatt[A_IQ]) strcat(buf, "*");
doheadingsmall(mainwin, y, 0, ftext, "Intelligence");
setcol(mainwin, lorecol); setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, ftext, "IQ");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
unsetcol(mainwin, lorecol); unsetcol(mainwin, lorecol);
} }
@ -7223,7 +7371,7 @@ void showlfstats(lifeform_t *lf, int showall) {
getconname(con, buf2); getconname(con, buf2);
sprintf(buf, "%d (%s)",con, buf2); sprintf(buf, "%d (%s)",con, buf2);
if (con != lf->baseatt[A_CON]) strcat(buf, "*"); if (con != lf->baseatt[A_CON]) strcat(buf, "*");
mvwprintw(mainwin, y, 0, ftext, "CON"); doheadingsmall(mainwin, y, 0, ftext, "Fitness");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
int con; int con;
@ -7231,8 +7379,29 @@ void showlfstats(lifeform_t *lf, int showall) {
con = getattr(lf, A_CON); con = getattr(lf, A_CON);
getconname(con, buf); getconname(con, buf);
if (con != lf->baseatt[A_CON]) strcat(buf, "*"); if (con != lf->baseatt[A_CON]) strcat(buf, "*");
doheadingsmall(mainwin, y, 0, ftext, "Fitness");
setcol(mainwin, lorecol);
wprintw(mainwin, "%s", buf); y++;
unsetcol(mainwin, lorecol);
}
if (showall) {
char buf2[BUFLEN];
int cha;
cha = getattr(lf, A_CHA);
getchaname(cha, buf2);
sprintf(buf, "%d (%s)",cha, buf2);
if (cha != lf->baseatt[A_CHA]) strcat(buf, "*");
doheadingsmall(mainwin, y, 0, ftext, "Charisma");
wprintw(mainwin, "%s", buf); y++;
} else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) {
int cha;
// just show name
cha = getattr(lf, A_CHA);
getconname(cha, buf);
if (cha != lf->baseatt[A_CHA]) strcat(buf, "*");
doheadingsmall(mainwin, y, 0, ftext, "Charisma");
setcol(mainwin, lorecol); setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, ftext, "CON");
wprintw(mainwin, "%s", buf); y++; wprintw(mainwin, "%s", buf); y++;
unsetcol(mainwin, lorecol); unsetcol(mainwin, lorecol);
} }
@ -7246,8 +7415,13 @@ void showlfstats(lifeform_t *lf, int showall) {
// now go to second column // now go to second column
mvwprintw(mainwin, y2, x2, ftext, "# Attacks"); doheadingsmall(mainwin, y2, x2, ftext, "# Attacks");
wprintw(mainwin, "%d", getmaxattacks(lf)); y2++; getattacks(lf, &min, &max);
if (min == max) {
wprintw(mainwin, "%d", max); y2++;
} else {
wprintw(mainwin, "%d-%d", min,max); y2++;
}
y2++; y2++;
// current weapon + dam // current weapon + dam
@ -7305,7 +7479,7 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(buf, "%s (%d-%d dmg)", w[i]->type->name,(int)mindam,(int)maxdam); sprintf(buf, "%s (%d-%d dmg)", w[i]->type->name,(int)mindam,(int)maxdam);
mvwprintw(mainwin, y2, x2, ftext, "Weapon"); doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
wprintw(mainwin, "%-20s", buf); y2++; wprintw(mainwin, "%-20s", buf); y2++;
// attack speed // attack speed
@ -7320,13 +7494,13 @@ void showlfstats(lifeform_t *lf, int showall) {
} else { } else {
// just show weapon name // just show weapon name
sprintf(buf, "%s", w[i]->type->name); sprintf(buf, "%s", w[i]->type->name);
mvwprintw(mainwin, y2, x2, ftext, "Weapon"); doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
wprintw(mainwin, "%-20s", buf); y2++; wprintw(mainwin, "%-20s", buf); y2++;
} }
} else { } else {
// no weapon // no weapon
sprintf(buf, "N/A"); sprintf(buf, "N/A");
mvwprintw(mainwin, y2, x2, ftext, "Current Weapon"); doheadingsmall(mainwin, y2, x2, ftext, "Current Weapon");
wprintw(mainwin, "%-20s", buf); y2++; wprintw(mainwin, "%-20s", buf); y2++;
} }
} // end for each weapon } // end for each weapon
@ -7372,7 +7546,7 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(dambuf, " (%d-%d dmg)",(int)mindam,(int)maxdam); sprintf(dambuf, " (%d-%d dmg)",(int)mindam,(int)maxdam);
} }
mvwprintw(mainwin, y2, x2, ftext, "Innate Attack"); doheadingsmall(mainwin, y2, x2, ftext, "Innate Attack");
wprintw(mainwin, "%s", buf); wprintw(mainwin, "%s", buf);
if (strlen(dambuf)) { if (strlen(dambuf)) {
if (lorelev >= PR_BEGINNER) setcol(mainwin, lorecol); if (lorelev >= PR_BEGINNER) setcol(mainwin, lorecol);
@ -7389,7 +7563,7 @@ void showlfstats(lifeform_t *lf, int showall) {
// no attacks at all? // no attacks at all?
if ((nweps == 0) && !op->first) { if ((nweps == 0) && !op->first) {
sprintf(buf, "N/A"); sprintf(buf, "N/A");
mvwprintw(mainwin, y2, x2, ftext, "Attack"); doheadingsmall(mainwin, y2, x2, ftext, "Attack");
wprintw(mainwin, "%-20s", buf); y2++; wprintw(mainwin, "%-20s", buf); y2++;
} }
@ -7400,11 +7574,10 @@ void showlfstats(lifeform_t *lf, int showall) {
// ARMOUR STUFF // ARMOUR STUFF
if (showall || (lorelev >= PR_NOVICE)) { if (showall || (lorelev >= PR_NOVICE)) {
arating = getarmourrating(lf); arating = getarmourrating(lf, NULL, NULL, NULL);
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
mvwprintw(mainwin, y2, x2, ftext, "Armour Rating"); doheadingsmall(mainwin, y2, x2, ftext, "Armour Rating");
/* /*
if (arating > 0) { if (arating > 0) {
wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++; wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++;
@ -7412,16 +7585,19 @@ void showlfstats(lifeform_t *lf, int showall) {
wprintw(mainwin, "%d", arating); y2++; wprintw(mainwin, "%d", arating); y2++;
} }
*/ */
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
wprintw(mainwin, "%d", arating); y2++; wprintw(mainwin, "%d", arating); y2++;
if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol); if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol);
} }
if (showall) { if (showall || (lorelev >= PR_NOVICE)) {
evasion = getevasion(lf); evasion = getevasion(lf);
mvwprintw(mainwin, y2, x2, ftext, "Evasion"); doheadingsmall(mainwin, y2, x2, ftext, "Evasion");
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
wprintw(mainwin, "%d%%", evasion); y2++; wprintw(mainwin, "%d%%", evasion); y2++;
y2++; // skip line y2++; // skip line
if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol);
} }
getspeednameshort(getactspeed(player), actbuf); getspeednameshort(getactspeed(player), actbuf);
@ -7433,7 +7609,7 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(buf, "Mv:%s Act:%s", movebuf,actbuf); sprintf(buf, "Mv:%s Act:%s", movebuf,actbuf);
} }
mvwprintw(mainwin, y2, x2, ftext, "Speed"); doheadingsmall(mainwin, y2, x2, ftext, "Speed");
wprintw(mainwin, "%-20s", buf); y2++; wprintw(mainwin, "%-20s", buf); y2++;
y2++; // skip line y2++; // skip line
@ -7442,10 +7618,10 @@ void showlfstats(lifeform_t *lf, int showall) {
if (showall) { if (showall) {
f = hasflag(lf->flags, F_HUNGER); f = hasflag(lf->flags, F_HUNGER);
if (f) { if (f) {
doheadingsmall(mainwin, y2, x2, ftext, "Hunger");
gethungername(gethungerlevel(f->val[0]), buf); gethungername(gethungerlevel(f->val[0]), buf);
capitalise(buf); capitalise(buf);
mvwprintw(mainwin, y2, x2, ftext, "Hunger");
wprintw(mainwin, "%-14s", buf); y2++; wprintw(mainwin, "%-14s", buf); y2++;
/* /*
if (showall) { if (showall) {
@ -7845,7 +8021,7 @@ void showlfstats(lifeform_t *lf, int showall) {
int exitnow = B_FALSE; int exitnow = B_FALSE;
// now show intrinsics on next page // now show intrinsics on next page
centre(mainwin, 0, "ABILITIES"); centre(mainwin, C_WHITE, 0, "ABILITIES");
y = 2; y = 2;
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
@ -7880,8 +8056,14 @@ void showlfstats(lifeform_t *lf, int showall) {
} else { } else {
strcpy(eb2, ""); strcpy(eb2, "");
} }
sprintf(buf, "%-12s%s%s", ot->name, ot->desc, eb2); setcol(mainwin, C_GREEN);
sprintf(buf, "%-12s", ot->name);
mvwprintw(mainwin, y, 0, buf); mvwprintw(mainwin, y, 0, buf);
unsetcol(mainwin, C_GREEN);
sprintf(buf, "%s%s", ot->desc, eb2);
wprintw(mainwin, buf);
if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) { if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
break; break;
@ -7913,16 +8095,20 @@ void showlfstats(lifeform_t *lf, int showall) {
doheading(mainwin, &y, 0, skilltitle); doheading(mainwin, &y, 0, skilltitle);
for (n = 0; n < MAXOF(numknown,numavailable); n++) { for (n = 0; n < MAXOF(numknown,numavailable); n++) {
if (n < numavailable) { if (n < numavailable) {
setcol(mainwin, C_RED);
mvwprintw(mainwin, y, 0, "- %s", mvwprintw(mainwin, y, 0, "- %s",
getskillname(available[n]->val[0]) ); getskillname(available[n]->val[0]) );
unsetcol(mainwin, C_RED);
} }
if (n < numknown) { if (n < numknown) {
setcol(mainwin, getskilllevelcolour(known[n]->val[1]));
mvwprintw(mainwin, y, 40, "%c %s (%s)%s", mvwprintw(mainwin, y, 40, "%c %s (%s)%s",
ismaxedskill(lf, known[n]->val[0]) ? '*' : '-', ismaxedskill(lf, known[n]->val[0]) ? '*' : '-',
getskillname(known[n]->val[0]), getskillname(known[n]->val[0]),
getskilllevelname(known[n]->val[1]), getskilllevelname(known[n]->val[1]),
//ismaxedskill(lf, known[n]->val[0]) ? "/MAX" : "", //ismaxedskill(lf, known[n]->val[0]) ? "/MAX" : "",
(known[n]->lifetime == FROMSPELL) ? "[spell]" : ""); (known[n]->lifetime == FROMSPELL) ? "[spell]" : "");
unsetcol(mainwin, getskilllevelcolour(known[n]->val[1]));
} }
if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) { if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
@ -7938,7 +8124,7 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(subheading, " %-4s%-26s%-15s%-13s%s","Lv","Spell", "School", "Power", "Cost"); sprintf(subheading, " %-4s%-26s%-15s%-13s%s","Lv","Spell", "School", "Power", "Cost");
centre(mainwin, y, "MAGIC"); y += 2; centre(mainwin, C_WHITE, y, "MAGIC"); y += 2;
doheading(mainwin, &y, 0, subheading); doheading(mainwin, &y, 0, subheading);
//if (!isplayer(lf)) { //if (!isplayer(lf)) {
// show spells monster can cast using mp // show spells monster can cast using mp
@ -7959,6 +8145,7 @@ void showlfstats(lifeform_t *lf, int showall) {
int power; int power;
int mpcost; int mpcost;
int castable = B_TRUE; int castable = B_TRUE;
int atwill = B_FALSE;
// power // power
power = getspellpower(lf, ot->id); power = getspellpower(lf, ot->id);
@ -7982,6 +8169,7 @@ void showlfstats(lifeform_t *lf, int showall) {
sprintf(mpbuf, "At will, every %d turn%s",f->val[2], sprintf(mpbuf, "At will, every %d turn%s",f->val[2],
(f->val[2] == 1) ? "" : "s"); (f->val[2] == 1) ? "" : "s");
} }
atwill = B_TRUE;
} else { } else {
mpcost = getmpcost(lf, ot->id); mpcost = getmpcost(lf, ot->id);
if (mpcost) { if (mpcost) {
@ -7991,15 +8179,19 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
} }
if ((mpcost > getmaxmp(lf)) || (power <= 0)) { if (!atwill) {
castable = B_FALSE; if ((mpcost > getmaxmp(lf)) || (power <= 0)) {
castable = B_FALSE;
}
} }
getspellname(ot->id, lf, spellname); getspellname(ot->id, lf, spellname);
if (!castable) setcol(mainwin, C_RED); if (castable) setcol(mainwin, C_GREEN);
else setcol(mainwin, C_RED);
sprintf(buf, " %-4d%-26s%-15s%-13s%s",thislev, spellname, getschoolnameshort(getspellschoolknown(lf, ot->id)), powerbuf, mpbuf); sprintf(buf, " %-4d%-26s%-15s%-13s%s",thislev, spellname, getschoolnameshort(getspellschoolknown(lf, ot->id)), powerbuf, mpbuf);
mvwprintw(mainwin, y, 0, "%s\n", buf); mvwprintw(mainwin, y, 0, "%s\n", buf);
if (!castable) unsetcol(mainwin, C_RED); if (castable) unsetcol(mainwin, C_GREEN);
else unsetcol(mainwin, C_RED);
anyfound = B_TRUE; anyfound = B_TRUE;
if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) { if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
@ -8017,7 +8209,7 @@ void showlfstats(lifeform_t *lf, int showall) {
int nfound = 0; int nfound = 0;
x = 0; // override x = 0; // override
// down a line. // down a line.
centre(mainwin, y, "EFFECTS"); centre(mainwin, C_WHITE, y, "EFFECTS");
y += 2; y += 2;
@ -8477,7 +8669,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} else if (mode == 'i') { } else if (mode == 'i') {
object_t *o; object_t *o;
cls(); cls();
centre(mainwin, 0, "INVENTORY"); centre(mainwin, C_WHITE, 0, "INVENTORY");
y = 2; y = 2;
if (lfhasflag(lf, F_NOPACK)) { if (lfhasflag(lf, F_NOPACK)) {
mvwprintw(mainwin, y, 0, "It cannot carry anything."); mvwprintw(mainwin, y, 0, "It cannot carry anything.");
@ -8506,7 +8698,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
// wait for key // wait for key
centre(mainwin, h-1, prompt); centre(mainwin, C_WHITE, h-1, prompt);
if (ch == '\0') { if (ch == '\0') {
ch = getch(); ch = getch();
} }
@ -8558,33 +8750,33 @@ void tombstone(lifeform_t *lf) {
cls(); cls();
y = 1; y = 1;
centre(mainwin, y, "R.I.P."); y++; centre(mainwin, C_GREY, y, "R.I.P."); y++;
//printf("%s\n",lf->name); //printf("%s\n",lf->name);
centre(mainwin, y, "%s (%ld points)",pname, calcscore(lf)); y++; centre(mainwin, C_GREY, y, "%s (%ld points)",pname, calcscore(lf)); y++;
if (player->cell->map->region->rtype->id == RG_WORLDMAP) { if (player->cell->map->region->rtype->id == RG_WORLDMAP) {
getregionname(buf, player->cell->map, B_TRUE); getregionname(buf, player->cell->map, B_TRUE);
centre(mainwin, y, "Died on %s.", buf); y++; centre(mainwin, C_GREY, y, "Died on %s.", buf); y++;
} else { } else {
getregionname(buf, player->cell->map, B_FALSE); getregionname(buf, player->cell->map, B_FALSE);
centre(mainwin, y, "Died on level %d of %s.", player->cell->map->depth, buf); y++; centre(mainwin, C_GREY, y, "Died on level %d of %s.", player->cell->map->depth, buf); y++;
} }
p = strtok_r(lf->lastdam,"^", &dummy); p = strtok_r(lf->lastdam,"^", &dummy);
if (p) { if (p) {
if (!strcmp(p, "you")) { if (!strcmp(p, "you")) {
centre(mainwin, y, "Committed suicide.",p); y++; centre(mainwin, C_GREY, y, "Committed suicide.",p); y++;
} else { } else {
centre(mainwin, y, "Killed by %s.",p); y++; centre(mainwin, C_GREY, y, "Killed by %s.",p); y++;
} }
p = strtok_r(NULL, "^", &dummy); p = strtok_r(NULL, "^", &dummy);
while (p) { while (p) {
centre(mainwin, y, "(%s)",p); y++; centre(mainwin, C_GREY, y, "(%s)",p); y++;
p = strtok_r(NULL, "^", &dummy); p = strtok_r(NULL, "^", &dummy);
} }
} else { } else {
centre(mainwin, y, "Killed by something unknown."); y++; centre(mainwin, C_GREY, y, "Killed by something unknown."); y++;
} }

3
io.h
View File

@ -24,7 +24,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars);
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail); cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def); char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
vault_t *askvault(char *prompttext); vault_t *askvault(char *prompttext);
void centre(WINDOW *win, int y, char *format, ... ); void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );
int chartodir(char ch); int chartodir(char ch);
char checkforkey(void); char checkforkey(void);
int cleanupgfx(void); int cleanupgfx(void);
@ -84,6 +84,7 @@ int getkey(void);
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev); enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev);
void handleinput(void); void handleinput(void);
void doheading(WINDOW *win, int *y, int x, char *what); void doheading(WINDOW *win, int *y, int x, char *what);
void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading);
void initgfx(void); void initgfx(void);
void initprompt(prompt_t *p, char *q1); void initprompt(prompt_t *p, char *q1);
int keycodetokey(int keycode); int keycodetokey(int keycode);

633
lf.c

File diff suppressed because it is too large Load Diff

14
lf.h
View File

@ -27,7 +27,7 @@ void callguards(lifeform_t *caller, lifeform_t *victim);
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost); int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost);
int candrink(lifeform_t *lf, object_t *o); int candrink(lifeform_t *lf, object_t *o);
int caneat(lifeform_t *lf, object_t *o); int caneat(lifeform_t *lf, object_t *o);
int canhear(lifeform_t *lf, cell_t *c); int canhear(lifeform_t *lf, cell_t *c, int volume);
int canlearn(lifeform_t *lf, enum SKILL skid); int canlearn(lifeform_t *lf, enum SKILL skid);
int canopendoors(lifeform_t *lf); int canopendoors(lifeform_t *lf);
int canpickup(lifeform_t *lf, object_t *o, int amt); int canpickup(lifeform_t *lf, object_t *o, int amt);
@ -87,7 +87,7 @@ enum ALLEGIENCE getallegiance(lifeform_t *lf);
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs); int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
object_t *getarmour(lifeform_t *lf, enum BODYPART bp); object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
int getarmournoise(lifeform_t *lf); int getarmournoise(lifeform_t *lf);
int getarmourrating(lifeform_t *lf); int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms);
int getattackspeed(lifeform_t *lf); int getattackspeed(lifeform_t *lf);
int getattpoints(lifeform_t *lf); int getattpoints(lifeform_t *lf);
int getattr(lifeform_t *lf, enum ATTRIB attr); int getattr(lifeform_t *lf, enum ATTRIB attr);
@ -128,7 +128,7 @@ char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer);
glyph_t *getlfglyph(lifeform_t *lf); glyph_t *getlfglyph(lifeform_t *lf);
enum MATERIAL getlfmaterial(lifeform_t *lf); enum MATERIAL getlfmaterial(lifeform_t *lf);
enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid); enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid);
int getmaxattacks(lifeform_t *lf); int getattacks(lifeform_t *lf, int *min, int *max);
float getmaxcarryweight(lifeform_t *lf); float getmaxcarryweight(lifeform_t *lf);
float getmaxliftweight(lifeform_t *lf); float getmaxliftweight(lifeform_t *lf);
int getmaxmp(lifeform_t *lf); int getmaxmp(lifeform_t *lf);
@ -164,10 +164,12 @@ race_t *getreallyrandomrace(enum RACECLASS wantrc);
enum SKILL getrandomskill(void); enum SKILL getrandomskill(void);
object_t *getrestob(lifeform_t *lf); object_t *getrestob(lifeform_t *lf);
enum SKILLLEVEL getskill(lifeform_t *lf, enum SKILL id); enum SKILLLEVEL getskill(lifeform_t *lf, enum SKILL id);
int getsounddist(int volume);
char *getspeedname(int speed, char *buf); char *getspeedname(int speed, char *buf);
char *getspeednameshort(int speed, char *buf); char *getspeednameshort(int speed, char *buf);
float getstatmod(lifeform_t *lf, enum ATTRIB att); float getstatmod(lifeform_t *lf, enum ATTRIB att);
enum CONBRACKET getconname(int str, char *buf); enum CHABRACKET getchaname(int cha, char *buf);
enum CONBRACKET getconname(int con, char *buf);
enum STRBRACKET getstrname(int str, char *buf); enum STRBRACKET getstrname(int str, char *buf);
enum DEXBRACKET getdexname(int dex, char *buf); enum DEXBRACKET getdexname(int dex, char *buf);
enum IQBRACKET getiqname(int iq, char *buf); enum IQBRACKET getiqname(int iq, char *buf);
@ -237,6 +239,7 @@ object_t *isstuck(lifeform_t *lf);
int isswimming(lifeform_t *lf); int isswimming(lifeform_t *lf);
int isundead(lifeform_t *lf); int isundead(lifeform_t *lf);
flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt); flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt);
int isweaponskill(enum SKILL skid);
void killjob(job_t *job); void killjob(job_t *job);
void killlf(lifeform_t *lf); void killlf(lifeform_t *lf);
void killrace(race_t *race); void killrace(race_t *race);
@ -256,7 +259,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
void modhunger(lifeform_t *lf, int amt); void modhunger(lifeform_t *lf, int amt);
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att); float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
int needstorest(lifeform_t *lf, char *validchars); int needstorest(lifeform_t *lf, char *validchars);
int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seetext); int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
void outfitlf(lifeform_t *lf); void outfitlf(lifeform_t *lf);
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground); int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat); void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat);
@ -270,6 +273,7 @@ void refreshlevelabilities(lifeform_t *lf);
void relinklf(lifeform_t *src, map_t *dst); void relinklf(lifeform_t *src, map_t *dst);
int rest(lifeform_t *lf, int onpurpose); int rest(lifeform_t *lf, int onpurpose);
void startresting(lifeform_t *lf, int willtrain); void startresting(lifeform_t *lf, int willtrain);
int rollcha(enum CHABRACKET bracket);
int rollcon(enum CONBRACKET bracket); int rollcon(enum CONBRACKET bracket);
int rolldex(enum DEXBRACKET bracket); int rolldex(enum DEXBRACKET bracket);
int rolliq(enum IQBRACKET bracket); int rolliq(enum IQBRACKET bracket);

108
map.c
View File

@ -622,7 +622,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
if (newcell && !newcell->type->solid) { if (newcell && !newcell->type->solid) {
int doorcount; int doorcount;
// if so, make sure there are no other adjacent doors // if so, make sure there are no other adjacent doors
doorcount = countadjcellswithflag(cell[i], F_DOOR); doorcount = countadjcellswithflag(cell[i], F_DOOR, DT_ORTH);
if (doorcount == 0) { if (doorcount == 0) {
// if there is only one way out of the adjacent empty cell, and // if there is only one way out of the adjacent empty cell, and
// walls to either side of the potential door location, then // walls to either side of the potential door location, then
@ -632,6 +632,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
makedoor(cell[i], dooropenchance); makedoor(cell[i], dooropenchance);
} else { } else {
setcelltype(cell[i], cell[i]->habitat->emptycelltype); setcelltype(cell[i], cell[i]->habitat->emptycelltype);
addflag(map->flags, F_ROOMEXIT, roomid, cell[i]->x, cell[i]->y, NULL);
} }
} else { } else {
// otherwise mark this as a _potential_ door location. // otherwise mark this as a _potential_ door location.
@ -651,6 +652,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
makedoor(poss[sel], dooropenchance); makedoor(poss[sel], dooropenchance);
} else { } else {
setcelltype(poss[sel], poss[sel]->habitat->emptycelltype); setcelltype(poss[sel], poss[sel]->habitat->emptycelltype);
addflag(map->flags, F_ROOMEXIT, roomid, poss[sel]->x, poss[sel]->y, NULL);
} }
doorsadded++; doorsadded++;
@ -843,9 +845,11 @@ void clearcell(cell_t *c) {
while (c->obpile->first) { while (c->obpile->first) {
killob(c->obpile->first); killob(c->obpile->first);
} }
c->known = B_FALSE; if (gamemode == GM_GAMESTARTED) {
c->knownglyph.ch = ' '; c->known = B_FALSE;
c->knownglyph.colour = C_GREY; c->knownglyph.ch = ' ';
c->knownglyph.colour = C_GREY;
}
} }
// returns true if something happened // returns true if something happened
@ -1322,13 +1326,21 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
return B_FALSE; return B_FALSE;
} }
int countadjcellswithflag(cell_t *cell, enum FLAG fid) { int countadjcellswithflag(cell_t *cell, enum FLAG fid, int dirtype) {
int d; int d;
int count = 0; int count = 0;
int start, end;
cell_t *newcell; cell_t *newcell;
for (d = D_N; d < MAXDIR_ORTH; d++) { if (dirtype == DT_ORTH) {
start = D_N;
end = D_W;
} else {
start = DC_N;
end = DC_NW;
}
for (d = start; d <= end; d++) {
newcell = getcellindir(cell, d); newcell = getcellindir(cell, d);
if (newcell && hasobwithflag(cell->obpile, fid)) { if (newcell && hasobwithflag(newcell->obpile, fid)) {
count++; count++;
} }
} }
@ -1389,6 +1401,18 @@ int countcellexits(cell_t *cell) {
return exits; return exits;
} }
int countcellexitsfor(lifeform_t *lf) {
int d;
int exits = 0;
assert(lf);
for (d = DC_N; d <= DC_NW; d++) {
if (moveclear(lf, d, NULL)) {
exits++;
}
}
return exits;
}
// //
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int wantrooms = B_TRUE; int wantrooms = B_TRUE;
@ -1418,7 +1442,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
int moved = 0; int moved = 0;
enum CELLTYPE emptycell; enum CELLTYPE emptycell,solidcell;
// fill entire maze with walls // fill entire maze with walls
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
@ -1430,6 +1454,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
// what kind of cells will 'empty' ones be? // what kind of cells will 'empty' ones be?
emptycell = map->habitat->emptycelltype; emptycell = map->habitat->emptycelltype;
solidcell = map->habitat->solidcelltype;
// pick initial random spot // pick initial random spot
cell = getrandomcell(map); cell = getrandomcell(map);
@ -1531,8 +1556,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
} }
// introduce loops // introduce loops
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) { for (x = 0; x < map->w; x++) {
@ -1593,8 +1616,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
} }
} }
// create rooms // create rooms
if (wantrooms) { if (wantrooms) {
numrooms = rnd(minrooms, maxrooms); numrooms = rnd(minrooms, maxrooms);
@ -1615,9 +1636,11 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
} }
if (!roomvault[i]) { if (!roomvault[i]) {
int rx,ry;
// just do a normal room // just do a normal room
createroom(map, i, NA, NA, 0, 0, NULL, NULL, &roomw[i],&roomh[i], 50, B_FALSE); createroom(map, i, NA, NA, 0, 0, &rx, &ry, &roomw[i],&roomh[i], 50, B_FALSE);
roomvault[i] = B_FALSE; roomvault[i] = B_FALSE;
linkexits(map, i, rx, ry, rx+roomw[i]-1, ry+roomh[i]-1);
} }
} }
} }
@ -1746,6 +1769,29 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} // end if wantrooms & nrooms>0 } // end if wantrooms & nrooms>0
if (db) dblog("Finished adding objects."); if (db) dblog("Finished adding objects.");
// now do a border
y = 0;
for (x = 0; x < map->w; x++) {
// n
c = getcellat(map, x, 0);
clearcell(c);
setcelltype(c,solidcell);
// s
c = getcellat(map, x, map->h-1);
clearcell(c);
setcelltype(c,solidcell);
}
for (y = 1; y < map->h-1; y++) {
// w
c = getcellat(map, 0, y);
clearcell(c);
setcelltype(c,solidcell);
// e
c = getcellat(map, map->w-1, y);
clearcell(c);
setcelltype(c,solidcell);
}
} }
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) { void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
@ -2340,7 +2386,7 @@ int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
if (db) dblog("linkexits for roomid %d", roomid); if (db) dblog("linkexits for roomid %d", roomid);
// find all doors // TODO: ...or "exits" // find all doors or f_roomexits
for (y = miny; y <= maxy; y++) { for (y = miny; y <= maxy; y++) {
for (x = minx; x <= maxx; x++) { for (x = minx; x <= maxx; x++) {
c = getcellat(m, x, y); c = getcellat(m, x, y);
@ -2631,7 +2677,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
msg("You see %s explosion!", (range > 0) ? "a huge" : "an"); msg("You see %s explosion!", (range > 0) ? "a huge" : "an");
} }
} else { } else {
noise(c, NULL, (range > 0) ? 6 : 5, "an explosion!", NULL); noise(c, NULL, NC_OTHER, (range > 0) ? 6 : 5, "an explosion!", NULL);
} }
for (y = c->y - range ; y <= c->y + range ; y++) { for (y = c->y - range ; y <= c->y + range ; y++) {
@ -2827,7 +2873,7 @@ object_t *findobidinmap(map_t *m, long id) {
// find the cell in 'map' which contains object oid // find the cell in 'map' which contains object oid
cell_t *findobinmap(map_t *m, enum OBCLASS oid) { cell_t *findobinmap(map_t *m, enum OBTYPE oid) {
cell_t *c; cell_t *c;
int x,y; int x,y;
for (y = 0; y < m->h; y++) { for (y = 0; y < m->h; y++) {
@ -3422,6 +3468,7 @@ object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tfl
void initmap(void) { void initmap(void) {
int vx,vy;
// habitats // habitats
// thingchance, obchance, vaultchance // thingchance, obchance, vaultchance
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 10); addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 10);
@ -3453,10 +3500,18 @@ void initmap(void) {
// link to first dungeon // link to first dungeon
addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_FIRSTDUNGEON, "staircase going down"); addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_FIRSTDUNGEON, "staircase going down");
// the village // the village
addregionthing(lastregionoutline, NA, 0, -1, RT_HABITAT, H_VILLAGE, NULL); /*
addregionthing(lastregionoutline, NA, 0, -1, RT_VAULT, NA, "potion_shop"); vx = 0; vy = 0;
addregionthing(lastregionoutline, NA, 0, -1, RT_VAULT, NA, "weapon_shop"); while ((vx == 0) && (vy == 0)) {
addregionthing(lastregionoutline, NA, 0, -1, RT_VAULT, NA, "armour_shop"); vx = rnd(-2,2);
vy = rnd(-2,2);
}
*/
vx = 0; vy = -1;
addregionthing(lastregionoutline, NA, vx, vy, RT_HABITAT, H_VILLAGE, NULL);
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "potion_shop");
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "weapon_shop");
addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "armour_shop");
addregionoutline(RG_FIRSTDUNGEON); addregionoutline(RG_FIRSTDUNGEON);
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair"); addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");
} }
@ -3981,6 +4036,17 @@ void setcellknown(cell_t *cell, int forcelev) {
//getcellglyph(&(cell->knownglyph), cell, player); //getcellglyph(&(cell->knownglyph), cell, player);
} }
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype) {
cell_t *cell[MAXCANDIDATES];
int ncells,i;
getradiuscells(centre, radius, dirtype, LOF_DONTNEED, B_TRUE, cell, &ncells);
for (i = 0; i < ncells; i++) {
cell_t *c;
c = cell[i];
setcellknown(c, forcelev);
}
}
void setcelltype(cell_t *cell, enum CELLTYPE id) { void setcelltype(cell_t *cell, enum CELLTYPE id) {
assert(cell); assert(cell);
cell->type = findcelltype(id); cell->type = findcelltype(id);
@ -4012,7 +4078,7 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
seen = B_TRUE; seen = B_TRUE;
} else { } else {
// very loud // very loud
noise(c, NULL, 7, "shattering glass.", NULL); noise(c, NULL, NC_OTHER, 7, "shattering glass.", NULL);
} }
if (target) { if (target) {

6
map.h
View File

@ -32,9 +32,10 @@ void calclight(map_t *map);
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force); int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force);
int countadjcellsoftype(cell_t *cell, int id); int countadjcellsoftype(cell_t *cell, int id);
int countadjrooms(cell_t *cell); int countadjrooms(cell_t *cell);
int countadjcellswithflag(cell_t *cell, enum FLAG fid); int countadjcellswithflag(cell_t *cell, enum FLAG fid, int dirtype);
int countadjwalls(cell_t *cell); int countadjwalls(cell_t *cell);
int countcellexits(cell_t *cell); int countcellexits(cell_t *cell);
int countcellexitsfor(lifeform_t *lf);
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings); void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings);
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
@ -56,7 +57,7 @@ map_t *findmap(int mid);
map_t *findmapofdepth(int depth); map_t *findmapofdepth(int depth);
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf); cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
object_t *findobidinmap(map_t *m, long id); object_t *findobidinmap(map_t *m, long id);
cell_t *findobinmap(map_t *m, enum OBCLASS oid); cell_t *findobinmap(map_t *m, enum OBTYPE oid);
region_t *findregion(int regionid); region_t *findregion(int regionid);
region_t *findregionbytype(enum REGIONTYPE rtid); region_t *findregionbytype(enum REGIONTYPE rtid);
map_t *findregionmap(int regionid, int depth); map_t *findregionmap(int regionid, int depth);
@ -104,6 +105,7 @@ void makedoor(cell_t *cell, int openchance);
void makelit(cell_t *c, enum LIGHTLEV how, int howlong); void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong); void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
void setcellknown(cell_t *cell, int forcelev); void setcellknown(cell_t *cell, int forcelev);
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
void setcelltype(cell_t *cell, enum CELLTYPE id); void setcelltype(cell_t *cell, enum CELLTYPE id);
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring); int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
void updateknowncells(void); void updateknowncells(void);

50
move.c
View File

@ -482,7 +482,7 @@ int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int d
} }
dist[d - DC_N] = thisdist; dist[d - DC_N] = thisdist;
if (thisdist > maxdist) { if (thisdist >= maxdist) {
maxdist = thisdist; maxdist = thisdist;
bestdir = d; bestdir = d;
} }
@ -569,10 +569,11 @@ int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, in
thisdist = getcelldist(c, dst); thisdist = getcelldist(c, dst);
} }
if (thisdist < mindist) { if (thisdist <= mindist) {
dist[d - DC_N] = thisdist; dist[d - DC_N] = thisdist;
mindist = thisdist; mindist = thisdist;
} else { } else {
// don't move AWAY from them.
dist[d - DC_N] = -1; dist[d - DC_N] = -1;
} }
} else { } else {
@ -823,7 +824,7 @@ int moveclear(lifeform_t *lf, int dir, enum ERROR *error) {
} }
} }
if ((lf->race->id == RC_DEMON) && hasob(cell->obpile, OT_PENTAGRAM)) { if ((lf->race->raceclass->id == RC_DEMON) && hasob(cell->obpile, OT_PENTAGRAM)) {
*error = E_PENTAGRAM; *error = E_PENTAGRAM;
return B_FALSE; return B_FALSE;
} }
@ -934,6 +935,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
} }
} }
// remember previous cells
lf->prevcell[1] = lf->prevcell[0];
lf->prevcell[0] = lf->cell;
// update lifeform // update lifeform
lf->cell = newcell; lf->cell = newcell;
@ -1172,7 +1177,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// in range of alarm? range is 3 * spell power cells. // in range of alarm? range is 3 * spell power cells.
if (getcelldist(lf->cell, l->cell) <= (alarm->val[2]*3)) { if (getcelldist(lf->cell, l->cell) <= (alarm->val[2]*3)) {
// alarm goes off // alarm goes off
noise(l->cell, NULL, 50, "a blaring siren!", NULL); noise(l->cell, NULL, NC_OTHER, 50, "a blaring siren!", NULL);
killflag(alarm); killflag(alarm);
} }
} }
@ -1184,25 +1189,23 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// are you about to go outside a shop with stolen goods? // are you about to go outside a shop with stolen goods?
if ((lf->cell->roomid == preshop) && (lf->cell->type->id != CT_FLOORSHOP)) { if ((lf->cell->roomid == preshop) && (lf->cell->type->id != CT_FLOORSHOP)) {
lifeform_t *shk; lifeform_t *shk;
int nitems = 0;
shk = findshopkeeper(lf->cell->map, preshop); shk = findshopkeeper(lf->cell->map, preshop);
if (shk) { // do you have any unpaid items from that shop?
int nitems = 0; if (shk && getowing(lf, preshop, &nitems)) {
// do you have any unpaid items from that shop? char saybuf[BUFLEN];
if (getowing(lf, preshop, &nitems)) { // warning...
char saybuf[BUFLEN]; switch (rnd(1,3)) {
// warning... case 1: sprintf(saybuf, "Hey! Where do you think you're going?");
switch (rnd(1,3)) { break;
case 1: sprintf(saybuf, "Hey! Where do you think you're going?"); case 2: sprintf(saybuf, "AHEM!");
break; break;
case 2: sprintf(saybuf, "AHEM!"); case 3: sprintf(saybuf, "I hope you are going to pay for %s!",
break; (nitems == 1) ? "that" : "those" );
case 3: sprintf(saybuf, "I hope you are going to pay for %s!", break;
(nitems == 1) ? "that" : "those" );
break;
}
say(shk, saybuf, SV_SHOUT);
didmsg = B_TRUE;
} }
say(shk, saybuf, SV_SHOUT);
didmsg = B_TRUE;
} }
} else if (lf->cell->roomid != preshop) { } else if (lf->cell->roomid != preshop) {
// you've left the shop // you've left the shop
@ -1532,7 +1535,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
// checking if we have LOS to the lifeform making // checking if we have LOS to the lifeform making
// sound, but in this case it's the door making // sound, but in this case it's the door making
// the sound, not the lf. // the sound, not the lf.
noise(where, NULL, 2, "a door opening.", NULL); noise(where, NULL, NC_OTHER, 2, "a door opening.", NULL);
} }
if (player && haslos(player, where)) { if (player && haslos(player, where)) {
needredraw = B_TRUE; needredraw = B_TRUE;
@ -1649,7 +1652,8 @@ int closedoor(lifeform_t *lf, object_t *o) {
int tryrun(lifeform_t *lf, int dir) { int tryrun(lifeform_t *lf, int dir) {
if (!trymove(lf, dir, B_TRUE)) { if (!trymove(lf, dir, B_TRUE)) {
addflag(lf->flags, F_RUNNING, dir, NA, NA, NULL); // success!
addflag(lf->flags, F_RUNNING, dir, B_FALSE, NA, NULL);
} }
return B_FALSE; return B_FALSE;
} }

377
objects.c
View File

@ -2070,6 +2070,11 @@ void brightflash(cell_t *centre, int range, lifeform_t *immunelf) {
} }
} }
void calcshopprice(object_t *o, flag_t *shopitemflag) {
// initial value
shopitemflag->val[0] = (int) getshopprice(o, o->pile->owner);
}
int canbepoisoned(enum OBTYPE oid) { int canbepoisoned(enum OBTYPE oid) {
flag_t *f; flag_t *f;
objecttype_t *ot; objecttype_t *ot;
@ -2602,6 +2607,7 @@ objecttype_t *findotn(char *name) {
modname = strrep(modname, "scrolls ", "scroll ", NULL); modname = strrep(modname, "scrolls ", "scroll ", NULL);
modname = strrep(modname, "sets ", "set ", NULL); modname = strrep(modname, "sets ", "set ", NULL);
modname = strrep(modname, "splashes ", "splash ", NULL); modname = strrep(modname, "splashes ", "splash ", NULL);
modname = strrep(modname, "sprigs ", "sprig ", NULL);
modname = strrep(modname, "suits ", "suit ", NULL); modname = strrep(modname, "suits ", "suit ", NULL);
modname = strrep(modname, "vials ", "vial ", NULL); modname = strrep(modname, "vials ", "vial ", NULL);
@ -3186,6 +3192,26 @@ object_t *getammo(lifeform_t *lf) {
return o; return o;
} }
objecttype_t *getbasicweaponforskill(enum SKILL skid) {
switch (skid) {
case SK_AXES:
return findot(OT_AXE);
case SK_CLUBS:
return findot(OT_CLUB);
case SK_LONGBLADES:
return findot(OT_LONGSWORD);
case SK_POLEARMS:
return findot(OT_SPEAR);
case SK_SHORTBLADES:
return findot(OT_SHORTSWORD);
case SK_STAVES:
return findot(OT_QUARTERSTAFF);
default:
break;
}
return NULL;
}
object_t *getrandomammo(lifeform_t *lf) { object_t *getrandomammo(lifeform_t *lf) {
object_t *gun; object_t *gun;
object_t *o; object_t *o;
@ -3211,6 +3237,26 @@ object_t *getrandomammo(lifeform_t *lf) {
return NULL; return NULL;
} }
objecttype_t *getrandomammofor(object_t *o) {
objecttype_t *ot;
objecttype_t *poss[MAXCANDIDATES];
int nposs = 0;
if (!o || !isfirearm(o)) {
return NULL;
}
for (ot = objecttype ; ot ; ot = ot->next) {
if (isammofor(ot, o)) {
poss[nposs++] = ot;
}
}
if (nposs) {
ot = poss[rnd(0,nposs-1)];
} else {
ot = NULL;
}
return ot;
}
brand_t *getrandombrandfor(objecttype_t *ot) { brand_t *getrandombrandfor(objecttype_t *ot) {
brand_t *br, **poss; brand_t *br, **poss;
brand_t *result = NULL; brand_t *result = NULL;
@ -3643,11 +3689,15 @@ char *getobequipinfo(object_t *o, char *buf) {
if (f->val[0] == BP_WEAPON) { if (f->val[0] == BP_WEAPON) {
if (hasflag(o->flags, F_TWOHANDED)) { if (hasflag(o->flags, F_TWOHANDED)) {
strcat(buf, " (two-handed weapon)"); strcat(buf, " (two-handed weapon)");
} else { } else if (ismeleeweapon(o)) {
strcat(buf, " (weapon)"); strcat(buf, " (weapon)");
} else {
strcat(buf, " (makeshift weapon)");
} }
} else if (f->val[0] == BP_SECWEAPON) { } else if (f->val[0] == BP_SECWEAPON) {
if (isshield(o)) { if (hasflag(o->flags, F_TWOHANDED)) {
strcat(buf, " (two-handed weapon)");
} else if (isshield(o)) {
strcat(buf, " (shield)"); strcat(buf, " (shield)");
} else if (ismeleeweapon(o)) { } else if (ismeleeweapon(o)) {
strcat(buf, " (second weapon)"); strcat(buf, " (second weapon)");
@ -3734,6 +3784,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
obmod_t *om; obmod_t *om;
int hasunknownmod = B_FALSE; int hasunknownmod = B_FALSE;
cell_t *where; cell_t *where;
int no_a = B_FALSE;
// default to normal name // default to normal name
if (hasflag(o->flags, F_VENDITEM)) { if (hasflag(o->flags, F_VENDITEM)) {
@ -3824,6 +3875,14 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
} // end if sight/smell } // end if sight/smell
} else if ((o->type->id == OT_SIGN) && !hasflag(o->flags, F_SIGNTEXT)) { } else if ((o->type->id == OT_SIGN) && !hasflag(o->flags, F_SIGNTEXT)) {
strcpy(basename, "blank sign"); strcpy(basename, "blank sign");
} else if (o->type->id == OT_MAP) {
flag_t *f;
f = hasflag(o->flags, F_MAPTO);
if (f && getskill(player, SK_CARTOGRAPHY)) {
sprintf(basename, "map to %s", f->text);
} else {
strcpy(basename, "map");
}
} else if (o->type->id == OT_WATERDEEP) { } else if (o->type->id == OT_WATERDEEP) {
sprintf(basename, "%s water", getwaterdepthname(getobdepth(o, player))); sprintf(basename, "%s water", getwaterdepthname(getobdepth(o, player)));
} else { } else {
@ -3906,7 +3965,12 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
if (f) { if (f) {
race_t *corpserace; race_t *corpserace;
corpserace = findrace(f->val[0]); corpserace = findrace(f->val[0]);
sprintf(basename, "%s corpse",corpserace->name); if (hasflag(corpserace->flags, F_UNIQUE)) {
sprintf(basename, "%s%s corpse",corpserace->name, getpossessive(corpserace->name));
no_a = B_TRUE;
} else {
sprintf(basename, "%s corpse",corpserace->name);
}
} }
} else if (o->type->id == OT_HEAD) { } else if (o->type->id == OT_HEAD) {
f = hasflag(o->flags, F_CORPSEOF); f = hasflag(o->flags, F_CORPSEOF);
@ -4169,13 +4233,18 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
f = hasflag(o->flags, F_SHOPITEM); f = hasflag(o->flags, F_SHOPITEM);
if (f) { if (f) {
char pricebuf[BUFLEN]; char pricebuf[BUFLEN];
sprintf(pricebuf, " [$%d%s]", f->val[0], o->pile->owner ? ", unpaid" : ""); // get price for _player_
sprintf(pricebuf, " [$%d%s]", (int)getshopprice(o, player), o->pile->owner ? ", unpaid" : "");
strcat(localbuf, pricebuf); strcat(localbuf, pricebuf);
} }
// apply prefix now! // apply prefix now!
if (count == 1) { if (count == 1) {
if (hasflag(o->flags, F_NO_A)) { if (hasflag(o->flags, F_NO_A)) {
no_a = B_TRUE;
}
if (no_a) {
if (o->type->id == OT_GOLD) { if (o->type->id == OT_GOLD) {
sprintf(prefix, "%d ",count); sprintf(prefix, "%d ",count);
} else { } else {
@ -4706,6 +4775,25 @@ int getshatterdam(object_t *o) {
return shatterdam; return shatterdam;
} }
float getshopprice(object_t *o, lifeform_t *buyer) {
float val;
val = getobvalue(o);
if (buyer) {
float pricepctmod = 0;
enum SKILLLEVEL slev;
// price goes up/down for charisma (+/- 25%)
pricepctmod -= ((getstatmod(buyer, A_CHA)/2) * -1);
// modify for speech (up to -30%);
slev = getskill(buyer, SK_SPEECH);
if (slev) {
pricepctmod -= (slev*5);
}
val = pctof(val, 100 + pricepctmod);
}
return val;
}
enum SKILLLEVEL gettechlevel(object_t *o) { enum SKILLLEVEL gettechlevel(object_t *o) {
flag_t *f; flag_t *f;
enum SKILLLEVEL tlev = PR_INEPT; enum SKILLLEVEL tlev = PR_INEPT;
@ -5289,9 +5377,8 @@ void initobjects(void) {
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addoc(OC_FLORA, "Plants", "All kinds of plants and foliage", ',', C_GREEN); addoc(OC_FLORA, "Plants", "Some kind of plant/foliage.", ',', C_GREEN);
addocnoun(lastobjectclass, "plant"); addocnoun(lastobjectclass, "plant");
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_GREY); addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_GREY);
addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY); addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY);
addocnoun(lastobjectclass, "food"); addocnoun(lastobjectclass, "food");
@ -5657,7 +5744,15 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6");
addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 40, OC_FLORA); addot(OT_MISTLETOE, "sprig of mistletoe", "A small cutting of mistletoe.", MT_PLANT, 0.01, OC_FLORA);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "leaf");
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, ",");
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6");
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 50, OC_FLORA);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%");
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MEDIUM, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MEDIUM, NA, NULL);
@ -5788,6 +5883,8 @@ void initobjects(void) {
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addot(OT_POT_RUM, "potion of rum", "String liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION); addot(OT_POT_RUM, "potion of rum", "String liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
addflag(lastot->flags, F_FLAMMABLE, 1, NA, NA, "medium fire");
addflag(lastot->flags, F_EXPLODEONDAM, DT_FIRE, NA, NA, "2d6");
addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION); addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addot(OT_POT_SLEEP, "potion of sleep", "Puts the drinker into a deep sleep.", MT_GLASS, 1, OC_POTION); addot(OT_POT_SLEEP, "potion of sleep", "Puts the drinker into a deep sleep.", MT_GLASS, 1, OC_POTION);
@ -5868,10 +5965,11 @@ void initobjects(void) {
addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL); addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 84, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 84, RR_UNCOMMON, NULL);
addot(OT_MAP, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL); addot(OT_GRAPHPAPER, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL);
addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL); addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL);
addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL);
addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL); addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL);
addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, 4, NA, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, 4, NA, NULL);
@ -6267,6 +6365,7 @@ void initobjects(void) {
// l1 // l1
addot(OT_S_CALMANIMALS, "calm animals", "Makes animals within the casters line of sight become peaceful.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_CALMANIMALS, "calm animals", "Makes animals within the casters line of sight become peaceful.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addot(OT_S_DETECTPOISON, "detect poison", "Detects any poisoned object in sight of the caster.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_DETECTPOISON, "detect poison", "Detects any poisoned object in sight of the caster.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
@ -6560,10 +6659,11 @@ void initobjects(void) {
// l3 // l3
addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL); //addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
@ -6617,11 +6717,12 @@ void initobjects(void) {
// translocation // translocation
/////////////////// ///////////////////
// l2 // l2
addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view. Becomes controlled at power VI.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_PULL, "pull", "Pulls lifeforms towards the caster.", MT_NOTHING, 0, OC_SPELL); addot(OT_S_PULL, "pull", "Pulls lifeforms towards the caster.", MT_NOTHING, 0, OC_SPELL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -6902,7 +7003,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "8d2"); addflag(lastot->flags, F_EXPLODEONDAM, DT_FIRE, NA, NA, "8d2");
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
addflag(lastot->flags, F_FLAMMABLE, 3, NA, NA, NULL); addflag(lastot->flags, F_FLAMMABLE, 3, NA, NA, NULL);
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
@ -7944,7 +8045,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 1, NULL); // '1' is randomized during generation
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
addot(OT_RING_CON, "ring of constitution", "Increases the wearer's constitution.", MT_METAL, 0.1, OC_RING); addot(OT_RING_CON, "ring of fitness", "Increases the wearer's fitness.", MT_METAL, 0.1, OC_RING);
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
@ -8284,7 +8385,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON); addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8+4"); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8");
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL);
@ -8584,8 +8685,8 @@ int isactivated(object_t *o) {
return B_FALSE; return B_FALSE;
} }
int isammofor(object_t *ammo, object_t *gun) { int isammofor(objecttype_t *ammo, object_t *gun) {
if (hasflagval(gun->flags, F_AMMOOB, ammo->type->id, NA, NA, NULL)) { if (hasflagval(gun->flags, F_AMMOOB, ammo->id, NA, NA, NULL)) {
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -8903,7 +9004,7 @@ int ismagical(object_t *o) {
switch (o->type->obclass->id) { switch (o->type->obclass->id) {
case OC_SCROLL: case OC_SCROLL:
switch (o->type->id) { switch (o->type->id) {
case OT_MAP: case OT_GRAPHPAPER:
case OT_SCR_NOTHING: case OT_SCR_NOTHING:
// these scrolls are non-magical // these scrolls are non-magical
break; break;
@ -9513,6 +9614,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
object_t *o, *existob; object_t *o, *existob;
int i; int i;
int db = B_FALSE; int db = B_FALSE;
flag_t *f;
reason = E_OK; reason = E_OK;
@ -9524,6 +9626,14 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
cell_t *newcell; cell_t *newcell;
newcell = getstairdestination(pit); newcell = getstairdestination(pit);
if (newcell) { if (newcell) {
if (haslos(player, dst->where)) {
char obname[BUFLEN];
char pitname[BUFLEN];
getobname(src, obname, src->amt);
getobname(pit, pitname, 1);
msg("%s fall%s down %s.", obname, (src->amt == 1) ? "s" : "", pitname);
}
dst = newcell->obpile; dst = newcell->obpile;
} }
} }
@ -9618,6 +9728,13 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
drawscreen(); drawscreen();
} }
// special effects when an object moves
f = hasflag(o->flags, F_SHOPITEM);
if (f) {
// recalculate object price baesd on who is holding it
calcshopprice(o, f);
}
// special effects if a lifeform picked up an object // special effects if a lifeform picked up an object
if (dst->owner) { if (dst->owner) {
flag_t *f; flag_t *f;
@ -9625,13 +9742,10 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
f = hasflag(o->flags, F_SHOPITEM); f = hasflag(o->flags, F_SHOPITEM);
if (f) { if (f) {
lifeform_t *shk; lifeform_t *shk;
shk = findshopkeeper(dst->owner->cell->map, f->val[1]);
if (shk && cansee(shk, dst->owner)) {
askforpayment(shk, dst->owner);
}
if (!isplayer(dst->owner)) { shk = findshopkeeper(dst->owner->cell->map, f->val[1]);
msg("xxxxxxxxxxxx"); if (shk) {
askforpayment(shk, dst->owner);
} }
} }
@ -9975,6 +10089,9 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (!lfhasflag(lf, F_HUMANOID) || !hasbp(lf, BP_HANDS)) { if (!lfhasflag(lf, F_HUMANOID) || !hasbp(lf, BP_HANDS)) {
// only humanoids can zap things // only humanoids can zap things
if (isplayer(lf)) {
msg("You lack the manual dexterity to operate this.");
}
return B_TRUE; return B_TRUE;
} }
@ -9988,7 +10105,11 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
// if not a wand, must know what a tool is before you can use it // if not a wand, must know what a tool is before you can use it
if (!isknown(o) && (o->type->obclass->id != OC_WAND)) {
// also use the same message whn you try to operate something non-operable
// to avoid using this to identify mistletoe.
if (!isoperable(o) ||
(!isknown(o) && (o->type->obclass->id != OC_WAND)) ) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You don't know how to use %s!", obname); msg("You don't know how to use %s!", obname);
} }
@ -10124,7 +10245,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
// construct list of possible ammo // construct list of possible ammo
clearretobs(); clearretobs();
for (oo = lf->pack->first ; oo ; oo = oo->next) { for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (isammofor(oo, o)) { if (isammofor(oo->type, o)) {
retobs[nretobs] = oo; retobs[nretobs] = oo;
nretobs++; nretobs++;
} }
@ -10311,7 +10432,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} }
// announce // announce
if (!seen) { if (!seen) {
noise(where, NULL, 0, "something spraying.", NULL); noise(where, NULL, NC_OTHER, 0, "something spraying.", NULL);
} }
} else if ((o->type->id == OT_EMPTYFLASK) || (o->type->id == OT_EMPTYVIAL)) { } else if ((o->type->id == OT_EMPTYFLASK) || (o->type->id == OT_EMPTYVIAL)) {
object_t *oo,*nextoo; object_t *oo,*nextoo;
@ -10389,6 +10510,32 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
msg("There is nothing here to fill your %s from.",noprefix(obname)); msg("There is nothing here to fill your %s from.",noprefix(obname));
} }
} }
} else if (o->type->id == OT_MISTLETOE) {
if (hasjob(lf, J_DRUID)) {
int amt;
if (isplayer(lf)) {
msg("You sacrifice %s.", obname);
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s sacrifices %s.", lfname, obname);
}
removeob(o, 1);
// regain mp
amt = getspellduration(getmaxmp(lf)/2, getmaxmp(lf), o->blessed);
if (amt > 0) {
if (isplayer(lf)) {
msg("You feel a surge of magical power!");
}
gainmp(lf, amt);
}
} else {
if (isplayer(lf)) {
msg("You don't know how to use this.");
}
}
} else if (o->type->id == OT_ORBDUNGEONEXIT) { } else if (o->type->id == OT_ORBDUNGEONEXIT) {
map_t *m; map_t *m;
m = lf->cell->map; m = lf->cell->map;
@ -10518,7 +10665,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You play a few notes on your panpipes."); msg("You play a few notes on your panpipes.");
} else { } else {
noise(lf->cell, lf, 3, "the sound of panpipes.", "plays a tune on its panpipes."); noise(lf->cell, lf, NC_OTHER, 3, "the sound of panpipes.", "plays a tune on its panpipes.");
} }
} else if (o->type->id == OT_PICKAXE) { } else if (o->type->id == OT_PICKAXE) {
int ch,dir; int ch,dir;
@ -11533,9 +11680,167 @@ int readsomething(lifeform_t *lf, object_t *o) {
// removeob one of the object // removeob one of the object
if (isplayer(lf)) msg("The scroll crumbles to dust."); if (isplayer(lf)) msg("The scroll crumbles to dust.");
removeob(o, 1); removeob(o, 1);
} else if (o->type->id == OT_GRAPHPAPER) {
if (isplayer(lf)) {
msg("You study your hand-drawn map for a while.");
}
} else if (o->type->id == OT_MAP) { } else if (o->type->id == OT_MAP) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You study your map for a while."); if (!getskill(lf, SK_CARTOGRAPHY)) {
msg("You can't comprehend this map.");
} else if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
int lfmx,lfmy,tmx,tmy;
int dist;
cell_t *c;
enum SKILLLEVEL slev;
f = hasflag(o->flags, F_MAPTO);
getmapcoords(lf->cell->map, &lfmx, &lfmy);
tmx = f->val[0];
tmy = f->val[1];
dist = abs(tmx - lfmx) + abs(tmy - lfmy);
slev = getskill(lf, SK_CARTOGRAPHY);
switch (slev) {
default:
msg("You can't comprehend this map.");
break;
case PR_NOVICE:
// here/not here
if (dist == 0) {
msg("%s is in this area!", f->text);
} else {
msg("%s isn't in this area.", f->text);
}
break;
case PR_BEGINNER:
// near/far dist to that map
if (dist == 0) {
msg("%s is in this area!", f->text);
} else if (dist == 1) {
msg("%s is very nearby.", f->text);
} else {
msg("%s isn't nearby.", f->text);
}
break;
case PR_ADEPT:
// x areas away
if (dist == 0) {
msg("%s is in this area!", f->text);
} else if (dist == 1) {
msg("%s is one area away.", f->text);
} else {
msg("%s is %d areas away.", f->text, dist);
}
break;
case PR_SKILLED:
// x areas away
// plus direction.
if (dist == 0) {
msg("%s is in this area!", f->text);
} else {
char dirbuf[BUFLEN];
if (dist == 1) {
sprintf(buf, "%s is one area away to the ", f->text);
} else {
sprintf(buf, "%s is %d areas away to the ", f->text, dist);
}
strcpy(dirbuf, "");
if (tmy < lfmy) {
strcpy(dirbuf, "north");
} else if (tmy > lfmy) {
strcpy(dirbuf, "south");
}
if (tmx > lfmx) {
strcat(dirbuf, "east");
} else if (tmx < lfmx) {
strcat(dirbuf, "west");
}
strcat(buf, dirbuf);
strcat(buf, ".");
msg("%s", buf);
}
break;
case PR_EXPERT:
// x areas away
// plus direction.
// plus distance within area.
if (dist == 0) {
int dist2;
char distbuf[BUFLEN];
c = findobinmap(lf->cell->map, f->val[2]);
dist2 = getcelldist(lf->cell, c);
if (dist2 >= 20) {
strcpy(distbuf, "(very far away)");
} else if (dist2 >= 10) {
strcpy(distbuf, "(far away)");
} else if (dist2 >= 5) {
strcpy(distbuf, "(nearby)");
} else {
strcpy(distbuf, "(very nearby)");
}
msg("%s is in this area %s!", f->text, distbuf);
} else {
char dirbuf[BUFLEN];
if (dist == 1) {
sprintf(buf, "%s is one area away to the ", f->text);
} else {
sprintf(buf, "%s is %d areas away to the ", f->text, dist);
}
strcpy(dirbuf, "");
if (tmy < lfmy) {
strcpy(dirbuf, "north");
} else if (tmy > lfmy) {
strcpy(dirbuf, "south");
}
if (tmx > lfmx) {
strcat(dirbuf, "east");
} else if (tmx < lfmx) {
strcat(dirbuf, "west");
}
strcat(buf, dirbuf);
strcat(buf, ".");
msg("%s", buf);
}
break;
case PR_MASTER:
// x,y coords.
// plus direction.
// plus show on map if in area.
if (dist == 0) {
msg("You have located %s in this area.", f->text);
c = findobinmap(lf->cell->map, f->val[2]);
setcellknownradius(c, slev, 5, DT_ORTH);
} else {
char dirbuf[BUFLEN];
char buf2[BUFLEN];
sprintf(buf, "%s is at %d,%d",f->text, tmx,tmy);
if (dist == 1) {
sprintf(buf2, " (one area away to the ");
} else {
sprintf(buf2, " (%d areas away to the ", dist);
}
strcpy(dirbuf, "");
if (tmy < lfmy) {
strcpy(dirbuf, "north");
} else if (tmy > lfmy) {
strcpy(dirbuf, "south");
}
if (tmx > lfmx) {
strcat(dirbuf, "east");
} else if (tmx < lfmx) {
strcat(dirbuf, "west");
}
strcat(buf2, dirbuf);
strcat(buf2, ")");
msg("%s%s", buf, buf2);
}
break;
}
} else {
msg("You need to be outside to get your bearings first.");
}
} }
} else if (o->type->id == OT_SCR_NOTHING) { } else if (o->type->id == OT_SCR_NOTHING) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -11914,7 +12219,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
seen = B_TRUE; seen = B_TRUE;
} else { } else {
noise(where, NULL, 3, "shattering glass.", NULL); noise(where, NULL, NC_OTHER, 3, "shattering glass.", NULL);
} }
if (target) { if (target) {
@ -12252,8 +12557,10 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL); addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
} else { } else {
// explode // explode
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0); if ((f->val[0] == NA) || (f->val[0] == damtype)) {
return howmuch; explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
return howmuch;
}
} }
} }
} else { } else {
@ -12261,9 +12568,11 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
// object dies! // object dies!
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL); addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
} else { } else {
// explode if ((f->val[0] == NA) || (f->val[0] == damtype)) {
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0); // explode
return howmuch; explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
return howmuch;
}
} }
} }
} }

View File

@ -26,6 +26,7 @@ void appendinscription(object_t *o, char *text);
void applyobmod(object_t *o, obmod_t *om); void applyobmod(object_t *o, obmod_t *om);
int blessob(object_t *o); int blessob(object_t *o);
void brightflash(cell_t *centre, int range, lifeform_t *immunelf); void brightflash(cell_t *centre, int range, lifeform_t *immunelf);
void calcshopprice(object_t *o, flag_t *shopitemflag);
int canbepoisoned(enum OBTYPE oid); int canbepoisoned(enum OBTYPE oid);
int canseeob(lifeform_t *lf, object_t *o); int canseeob(lifeform_t *lf, object_t *o);
object_t *canstackob(obpile_t *op, object_t *match); object_t *canstackob(obpile_t *op, object_t *match);
@ -67,7 +68,9 @@ int getobvalue(object_t *o);
//int getobtypevalue(objecttype_t *ot); //int getobtypevalue(objecttype_t *ot);
char *getaccuracyname(int accpct); char *getaccuracyname(int accpct);
object_t *getammo(lifeform_t *lf); object_t *getammo(lifeform_t *lf);
objecttype_t *getbasicweaponforskill(enum SKILL skid);
object_t *getrandomammo(lifeform_t *lf); object_t *getrandomammo(lifeform_t *lf);
objecttype_t *getrandomammofor(object_t *o);
brand_t *getrandombrandfor(objecttype_t *ot); brand_t *getrandombrandfor(objecttype_t *ot);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity); objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity);
char *getdamname(enum DAMTYPE damtype); char *getdamname(enum DAMTYPE damtype);
@ -110,6 +113,7 @@ enum SPELLSCHOOL getschool(enum OBTYPE sid);
char *getschoolname(enum SPELLSCHOOL sch); char *getschoolname(enum SPELLSCHOOL sch);
char *getschoolnameshort(enum SPELLSCHOOL sch); char *getschoolnameshort(enum SPELLSCHOOL sch);
int getshatterdam(object_t *o); int getshatterdam(object_t *o);
float getshopprice(object_t *o, lifeform_t *buyer);
enum SKILLLEVEL gettechlevel(object_t *o); enum SKILLLEVEL gettechlevel(object_t *o);
int getthrowdam(object_t *o); int getthrowdam(object_t *o);
char *gettopobname(cell_t *c, char *retbuf); char *gettopobname(cell_t *c, char *retbuf);
@ -128,7 +132,7 @@ void ignite(object_t *o);
void initobjects(void); void initobjects(void);
flag_t *isarmour(object_t *o); flag_t *isarmour(object_t *o);
int isactivated(object_t *o); int isactivated(object_t *o);
int isammofor(object_t *ammo, object_t *gun); int isammofor(objecttype_t *ammo, object_t *gun);
int isbadfood(object_t *o); int isbadfood(object_t *o);
int isbetterarmourthan(object_t *a, object_t *b); int isbetterarmourthan(object_t *a, object_t *b);
int isbetterwepthan(object_t *a, object_t *b); int isbetterwepthan(object_t *a, object_t *b);

137
spell.c
View File

@ -1345,9 +1345,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
taketime(user, getactspeed(user)*2); taketime(user, getactspeed(user)*2);
// all in range must pass a morale check or flee // all in range must pass a morale check or flee
for (target = user->cell->map->lf ; target ; target = target->next) { for (target = user->cell->map->lf ; target ; target = target->next) {
if ((target != user) && cansee(target, user) && areenemies(target, user)) { if ((target != user) && cansee(target, user) && areenemies(target, user)) {
if (canhear(target, user->cell)) { if (canhear(target, user->cell, 4)) {
scare(target, user, rnd(5,10), 0); scare(target, user, rnd(5,10), 0);
} }
} }
@ -1355,7 +1356,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (abilid == OT_A_HURRICANESTRIKE) { } else if (abilid == OT_A_HURRICANESTRIKE) {
int dir; int dir;
cell_t *c; cell_t *c;
flag_t *f,*f2; flag_t *f,*f2,*f3;
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You cannot do that while swimming."); if (isplayer(user)) msg("You cannot do that while swimming.");
@ -1370,6 +1371,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
f = addflag(user->flags, F_NOTIME, B_TRUE, NA, NA, NULL); f = addflag(user->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
// lower accuracy // lower accuracy
f2 = addflag(user->flags, F_ACCURACYMOD, -20, NA, NA, NULL); f2 = addflag(user->flags, F_ACCURACYMOD, -20, NA, NA, NULL);
// remember we are doing a hurricane attack to avoid lots of
// "there is nothing to attack there" messages.
f3 = addflag(user->flags, F_HURRICANESTRIKE, B_TRUE, NA, NA, NULL);
// attack all adjacent enemies // attack all adjacent enemies
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(user->cell, dir); c = getcellindir(user->cell, dir);
@ -1380,6 +1384,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// remove temporary flags // remove temporary flags
killflag(f); killflag(f);
killflag(f2); killflag(f2);
killflag(f3);
} else if (abilid == OT_A_HIDE) { } else if (abilid == OT_A_HIDE) {
int penalty = 0; int penalty = 0;
@ -1547,6 +1552,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
addflag(caster->flags, F_BOOSTSPELL, spellid, cost, power, NULL); addflag(caster->flags, F_BOOSTSPELL, spellid, cost, power, NULL);
} }
} }
// druids gain power from nearby plants
if (hasjob(caster, J_DRUID)) {
cell_t *c;
int d;
float totweight = 0;
int powerinc = 0;
for (d = DC_N; d <= DC_NW; d++) {
c = getcellindir(caster->cell, d);
if (c) {
object_t *o;
for (o = c->obpile->first ; o ; o = o->next){
if (o->type->obclass->id == OC_FLORA) totweight += getobweight(o);
}
}
}
powerinc = totweight / 50;
if (powerinc > 0) {
power += powerinc;
}
}
} }
// switch based on spell effects... // switch based on spell effects...
@ -1843,16 +1869,28 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
} else { } else {
int tries = 0,maxtries = 10; int tries = 0,maxtries = 10;
// pick a random location if (lfhasflag(caster, F_CONTROL) && (power < 6)) {
targcell = NULL; power = 6;
while (!targcell || !cellwalkable(caster, targcell, NULL) || celldangerous(caster, targcell, B_FALSE, NULL)) { }
int i; if (power >= 6) {
i = rnd(0,caster->nlos-1); // controlled
targcell = caster->los[i]; if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
tries++; if (!targcell) {
if (tries >= maxtries) {
fizzle(caster); fizzle(caster);
return B_FALSE; return B_TRUE;
}
} else {
// pick a random location
targcell = NULL;
while (!targcell || !cellwalkable(caster, targcell, NULL) || celldangerous(caster, targcell, B_FALSE, NULL)) {
int i;
i = rnd(0,caster->nlos-1);
targcell = caster->los[i];
tries++;
if (tries >= maxtries) {
fizzle(caster);
return B_FALSE;
}
} }
} }
teleportto(caster, targcell, B_TRUE); teleportto(caster, targcell, B_TRUE);
@ -4532,7 +4570,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (ismetal(o->material->id)) { if (ismetal(o->material->id)) {
flag_t *f; flag_t *f;
f = isequipped(o); f = isequipped(o);
if ((f->val[0] != BP_WEAPON) && (f->val[0] != BP_SECWEAPON)) { if (f && (f->val[0] != BP_WEAPON) && (f->val[0] != BP_SECWEAPON)) {
gotmetal = B_TRUE; gotmetal = B_TRUE;
metalweight += getobweight(o); metalweight += getobweight(o);
break; break;
@ -4639,7 +4677,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
// find new map ! // find new map !
newmap = findmapofdepth(newdepth);
//newmap = findmapofdepth(newdepth);
newmap = findregionmap(caster->cell->map->region->id, newdepth);
if (!newmap) { if (!newmap) {
// create new map // create new map
newmap = addmap(); newmap = addmap();
@ -4739,7 +4779,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
getlfname(target, targname); getlfname(target, targname);
howlong = getspellduration(20,40,blessed) + (power*2); // time is based on spellpower
howlong = getspellduration(5,10,blessed) + (power*2);
if (!isplayer(target) && cansee(player, target) ) { if (!isplayer(target) && cansee(player, target) ) {
willannounce = B_TRUE; willannounce = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -5218,6 +5259,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_MENDING) { } else if (spellid == OT_S_MENDING) {
object_t *o; object_t *o;
int donesomething = B_FALSE;
flag_t *f;
char fullobname[BUFLEN];
char obname[BUFLEN];
getobname(o, obname, o->amt);
if (isplayer(caster)) {
sprintf(fullobname, "Your %s", noprefix(obname));
} else if (cansee(player, caster)) {
sprintf(fullobname, "%s%s %s", castername, getpossessive(castername), noprefix(obname));
} else {
strcpy(fullobname, "");
}
if (targob) { if (targob) {
o = targob; o = targob;
@ -5230,34 +5284,43 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
if (isplayer(caster)) { f = hasflag(o->flags, F_OBHP);
flag_t *f; if (f && isdamaged(o)) {
f = hasflag(o->flags, F_OBHP); if (blessed == B_CURSED) {
if (!f) { if (isplayer(caster) || cansee(player, caster)) msg("%s deteriorates!", fullobname);
nothinghappens(); takedamage(o, rnd(1,6) + power, DT_DIRECT);
return B_TRUE; donesomething = B_TRUE;
} else { } else {
char obname[BUFLEN]; f->val[0] += (rnd(1,6) + power);
getobname(o, obname, o->amt);
if (blessed) { if (f->val[0] >= f->val[1]) {
f->val[0] += (rnd(1,6) + power); if (isplayer(caster) || cansee(player, caster)) msg("%s is completely repaied!", fullobname);
f->val[0] = f->val[1];
if (f->val[0] >= f->val[1]) {
msg("Your %s is completely repaired!", noprefix(obname));
f->val[0] = f->val[1];
} else {
msg("Your %s is repaired a little!", noprefix(obname));
}
} else { } else {
msg("Your %s deteriorates!", noprefix(obname)); if (isplayer(caster) || cansee(player, caster)) msg("%s is repaired a little!", fullobname);
takedamage(o, rnd(1,6) + power, DT_DIRECT);
} }
donesomething = B_TRUE;
}
}
// fix dulled weapons
if (!iscursed(o)) {
f = hasflag(o->flags, F_BONUS);
if (f && (f->val[0] < 0)) {
killflag(f);
if (isplayer(caster) || cansee(player, caster)) msg("%s seems more effective!", fullobname);
donesomething = B_TRUE;
}
}
if (donesomething) {
if (strlen(fullobname)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else { } else {
// monsters can't repair things! nothinghappens();
return B_TRUE;
} }
} else if (spellid == OT_S_PACIFY) { } else if (spellid == OT_S_PACIFY) {
char targetname[BUFLEN]; char targetname[BUFLEN];
@ -6712,7 +6775,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
o = relinkob(o, newloc->obpile); o = relinkob(o, newloc->obpile);
} }
if (o) { if (o) {
noise(caster->cell, NULL, 1, "something hitting the ground.", NULL); noise(caster->cell, NULL, NC_OTHER, 1, "something hitting the ground.", NULL);
if (!isblind(caster)) { if (!isblind(caster)) {
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : ""); msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
} }
@ -6913,6 +6976,10 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) {
} }
if (spellid == OT_S_DETECTLIFE) { if (spellid == OT_S_DETECTLIFE) {
if (power >= 6) {
strcat(buf, "(ctrl)");
}
} else if (spellid == OT_S_DETECTLIFE) {
if (power >= 5) { if (power >= 5) {
strcat(buf, "(enhanced)"); strcat(buf, "(enhanced)");
} }

30
text.c
View File

@ -119,14 +119,16 @@ char *getattrabbrev(enum ATTRIB att) {
switch (att) { switch (att) {
case A_NONE: case A_NONE:
return "??"; return "??";
case A_STR: case A_CHA:
return "St"; return "Ch";
case A_IQ: case A_CON:
return "Iq"; return "Fi";
case A_DEX: case A_DEX:
return "Dx"; return "Dx";
case A_CON: case A_IQ:
return "Cn"; return "Iq";
case A_STR:
return "St";
} }
return "??"; return "??";
} }
@ -135,14 +137,16 @@ char *getattrname(enum ATTRIB att) {
switch (att) { switch (att) {
case A_NONE: case A_NONE:
return "?attrib_none?"; return "?attrib_none?";
case A_STR: case A_CHA:
return "strength"; return "charisma";
case A_IQ: case A_CON:
return "intelligence"; return "fitness";
case A_DEX: case A_DEX:
return "dexterity"; return "dexterity";
case A_CON: case A_IQ:
return "constitution"; return "intelligence";
case A_STR:
return "strength";
} }
return "?badattrib?"; return "?badattrib?";
} }
@ -396,6 +400,8 @@ char *makeplural(char *text) {
if (rv) return newtext; if (rv) return newtext;
newtext = strrep(newtext, "set ", "sets ", &rv); newtext = strrep(newtext, "set ", "sets ", &rv);
if (rv) return newtext; if (rv) return newtext;
newtext = strrep(newtext, "sprig ", "sprigs ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "suit ", "suits ", &rv); newtext = strrep(newtext, "suit ", "suits ", &rv);
if (rv) return newtext; if (rv) return newtext;
newtext = strrep(newtext, "vial ", "vials ", &rv); newtext = strrep(newtext, "vial ", "vials ", &rv);