* [+] need to set "needredraw" every time we exit:

- [+] make eating take longer - depends on lf size and food sizes
* [+] stop eating if something attacks you!
- [+] change spell code to cope with caster = NULL!!
- [+] why are rooms never more than 2 high
* [+] traps
* [+] eating bug again
* [+] disarm trap skill?
- [+] lots of needredraw bugs
- [+] bug with cursor jumping around lots
- [+] draw darkened visible cells in blue
* [+] shadow cloak
- [+] tree shouldn't prevent resting!
- [+] make plants not attack druids
* [+] cooking
- [+] stop eating if your eating object is no longer with you
* [+] FLAG CORRUPTION BUG
- [+] pet walking back and forth on rotted objects
- [+] purified food shouldn't decay anymore.
- [+] plants shouldn't sleep
- [+] RESTING on statbar not being cleared. the add of f_interrupted
      was clearing statdirty before f_asleep got removed in killflag().
- [+] AI:  don't eat if in battle
- [+] reduce projectile damage
- [+] show raceclass in statbars
- [+] smoke should make you cough.
- [+] when going up levle, only prompt for spells you can cast?? (don't
      show "NOTCASTABLE")
- [+] Your young hawk dies.  The stirge releases something!
- [+] sleeping thigns shoudn't follow you up/down stairs.
- [+] when throw'ng an object, don't let it stack (otherwise we might
      destroy too much)
- [+] don't draw "c  - " for nopickup objects.
- [+] saving throw for traps if you know about it.
- [+] druid - get xp for calming animals
- [+] rogue- get xp for picking locks, disarming traps.  
- [+] metal should be immune to most damage types
* [+] make heavy blow need HEAVY weapon, not bashing.
- [+] can't rest/train while levitating!
- [+] gas traps only go off once.
- [+] bug: The goblin throws a boulder at you.  A boulder misses you.
- [+] don't give short sword skill to wizard.
- [+] hearing range based on listen skill
* [+] coldness disease:
- [+] CRASH when swapping places
- [+] bug: i can teleport into an impassable object!
- [+] add: "really target (your ally)?"
- [+] give wizards school-based skill instead of manaspike + wildmagic
- [+] LevUp still not being cleared!!!
* [+] why is air wizard being prompted for call lightning at level 2???
* [+] summon weapon (summoning)
- [+] hold portal (mod)
- [+] reveal hidden
- [+] stench (death)
- [+] frostbite (minor but direct cold damage. 1dpower. maxpower 3)
- [+] grease (modific) creates oil in a circle
- [+] fear (death)
- [+] seeinvis (div)
- [+] locate obejct (div) tells you where a seen objcet is.
- [+] swap places (transl) "twiddle"
- [+] fire brand (fire, melee attaks deal fire damage)
- [+] iceedge
- [+] lore (div, temporary knowledge from a particular school?)
- [+] icicle (cold, deals cold dam and knocks enemies away)
* [+] chill (ice, 1d3 damage per exposed body part)
- [+] hail storm (ice, big damage in area)
- [+] wall of ice (creates icy wall, hp based on power)
This commit is contained in:
Rob Pearce 2011-05-12 01:49:35 +00:00
parent 7b753b5f0f
commit 858a264b07
22 changed files with 2942 additions and 633 deletions

30
ai.c
View File

@ -364,6 +364,19 @@ int aipickup(lifeform_t *lf, object_t *o) {
return B_FALSE; return B_FALSE;
} }
int aipickupok(lifeform_t *lf, object_t *o) {
int ok = B_FALSE;
if (isedible(o)) {
if (caneat(lf, o)) {
ok = B_TRUE;
}
} else if (canpickup(lf, o, 1)) {
ok = B_TRUE;
}
return ok;
}
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target) { int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target) {
switch (o->type->id) { switch (o->type->id) {
case OT_POT_INVIS: case OT_POT_INVIS:
@ -863,10 +876,12 @@ void aiturn(lifeform_t *lf) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
// look for any object which we want // look for any object which we want
if (db) dblog(".oO { looking for any ob which i want. }"); if (!isinbattle(lf)) {
if (lookforobs(lf, B_ANY)) { if (db) dblog(".oO { looking for any ob which i want. }");
if (db) dblog(".oO { found ob that i want. returning. }"); if (lookforobs(lf, B_ANY)) {
return; if (db) dblog(".oO { found ob that i want. returning. }");
return;
}
} }
@ -1456,7 +1471,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
// current cell has an object we want? // current cell has an object we want?
o = hasobmulti(lf->cell->obpile, oid, noids); o = hasobmulti(lf->cell->obpile, oid, noids);
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf,o)) ) { if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
if (db) dblog(".oO { current cell has ob i want (%s) }",o->type->name); if (db) dblog(".oO { current cell has ob 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;
@ -1518,7 +1533,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
c = lf->los[i]; c = lf->los[i];
if (!c->lf && !lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) { if (!c->lf && !lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) {
o = hasobmulti(c->obpile, oid, noids); o = hasobmulti(c->obpile, oid, noids);
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf,o)) ) { if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
if (db) dblog(".oO { remote cell has ob i want (%s). setting f_targetcell. }",o->type->name); if (db) dblog(".oO { remote cell has ob i want (%s). setting f_targetcell. }",o->type->name);
gothere = B_TRUE; gothere = B_TRUE;
} }
@ -1526,7 +1541,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
// has an object with a flag we want? // has an object with a flag we want?
for (n = 0; n < nwantflags; n++) { for (n = 0; n < nwantflags; n++) {
o = hasobwithflag(c->obpile, wantflag[n]); o = hasobwithflag(c->obpile, wantflag[n]);
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf, o)) ) { if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
if (db) dblog(".oO { remote cell has ob with flag i want (%s) }", o->type->name); if (db) dblog(".oO { remote cell has ob with flag i want (%s) }", o->type->name);
gothere = B_TRUE; gothere = B_TRUE;
} }
@ -1538,7 +1553,6 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
f = hasflag(lf->flags, F_WANTSBETTERWEP); f = hasflag(lf->flags, F_WANTSBETTERWEP);
if (f) { if (f) {
if (!covetsonly || (f->val[1] == B_COVETS)) { if (!covetsonly || (f->val[1] == B_COVETS)) {
o = hasbetterweapon(lf, c->obpile); o = hasbetterweapon(lf, c->obpile);
if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) { if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) {
if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name); if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name);

1
ai.h
View File

@ -9,6 +9,7 @@ object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit); flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
void aimovetotargetcell(lifeform_t *lf, flag_t *f); void aimovetotargetcell(lifeform_t *lf, flag_t *f);
int aipickup(lifeform_t *lf, object_t *o); int aipickup(lifeform_t *lf, object_t *o);
int aipickupok(lifeform_t *lf, object_t *o);
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target); int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target);
int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG purpose); int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG purpose);
void aiturn(lifeform_t *lf); void aiturn(lifeform_t *lf);

View File

@ -60,9 +60,7 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
case PR_EXPERT: actualdam = pctof(50, dam); break; case PR_EXPERT: actualdam = pctof(50, dam); break;
case PR_MASTER: actualdam = pctof(40, dam); break; case PR_MASTER: actualdam = pctof(40, dam); break;
} }
if (actualdam > 0) { limit(&actualdam, 1, NA);
limit(&dam, 1, NA);
}
} }
// modify for rust // modify for rust
@ -130,7 +128,7 @@ int attackcell(lifeform_t *lf, cell_t *c) {
// anyone there? if so just attack. // anyone there? if so just attack.
if (c->lf) { if (c->lf) {
if (isplayer(lf) && !areenemies(lf,c->lf)) { if (isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) {
char ch; char ch;
char victimname[BUFLEN]; char victimname[BUFLEN];
char buf[BUFLEN]; char buf[BUFLEN];
@ -184,11 +182,15 @@ int attackcell(lifeform_t *lf, cell_t *c) {
if (getskill(lf, SK_TWOWEAPON)) { if (getskill(lf, SK_TWOWEAPON)) {
wep[nweps] = getsecmeleeweapon(lf); wep[nweps] = getsecmeleeweapon(lf);
if (wep[nweps]) { if (wep[nweps]) {
damflag[nweps] = hasflag(wep[nweps]->flags, F_DAM); if ((nweps >= 1) && (wep[nweps] == wep[nweps-1])) {
validwep[nweps] = B_TRUE; // can't be the same as first one
lastweaponidx = nweps; } else {
nweps++; damflag[nweps] = hasflag(wep[nweps]->flags, F_DAM);
gotweapon = B_TRUE; validwep[nweps] = B_TRUE;
lastweaponidx = nweps;
nweps++;
gotweapon = B_TRUE;
}
} }
} }
@ -691,6 +693,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int dir; int dir;
cell_t *c; cell_t *c;
int nmatched = 0; int nmatched = 0;
char lfname[BUFLEN];
getlfname(lf, lfname);
// count adjacent allies of name xx // count adjacent allies of name xx
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(victim->cell, dir); c = getcellindir(victim->cell, dir);
@ -702,10 +706,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
if (nmatched >= f->val[2]) { if (nmatched >= f->val[2]) {
char damstring[BUFLEN]; char damstring[BUFLEN];
sprintf(damstring, "a %s pack", f->text); sprintf(damstring, "%s pack", lfname);
losehp(victim, f->val[0], f->val[1], lf, damstring); losehp(victim, f->val[0], f->val[1], lf, damstring);
if (isplayer(victim) || cansee(player, victim)) { if (isplayer(victim) || cansee(player, victim)) {
msg("The %s pack attacks %s!", f->text, victimname); msg("%s pack attacks %s!", lfname, victimname);
} }
} }
} }
@ -1232,7 +1236,11 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
flag_t *f; flag_t *f;
for (f = wep->flags->first ; f ; f = f->next) { for (f = wep->flags->first ; f ; f = f->next) {
if (f->id == F_ONFIRE) { if (f->id == F_ONFIRE) {
*(dam + *ndam) = rolldie(2,6); if (f->text) {
*(dam + *ndam) = roll(f->text);
} else {
*(dam + *ndam) = rolldie(2,6);
}
*(damtype + *ndam) = DT_FIRE; *(damtype + *ndam) = DT_FIRE;
(*ndam)++; (*ndam)++;
} else if (f->id == F_FROZEN) { } else if (f->id == F_FROZEN) {
@ -1252,6 +1260,10 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
return "defeat"; return "defeat";
} }
if (getraceclass(victim) == RC_PLANT) {
return "destroy";
}
if (wep) { if (wep) {
flag_t *f; flag_t *f;
for (f = wep->flags->first ; f ; f = f->next) { for (f = wep->flags->first ; f ; f = f->next) {
@ -1304,12 +1316,13 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
} }
} }
if (getraceclass(victim) == RC_UNDEAD) {
// can't "kill" the undead
return "destroy";
}
return "kill"; return "kill";
} }
void getdamrange(flag_t *f, int *min, int *max) { void getdamrange(flag_t *f, int *min, int *max) {
int mindam,maxdam; int mindam,maxdam;
@ -1670,7 +1683,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
flag_t *f; flag_t *f;
lifeform_t *victim; lifeform_t *victim;
lifeform_t *owner; lifeform_t *owner = NULL;
object_t *wep; object_t *wep;
if (!where) return; if (!where) return;

105
defs.h
View File

@ -39,6 +39,7 @@ enum SKILL {
SK_ARMOUR = 1, SK_ARMOUR = 1,
SK_ATHLETICS, SK_ATHLETICS,
SK_BACKSTAB, SK_BACKSTAB,
SK_COOKING,
SK_FIRSTAID, SK_FIRSTAID,
SK_LISTEN, SK_LISTEN,
SK_LOCKPICKING, SK_LOCKPICKING,
@ -48,6 +49,7 @@ enum SKILL {
SK_SPOTHIDDEN, SK_SPOTHIDDEN,
SK_STEALTH, SK_STEALTH,
SK_TECHUSAGE, SK_TECHUSAGE,
SK_TRAPS,
SK_TWOWEAPON, SK_TWOWEAPON,
// knowledge // knowledge
SK_LORE_ARCANA, SK_LORE_ARCANA,
@ -79,7 +81,7 @@ enum SKILL {
SK_SS_TRANSLOCATION, SK_SS_TRANSLOCATION,
SK_SS_WILD, SK_SS_WILD,
}; };
#define MAXSKILLS 40 #define MAXSKILLS 42
// proficiency levels // proficiency levels
enum SKILLLEVEL { enum SKILLLEVEL {
@ -131,6 +133,7 @@ enum CHECKTYPE {
SC_IQ, SC_IQ,
SC_CON, SC_CON,
////////// //////////
SC_DISARM,
SC_DODGE, SC_DODGE,
SC_SHIELDBLOCK, SC_SHIELDBLOCK,
SC_FALL, SC_FALL,
@ -229,7 +232,7 @@ enum LFCONDITION {
#define MAXRETCELLS 80 #define MAXRETCELLS 80
#define MAXCHOICES 150 #define MAXCHOICES 200
#define MAXDEPTH 25 // max dungeon depth #define MAXDEPTH 25 // max dungeon depth
@ -247,8 +250,8 @@ enum LFCONDITION {
#define MIN_ROOMH 4 #define MIN_ROOMH 4
#define MIN_ROOMW 4 #define MIN_ROOMW 4
#define MAX_ROOMW (MAX_MAPW / 5) #define MAX_ROOMW (MAX_MAPW / 3)
#define MAX_ROOMH (MAX_MAPH / 5) #define MAX_ROOMH (MAX_MAPH / 3)
#define MAXDIR_ORTH 4 #define MAXDIR_ORTH 4
#define MAXDIR_COMPASS 8 #define MAXDIR_COMPASS 8
@ -553,6 +556,7 @@ enum RACECLASS {
RC_SLIME, RC_SLIME,
RC_MAGIC, RC_MAGIC,
RC_OTHER, RC_OTHER,
RC_PLANT,
RC_UNDEAD, RC_UNDEAD,
}; };
@ -597,6 +601,11 @@ enum RACE {
R_TROGLODYTE, R_TROGLODYTE,
R_TROLL, R_TROLL,
R_XAT, R_XAT,
// plants
R_CACTUS,
R_DREAMFUNGUS,
R_SAWGRASS,
R_TREE,
// animals // animals
R_ANT, R_ANT,
R_ANTS, R_ANTS,
@ -693,6 +702,7 @@ enum MATERIAL {
MT_ACID = 23, MT_ACID = 23,
MT_SILK = 24, MT_SILK = 24,
MT_OIL = 25, MT_OIL = 25,
MT_PLANT = 26,
}; };
// Object Types // Object Types
@ -700,6 +710,7 @@ enum OBTYPE {
OT_NONE, OT_NONE,
// dungeon features // dungeon features
OT_BOULDER, OT_BOULDER,
OT_ICICLE,
OT_STATUE, OT_STATUE,
OT_DOORWOOD, OT_DOORWOOD,
OT_DOORIRON, OT_DOORIRON,
@ -710,12 +721,21 @@ enum OBTYPE {
OT_STAIRSUP, OT_STAIRSUP,
OT_VENDINGMACHINE, OT_VENDINGMACHINE,
OT_PORTAL, OT_PORTAL,
// traps
OT_TRAPROCK,
OT_TRAPARROW,
OT_TRAPARROWP,
OT_TRAPGAS,
OT_TRAPFIRE,
OT_TRAPMINE,
OT_TRAPTRIP,
// rocks // rocks
OT_GOLD, OT_GOLD,
OT_STONE, OT_STONE,
OT_ASH, OT_ASH,
OT_ASHEXPLODE, OT_ASHEXPLODE,
OT_ASHCONCEAL, OT_ASHCONCEAL,
OT_ASHSLEEP,
OT_GEMOFSEEING, OT_GEMOFSEEING,
// food // food
OT_BERRY, OT_BERRY,
@ -726,6 +746,8 @@ enum OBTYPE {
OT_MUSHROOM, OT_MUSHROOM,
OT_BREADSTALE, OT_BREADSTALE,
OT_CHEESE, OT_CHEESE,
OT_STEW,
OT_JERKY,
OT_ROASTMEAT, OT_ROASTMEAT,
OT_BREADFRESH, OT_BREADFRESH,
OT_CHOCOLATE, OT_CHOCOLATE,
@ -786,6 +808,7 @@ enum OBTYPE {
OT_MAN_ARMOUR, OT_MAN_ARMOUR,
OT_MAN_ATHLETICS, OT_MAN_ATHLETICS,
OT_MAN_BACKSTAB, OT_MAN_BACKSTAB,
OT_MAN_COOKING,
OT_MAN_FIRSTAID, OT_MAN_FIRSTAID,
OT_MAN_LISTEN, OT_MAN_LISTEN,
OT_MAN_LOCKPICKING, OT_MAN_LOCKPICKING,
@ -795,6 +818,7 @@ enum OBTYPE {
OT_MAN_SPOTHIDDEN, OT_MAN_SPOTHIDDEN,
OT_MAN_STEALTH, OT_MAN_STEALTH,
OT_MAN_TECHUSAGE, OT_MAN_TECHUSAGE,
OT_MAN_TRAPS,
OT_MAN_TWOWEAPON, OT_MAN_TWOWEAPON,
// manuals of knowledge // manuals of knowledge
OT_MAN_LORE_ARCANA, OT_MAN_LORE_ARCANA,
@ -838,13 +862,18 @@ enum OBTYPE {
OT_SB_WEAKEN, OT_SB_WEAKEN,
OT_SB_FEEBLEMIND, OT_SB_FEEBLEMIND,
OT_SB_BLINDNESS, OT_SB_BLINDNESS,
OT_SB_POSSESSION,
OT_SB_STENCH,
// -- divination // -- divination
OT_SB_DETECTAURA, OT_SB_DETECTAURA,
OT_SB_DETECTLIFE, OT_SB_DETECTLIFE,
OT_SB_DETECTOBS, OT_SB_DETECTOBS,
OT_SB_LOCATEOBJECT,
OT_SB_LORE,
OT_SB_REVEALHIDDEN, OT_SB_REVEALHIDDEN,
OT_SB_IDENTIFY, OT_SB_IDENTIFY,
OT_SB_MAPPING, OT_SB_MAPPING,
OT_SB_SEEINVIS,
// -- elemental - air // -- elemental - air
OT_SB_AIRBLAST, OT_SB_AIRBLAST,
OT_SB_CALLLIGHTNING, OT_SB_CALLLIGHTNING,
@ -853,16 +882,22 @@ enum OBTYPE {
OT_SB_LIGHTNINGSTORM, OT_SB_LIGHTNINGSTORM,
OT_SB_WINDSHIELD, OT_SB_WINDSHIELD,
// -- elemental - fire // -- elemental - fire
OT_SB_SPARK, OT_SB_BLADEBURN,
OT_SB_BURNINGWAVE,
OT_SB_FIREDART, OT_SB_FIREDART,
OT_SB_FIREBALL, OT_SB_FIREBALL,
OT_SB_FLAMEPILLAR, OT_SB_FLAMEPILLAR,
OT_SB_FLAMEBURST, OT_SB_FLAMEBURST,
OT_SB_BURNINGWAVE, OT_SB_SPARK,
// -- elemental - ice // -- elemental - ice
OT_SB_CHILL,
OT_SB_CONECOLD, OT_SB_CONECOLD,
OT_SB_FREEZEOB,
OT_SB_COLDBURST, OT_SB_COLDBURST,
OT_SB_FREEZEOB,
OT_SB_FROSTBITE,
OT_SB_ICEEDGE,
OT_SB_ICICLE,
OT_SB_WALLOFICE,
// -- elemental - earth // -- elemental - earth
OT_SB_DIG, OT_SB_DIG,
// -- gravity // -- gravity
@ -886,7 +921,9 @@ enum OBTYPE {
OT_SB_CHARM, OT_SB_CHARM,
// -- modification // -- modification
OT_SB_GASEOUSFORM, OT_SB_GASEOUSFORM,
OT_SB_GREASE,
OT_SB_KNOCK, OT_SB_KNOCK,
OT_SB_HOLDPORTAL,
OT_SB_INSCRIBE, OT_SB_INSCRIBE,
OT_SB_INVISIBILITY, OT_SB_INVISIBILITY,
OT_SB_LIGHT, OT_SB_LIGHT,
@ -898,11 +935,13 @@ enum OBTYPE {
OT_SB_STICKTOSNAKE, OT_SB_STICKTOSNAKE,
// -- summoning // -- summoning
OT_SB_CREATEMONSTER, OT_SB_CREATEMONSTER,
OT_SB_SUMMONWEAPON,
// -- translocation // -- translocation
OT_SB_BLINK, OT_SB_BLINK,
OT_SB_DISPERSAL, OT_SB_DISPERSAL,
OT_SB_GATE, OT_SB_GATE,
OT_SB_TELEPORT, OT_SB_TELEPORT,
OT_SB_TWIDDLE,
// -- wild can't be learned from books // -- wild can't be learned from books
// spells // spells
// -- allomancy // -- allomancy
@ -925,30 +964,41 @@ enum OBTYPE {
OT_S_BLINDNESS, OT_S_BLINDNESS,
OT_S_POISONBOLT, OT_S_POISONBOLT,
OT_S_POSSESSION, OT_S_POSSESSION,
OT_S_STENCH,
// -- divination // -- divination
OT_S_DETECTAURA, OT_S_DETECTAURA,
OT_S_DETECTLIFE, OT_S_DETECTLIFE,
OT_S_DETECTOBS, OT_S_DETECTOBS,
OT_S_DETECTMAGIC, OT_S_DETECTMAGIC,
OT_S_LOCATEOBJECT,
OT_S_LORE,
OT_S_REVEALHIDDEN, OT_S_REVEALHIDDEN,
OT_S_SEEINVIS,
OT_S_IDENTIFY, OT_S_IDENTIFY,
OT_S_MAPPING, OT_S_MAPPING,
// -- elemental - air // -- elemental - air
OT_S_AIRBLAST, OT_S_AIRBLAST,
OT_S_CLOUDKILL, OT_S_CLOUDKILL,
OT_S_GUSTOFWIND, OT_S_GUSTOFWIND,
OT_S_MIST,
OT_S_WINDSHIELD, OT_S_WINDSHIELD,
// -- elemental - fire // -- elemental - fire
OT_S_SPARK, OT_S_BLADEBURN,
OT_S_BURNINGWAVE,
OT_S_FIREDART, OT_S_FIREDART,
OT_S_FIREBALL, OT_S_FIREBALL,
OT_S_FLAMEPILLAR, OT_S_FLAMEPILLAR,
OT_S_FLAMEBURST, OT_S_FLAMEBURST,
OT_S_BURNINGWAVE, OT_S_SPARK,
// -- elemental - ice // -- elemental - ice
OT_S_CHILL,
OT_S_COLDBURST, OT_S_COLDBURST,
OT_S_CONECOLD, OT_S_CONECOLD,
OT_S_FREEZEOB, OT_S_FREEZEOB,
OT_S_FROSTBITE,
OT_S_ICEEDGE,
OT_S_ICICLE,
OT_S_WALLOFICE,
// -- gravity // -- gravity
OT_S_GRAVLOWER, OT_S_GRAVLOWER,
OT_S_GRAVBOOST, OT_S_GRAVBOOST,
@ -972,6 +1022,8 @@ enum OBTYPE {
OT_S_DARKNESS, OT_S_DARKNESS,
OT_S_ENCHANT, OT_S_ENCHANT,
OT_S_GASEOUSFORM, OT_S_GASEOUSFORM,
OT_S_GREASE,
OT_S_HOLDPORTAL,
OT_S_INSCRIBE, OT_S_INSCRIBE,
OT_S_INVISIBILITY, OT_S_INVISIBILITY,
OT_S_KNOCK, OT_S_KNOCK,
@ -1010,12 +1062,14 @@ enum OBTYPE {
OT_S_WATERJET, OT_S_WATERJET,
// -- summoning // -- summoning
OT_S_CREATEMONSTER, OT_S_CREATEMONSTER,
OT_S_SUMMONWEAPON,
// -- translocation // -- translocation
OT_S_BLINK, OT_S_BLINK,
OT_S_PULL, OT_S_PULL,
OT_S_DISPERSAL, OT_S_DISPERSAL,
OT_S_GATE, OT_S_GATE,
OT_S_TELEPORT, OT_S_TELEPORT,
OT_S_TWIDDLE,
// -- wild // -- wild
OT_S_MANASPIKE, OT_S_MANASPIKE,
OT_S_DETONATE, OT_S_DETONATE,
@ -1030,6 +1084,9 @@ enum OBTYPE {
OT_A_LEARN, OT_A_LEARN,
OT_A_LEVELUP, OT_A_LEVELUP,
// abilities // abilities
OT_A_COOK,
OT_A_DARKWALK,
OT_A_DISARM,
OT_A_FLURRY, OT_A_FLURRY,
OT_A_GRAB, OT_A_GRAB,
OT_A_CHARGE, OT_A_CHARGE,
@ -1125,10 +1182,12 @@ enum OBTYPE {
OT_FIREMED, OT_FIREMED,
OT_FIRESMALL, OT_FIRESMALL,
OT_HAILSTORM, OT_HAILSTORM,
OT_ICEWALL,
OT_MAGICBARRIER, OT_MAGICBARRIER,
OT_STEAMCLOUD, OT_STEAMCLOUD,
OT_STEAMPUFF, OT_STEAMPUFF,
OT_SLEETSTORM, OT_SLEETSTORM,
OT_MIST,
OT_SMOKECLOUD, OT_SMOKECLOUD,
OT_SMOKEPUFF, OT_SMOKEPUFF,
OT_POISONCLOUD, OT_POISONCLOUD,
@ -1281,6 +1340,7 @@ enum OBTYPE {
OT_REVOLVER, OT_REVOLVER,
OT_SLING, OT_SLING,
// special weapons // special weapons
OT_ENERGYBLADE,
OT_HANDOFGOD, OT_HANDOFGOD,
@ -1338,6 +1398,7 @@ enum ALLEGIENCE {
}; };
enum POISONTYPE { enum POISONTYPE {
P_COLD,
P_FOOD, P_FOOD,
P_GAS, P_GAS,
P_VENOM, P_VENOM,
@ -1373,6 +1434,9 @@ enum FLAG {
F_NOPICKUP, // cannot pick this up F_NOPICKUP, // cannot pick this up
F_IMPASSABLE, // cannot walk past this if your size if v0 or smaller F_IMPASSABLE, // cannot walk past this if your size if v0 or smaller
F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it
F_CAUSESCOUGH, // being in this ob's cell will make you cough unless
// immune to gas.
// v0 = con skillcheck difficulty.
F_BLOCKSVIEW, // if v0 = true, cannot see past this F_BLOCKSVIEW, // if v0 = true, cannot see past this
// if v0 > 0, reduces your vision by v0. // if v0 > 0, reduces your vision by v0.
F_BLOCKSTHROW, // cannot throw past this F_BLOCKSTHROW, // cannot throw past this
@ -1436,6 +1500,7 @@ enum FLAG {
F_TAINTED, // will give food poisoning if you eat/drink it F_TAINTED, // will give food poisoning if you eat/drink it
F_EDIBLE, // you can eat this. val1 = nutrition. 100 = a meal F_EDIBLE, // you can eat this. val1 = nutrition. 100 = a meal
// -1 means "nutrition is weight x abs(val1)" // -1 means "nutrition is weight x abs(val1)"
// v2 = nutrition left when partially eaten
F_DRINKABLE, // you can drink this. val1 = nutrition. 100 = a meal F_DRINKABLE, // you can drink this. val1 = nutrition. 100 = a meal
// -1 means "nutrition is weight x abs(val1)" // -1 means "nutrition is weight x abs(val1)"
F_OPERABLE, // can operate? F_OPERABLE, // can operate?
@ -1444,12 +1509,18 @@ enum FLAG {
F_PICKLOCKS, // can pick locks? val0=% change, F_PICKLOCKS, // can pick locks? val0=% change,
// val1=b_false, f_dieonfail, f_bluntonfail // val1=b_false, f_dieonfail, f_bluntonfail
F_LOCKABLE,// this object can be locked F_LOCKABLE,// this object can be locked
F_TRAP, // this object is a trap. v0 is sc_disarm difficulty.
// (NA = impossible)
// if v1 = true, trap will go off if you fail your 2nd disarm
// check.
// v2 = sc_dodge difficulty
// doors // doors
F_DOOR, // this object is a door - ie. can open it F_DOOR, // this object is a door - ie. can open it
F_OPEN, // is this door open? F_OPEN, // is this door open?
F_LOCKED,// door is locked F_LOCKED,// door is locked
F_JAMMED, // is this door jammed? // v1 is difficulty to disarm
F_SECRETDOOR, // this door is secret. v0 is sc_search difficulty F_JAMMED, // is this door jammed? v0 is # turns it'll take to open it.
F_SECRET, // this object is secret. v0 is sc_search difficulty
// to find it. // to find it.
// stairs / teleporters / portals // stairs / teleporters / portals
F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in
@ -1487,6 +1558,7 @@ enum FLAG {
// v0 = enum RUSTINESS. // v0 = enum RUSTINESS.
// object mods/effects // object mods/effects
F_ONFIRE, // burning, also deals extra fire damage F_ONFIRE, // burning, also deals extra fire damage
// option text = xdx amount of damage.
F_HEADLESS, // for corpses. can go on LFs too. F_HEADLESS, // for corpses. can go on LFs too.
F_MASTERWORK, // weps do higher damager, armour protects better F_MASTERWORK, // weps do higher damager, armour protects better
F_SHODDY, // weps do less damage, armour protects less. F_SHODDY, // weps do less damage, armour protects less.
@ -1548,6 +1620,7 @@ enum FLAG {
F_NODIECONVERTTEXT, // don't anounce when this object changes F_NODIECONVERTTEXT, // don't anounce when this object changes
// misc flags // misc flags
F_LINKOB, // val0 = linked object id F_LINKOB, // val0 = linked object id
F_LINKRACE, // val0 = linked race id
// scroll flags // scroll flags
F_LINKSPELL, // val0 = spell this scroll will cast when read F_LINKSPELL, // val0 = spell this scroll will cast when read
// v1 = spell power // v1 = spell power
@ -1664,6 +1737,7 @@ enum FLAG {
// when at zero, lf vanishes. // when at zero, lf vanishes.
F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on
// sight // sight
F_HARMLESS, // it is safe to rest around this lf
F_HOSTILE, // lf will attack the player if in sight F_HOSTILE, // lf will attack the player if in sight
F_FRIENDLY, // lf will attack all non-players if in sight F_FRIENDLY, // lf will attack all non-players if in sight
F_WANTS, // lf will try to pick up object type val0. if F_WANTS, // lf will try to pick up object type val0. if
@ -1721,6 +1795,7 @@ enum FLAG {
// v0=slot (0-9) // v0=slot (0-9)
// text=spell text // text=spell text
// for monsters // for monsters
F_DOESNTMOVE, // this race doesn't move (but can still attack)
F_HUMANOID, // this race can wear armour / use weapons F_HUMANOID, // this race can wear armour / use weapons
F_INSECT, // this race is classed as an insect F_INSECT, // this race is classed as an insect
F_UNDEAD, // this race is classed as undead F_UNDEAD, // this race is classed as undead
@ -1855,6 +1930,7 @@ enum FLAG {
F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times
// we can do it. // we can do it.
F_INTERRUPTED, // somethign interrupted our rest. stop! F_INTERRUPTED, // somethign interrupted our rest. stop!
F_EATING, // lf is eating obid v0
F_TRAINING, // are we training? cleared on any action other than rest. F_TRAINING, // are we training? cleared on any action other than rest.
// v2 = if not NA, it is the training counter. // v2 = if not NA, it is the training counter.
// when it hits 0, you finish trainign. // when it hits 0, you finish trainign.
@ -2045,6 +2121,7 @@ enum ERROR {
E_PARTVEGETARIAN = 50, E_PARTVEGETARIAN = 50,
E_CARNIVORE = 51, E_CARNIVORE = 51,
E_NOOB = 52, E_NOOB = 52,
E_LEVITATING = 53,
}; };
@ -2118,7 +2195,8 @@ typedef struct cell_s {
struct celltype_s *type; struct celltype_s *type;
struct obpile_s *obpile; struct obpile_s *obpile;
enum LIGHTLEV lit; enum LIGHTLEV lit;
enum LIGHTLEV origlit; enum LIGHTLEV origlit; // for timed light
enum LIGHTLEV lastlit;
int origlittimer; int origlittimer;
int littimer; int littimer;
@ -2208,6 +2286,8 @@ typedef struct lifeform_s {
int polyrevert; // about to revert form a polymorph? int polyrevert; // about to revert form a polymorph?
int turnsskipped; // don't need to save this
// for loading // for loading
long oblist[MAXPILEOBS]; long oblist[MAXPILEOBS];
int x,y; int x,y;
@ -2383,6 +2463,7 @@ enum BRAND {
BR_SHARPNESS, BR_SHARPNESS,
BR_PYROMANIA, BR_PYROMANIA,
BR_REVENGE, BR_REVENGE,
BR_SHADOWS,
BR_SLOTH, BR_SLOTH,
BR_SPEED, BR_SPEED,
BR_POWER, BR_POWER,

View File

@ -9,6 +9,7 @@ B = bat
d = canine/dog d = canine/dog
e = eye e = eye
f = feline/cat f = feline/cat
F = flora (flowers, plants, etc)
g = goblin g = goblin
i = insect i = insect
j = jelly/ooze/leech j = jelly/ooze/leech

107
flag.c
View File

@ -5,6 +5,7 @@
#include "flag.h" #include "flag.h"
#include "io.h" #include "io.h"
#include "lf.h" #include "lf.h"
#include "map.h"
#include "objects.h" #include "objects.h"
#include "spell.h" #include "spell.h"
#include "text.h" #include "text.h"
@ -24,8 +25,8 @@ flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid) { flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid) {
flag_t *f; flag_t *f;
map_t *redolight = NULL;
int i; int i;
int doredraw = B_FALSE;
// identified things mean all new flags are autmaticlaly known. // identified things mean all new flags are autmaticlaly known.
if (hasflag(fp, F_IDENTIFIED)) { if (hasflag(fp, F_IDENTIFIED)) {
@ -36,6 +37,22 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
return NULL; return NULL;
} }
if (gamemode == GM_GAMESTARTED) {
if ((id == F_PRODUCESLIGHT) || (id == F_ASLEEP) ) {
if (fp->owner && fp->owner->cell) {
if (fp->owner->cell->map == player->cell->map) {
redolight = fp->owner->cell->map;
}
} else if (fp->ob) {
cell_t *obloc;
obloc = getoblocation(fp->ob);
if (obloc && (obloc->map == player->cell->map)) {
redolight = obloc->map;
}
}
}
}
// certain flags stack... // certain flags stack...
if (flagstacks(id)) { if (flagstacks(id)) {
f = hasflag(fp, id); f = hasflag(fp, id);
@ -146,7 +163,8 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
} }
} }
// player flags which cause a redraw // player flags which cause a redraw
doredraw = flagcausesredraw(f->pile->owner, f->id); if (flagcausesredraw(f->pile->owner, f->id)) needredraw = B_TRUE;
if (flagcausesstatredraw(f->pile->owner, f->id)) statdirty = B_TRUE;
} else if (f->pile->ob) { } else if (f->pile->ob) {
if (announceobflaggain(f->pile->ob, f)) { if (announceobflaggain(f->pile->ob, f)) {
f->known = B_TRUE; f->known = B_TRUE;
@ -176,9 +194,12 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
} }
} }
if ((gamemode == GM_GAMESTARTED) && doredraw) { if ((gamemode == GM_GAMESTARTED) && (needredraw || statdirty || redolight)) {
statdirty = B_TRUE; if (redolight) {
needredraw = B_TRUE; needredraw = B_TRUE;
calclight(redolight);
precalclos(player);
}
drawscreen(); drawscreen();
} }
return f; return f;
@ -228,12 +249,15 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
if (isplayer(lf)) { if (isplayer(lf)) {
// player // player
switch (fid) { switch (fid) {
case F_ASLEEP:
case F_BLIND: case F_BLIND:
case F_DETECTLIFE: case F_DETECTLIFE:
case F_DETECTOBS: case F_DETECTOBS:
case F_FASTMOVE: case F_FASTMOVE:
case F_HIDING: case F_HIDING:
case F_INVISIBLE: case F_INVISIBLE:
case F_PRODUCESLIGHT:
case F_PRONE:
case F_RAGE: case F_RAGE:
case F_SEEINDARK: case F_SEEINDARK:
case F_SEEINVIS: case F_SEEINVIS:
@ -246,7 +270,11 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
} }
} else if (haslos(player, lf->cell)) { } else if (haslos(player, lf->cell)) {
switch (fid) { switch (fid) {
case F_ASLEEP:
case F_HIDING:
case F_INVISIBLE: case F_INVISIBLE:
case F_PRODUCESLIGHT:
case F_PRONE:
return B_TRUE; return B_TRUE;
default: default:
break; break;
@ -256,6 +284,33 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
return B_FALSE; return B_FALSE;
} }
int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
if (!lf || !isplayer(lf)) return B_FALSE;
switch (fid) {
case F_ASLEEP:
case F_BLIND:
case F_EATING:
case F_FASTMOVE:
case F_HASNEWLEVEL:
case F_HIDING:
case F_INVISIBLE:
case F_PARALYZED:
case F_POISONED:
case F_PRODUCESLIGHT:
case F_PRONE:
case F_RAGE:
case F_SPRINTING:
case F_SLOWMOVE:
case F_TIRED:
case F_TRAINING:
return B_TRUE;
default:
break;
}
return B_FALSE;
}
int flagstacks(enum FLAG fid) { int flagstacks(enum FLAG fid) {
int res = B_FALSE; int res = B_FALSE;
switch (fid) { switch (fid) {
@ -356,13 +411,31 @@ int killflagsofid(flagpile_t *fp, enum FLAG fid) {
void killflag(flag_t *f) { void killflag(flag_t *f) {
flag_t *nextone, *lastone; flag_t *nextone, *lastone;
lifeform_t *lf; lifeform_t *lf;
int doredraw = B_FALSE; map_t *redolight = NULL;
int redostat = B_FALSE;
int redoscreen = B_FALSE;
lf = f->pile->owner; lf = f->pile->owner;
if (gamemode == GM_GAMESTARTED) {
if ((f->id == F_PRODUCESLIGHT) || (f->id == F_ASLEEP) ) {
if (lf && lf->cell) {
if (lf->cell->map == player->cell->map) {
redolight = lf->cell->map;
}
} else if (f->pile->ob) {
cell_t *obloc;
obloc = getoblocation(f->pile->ob);
if (obloc && (obloc->map == player->cell->map)) {
redolight = obloc->map;
}
}
}
}
// flags which cause a redraw // flags which cause a redraw
doredraw = flagcausesredraw(f->pile->owner, f->id); if (flagcausesredraw(f->pile->owner, f->id)) redoscreen = B_TRUE;
if (flagcausesstatredraw(f->pile->owner, f->id)) redostat = B_TRUE;
// notify // notify
if ((gamemode == GM_GAMESTARTED)) { if ((gamemode == GM_GAMESTARTED)) {
@ -436,10 +509,20 @@ void killflag(flag_t *f) {
lastone->next = nextone; lastone->next = nextone;
} }
if ((gamemode == GM_GAMESTARTED) && doredraw) { if (gamemode == GM_GAMESTARTED) {
statdirty = B_TRUE; if (redolight) {
needredraw = B_TRUE; calclight(redolight);
drawscreen(); precalclos(player);
}
if (redoscreen || redolight) {
needredraw = B_TRUE;
}
if (redostat) {
statdirty = B_TRUE;
}
if (statdirty || needredraw || redolight) {
drawscreen();
}
} }
} }

1
flag.h
View File

@ -10,6 +10,7 @@ void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime); void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int countflags(flagpile_t *fp); int countflags(flagpile_t *fp);
int flagcausesredraw(lifeform_t *lf, enum FLAG fid); int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid);
int flagstacks(enum FLAG fid); int flagstacks(enum FLAG fid);
int modcounter(flagpile_t *fp, int amt); int modcounter(flagpile_t *fp, int amt);
flag_t *hasflag(flagpile_t *fp, int id); flag_t *hasflag(flagpile_t *fp, int id);

317
io.c
View File

@ -72,6 +72,7 @@ int msgmod = B_FALSE;
void addchoice(prompt_t *p, char ch, char *text, char *desc, void *data) { void addchoice(prompt_t *p, char ch, char *text, char *desc, void *data) {
assert(p->choice[p->nchoices].text == NULL);
p->choice[p->nchoices].ch = ch; p->choice[p->nchoices].ch = ch;
p->choice[p->nchoices].text = strdup(text); p->choice[p->nchoices].text = strdup(text);
if (desc) { if (desc) {
@ -230,6 +231,7 @@ void anim(cell_t *src, cell_t *dst, char ch, int colour) {
} }
// show cursor // show cursor
curs_set(1); curs_set(1);
needredraw = B_TRUE;
} }
void animradial(cell_t *src, int radius, char ch, int colour) { void animradial(cell_t *src, int radius, char ch, int colour) {
@ -269,6 +271,7 @@ void animradial(cell_t *src, int radius, char ch, int colour) {
// show cursor // show cursor
curs_set(1); curs_set(1);
needredraw = B_TRUE;
} }
void animradialorth(cell_t *src, int radius, char ch,int colour) { void animradialorth(cell_t *src, int radius, char ch,int colour) {
@ -307,6 +310,7 @@ void animradialorth(cell_t *src, int radius, char ch,int colour) {
} }
// show cursor // show cursor
curs_set(1); curs_set(1);
needredraw = B_TRUE;
} }
@ -339,6 +343,7 @@ void animsky(cell_t *src, char ch, int colour) {
// show cursor // show cursor
curs_set(1); curs_set(1);
needredraw = B_TRUE;
} }
char askchar(char *prompt, char *validchars, char *def, int showchars) { char askchar(char *prompt, char *validchars, char *def, int showchars) {
@ -374,6 +379,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
mvwprintw(msgwin, 0, 0, buf); mvwprintw(msgwin, 0, 0, buf);
wrefresh(msgwin); wrefresh(msgwin);
curs_set(1);
valid = B_FALSE; valid = B_FALSE;
while (!valid) { while (!valid) {
ch = getkey(); ch = getkey();
@ -385,6 +391,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
valid = B_FALSE; valid = B_FALSE;
} }
} }
curs_set(0);
clearmsg(); clearmsg();
if ((ch == 13) && def) { if ((ch == 13) && def) {
return def[0]; return def[0];
@ -422,13 +429,14 @@ cell_t *askcoords(char *prompt, int targettype) {
valid = B_TRUE; valid = B_TRUE;
} else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) { } else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) {
valid = B_TRUE; valid = B_TRUE;
} else if ((targettype & TT_OBJECT) && hasobject(c)) { } else if ((targettype & TT_OBJECT) && hasknownobject(c)) {
valid = B_TRUE; valid = B_TRUE;
} }
if (targettype & TT_DOOR) { if (targettype & TT_DOOR) {
object_t *o; object_t *o;
o = hasobwithflag(c->obpile, F_DOOR); o = hasobwithflag(c->obpile, F_DOOR);
if (o && !hasflag(o->flags, F_SECRETDOOR)) { if (o && !hasflag(o->flags, F_SECRET)) {
valid = B_TRUE; valid = B_TRUE;
} }
} }
@ -772,6 +780,8 @@ char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def)
strcat(buf, "]"); strcat(buf, "]");
} }
curs_set(1);
asprintf(&ending, "%c ",punc); asprintf(&ending, "%c ",punc);
strcat(buf, ending); strcat(buf, ending);
free(ending); free(ending);
@ -784,6 +794,7 @@ char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def)
if (def && (strlen(retbuf) == 0)) { if (def && (strlen(retbuf) == 0)) {
strcpy(retbuf, def); strcpy(retbuf, def);
} }
drawcursor();
return retbuf; return retbuf;
} }
@ -1137,6 +1148,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You are nauseated by a disgusting stench!"); msg("You are nauseated by a disgusting stench!");
donesomething = B_TRUE; donesomething = B_TRUE;
} else {
msg("%s looks very unwell.",lfname);
donesomething = B_TRUE;
} }
break; break;
case F_NONCORPOREAL: case F_NONCORPOREAL:
@ -1231,7 +1245,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break; break;
case F_TREMORSENSE: case F_TREMORSENSE:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("You can 'see' by sensing vibrations around you."); msg("You can now 'see' by sensing vibrations around you.");
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
@ -1282,6 +1296,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
if (donesomething) statdirty = B_TRUE; if (donesomething) statdirty = B_TRUE;
if (statdirty || needredraw) {
drawscreen();
}
return donesomething; return donesomething;
} }
@ -1300,8 +1318,8 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
if (isdead(lf) || isdead(player)) return B_FALSE; if (isdead(lf) || isdead(player)) return B_FALSE;
getlfname(lf, lfname); getlfname(lf, lfname);
// player can't see? // player can't see this?
if (!cansee(player, lf)) { if (!cansee(player, lf) && !isplayer(lf)) {
return B_FALSE; return B_FALSE;
} }
switch (f->id) { switch (f->id) {
@ -1349,7 +1367,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break; break;
case F_ATTACHEDTO: case F_ATTACHEDTO:
lf2 = findlf(NULL, f->val[0]); lf2 = findlf(NULL, f->val[0]);
if (lf2) { if (lf2 && !isdead(lf2)) {
char buf[BUFLEN]; char buf[BUFLEN];
getlfname(lf2, buf); getlfname(lf2, buf);
msg("%s %s %s!",lfname, isplayer(lf) ? "release" : "releases", buf); msg("%s %s %s!",lfname, isplayer(lf) ? "release" : "releases", buf);
@ -1857,11 +1875,11 @@ void announceobflagloss(object_t *o, flag_t *f) {
object_t *askobject(obpile_t *op, char *prompt, int *count, long opts) { object_t *askobject(obpile_t *op, char *prompt, int *count, long opts) {
return doaskobject(op, prompt, count, opts, F_NONE); return doaskobject(op, prompt, count, B_TRUE, opts, F_NONE);
} }
object_t *askobjectwithflag(obpile_t *op, char *prompt, int *count, long opts, enum FLAG withflag) { object_t *askobjectwithflag(obpile_t *op, char *prompt, int *count, long opts, enum FLAG withflag) {
return doaskobject(op, prompt, count, opts, withflag, F_NONE); return doaskobject(op, prompt, count, B_TRUE, opts, withflag, F_NONE);
} }
/* /*
@ -1881,7 +1899,7 @@ int contains(enum OBCLASS *array, int nargs, enum OBCLASS want) {
return B_FALSE; return B_FALSE;
} }
void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters) { void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup) {
int lastclass = OC_NULL; int lastclass = OC_NULL;
int i; int i;
int useobletters = B_TRUE; int useobletters = B_TRUE;
@ -1917,17 +1935,21 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
selchar = ' '; selchar = ' ';
} }
sprintf(buf, "%c %c - %s", selchar, useobletters ? mylist[i]->letter : myletters[i], if (forpickup && hasflag(mylist[i]->flags, F_NOPICKUP)) {
obname); sprintf(buf, "%c %s", selchar, obname);
} else {
sprintf(buf, "%c %c - %s", selchar, useobletters ? mylist[i]->letter : myletters[i],
obname);
}
setobcolour(win, mylist[i]); setobcolour(win, mylist[i], B_TRUE);
getobextrainfo(mylist[i], infobuf); getobextrainfo(mylist[i], infobuf);
getobequipinfo(mylist[i], equipbuf); getobequipinfo(mylist[i], equipbuf);
mvwprintw(win, *y, 0, "%s%s", buf, infobuf); mvwprintw(win, *y, 0, "%s%s", buf, infobuf);
unsetobcolour(win, mylist[i]); setobcolour(win, mylist[i], B_FALSE);
if (strlen(equipbuf)) { if (strlen(equipbuf)) {
setcol(win, C_BROWN); setcol(win, C_BROWN);
@ -1940,7 +1962,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
*counter = i; *counter = i;
} }
object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) { object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, long opts, ...) {
int c,i; int c,i;
object_t *mylist[MAXPILEOBS+1]; object_t *mylist[MAXPILEOBS+1];
char myletters[MAXPILEOBS+1]; char myletters[MAXPILEOBS+1];
@ -1981,6 +2003,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]"); centre(mainwin, getmaxy(mainwin)-1, "[Press any key]");
getch(); getch();
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
return NULL; return NULL;
@ -2065,7 +2088,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
// list the objects // list the objects
y = 2; y = 2;
listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters ); listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters , forpickup);
if (mylist[i] == NULL) { if (mylist[i] == NULL) {
nextpage = -1; nextpage = -1;
@ -2124,6 +2147,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
*count = o->amt; *count = o->amt;
} }
// display game windows again // display game windows again
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
return o; return o;
@ -2131,6 +2155,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
} else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing } else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing
reason = E_SELNOTHING; reason = E_SELNOTHING;
// display game windows again // display game windows again
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
return NULL; return NULL;
@ -2154,10 +2179,9 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
} }
} }
// clear msg bar
clearmsg();
// display game windows again // display game windows again
needredraw = B_TRUE;
clearmsg();
drawscreen(); drawscreen();
return NULL; return NULL;
} }
@ -2194,6 +2218,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]"); centre(mainwin, getmaxy(mainwin)-1, "[Press any key]");
getch(); getch();
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
return B_TRUE; return B_TRUE;
@ -2253,7 +2278,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
// list the objects // list the objects
y = 2; y = 2;
listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters ); listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters , B_TRUE);
if (mylist[i] == NULL) { if (mylist[i] == NULL) {
nextpage = -1; nextpage = -1;
@ -2330,6 +2355,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
reason = E_SELNOTHING; reason = E_SELNOTHING;
nretobs = 0; nretobs = 0;
// display game windows again // display game windows again
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
return B_TRUE; return B_TRUE;
@ -2381,6 +2407,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
clearmsg(); clearmsg();
// display game windows again // display game windows again
needredraw = B_TRUE;
drawscreen(); drawscreen();
if (nretobs <= 0) { if (nretobs <= 0) {
return B_TRUE; return B_TRUE;
@ -2425,6 +2452,7 @@ char checkforkey(void) {
ch = getch(); ch = getch();
nodelay(mainwin, FALSE); nodelay(mainwin, FALSE);
if (ch == ERR) ch = '\0'; if (ch == ERR) ch = '\0';
if (ch == ' ') ch = '\0';
return ch; return ch;
} }
@ -2491,6 +2519,7 @@ void updateviewfor(cell_t *cell) {
void drawscreen(void) { void drawscreen(void) {
int didstatus = B_FALSE;
if (gamemode < GM_GAMESTARTED) { if (gamemode < GM_GAMESTARTED) {
return; return;
} }
@ -2499,12 +2528,17 @@ void drawscreen(void) {
drawstatus(); drawstatus();
wrefresh(statwin); wrefresh(statwin);
statdirty = B_FALSE; statdirty = B_FALSE;
didstatus = B_TRUE;
} }
if (needredraw) { if (needredraw) {
updateviewfor(player->cell); updateviewfor(player->cell);
drawlevelfor(player); drawlevelfor(player);
drawcursor(); // this will call redraw gamewin //drawcursor(); // this will call redraw gamewin
}
if (didstatus && !needredraw) {
drawcursor();
} }
} }
@ -2610,7 +2644,11 @@ void describeob(object_t *o) {
// other extra damage or effects? // other extra damage or effects?
f = hasflag(o->flags, F_ONFIRE); f = hasflag(o->flags, F_ONFIRE);
if (f) { if (f) {
mvwprintw(mainwin, y, 0, " It also inflicts extra burning damage."); if (f->text) {
mvwprintw(mainwin, y, 0, " It also inflicts %s extra burning damage.", f->text);
} else {
mvwprintw(mainwin, y, 0, " It also inflicts extra burning damage.");
}
y++; y++;
} }
@ -2699,21 +2737,90 @@ void describeob(object_t *o) {
y++; y++;
} }
// skip line
y++;
// immunities // immunities
for (i = 0; i < MAXDAMTYPE; i++) { strcpy(buf, "");
if (isimmuneto(o->flags, i)) { f = hasflagval(o->flags, F_DTIMMUNE, DT_ALL, NA, NA, NULL);
mvwprintw(mainwin, y, 0, "It is immune to %s.",getdamnamenoun(i)); if (f) {
y++; sprintf(buf, "It is immune to %s", getdamname(DT_ALL));
} } else {
if (isresistantto(o->flags, i)) { int first = B_TRUE;
mvwprintw(mainwin, y, 0, "It is resistant to %s.",getdamnamenoun(i)); for (i = 0; i < MAXDAMTYPE; i++) {
y++; f = isimmuneto(o->flags, i);
} if (f) {
if (isvulnto(o->flags, i)) { char buf2[BUFLEN];
mvwprintw(mainwin, y, 0, "It is vulnerable to %s.",getdamnamenoun(i)); if (first) {
y++; sprintf(buf2, "It is immune to: %s", getdamname(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamname(i));
}
strcat(buf, buf2);
}
} }
} }
if (strlen(buf) > 0) {
strcat(buf, ".");
mvwprintw(mainwin, y, 0, buf);
y++;
}
// resistances
strcpy(buf, "");
f = hasflagval(o->flags, F_DTRESIST, DT_ALL, NA, NA, NULL);
if (f) {
sprintf(buf, "It is resistant to %s", getdamname(DT_ALL));
} else {
int first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
f = isresistantto(o->flags, i);
if (f) {
char buf2[BUFLEN];
if (first) {
sprintf(buf2, "It is resistant to: %s", getdamname(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamname(i));
}
strcat(buf, buf2);
}
}
}
if (strlen(buf) > 0) {
strcat(buf, ".");
mvwprintw(mainwin, y, 0, buf);
y++;
}
// vulnerabilities
strcpy(buf, "");
f = hasflagval(o->flags, F_DTVULN, DT_ALL, NA, NA, NULL);
if (f) {
sprintf(buf, "It is vulnerable to %s", getdamname(DT_ALL));
} else {
int first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
f = isvulnto(o->flags, i);
if (f) {
char buf2[BUFLEN];
if (first) {
sprintf(buf2, "It is vulnerable to: %s", getdamname(i));
first = B_FALSE;
} else {
sprintf(buf2, ", %s", getdamname(i));
}
strcat(buf, buf2);
}
}
}
if (strlen(buf) > 0) {
strcat(buf, ".");
mvwprintw(mainwin, y, 0, buf);
y++;
}
// been made invulnerable ? // been made invulnerable ?
if (hasflag(o->type->flags, F_DAMAGABLE) && !hasflag(o->flags, F_DAMAGABLE)) { if (hasflag(o->type->flags, F_DAMAGABLE) && !hasflag(o->flags, F_DAMAGABLE)) {
@ -3020,7 +3127,7 @@ void describeob(object_t *o) {
// skill type? // skill type?
f = hasflag(o->flags, F_USESSKILL); f = hasflag(o->flags, F_USESSKILL);
if (f) { if (f && (f->val[0] != SK_NONE)) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
enum COLOUR col; enum COLOUR col;
slev = getskill(player, f->val[0]); slev = getskill(player, f->val[0]);
@ -3061,6 +3168,7 @@ void describeob(object_t *o) {
// wait for key // wait for key
getch(); getch();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
needredraw = B_TRUE;
drawscreen(); drawscreen();
} }
@ -3114,6 +3222,7 @@ void describespell(objecttype_t *ot) {
// wait for key // wait for key
getch(); getch();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
needredraw = B_TRUE;
drawscreen(); drawscreen();
} }
@ -3629,6 +3738,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
killobpile(op); killobpile(op);
needredraw = B_TRUE;
drawscreen(); drawscreen();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
} }
@ -3713,6 +3823,7 @@ void doknowledgelist(void) {
wrefresh(mainwin); wrefresh(mainwin);
getch(); getch();
needredraw = B_TRUE;
clearmsg(); clearmsg();
drawscreen(); drawscreen();
} }
@ -3729,6 +3840,9 @@ void dolook(cell_t *where, int onpurpose) {
// (also count objects without this flag) // (also count objects without this flag)
numobs = 0; numobs = 0;
for (o = where->obpile->first ; o ; o = o->next) { for (o = where->obpile->first ; o ; o = o->next) {
if (hasflag(o->flags, F_SECRET)) continue;
if (hasflag(o->flags, F_COSMETIC)) continue;
f = hasflag(o->flags, F_THEREISHERE); f = hasflag(o->flags, F_THEREISHERE);
if (f) { if (f) {
// doens't matter if you're blind // doens't matter if you're blind
@ -3737,10 +3851,10 @@ void dolook(cell_t *where, int onpurpose) {
interrupt(player); interrupt(player);
seensomething = B_TRUE; seensomething = B_TRUE;
} else { } else {
if (onpurpose || !hasflag(o->flags, F_COSMETIC)) { //if (onpurpose) {
if (!numobs) firstob = o; if (!numobs) firstob = o;
numobs++; numobs++;
} // }
} }
} }
@ -3787,7 +3901,7 @@ void dolook(cell_t *where, int onpurpose) {
// if wantunknown is set, lsit spells we DONT know. // if wantunknown is set, lsit spells we DONT know.
// otherwise list spells we DO know. // otherwise list spells we DO know.
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown) { void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantinvalid) {
char ch; char ch;
flag_t *f; flag_t *f;
char buf[BUFLEN]; char buf[BUFLEN];
@ -3947,8 +4061,10 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
strcat(costbuf, mpdesc[i]); strcat(costbuf, mpdesc[i]);
sprintf(buf, "%-30s%s", buf2, costbuf); sprintf(buf, "%-30s%s", buf2, costbuf);
// letter doesn't matter if (wantinvalid || validspell[i]) {
addchoice(pr, 'a', buf2, buf, ot); // letter doesn't matter
addchoice(pr, 'a', buf2, buf, ot);
}
} }
} }
@ -3959,7 +4075,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly) {
// init the prompt if required. // init the prompt if required.
if (spellid == OT_NONE) { if (spellid == OT_NONE) {
makespellchoicelist(&prompt, player, "Use which spell/ability:","Describe which spell/ability:", SS_NONE, B_FALSE); makespellchoicelist(&prompt, player, "Use which spell/ability:","Describe which spell/ability:", SS_NONE, B_FALSE, B_TRUE);
} }
finished = B_FALSE; finished = B_FALSE;
@ -4027,7 +4143,7 @@ void domemmagic(void) {
char ch; char ch;
int slot; int slot;
objecttype_t *ot; objecttype_t *ot;
makespellchoicelist(&prompt, player, "Memorise which spell/ability:","Describe which spell/ability",SS_NONE, B_FALSE); makespellchoicelist(&prompt, player, "Memorise which spell/ability:","Describe which spell/ability",SS_NONE, B_FALSE, B_TRUE);
if (prompt.nchoices <= 0) { if (prompt.nchoices <= 0) {
msg("You don't have any spells or abilities!"); msg("You don't have any spells or abilities!");
return; return;
@ -4063,6 +4179,7 @@ void domsghist(void) {
getch(); getch();
// restore screen // restore screen
//cls(); //cls();
needredraw = B_TRUE;
drawscreen(); drawscreen();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
} }
@ -4173,7 +4290,7 @@ void doexplain(char *question) {
where = askcoords(question, TT_NONE); where = askcoords(question, TT_NONE);
if (!where) { if (!where) {
clearmsg(); clearmsg();
return; break;
} }
// explain it // explain it
@ -4249,6 +4366,7 @@ void dohelp(void) {
centre(mainwin, h-1, "[Press any key]"); centre(mainwin, h-1, "[Press any key]");
getch(); getch();
needredraw = B_TRUE;
drawscreen(); drawscreen();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
} }
@ -4524,6 +4642,9 @@ void dorest(void) {
rest(player, B_TRUE); rest(player, B_TRUE);
} else { } else {
switch (reason) { switch (reason) {
case E_LEVITATING:
msg("You cannot rest while levitating in mid-air!");
break;
case E_MONSTERNEARBY: case E_MONSTERNEARBY:
msg("You cannot rest - there are monsters nearby!"); msg("You cannot rest - there are monsters nearby!");
break; break;
@ -4762,6 +4883,8 @@ void drawcursor(void) {
// move cursor to player position // move cursor to player position
wmove(gamewin, player->cell->y - viewy, player->cell->x - viewx); wmove(gamewin, player->cell->y - viewy, player->cell->x - viewx);
wrefresh(gamewin); wrefresh(gamewin);
// turn on cursor
curs_set(1);
} }
void drawlevelfor(lifeform_t *lf) { void drawlevelfor(lifeform_t *lf) {
@ -4770,16 +4893,18 @@ void drawlevelfor(lifeform_t *lf) {
map_t *map; map_t *map;
map = lf->cell->map; map = lf->cell->map;
needredraw = B_FALSE;
numdraws++; numdraws++;
// turn off cursor // turn off cursor
curs_set(0); curs_set(0);
// TODO: draw to buffer here...
// buffer is an array of 'glyph_t's
wclear(gamewin); wclear(gamewin);
for (y = viewy; y < viewy + viewh; y++) { for (y = viewy; y < viewy + viewh; y++) {
for (x = viewx; x < viewx + vieww; x++) { for (x = viewx; x < viewx + vieww; x++) {
if ((x == lf->cell->x + 1) && (y == lf->cell->y)) {
dblog("x");
}
cell = getcellat(map, x, y); cell = getcellat(map, x, y);
if (cell) { if (cell) {
glyph_t glyph,screenglyph; glyph_t glyph,screenglyph;
@ -4800,10 +4925,8 @@ void drawlevelfor(lifeform_t *lf) {
} }
} }
} }
// turn on cursor // move cursor to the player's position and blit
curs_set(1); drawcursor();
// move it to the player's position
wmove(gamewin, lf->y - viewy, lf->x - viewx);
} }
void doheading(WINDOW *win, int *y, int x, char *what) { void doheading(WINDOW *win, int *y, int x, char *what) {
@ -4928,6 +5051,29 @@ int drop(object_t *o, int count) {
return B_FALSE; return B_FALSE;
} }
void dumpspells(void) {
objecttype_t *ot;
enum SPELLSCHOOL ss;
int lev;
dblog("Spell dump:");
for (ss = 0; ss < SS_LAST; ss++) {
dblog("%s", getschoolname(ss));
for (lev = 1; lev <= MAXSPELLLEV; lev++) {
dblog("\tLevel %d:", lev);
// get list of spells/abilities we can cast at will
for (ot = objecttype ; ot ; ot = ot->next) {
if (ot->obclass->id == OC_SPELL) {
// matches the current school & level?
if ((getspellschool(ot->id) == ss) && (getspelllevel(ot->id) == lev)) {
dblog("\t\t%s", ot->name);
}
}
}
}
}
}
char getchoice(prompt_t *prompt) { char getchoice(prompt_t *prompt) {
int i; int i;
int y; int y;
@ -4938,6 +5084,7 @@ char getchoice(prompt_t *prompt) {
int nextpage = -1; int nextpage = -1;
int lastline = SCREENH - 4; int lastline = SCREENH - 4;
gotheadings = B_FALSE; gotheadings = B_FALSE;
for (i = 0; i < prompt->nchoices; i++) { for (i = 0; i < prompt->nchoices; i++) {
if (prompt->choice[i].heading) { if (prompt->choice[i].heading) {
@ -4946,6 +5093,7 @@ char getchoice(prompt_t *prompt) {
} }
} }
curs_set(1);
// loop until result is valid // loop until result is valid
sel = -1; sel = -1;
while (sel == -1) { while (sel == -1) {
@ -5013,11 +5161,13 @@ char getchoice(prompt_t *prompt) {
} }
if ((gamemode == GM_GAMESTARTED)) { if ((gamemode == GM_GAMESTARTED)) {
needredraw = B_TRUE;
drawscreen(); drawscreen();
} else { } else {
cls(); cls();
wrefresh(mainwin); wrefresh(mainwin);
} }
curs_set(0);
// return NUL or result char // return NUL or result char
if (ch == 27) { if (ch == 27) {
return '\0'; return '\0';
@ -5062,6 +5212,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
doneheading = B_FALSE; doneheading = B_FALSE;
// loop until result is valid // loop until result is valid
curs_set(1);
sel = -1; sel = -1;
while (sel == -1) { while (sel == -1) {
int atbottom; int atbottom;
@ -5268,11 +5419,13 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
} }
if ((gamemode == GM_GAMESTARTED)) { if ((gamemode == GM_GAMESTARTED)) {
needredraw = B_TRUE;
drawscreen(); drawscreen();
} else { } else {
cls(); cls();
wrefresh(mainwin); wrefresh(mainwin);
} }
curs_set(0);
// return NUL or result char // return NUL or result char
if (ch == 27) { if (ch == 27) {
return '\0'; return '\0';
@ -5725,8 +5878,10 @@ void more(void) {
strcat(msgbuf, MORESTRING); strcat(msgbuf, MORESTRING);
//mvwprintw(msgwin, 0, 0, msgbuf); //mvwprintw(msgwin, 0, 0, msgbuf);
drawmsg(); drawmsg();
curs_set(1);
// wait for space // wait for space
while (getch() != ' '); while (getch() != ' ');
curs_set(0);
// clear msg // clear msg
clearmsg(); clearmsg();
} }
@ -5847,6 +6002,7 @@ void drawstatus(void) {
getplayernamefull(pname); getplayernamefull(pname);
curs_set(0);
wclear(statwin); wclear(statwin);
xpleft = getxpforlev(player->level + 1) - player->xp; xpleft = getxpforlev(player->level + 1) - player->xp;
@ -5989,16 +6145,16 @@ void drawstatus(void) {
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) { if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
if (poisonthreatenslife(player, f)) { if (poisonthreatenslife(player, f)) {
setcol(statwin, C_GREEN); setcol(statwin, C_GREEN);
wprintw(statwin, " Poison(bad)"); wprintw(statwin, " %s(bad)", getpoisondesc(f->val[0]));
unsetcol(statwin, C_GREEN); unsetcol(statwin, C_GREEN);
} else { } else {
setcol(statwin, C_BROWN); setcol(statwin, C_BROWN);
wprintw(statwin, " Poisoned(mild)"); wprintw(statwin, " %s(mild)", getpoisondesc(f->val[0]));
unsetcol(statwin, C_BROWN); unsetcol(statwin, C_BROWN);
} }
} else { } else {
setcol(statwin, C_GREEN); setcol(statwin, C_GREEN);
wprintw(statwin, " Poisoned"); wprintw(statwin, " %s", getpoisondesc(f->val[0]));
unsetcol(statwin, C_GREEN); unsetcol(statwin, C_GREEN);
} }
} }
@ -6232,26 +6388,35 @@ void unsetcol(WINDOW *win, enum COLOUR col) {
} }
} }
void setobcolour(WINDOW *win, object_t *o) { void setobcolour(WINDOW *win, object_t *o, int set) {
if (!o) return; void (*funcptr)(WINDOW *, enum COLOUR);
if (o->blessknown) { // which function?
if (iscursed(o)) { if (set) {
setcol(win, C_RED); funcptr = setcol;
} else if (isblessed(o)) { } else {
setcol(win, C_CYAN); funcptr = unsetcol;
}
} }
} if (!o) return;
void unsetobcolour(WINDOW *win, object_t *o) {
if (!o) return;
if (o->blessknown) { if (o->blessknown) {
if (iscursed(o)) { if (iscursed(o)) {
unsetcol(win, C_RED); funcptr(win, C_RED);
return;
} else if (isblessed(o)) { } else if (isblessed(o)) {
unsetcol(win, C_CYAN); funcptr(win, C_CYAN);
return;
} }
} }
if ((getskill(player, SK_COOKING) >= PR_BEGINNER) && isbadfood(o)) {
funcptr(win, C_GREEN);
return;
}
if (lfhasflag(player, F_DETECTMAGIC) && ismagical(o)) {
funcptr(win, C_BOLDGREEN);
return;
}
} }
void showlfarmour(lifeform_t *lf) { void showlfarmour(lifeform_t *lf) {
@ -6296,9 +6461,9 @@ void showlfarmour(lifeform_t *lf) {
} }
mvwprintw(mainwin, y, 0, "%s", buf); mvwprintw(mainwin, y, 0, "%s", buf);
setobcolour(mainwin, o); setobcolour(mainwin, o, B_TRUE);
wprintw(mainwin, "%s", rhs); wprintw(mainwin, "%s", rhs);
unsetobcolour(mainwin, o); setobcolour(mainwin, o, B_FALSE);
y++; y++;
} }
} }
@ -6328,6 +6493,7 @@ void showlfarmour(lifeform_t *lf) {
*/ */
getch(); getch();
needredraw = B_TRUE;
drawscreen(); drawscreen();
real_clearmsg(B_TRUE); real_clearmsg(B_TRUE);
} }
@ -6424,6 +6590,9 @@ void showlfstats(lifeform_t *lf, int showall) {
if (isplayer(lf)) { if (isplayer(lf)) {
mvwprintw(mainwin, y, 0, ftext, "Race"); mvwprintw(mainwin, y, 0, ftext, "Race");
wprintw(mainwin, "%-20s", lf->race->name); y++; wprintw(mainwin, "%-20s", lf->race->name); y++;
} else {
mvwprintw(mainwin, y, 0, ftext, "Type");
wprintw(mainwin, "%-20s", lf->race->raceclass->name); y++;
} }
j = getjob(lf); j = getjob(lf);
@ -7274,11 +7443,12 @@ void showlfstats(lifeform_t *lf, int showall) {
getskillname(available[n]->val[0]) ); getskillname(available[n]->val[0]) );
} }
if (n < numknown) { if (n < numknown) {
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]" : "");
} }
if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) { if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
@ -7625,8 +7795,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
f = lfhasknownflag(lf, F_PACKATTACK); f = lfhasknownflag(lf, F_PACKATTACK);
if (f && (f->known)) { if (f && (f->known)) {
sprintf(buf,"%s deal%s extra damage when in a %s pack.", you(lf), isplayer(lf) ? "" : "s", sprintf(buf,"%s deal%s extra damage when in a pack.", you(lf), isplayer(lf) ? "" : "s");
f->text);
mvwprintw(mainwin, y, 0, buf); mvwprintw(mainwin, y, 0, buf);
y++; y++;
} }
@ -7742,7 +7911,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
f = lfhasknownflag(lf, F_TREMORSENSE); f = lfhasknownflag(lf, F_TREMORSENSE);
if (f) { if (f) {
mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around you.", you(lf)); mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around %s.", you(lf), you(lf));
y++; y++;
} }
f = lfhasknownflag(lf, F_WINDSHIELD); f = lfhasknownflag(lf, F_WINDSHIELD);
@ -7858,6 +8027,7 @@ void showlfstats(lifeform_t *lf, int showall) {
needredraw = B_TRUE; needredraw = B_TRUE;
cls(); wrefresh(mainwin); cls(); wrefresh(mainwin);
needredraw = B_TRUE;
drawscreen(); drawscreen();
wrefresh(gamewin); wrefresh(gamewin);
wrefresh(statwin); wrefresh(statwin);
@ -7883,6 +8053,7 @@ void tombstone(lifeform_t *lf) {
centre(mainwin, y, "R.I.P."); y++; centre(mainwin, y, "R.I.P."); y++;
//printf("%s\n",lf->name); //printf("%s\n",lf->name);
centre(mainwin, y, "%s",pname); y++; centre(mainwin, y, "%s",pname); y++;
centre(mainwin, y, "Died on level %d of the dungeon.", lf->cell->map->depth); y++;
p = strtok_r(lf->lastdam,"^", &dummy); p = strtok_r(lf->lastdam,"^", &dummy);
if (p) { if (p) {

10
io.h
View File

@ -15,7 +15,7 @@ int announceobflaggain(object_t *o, flag_t *f);
void announceobflagloss(object_t *o, flag_t *f); void announceobflagloss(object_t *o, flag_t *f);
object_t *askobject(obpile_t *op, char *title, int *count, long opts); object_t *askobject(obpile_t *op, char *title, int *count, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag); object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag);
object_t *doaskobject(obpile_t *op, char *title, int *count, long opts, ...); object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, long opts, ...);
int askobjectmulti(obpile_t *op, char *prompt, long opts); int askobjectmulti(obpile_t *op, char *prompt, long opts);
char askchar(char *prompt, char *validchars, char *def, int showchars); char askchar(char *prompt, char *validchars, char *def, int showchars);
cell_t *askcoords(char *prompt, int targettype); cell_t *askcoords(char *prompt, int targettype);
@ -72,6 +72,7 @@ void drawmsg(void);
void drawscreen(void); void drawscreen(void);
void drawstatus(void); void drawstatus(void);
int drop(object_t *o, int count); int drop(object_t *o, int count);
void dumpspells(void);
char getchoice(prompt_t *prompt); char getchoice(prompt_t *prompt);
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart); char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
int getkey(void); int getkey(void);
@ -81,8 +82,8 @@ void doheading(WINDOW *win, int *y, int x, char *what);
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);
void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters); void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup);
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown); void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantinvalid);
void more(void); void more(void);
void warn(char *format, ... ); void warn(char *format, ... );
void msg(char *format, ... ); void msg(char *format, ... );
@ -95,8 +96,7 @@ void redraw(void);
int savequit(void); int savequit(void);
void setcol(WINDOW *win, enum COLOUR col); void setcol(WINDOW *win, enum COLOUR col);
void unsetcol(WINDOW *win, enum COLOUR col); void unsetcol(WINDOW *win, enum COLOUR col);
void setobcolour(WINDOW *win, object_t *o); void setobcolour(WINDOW *win, object_t *o, int set);
void unsetobcolour(WINDOW *win, object_t *o);
void showlfarmour(lifeform_t *lf); void showlfarmour(lifeform_t *lf);
void showlfstats(lifeform_t *lf, int showall); void showlfstats(lifeform_t *lf, int showall);
void tombstone(lifeform_t *lf); void tombstone(lifeform_t *lf);

1026
lf.c

File diff suppressed because it is too large Load Diff

10
lf.h
View File

@ -14,6 +14,7 @@ void autoskill(lifeform_t *lf);
void autotarget(lifeform_t *lf); void autotarget(lifeform_t *lf);
void autoweild(lifeform_t *lf); void autoweild(lifeform_t *lf);
int appearsrandomly(enum RACE rid); int appearsrandomly(enum RACE rid);
void awardxpfor(lifeform_t *killed, float pct);
void bleed(lifeform_t *lf); void bleed(lifeform_t *lf);
void breakallgrabs(lifeform_t *lf); void breakallgrabs(lifeform_t *lf);
int calcxp(lifeform_t *lf); int calcxp(lifeform_t *lf);
@ -28,6 +29,7 @@ int canpolymorphto(enum RACE rid);
int canpush(lifeform_t *lf, object_t *o, int dir); int canpush(lifeform_t *lf, object_t *o, int dir);
int canquaff(lifeform_t *lf, object_t *o); int canquaff(lifeform_t *lf, object_t *o);
int cansee(lifeform_t *viewer, lifeform_t *viewee); int cansee(lifeform_t *viewer, lifeform_t *viewee);
int cansleep(lifeform_t *lf);
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where); int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
int canweild(lifeform_t *lf, object_t *o); int canweild(lifeform_t *lf, object_t *o);
int cantakeoff(lifeform_t *lf, object_t *o); int cantakeoff(lifeform_t *lf, object_t *o);
@ -132,6 +134,7 @@ char *getplayername(char *buf);
char *getplayernamefull(char *buf); char *getplayernamefull(char *buf);
int getpoisondamchance(enum POISONTYPE ptype); int getpoisondamchance(enum POISONTYPE ptype);
char *getpoisondamverb(enum POISONTYPE ptype); char *getpoisondamverb(enum POISONTYPE ptype);
char *getpoisondesc(enum POISONTYPE ptype);
char *getpoisonname(enum POISONTYPE ptype); char *getpoisonname(enum POISONTYPE ptype);
int getraceclass(lifeform_t *lf); int getraceclass(lifeform_t *lf);
int getracerarity(map_t *map, enum RACE rid); int getracerarity(map_t *map, enum RACE rid);
@ -167,6 +170,7 @@ flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text); flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
flag_t *lfhasknownflag(lifeform_t *lf, enum FLAG fid); flag_t *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text); flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
int lfproduceslight(lifeform_t *lf);
int lockpick(lifeform_t *lf, object_t *target, object_t *device); int lockpick(lifeform_t *lf, object_t *target, object_t *device);
void loseobflags(lifeform_t *lf, object_t *o, int kind); void loseobflags(lifeform_t *lf, object_t *o, int kind);
int hasbp(lifeform_t *lf, enum BODYPART bp); int hasbp(lifeform_t *lf, enum BODYPART bp);
@ -191,6 +195,7 @@ int isfriendly(lifeform_t *lf);
int isgenius(lifeform_t *lf); int isgenius(lifeform_t *lf);
int isimmobile(lifeform_t *lf); int isimmobile(lifeform_t *lf);
flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt); flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
int isinbattle(lifeform_t *lf);
int isingunrange(lifeform_t *lf, cell_t *where); int isingunrange(lifeform_t *lf, cell_t *where);
int isloreskill(enum SKILL skid); int isloreskill(enum SKILL skid);
int ismaxedskill(lifeform_t *lf, enum SKILL skid); int ismaxedskill(lifeform_t *lf, enum SKILL skid);
@ -198,6 +203,7 @@ int ispeaceful(lifeform_t *lf);
int ispetof(lifeform_t *lf, lifeform_t *owner); int ispetof(lifeform_t *lf, lifeform_t *owner);
int isplayer(lifeform_t *lf); int isplayer(lifeform_t *lf);
flag_t *ispoisoned(lifeform_t *lf); flag_t *ispoisoned(lifeform_t *lf);
flag_t *ispoisonedwith(lifeform_t *lf, enum POISONTYPE pt);
int ispolymorphed(lifeform_t *lf); int ispolymorphed(lifeform_t *lf);
int isprone(lifeform_t *lf); int isprone(lifeform_t *lf);
flag_t *isresistantto(flagpile_t *fp, enum DAMTYPE dt); flag_t *isresistantto(flagpile_t *fp, enum DAMTYPE dt);
@ -213,7 +219,7 @@ int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, ch
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam); int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam);
void losemp(lifeform_t *lf, int amt); void losemp(lifeform_t *lf, int amt);
void makefriendly(lifeform_t *lf, int howlong); void makefriendly(lifeform_t *lf, int howlong);
void makenauseated(lifeform_t *lf, int amt, int howlong); int makenauseated(lifeform_t *lf, int amt, int howlong);
void makenoise(lifeform_t *lf, enum NOISETYPE nid); void makenoise(lifeform_t *lf, enum NOISETYPE nid);
void makepeaceful(lifeform_t *lf); void makepeaceful(lifeform_t *lf);
lifeform_t *makezombie(object_t *o); lifeform_t *makezombie(object_t *o);
@ -227,6 +233,7 @@ void noise(cell_t *c, lifeform_t *noisemaker, 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);
int poisoncausesvomit(enum POISONTYPE ptype);
int poisonthreatenslife(lifeform_t *lf, flag_t *f); int poisonthreatenslife(lifeform_t *lf, flag_t *f);
void practice(lifeform_t *lf, enum SKILL skid); void practice(lifeform_t *lf, enum SKILL skid);
void precalclos(lifeform_t *lf); void precalclos(lifeform_t *lf);
@ -256,6 +263,7 @@ int skillcheckvs(lifeform_t *lf1, enum CHECKTYPE ct1, int mod1, lifeform_t *lf2,
int slipon(lifeform_t *lf, object_t *o); int slipon(lifeform_t *lf, object_t *o);
void sortlf(map_t *map, lifeform_t *lf); void sortlf(map_t *map, lifeform_t *lf);
int stone(lifeform_t *lf); int stone(lifeform_t *lf);
void stopeating(lifeform_t *lf);
void stopresting(lifeform_t *lf); void stopresting(lifeform_t *lf);
void stoprunning(lifeform_t *lf); void stoprunning(lifeform_t *lf);
int testammo(lifeform_t *lf, object_t *o); int testammo(lifeform_t *lf, object_t *o);

59
log.txt
View File

@ -4,50 +4,15 @@
====== NEW LOGFILE ==== ====== NEW LOGFILE ====
givejob() starting. givejob() starting.
fireat(): dam = throwdam(2) * speed(3) = 6 x
fireat(): dam = throwdam(2) * speed(3) = 6 x
fireat(): dam = throwdam(3) * speed(3) = 9 x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met } x
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
fireat(): dam = throwdam(2) * speed(2) = 4
xxx
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
fireat(): dam = throwdam(3) * speed(2) = 6
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast charge - specific spell check failed }
.oO { cant cast charge - specific spell check failed }
fireat(): dam = throwdam(2) * speed(2) = 4
fireat(): dam = throwdam(2) * speed(3) = 6
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
.oO { cant cast suck blood - targetting conditions cannot be met }
xxx
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
fireat(): dam = throwdam(2) * speed(3) = 6
fireat(): dam = throwdam(3) * speed(3) = 9
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
.oO { cant cast grab - targetting conditions cannot be met }
xxx

100
map.c
View File

@ -24,6 +24,10 @@ extern enum OBCLASS sortorder[];
extern enum ERROR reason; extern enum ERROR reason;
extern enum GAMEMODE gamemode;
extern int needredraw;
cell_t *addcell(map_t *m, int x, int y) { cell_t *addcell(map_t *m, int x, int y) {
cell_t *cell; cell_t *cell;
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t)); m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
@ -143,7 +147,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
//if (lf->cell->map->beingcreated) { //if (lf->cell->map->beingcreated) {
if (autogen) { if (autogen) {
// sometimes start off asleep in new maps // sometimes start off asleep in new maps
if (!lfhasflag(lf, F_DEAF)) { if (!lfhasflag(lf, F_DEAF) && cansleep(lf)) {
// TODO: base this on the time, and whether monster is nocturnal // TODO: base this on the time, and whether monster is nocturnal
if (rnd(1,2) == 1) { if (rnd(1,2) == 1) {
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
@ -232,7 +236,13 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
char buf[BUFLEN]; char buf[BUFLEN];
int i; int i;
for (i = 0; i < nobs; i++) { for (i = 0; i < nobs; i++) {
if (getrandomob(c->map, buf)) addob(lf->pack, buf); if (getrandomob(c->map, buf)) {
object_t *o;
o = addob(lf->pack, buf);
if (o && !canpickup(lf, o, o->amt)) {
killob(o);
}
}
} }
} }
} }
@ -414,7 +424,7 @@ int getcelldistorth(cell_t *src, cell_t *dst) { // add x/y
} }
//populates 'g' with the contects of cell 'c', as seen by 'viewer' //populates 'g' with the contects of cell 'c', as seen by 'viewer'
// if we can't see anything there, set g->ch to NUL. // if we don't have LOS to there, set g->ch to NUL.
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) { void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
glyph_t tempgl; glyph_t tempgl;
@ -424,7 +434,6 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
if (haslos(viewer, c)) { if (haslos(viewer, c)) {
// show cell contents // show cell contents
//drawcellwithcontents(cell, x-viewx, y-viewy); //drawcellwithcontents(cell, x-viewx, y-viewy);
if (c->lf && cansee(viewer, c->lf)) { // lifeform here which we can see if (c->lf && cansee(viewer, c->lf)) { // lifeform here which we can see
// draw the lf's race glyph // draw the lf's race glyph
*g = *(getlfglyph(c->lf)); *g = *(getlfglyph(c->lf));
@ -449,25 +458,25 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
// draw highest object in sort order // draw highest object in sort order
o = gettopobject(c); o = gettopobject(c);
if (hasobwithflag(c->obpile, F_SECRETDOOR)) { if (o) {
celltype_t *ct;
ct = findcelltype(getwallcelltype(c->map->habitat));
*g = ct->glyph;
} else if (o) {
// return the object's glyph // return the object's glyph
*g = *(getglyph(o)); *g = *(getglyph(o));
} else { } else {
// should never happen. if it does, just show the // objects here, but we can't see them. draw the cell.
// first object // otherwise just draw the cell
dblog("Warn: sorted object glyph drawing matching nothing!"); //*g = c->obpile->first->type->obclass->glyph;
//mvwprintw(gamewin, y, x, "%c", cell->obpile->first->type->obclass->glyph); *g = c->type->glyph;
//drawglyph(&cell->obpile->first->type->obclass->glyph, x, y); if (!islit(c)) {
*g = c->obpile->first->type->obclass->glyph; g->colour = C_BLUE;
}
} }
} else { } else {
// draw cell normally // draw cell normally
//drawcell(cell, x, y); //drawcell(cell, x, y);
*g = c->type->glyph; *g = c->type->glyph;
if (!islit(c)) {
g->colour = C_BLUE;
}
} }
} else { // can't see the cell } else { // can't see the cell
void *thing; void *thing;
@ -533,9 +542,8 @@ object_t *gettopobject(cell_t *where) {
// draw impassable objects first... // draw impassable objects first...
o = hasobwithflag(where->obpile, F_IMPASSABLE); o = hasobwithflag(where->obpile, F_IMPASSABLE);
if (o) { if (o) {
// ignore secret doors // ignore hidden traps, but not secret doors
if (issecretdoor(o)) { if (hasflag(o->flags, F_SECRET) && !isdoor(o, NULL)) {
return NULL;
} else { } else {
return o; return o;
} }
@ -549,9 +557,7 @@ object_t *gettopobject(cell_t *where) {
// appear first. // appear first.
for (o = where->obpile->last ; o ; o = o->prev) { for (o = where->obpile->last ; o ; o = o->prev) {
if (o->type->obclass->id == sortorder[c]) { if (o->type->obclass->id == sortorder[c]) {
if (issecretdoor(o)) { if (!hasflag(o->flags, F_SECRET)){
return NULL;
} else {
return o; return o;
} }
} }
@ -564,10 +570,20 @@ object_t *gettopobject(cell_t *where) {
void calclight(map_t *map) { void calclight(map_t *map) {
int x,y; int x,y;
cell_t *c; cell_t *c;
int i;
// remember lit values for cells in player's los
if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < player->nlos; i++) {
player->los[i]->lastlit = player->los[i]->lit;
}
}
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++) {
c = getcellat(map, x,y); c = getcellat(map, x,y);
//if (c && (c->lit == L_PERMLIGHT) && (c->lit != L_PERMDARK)) c->lit = B_FALSE; //if (c && (c->lit == L_PERMLIGHT) && (c->lit != L_PERMDARK)) c->lit = B_FALSE;
c->lastlit = c->lit;
if (c && (c->lit != L_PERMLIGHT) && (c->lit != L_PERMDARK)) c->lit = B_FALSE; if (c && (c->lit != L_PERMLIGHT) && (c->lit != L_PERMDARK)) c->lit = B_FALSE;
} }
} }
@ -580,7 +596,7 @@ void calclight(map_t *map) {
// lit based on depth // lit based on depth
if ((map->depth <= 5) && (c->lit != L_PERMDARK)) { if ((map->depth <= 5) && (c->lit != L_PERMDARK)) {
c->lit = L_PERMLIGHT; makelit(c, L_PERMLIGHT, -1);
} }
// TODO: has dark producing lf? // TODO: has dark producing lf?
@ -588,20 +604,10 @@ void calclight(map_t *map) {
// has lightproducing lf? (ie.hasflag f_produceslight) // has lightproducing lf? (ie.hasflag f_produceslight)
if (c->lf) { if (c->lf) {
if (lfhasflag(c->lf, F_PRODUCESLIGHT)) { radius = lfproduceslight(c->lf);
sumflags(c->lf->flags, F_PRODUCESLIGHT, &radius, NULL, NULL); if (radius) {
makelitradius(c, radius, L_TEMP, -1); makelitradius(c, radius, L_TEMP, -1);
} }
// objects in hands or on body...
for (o = c->lf->pack->first ; o ; o = o->next) {
if (isequipped(o)) {
radius = obproduceslight(o);
if (radius) {
makelitradius(c, radius, L_TEMP, -1);
}
}
}
} }
// has light-producing object on ground? // has light-producing object on ground?
for (o = c->obpile->first ; o ; o = o->next) { for (o = c->obpile->first ; o ; o = o->next) {
@ -614,6 +620,15 @@ void calclight(map_t *map) {
} }
} }
} }
// did any lit values within player's los change?
if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < player->nlos; i++) {
if (player->los[i]->lastlit != player->los[i]->lit) {
needredraw = B_TRUE;
break;
}
}
}
} }
int calcroompos(map_t *map, int w, int h, int *bx, int *by) { int calcroompos(map_t *map, int w, int h, int *bx, int *by) {
@ -1516,7 +1531,7 @@ printf("dump of map '%s' (%d x %d):\n",map->name, map->w, map->h);
} }
} }
// dirtype of DT_COMPASS will give a square explosion // dirtype of DT_ORTH will give a square explosion
// dirtype of DT_COMPASS will give a circular explosion // dirtype of DT_COMPASS will give a circular explosion
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce) { void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce) {
int x,y; int x,y;
@ -1589,7 +1604,6 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
} }
damageallobs(o, c->obpile, dam, DT_EXPLOSIVE); damageallobs(o, c->obpile, dam, DT_EXPLOSIVE);
if (killwalls) { if (killwalls) {
@ -2090,6 +2104,16 @@ int hasobject(cell_t *c) {
return B_FALSE; return B_FALSE;
} }
int hasknownobject(cell_t *c) {
object_t *o;
for (o = c->obpile->first ; o ; o = o->next) {
if (o && !hasflag(o->flags, F_SECRET)) {
return B_TRUE;
}
}
return B_FALSE;
}
int isadjacent(cell_t *src, cell_t *dst) { int isadjacent(cell_t *src, cell_t *dst) {
if (getcelldist(src, dst) == 1) { if (getcelldist(src, dst) == 1) {
return B_TRUE; return B_TRUE;
@ -2403,7 +2427,7 @@ void makedoor(cell_t *cell) {
chance = rolldie(1,6) - (m->depth / 10); chance = rolldie(1,6) - (m->depth / 10);
if (chance <= 1) { if (chance <= 1) {
addflag(o->flags, F_LOCKED, B_TRUE, NA, NA, NULL); addflag(o->flags, F_LOCKED, B_TRUE, 19 + (m->depth), NA, NULL);
} }
// make it secret? // make it secret?
@ -2414,7 +2438,7 @@ void makedoor(cell_t *cell) {
// l10 = 25 // l10 = 25
// l20 = 30 // l20 = 30
if (chance <= 1) { if (chance <= 1) {
addflag(o->flags, F_SECRETDOOR, 20 + (m->depth / 2), NA, NA, NULL); addflag(o->flags, F_SECRET, 20 + (m->depth / 2), NA, NA, NULL);
} }
} }
} }

1
map.h
View File

@ -46,6 +46,7 @@ int getslipperyness(cell_t *c, object_t **slipob);
cell_t *getstairdestination(object_t *o); cell_t *getstairdestination(object_t *o);
object_t *hasenterableobject(cell_t *c); object_t *hasenterableobject(cell_t *c);
lifeform_t *haslf(cell_t *c); lifeform_t *haslf(cell_t *c);
int hasknownobject(cell_t *c);
int hasobject(cell_t *c); int hasobject(cell_t *c);
int isadjacent(cell_t *src, cell_t *dst); int isadjacent(cell_t *src, cell_t *dst);
int isdark(cell_t *c); int isdark(cell_t *c);

123
move.c
View File

@ -73,6 +73,12 @@ int canmove(lifeform_t *lf, int dir, enum ERROR *error) {
} }
} }
// not attacking
if (lfhasflag(lf, F_DOESNTMOVE) && !cell->lf) {
*error = E_CANTMOVE;
return B_FALSE;
}
return cellwalkable(lf, cell, error); return cellwalkable(lf, cell, error);
} }
@ -209,7 +215,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
rdata = o; rdata = o;
if (error) { if (error) {
if (isdoor(o, NULL)) { if (isdoor(o, NULL)) {
if (hasflag(o->flags, F_SECRETDOOR)) { if (hasflag(o->flags, F_SECRET)) {
*error = E_WALLINWAY; *error = E_WALLINWAY;
} else { } else {
*error = E_DOORINWAY; *error = E_DOORINWAY;
@ -658,6 +664,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
getlfname(lf, lfname); getlfname(lf, lfname);
if (isplayer(lf) || cansee(player, lf)) {
needredraw = B_TRUE;
}
if (newcell->map != lf->cell->map) { if (newcell->map != lf->cell->map) {
changedlev = B_TRUE; changedlev = B_TRUE;
} }
@ -690,8 +700,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
newcell->lf = lf; newcell->lf = lf;
// update light // update light
if (changedlev && isplayer(lf)) { if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
calclight(lf->cell->map); calclight(lf->cell->map);
precalclos(lf);
}
if (isplayer(lf) || cansee(player, lf)) {
needredraw = B_TRUE;
} }
didmsg = moveeffects(lf); didmsg = moveeffects(lf);
@ -806,7 +821,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// instead. // instead.
// if you walked into a new fully lit room, reveal it // if you walked into a new fully lit room, reveal it
if ((postroom > 0) && (postroom != preroom)) { if ((postroom > 0) && (postroom != preroom)) {
cell_t *c[MAXRETCELLS]; cell_t *c[MAX_MAPW*MAX_MAPH];
int ncells; int ncells;
int i,alllit = B_TRUE,allknown = B_TRUE; int i,alllit = B_TRUE,allknown = B_TRUE;
@ -831,7 +846,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
} }
} }
// does anyone else see you? // does anyone else see you?
if ((gamemode == GM_GAMESTARTED)) { if ((gamemode == GM_GAMESTARTED)) {
for (l = newcell->map->lf ; l ; l = l->next) { for (l = newcell->map->lf ; l ; l = l->next) {
@ -917,7 +931,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
// just moved into a dark area - announce it. // just moved into a dark area - announce it.
if (postdark && !predark && !lfhasflag(lf, F_DONEDARKMSG)) { if (postdark && !predark && !lfhasflag(lf, F_DONEDARKMSG)) {
msg("It is pitch black!"); msg("It is %s!", (lf->cell->lit == L_PERMDARK) ? "unnaturally dark" : "pitch black");
addflag(lf->flags, F_DONEDARKMSG, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_DONEDARKMSG, B_TRUE, NA, NA, NULL);
dontclearmsg = B_TRUE; dontclearmsg = B_TRUE;
} }
@ -985,11 +999,39 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
// slip on blood in new cell? // slip on blood in new cell?
if (!isairborne(lf)) { if (!isairborne(lf)) {
int slip; int slip;
object_t *o,*nexto;
object_t *slipob; object_t *slipob;
slip = getslipperyness(newcell, &slipob); slip = getslipperyness(newcell, &slipob);
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) { if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
slipon(lf, slipob); slipon(lf, slipob);
} }
// activate traps
for (o = newcell->obpile->first ; o ; o = nexto ) {
nexto = o->next;
if (hasflag(o->flags, F_TRAP)) {
char trapname[BUFLEN];
getobname(o, trapname, 1);
if (haslos(player, newcell)) {
msg("%s trigger%s %s!", lfname, isplayer(lf) ? "" : "s", trapname);
if (isplayer(lf)) more();
}
trapeffects(o, o->type->id, lf);
interrupt(lf);
if (haslos(player, newcell)) {
// no longer hidden
killflagsofid(o->flags, F_SECRET);
}
switch (o->type->id) {
case OT_TRAPGAS:
removeob(o, o->amt);
break;
default:
break;
}
}
}
} }
return B_FALSE; return B_FALSE;
@ -1043,7 +1085,6 @@ int opendoor(lifeform_t *lf, object_t *o) {
doorcell = o->pile->where; doorcell = o->pile->where;
assert(doorcell); assert(doorcell);
getobname(o, obname, 1); getobname(o, obname, 1);
if (!isdoor(o, NULL)) { if (!isdoor(o, NULL)) {
@ -1079,14 +1120,19 @@ int opendoor(lifeform_t *lf, object_t *o) {
int openit = B_TRUE; int openit = B_TRUE;
f = hasflag(o->flags, F_JAMMED); f = hasflag(o->flags, F_JAMMED);
if (f) { if (f) {
int amt;
amt = getattr(lf, A_STR) - 10;
if (amt < 0) amt = 0;
f->val[0] --;
// loosen a bit
if (lf && isplayer(lf)) { if (lf && isplayer(lf)) {
msg("You yank on the door but it holds fast."); msg("You yank on the door but it holds fast.");
} }
if (f->val[0] <= 0) { // loosen a bit
killflag(f); if (amt) {
f->val[0] -= amt;
if (f->val[0] <= 0) {
killflag(f);
}
} }
openit = B_FALSE; // don't open the door openit = B_FALSE; // don't open the door
} }
@ -1099,6 +1145,8 @@ int opendoor(lifeform_t *lf, object_t *o) {
if (f) killflag(f); if (f) killflag(f);
f = hasflag(o->flags, F_BLOCKSVIEW); f = hasflag(o->flags, F_BLOCKSVIEW);
if (f) killflag(f); if (f) killflag(f);
f = hasflag(o->flags, F_SECRET);
if (f) killflag(f);
if (lf) { if (lf) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -1223,6 +1271,10 @@ int closedoor(lifeform_t *lf, object_t *o) {
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
touch(lf, o); touch(lf, o);
} }
if (player && haslos(player, cell)) {
needredraw = B_TRUE;
drawscreen();
}
} }
return B_FALSE; return B_FALSE;
@ -1448,7 +1500,23 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
return B_FALSE; return B_FALSE;
} }
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose) {
cell_t *cell1,*cell2;
cell1 = lf1->cell;
cell2 = lf2->cell;
// make lf who is there vanish temporarily...
cell2->lf = NULL;
lf2->cell = NULL;
// move you..
moveto(lf1, cell2, onpurpose, B_FALSE);
// move them...
lf2->cell = cell1;
cell1->lf = lf2;
}
// teleport somewhere, along with puffs of smoke etc // teleport somewhere, along with puffs of smoke etc
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) { int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
@ -1681,25 +1749,13 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
case E_LFINWAY: case E_LFINWAY:
if (canswapwith(lf, cell->lf)) { if (canswapwith(lf, cell->lf)) {
lifeform_t *lfinway; lifeform_t *lfinway;
cell_t *oldcell;
// otherwise swap locations. // otherwise swap locations.
// make lf who is there vanish temporarily...
lfinway = cell->lf; lfinway = cell->lf;
cell->lf = NULL;
lfinway->cell = NULL;
// remember your cell swapplaces(lf, lfinway, onpurpose);
oldcell = lf->cell;
// move you..
moveto(lf, cell, onpurpose, B_FALSE);
if (onpurpose) taketime(lf, getmovespeed(lf)); if (onpurpose) taketime(lf, getmovespeed(lf));
// move them...
lfinway->cell = oldcell;
oldcell->lf = lfinway;
reason = E_OK;
if (isplayer(lf)) { if (isplayer(lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lfinway, lfname); getlfname(lfinway, lfname);
@ -1769,7 +1825,6 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
//object_t *o; //object_t *o;
iq = getiqname(getattr(lf, A_IQ), NULL); iq = getiqname(getattr(lf, A_IQ), NULL);
// default // default
if (error) { if (error) {
*error = E_OK; *error = E_OK;
@ -1808,7 +1863,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
} }
} }
// for intelligent things... // for at least average iq things...
if (iq >= IQ_AVERAGE) { if (iq >= IQ_AVERAGE) {
// don't move if in pain // don't move if in pain
if (lfhasflag(lf, F_PAIN)) { if (lfhasflag(lf, F_PAIN)) {
@ -1832,8 +1887,26 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
killflag(f); killflag(f);
} }
} }
if (hasflag(o->flags, F_TRAP)) {
if (hasflag(o->flags, F_SECRET)) {
// hidden traps?
if (iq >= IQ_SMART) {
if (error) *error = E_WONT;
return B_FALSE;
}
} else {
// non-hidden traps?
if (iq >= IQ_AVERAGE) {
if (error) *error = E_WONT;
return B_FALSE;
}
}
}
} }
return B_TRUE; return B_TRUE;
} }

1
move.h
View File

@ -21,6 +21,7 @@ int opendoorat(lifeform_t *lf, cell_t *c);
int opendoor(lifeform_t *lf, object_t *o); int opendoor(lifeform_t *lf, object_t *o);
int pullnextto(lifeform_t *lf, cell_t *c); int pullnextto(lifeform_t *lf, cell_t *c);
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg); int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg);
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose);
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke); int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke);
int trymove(lifeform_t *lf, int dir, int onpurpose); int trymove(lifeform_t *lf, int dir, int onpurpose);
int tryrun(lifeform_t *lf, int dir); int tryrun(lifeform_t *lf, int dir);

52
nexus.c
View File

@ -197,6 +197,19 @@ int main(int argc, char **argv) {
getchoice(&prompt); getchoice(&prompt);
sk = (skill_t *) prompt.result; sk = (skill_t *) prompt.result;
giveskill(player, sk->id); giveskill(player, sk->id);
switch (sk->id) {
case SK_SS_AIR:
addflag(player->flags, F_CANCAST, OT_S_MIST, NA, NA, NULL);
break;
case SK_SS_COLD:
addflag(player->flags, F_CANCAST, OT_S_FROSTBITE, NA, NA, NULL);
break;
case SK_SS_FIRE:
addflag(player->flags, F_CANCAST, OT_S_SPARK, NA, NA, NULL);
break;
default:
break;
}
} }
@ -271,6 +284,9 @@ int main(int argc, char **argv) {
} }
} }
needredraw = B_TRUE;
statdirty = B_TRUE;
// show level // show level
drawscreen(); drawscreen();
@ -471,10 +487,12 @@ void donextturn(map_t *map) {
// pre-calculate line of sight for this lifeform // pre-calculate line of sight for this lifeform
precalclos(who); precalclos(who);
/*
if (isplayer(who) || cansee(player, who)) { if (isplayer(who) || cansee(player, who)) {
needredraw = B_TRUE; needredraw = B_TRUE;
drawscreen(); drawscreen();
} }
*/
// update gun targets // update gun targets
autotarget(who); autotarget(who);
@ -491,6 +509,24 @@ void donextturn(map_t *map) {
int donormalmove = B_TRUE; int donormalmove = B_TRUE;
flag_t *f; flag_t *f;
// eating?
if (donormalmove) {
f = lfhasflag(who, F_EATING);
if (f) {
object_t *o;
o = findobbyid(who->pack, atol(f->text));
if (!o) {
o = findobidinmap(who->cell->map, atol(f->text));
}
if (o && caneat(who, o) && (getoblocation(o) == who->cell)) {
eat(who,o);
donormalmove = B_FALSE;
} else {
killflag(f);
}
}
}
// resting? // resting?
if (donormalmove) { if (donormalmove) {
f = isresting(who); f = isresting(who);
@ -503,6 +539,12 @@ void donextturn(map_t *map) {
msg("Stopped %s.",(f->id == F_TRAINING) ? "training" : "resting"); msg("Stopped %s.",(f->id == F_TRAINING) ? "training" : "resting");
killflag(f); killflag(f);
} else { } else {
if (isplayer(who)) {
if (++who->turnsskipped >= 10) {
msg("Time passes...");
who->turnsskipped = 0;
}
}
rest(who, B_TRUE); rest(who, B_TRUE);
donormalmove = B_FALSE; donormalmove = B_FALSE;
} }
@ -513,6 +555,12 @@ void donextturn(map_t *map) {
if (donormalmove) { if (donormalmove) {
// paralyzed etc? // paralyzed etc?
if (isimmobile(who)) { if (isimmobile(who)) {
if (isplayer(who)) {
if (++who->turnsskipped >= 10) {
msg("Time passes...");
who->turnsskipped = 0;
}
}
rest(who, B_FALSE); rest(who, B_FALSE);
donormalmove = B_FALSE; donormalmove = B_FALSE;
} }
@ -535,8 +583,10 @@ void donextturn(map_t *map) {
if (hasflag(player->flags, F_ASLEEP)) { if (hasflag(player->flags, F_ASLEEP)) {
// ooo is this right ? // ooo is this right ?
needredraw = B_FALSE; needredraw = B_FALSE;
/*
} else if (isdead(who) || cansee(player, who)) { } else if (isdead(who) || cansee(player, who)) {
needredraw = B_TRUE; needredraw = B_TRUE;
*/
} }
// check for death etc // check for death etc
@ -550,8 +600,6 @@ void donextturn(map_t *map) {
// note: can't use 'who->' below since 'who' might have died // note: can't use 'who->' below since 'who' might have died
// and been de-alloced during checkdeath() above. // and been de-alloced during checkdeath() above.
timeeffectsworld(player->cell->map); // in case the player changed levels! timeeffectsworld(player->cell->map); // in case the player changed levels!
} }
char *getdirname(int dir) { char *getdirname(int dir) {

628
objects.c

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour); objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour);
object_t *addob(obpile_t *where, char *name); object_t *addob(obpile_t *where, char *name);
object_t *addobject(obpile_t *where, char *name, int canstack); object_t *addobject(obpile_t *where, char *name, int canstack);
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf); int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof);
obmod_t *addobmod(enum OBMOD id, char *prefix); obmod_t *addobmod(enum OBMOD id, char *prefix);
obpile_t *addobpile(lifeform_t *owner, cell_t *where); obpile_t *addobpile(lifeform_t *owner, cell_t *where);
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes); void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
@ -120,6 +120,7 @@ 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(object_t *ammo, object_t *gun);
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);
int isblessed(object_t *o); int isblessed(object_t *o);
@ -167,6 +168,7 @@ void makeknown(enum OBTYPE otid);
void maketried(enum OBTYPE otid); void maketried(enum OBTYPE otid);
void makewet(object_t *o, int amt); void makewet(object_t *o, int amt);
object_t *moveob(object_t *src, obpile_t *dst, int howmany); object_t *moveob(object_t *src, obpile_t *dst, int howmany);
object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok);
void modbonus(object_t *o, int amt); void modbonus(object_t *o, int amt);
//object_t *newobeffects(object_t *o); //object_t *newobeffects(object_t *o);
void obaction(object_t *o, char *text); void obaction(object_t *o, char *text);
@ -198,6 +200,7 @@ int takedamage(object_t *o, unsigned int howmuch, int damtype);
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce); int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce);
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm); int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
void timeeffectsob(object_t *o); void timeeffectsob(object_t *o);
void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf);
void turnoff(lifeform_t *lf, object_t *o); void turnoff(lifeform_t *lf, object_t *o);
void turnon(lifeform_t *lf, object_t *o); void turnon(lifeform_t *lf, object_t *o);
int uncurseob(object_t *o, int *seen); int uncurseob(object_t *o, int *seen);

936
spell.c

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid);
int getspellrange(enum OBTYPE spellid, int power); int getspellrange(enum OBTYPE spellid, int power);
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf); char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
void pullobto(object_t *o, lifeform_t *lf); void pullobto(object_t *o, lifeform_t *lf);
void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYPE sid, int power);
void stopspell(lifeform_t *caster, enum OBTYPE spellid); void stopspell(lifeform_t *caster, enum OBTYPE spellid);
void stopallspells(lifeform_t *lf); void stopallspells(lifeform_t *lf);
int summonlfs(lifeform_t *caster, enum RACECLASS wantrc, enum LFSIZE wantsize, int howmany, int lifetime); int summonlfs(lifeform_t *caster, enum RACECLASS wantrc, enum LFSIZE wantsize, int howmany, int lifetime);

4
text.c
View File

@ -276,7 +276,9 @@ char *gettimetextfuzzy(char *retbuf, int wantpm) {
} }
char *getweighttext(float weight, char *buf) { char *getweighttext(float weight, char *buf) {
if (weight >= 1) { if (weight == 0) {
sprintf(buf, "nothing");
} else if (weight >= 1) {
if ((int)weight == weight) { // ie. is weight an integer? if ((int)weight == weight) { // ie. is weight an integer?
sprintf(buf, "%0.0f kg",weight); sprintf(buf, "%0.0f kg",weight);
} else { } else {