* [+] 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

22
ai.c
View File

@ -364,6 +364,19 @@ int aipickup(lifeform_t *lf, object_t *o) {
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) {
switch (o->type->id) {
case OT_POT_INVIS:
@ -863,11 +876,13 @@ void aiturn(lifeform_t *lf) {
///////////////////////////////////////////////
// look for any object which we want
if (!isinbattle(lf)) {
if (db) dblog(".oO { looking for any ob which i want. }");
if (lookforobs(lf, B_ANY)) {
if (db) dblog(".oO { found ob that i want. returning. }");
return;
}
}
// not attacking anyone in particular
@ -1456,7 +1471,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
// current cell has an object we want?
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);
// try to pick it up
if (!aipickup(lf, o)) return B_TRUE;
@ -1518,7 +1533,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
c = lf->los[i];
if (!c->lf && !lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) {
o = hasobmulti(c->obpile, oid, noids);
if (o && !isdangerousob(o, lf, B_TRUE) && (canpickup(lf, o, 1) || caneat(lf,o)) ) {
if (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);
gothere = B_TRUE;
}
@ -1526,7 +1541,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
// has an object with a flag we want?
for (n = 0; n < nwantflags; 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);
gothere = B_TRUE;
}
@ -1538,7 +1553,6 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
f = hasflag(lf->flags, F_WANTSBETTERWEP);
if (f) {
if (!covetsonly || (f->val[1] == B_COVETS)) {
o = hasbetterweapon(lf, c->obpile);
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);

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);
void aimovetotargetcell(lifeform_t *lf, flag_t *f);
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 aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG purpose);
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_MASTER: actualdam = pctof(40, dam); break;
}
if (actualdam > 0) {
limit(&dam, 1, NA);
}
limit(&actualdam, 1, NA);
}
// modify for rust
@ -130,7 +128,7 @@ int attackcell(lifeform_t *lf, cell_t *c) {
// anyone there? if so just attack.
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 victimname[BUFLEN];
char buf[BUFLEN];
@ -184,6 +182,9 @@ int attackcell(lifeform_t *lf, cell_t *c) {
if (getskill(lf, SK_TWOWEAPON)) {
wep[nweps] = getsecmeleeweapon(lf);
if (wep[nweps]) {
if ((nweps >= 1) && (wep[nweps] == wep[nweps-1])) {
// can't be the same as first one
} else {
damflag[nweps] = hasflag(wep[nweps]->flags, F_DAM);
validwep[nweps] = B_TRUE;
lastweaponidx = nweps;
@ -191,6 +192,7 @@ int attackcell(lifeform_t *lf, cell_t *c) {
gotweapon = B_TRUE;
}
}
}
// then use all our innate attacks..
for (f = lf->flags->first ; f; f = f->next) {
@ -691,6 +693,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int dir;
cell_t *c;
int nmatched = 0;
char lfname[BUFLEN];
getlfname(lf, lfname);
// count adjacent allies of name xx
for (dir = DC_N; dir <= DC_NW; 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]) {
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);
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;
for (f = wep->flags->first ; f ; f = f->next) {
if (f->id == F_ONFIRE) {
if (f->text) {
*(dam + *ndam) = roll(f->text);
} else {
*(dam + *ndam) = rolldie(2,6);
}
*(damtype + *ndam) = DT_FIRE;
(*ndam)++;
} 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";
}
if (getraceclass(victim) == RC_PLANT) {
return "destroy";
}
if (wep) {
flag_t *f;
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";
}
void getdamrange(flag_t *f, int *min, int *max) {
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) {
flag_t *f;
lifeform_t *victim;
lifeform_t *owner;
lifeform_t *owner = NULL;
object_t *wep;
if (!where) return;

105
defs.h
View File

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

View File

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

101
flag.c
View File

@ -5,6 +5,7 @@
#include "flag.h"
#include "io.h"
#include "lf.h"
#include "map.h"
#include "objects.h"
#include "spell.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 *f;
map_t *redolight = NULL;
int i;
int doredraw = B_FALSE;
// identified things mean all new flags are autmaticlaly known.
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;
}
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...
if (flagstacks(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
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) {
if (announceobflaggain(f->pile->ob, f)) {
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) {
statdirty = B_TRUE;
if ((gamemode == GM_GAMESTARTED) && (needredraw || statdirty || redolight)) {
if (redolight) {
needredraw = B_TRUE;
calclight(redolight);
precalclos(player);
}
drawscreen();
}
return f;
@ -228,12 +249,15 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
if (isplayer(lf)) {
// player
switch (fid) {
case F_ASLEEP:
case F_BLIND:
case F_DETECTLIFE:
case F_DETECTOBS:
case F_FASTMOVE:
case F_HIDING:
case F_INVISIBLE:
case F_PRODUCESLIGHT:
case F_PRONE:
case F_RAGE:
case F_SEEINDARK:
case F_SEEINVIS:
@ -246,7 +270,11 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
}
} else if (haslos(player, lf->cell)) {
switch (fid) {
case F_ASLEEP:
case F_HIDING:
case F_INVISIBLE:
case F_PRODUCESLIGHT:
case F_PRONE:
return B_TRUE;
default:
break;
@ -256,6 +284,33 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
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 res = B_FALSE;
switch (fid) {
@ -356,13 +411,31 @@ int killflagsofid(flagpile_t *fp, enum FLAG fid) {
void killflag(flag_t *f) {
flag_t *nextone, *lastone;
lifeform_t *lf;
int doredraw = B_FALSE;
map_t *redolight = NULL;
int redostat = B_FALSE;
int redoscreen = B_FALSE;
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
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
if ((gamemode == GM_GAMESTARTED)) {
@ -436,11 +509,21 @@ void killflag(flag_t *f) {
lastone->next = nextone;
}
if ((gamemode == GM_GAMESTARTED) && doredraw) {
statdirty = B_TRUE;
if (gamemode == GM_GAMESTARTED) {
if (redolight) {
calclight(redolight);
precalclos(player);
}
if (redoscreen || redolight) {
needredraw = B_TRUE;
}
if (redostat) {
statdirty = B_TRUE;
}
if (statdirty || needredraw || redolight) {
drawscreen();
}
}
}
void killflagpile(flagpile_t *fp) {

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);
int countflags(flagpile_t *fp);
int flagcausesredraw(lifeform_t *lf, enum FLAG fid);
int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid);
int flagstacks(enum FLAG fid);
int modcounter(flagpile_t *fp, int amt);
flag_t *hasflag(flagpile_t *fp, int id);

293
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) {
assert(p->choice[p->nchoices].text == NULL);
p->choice[p->nchoices].ch = ch;
p->choice[p->nchoices].text = strdup(text);
if (desc) {
@ -230,6 +231,7 @@ void anim(cell_t *src, cell_t *dst, char ch, int colour) {
}
// show cursor
curs_set(1);
needredraw = B_TRUE;
}
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
curs_set(1);
needredraw = B_TRUE;
}
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
curs_set(1);
needredraw = B_TRUE;
}
@ -339,6 +343,7 @@ void animsky(cell_t *src, char ch, int colour) {
// show cursor
curs_set(1);
needredraw = B_TRUE;
}
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);
wrefresh(msgwin);
curs_set(1);
valid = B_FALSE;
while (!valid) {
ch = getkey();
@ -385,6 +391,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
valid = B_FALSE;
}
}
curs_set(0);
clearmsg();
if ((ch == 13) && def) {
return def[0];
@ -422,13 +429,14 @@ cell_t *askcoords(char *prompt, int targettype) {
valid = B_TRUE;
} else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) {
valid = B_TRUE;
} else if ((targettype & TT_OBJECT) && hasobject(c)) {
} else if ((targettype & TT_OBJECT) && hasknownobject(c)) {
valid = B_TRUE;
}
if (targettype & TT_DOOR) {
object_t *o;
o = hasobwithflag(c->obpile, F_DOOR);
if (o && !hasflag(o->flags, F_SECRETDOOR)) {
if (o && !hasflag(o->flags, F_SECRET)) {
valid = B_TRUE;
}
}
@ -772,6 +780,8 @@ char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def)
strcat(buf, "]");
}
curs_set(1);
asprintf(&ending, "%c ",punc);
strcat(buf, ending);
free(ending);
@ -784,6 +794,7 @@ char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def)
if (def && (strlen(retbuf) == 0)) {
strcpy(retbuf, def);
}
drawcursor();
return retbuf;
}
@ -1137,6 +1148,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
if (isplayer(lf)) {
msg("You are nauseated by a disgusting stench!");
donesomething = B_TRUE;
} else {
msg("%s looks very unwell.",lfname);
donesomething = B_TRUE;
}
break;
case F_NONCORPOREAL:
@ -1231,7 +1245,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break;
case F_TREMORSENSE:
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;
}
break;
@ -1282,6 +1296,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
if (donesomething) statdirty = B_TRUE;
if (statdirty || needredraw) {
drawscreen();
}
return donesomething;
}
@ -1300,8 +1318,8 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
if (isdead(lf) || isdead(player)) return B_FALSE;
getlfname(lf, lfname);
// player can't see?
if (!cansee(player, lf)) {
// player can't see this?
if (!cansee(player, lf) && !isplayer(lf)) {
return B_FALSE;
}
switch (f->id) {
@ -1349,7 +1367,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break;
case F_ATTACHEDTO:
lf2 = findlf(NULL, f->val[0]);
if (lf2) {
if (lf2 && !isdead(lf2)) {
char buf[BUFLEN];
getlfname(lf2, 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) {
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) {
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;
}
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 i;
int useobletters = B_TRUE;
@ -1917,17 +1935,21 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
selchar = ' ';
}
if (forpickup && hasflag(mylist[i]->flags, F_NOPICKUP)) {
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);
getobequipinfo(mylist[i], equipbuf);
mvwprintw(win, *y, 0, "%s%s", buf, infobuf);
unsetobcolour(win, mylist[i]);
setobcolour(win, mylist[i], B_FALSE);
if (strlen(equipbuf)) {
setcol(win, C_BROWN);
@ -1940,7 +1962,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
*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;
object_t *mylist[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]");
getch();
needredraw = B_TRUE;
clearmsg();
drawscreen();
return NULL;
@ -2065,7 +2088,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
// list the objects
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) {
nextpage = -1;
@ -2124,6 +2147,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, long opts, ...) {
*count = o->amt;
}
// display game windows again
needredraw = B_TRUE;
clearmsg();
drawscreen();
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
reason = E_SELNOTHING;
// display game windows again
needredraw = B_TRUE;
clearmsg();
drawscreen();
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
needredraw = B_TRUE;
clearmsg();
drawscreen();
return NULL;
}
@ -2194,6 +2218,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]");
getch();
needredraw = B_TRUE;
clearmsg();
drawscreen();
return B_TRUE;
@ -2253,7 +2278,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
// list the objects
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) {
nextpage = -1;
@ -2330,6 +2355,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
reason = E_SELNOTHING;
nretobs = 0;
// display game windows again
needredraw = B_TRUE;
clearmsg();
drawscreen();
return B_TRUE;
@ -2381,6 +2407,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
clearmsg();
// display game windows again
needredraw = B_TRUE;
drawscreen();
if (nretobs <= 0) {
return B_TRUE;
@ -2425,6 +2452,7 @@ char checkforkey(void) {
ch = getch();
nodelay(mainwin, FALSE);
if (ch == ERR) ch = '\0';
if (ch == ' ') ch = '\0';
return ch;
}
@ -2491,6 +2519,7 @@ void updateviewfor(cell_t *cell) {
void drawscreen(void) {
int didstatus = B_FALSE;
if (gamemode < GM_GAMESTARTED) {
return;
}
@ -2499,12 +2528,17 @@ void drawscreen(void) {
drawstatus();
wrefresh(statwin);
statdirty = B_FALSE;
didstatus = B_TRUE;
}
if (needredraw) {
updateviewfor(player->cell);
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?
f = hasflag(o->flags, F_ONFIRE);
if (f) {
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++;
}
@ -2699,21 +2737,90 @@ void describeob(object_t *o) {
y++;
}
// skip line
y++;
// immunities
strcpy(buf, "");
f = hasflagval(o->flags, F_DTIMMUNE, DT_ALL, NA, NA, NULL);
if (f) {
sprintf(buf, "It is immune to %s", getdamname(DT_ALL));
} else {
int first = B_TRUE;
for (i = 0; i < MAXDAMTYPE; i++) {
if (isimmuneto(o->flags, i)) {
mvwprintw(mainwin, y, 0, "It is immune to %s.",getdamnamenoun(i));
f = isimmuneto(o->flags, i);
if (f) {
char buf2[BUFLEN];
if (first) {
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++;
}
if (isresistantto(o->flags, i)) {
mvwprintw(mainwin, y, 0, "It is resistant to %s.",getdamnamenoun(i));
// 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++;
}
if (isvulnto(o->flags, i)) {
mvwprintw(mainwin, y, 0, "It is vulnerable to %s.",getdamnamenoun(i));
// 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 ?
if (hasflag(o->type->flags, F_DAMAGABLE) && !hasflag(o->flags, F_DAMAGABLE)) {
@ -3020,7 +3127,7 @@ void describeob(object_t *o) {
// skill type?
f = hasflag(o->flags, F_USESSKILL);
if (f) {
if (f && (f->val[0] != SK_NONE)) {
enum SKILLLEVEL slev;
enum COLOUR col;
slev = getskill(player, f->val[0]);
@ -3061,6 +3168,7 @@ void describeob(object_t *o) {
// wait for key
getch();
real_clearmsg(B_TRUE);
needredraw = B_TRUE;
drawscreen();
}
@ -3114,6 +3222,7 @@ void describespell(objecttype_t *ot) {
// wait for key
getch();
real_clearmsg(B_TRUE);
needredraw = B_TRUE;
drawscreen();
}
@ -3629,6 +3738,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
killobpile(op);
needredraw = B_TRUE;
drawscreen();
real_clearmsg(B_TRUE);
}
@ -3713,6 +3823,7 @@ void doknowledgelist(void) {
wrefresh(mainwin);
getch();
needredraw = B_TRUE;
clearmsg();
drawscreen();
}
@ -3729,6 +3840,9 @@ void dolook(cell_t *where, int onpurpose) {
// (also count objects without this flag)
numobs = 0;
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);
if (f) {
// doens't matter if you're blind
@ -3737,10 +3851,10 @@ void dolook(cell_t *where, int onpurpose) {
interrupt(player);
seensomething = B_TRUE;
} else {
if (onpurpose || !hasflag(o->flags, F_COSMETIC)) {
//if (onpurpose) {
if (!numobs) firstob = o;
numobs++;
}
// }
}
}
@ -3787,7 +3901,7 @@ void dolook(cell_t *where, int onpurpose) {
// if wantunknown is set, lsit spells we DONT 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;
flag_t *f;
char buf[BUFLEN];
@ -3947,9 +4061,11 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
strcat(costbuf, mpdesc[i]);
sprintf(buf, "%-30s%s", buf2, costbuf);
if (wantinvalid || validspell[i]) {
// letter doesn't matter
addchoice(pr, 'a', buf2, buf, ot);
}
}
}
void domagic(enum OBTYPE spellid, int cellx, int celly) {
@ -3959,7 +4075,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly) {
// init the prompt if required.
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;
@ -4027,7 +4143,7 @@ void domemmagic(void) {
char ch;
int slot;
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) {
msg("You don't have any spells or abilities!");
return;
@ -4063,6 +4179,7 @@ void domsghist(void) {
getch();
// restore screen
//cls();
needredraw = B_TRUE;
drawscreen();
real_clearmsg(B_TRUE);
}
@ -4173,7 +4290,7 @@ void doexplain(char *question) {
where = askcoords(question, TT_NONE);
if (!where) {
clearmsg();
return;
break;
}
// explain it
@ -4249,6 +4366,7 @@ void dohelp(void) {
centre(mainwin, h-1, "[Press any key]");
getch();
needredraw = B_TRUE;
drawscreen();
real_clearmsg(B_TRUE);
}
@ -4524,6 +4642,9 @@ void dorest(void) {
rest(player, B_TRUE);
} else {
switch (reason) {
case E_LEVITATING:
msg("You cannot rest while levitating in mid-air!");
break;
case E_MONSTERNEARBY:
msg("You cannot rest - there are monsters nearby!");
break;
@ -4762,6 +4883,8 @@ void drawcursor(void) {
// move cursor to player position
wmove(gamewin, player->cell->y - viewy, player->cell->x - viewx);
wrefresh(gamewin);
// turn on cursor
curs_set(1);
}
void drawlevelfor(lifeform_t *lf) {
@ -4770,16 +4893,18 @@ void drawlevelfor(lifeform_t *lf) {
map_t *map;
map = lf->cell->map;
needredraw = B_FALSE;
numdraws++;
// turn off cursor
curs_set(0);
// TODO: draw to buffer here...
// buffer is an array of 'glyph_t's
wclear(gamewin);
for (y = viewy; y < viewy + viewh; y++) {
for (x = viewx; x < viewx + vieww; x++) {
if ((x == lf->cell->x + 1) && (y == lf->cell->y)) {
dblog("x");
}
cell = getcellat(map, x, y);
if (cell) {
glyph_t glyph,screenglyph;
@ -4800,10 +4925,8 @@ void drawlevelfor(lifeform_t *lf) {
}
}
}
// turn on cursor
curs_set(1);
// move it to the player's position
wmove(gamewin, lf->y - viewy, lf->x - viewx);
// move cursor to the player's position and blit
drawcursor();
}
void doheading(WINDOW *win, int *y, int x, char *what) {
@ -4928,6 +5051,29 @@ int drop(object_t *o, int count) {
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) {
int i;
int y;
@ -4938,6 +5084,7 @@ char getchoice(prompt_t *prompt) {
int nextpage = -1;
int lastline = SCREENH - 4;
gotheadings = B_FALSE;
for (i = 0; i < prompt->nchoices; i++) {
if (prompt->choice[i].heading) {
@ -4946,6 +5093,7 @@ char getchoice(prompt_t *prompt) {
}
}
curs_set(1);
// loop until result is valid
sel = -1;
while (sel == -1) {
@ -5013,11 +5161,13 @@ char getchoice(prompt_t *prompt) {
}
if ((gamemode == GM_GAMESTARTED)) {
needredraw = B_TRUE;
drawscreen();
} else {
cls();
wrefresh(mainwin);
}
curs_set(0);
// return NUL or result char
if (ch == 27) {
return '\0';
@ -5062,6 +5212,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
doneheading = B_FALSE;
// loop until result is valid
curs_set(1);
sel = -1;
while (sel == -1) {
int atbottom;
@ -5268,11 +5419,13 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
}
if ((gamemode == GM_GAMESTARTED)) {
needredraw = B_TRUE;
drawscreen();
} else {
cls();
wrefresh(mainwin);
}
curs_set(0);
// return NUL or result char
if (ch == 27) {
return '\0';
@ -5725,8 +5878,10 @@ void more(void) {
strcat(msgbuf, MORESTRING);
//mvwprintw(msgwin, 0, 0, msgbuf);
drawmsg();
curs_set(1);
// wait for space
while (getch() != ' ');
curs_set(0);
// clear msg
clearmsg();
}
@ -5847,6 +6002,7 @@ void drawstatus(void) {
getplayernamefull(pname);
curs_set(0);
wclear(statwin);
xpleft = getxpforlev(player->level + 1) - player->xp;
@ -5989,16 +6145,16 @@ void drawstatus(void) {
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
if (poisonthreatenslife(player, f)) {
setcol(statwin, C_GREEN);
wprintw(statwin, " Poison(bad)");
wprintw(statwin, " %s(bad)", getpoisondesc(f->val[0]));
unsetcol(statwin, C_GREEN);
} else {
setcol(statwin, C_BROWN);
wprintw(statwin, " Poisoned(mild)");
wprintw(statwin, " %s(mild)", getpoisondesc(f->val[0]));
unsetcol(statwin, C_BROWN);
}
} else {
setcol(statwin, C_GREEN);
wprintw(statwin, " Poisoned");
wprintw(statwin, " %s", getpoisondesc(f->val[0]));
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) {
void (*funcptr)(WINDOW *, enum COLOUR);
// which function?
if (set) {
funcptr = setcol;
} else {
funcptr = unsetcol;
}
if (!o) return;
if (o->blessknown) {
if (iscursed(o)) {
setcol(win, C_RED);
} else if (isblessed(o)) {
setcol(win, C_CYAN);
}
}
}
void unsetobcolour(WINDOW *win, object_t *o) {
if (!o) return;
if (o->blessknown) {
if (iscursed(o)) {
unsetcol(win, C_RED);
funcptr(win, C_RED);
return;
} 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) {
@ -6296,9 +6461,9 @@ void showlfarmour(lifeform_t *lf) {
}
mvwprintw(mainwin, y, 0, "%s", buf);
setobcolour(mainwin, o);
setobcolour(mainwin, o, B_TRUE);
wprintw(mainwin, "%s", rhs);
unsetobcolour(mainwin, o);
setobcolour(mainwin, o, B_FALSE);
y++;
}
}
@ -6328,6 +6493,7 @@ void showlfarmour(lifeform_t *lf) {
*/
getch();
needredraw = B_TRUE;
drawscreen();
real_clearmsg(B_TRUE);
}
@ -6424,6 +6590,9 @@ void showlfstats(lifeform_t *lf, int showall) {
if (isplayer(lf)) {
mvwprintw(mainwin, y, 0, ftext, "Race");
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);
@ -7274,11 +7443,12 @@ void showlfstats(lifeform_t *lf, int showall) {
getskillname(available[n]->val[0]) );
}
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]) ? '*' : '-',
getskillname(known[n]->val[0]),
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)) {
exitnow = B_TRUE;
@ -7625,8 +7795,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_PACKATTACK);
if (f && (f->known)) {
sprintf(buf,"%s deal%s extra damage when in a %s pack.", you(lf), isplayer(lf) ? "" : "s",
f->text);
sprintf(buf,"%s deal%s extra damage when in a pack.", you(lf), isplayer(lf) ? "" : "s");
mvwprintw(mainwin, y, 0, buf);
y++;
}
@ -7742,7 +7911,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_TREMORSENSE);
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++;
}
f = lfhasknownflag(lf, F_WINDSHIELD);
@ -7858,6 +8027,7 @@ void showlfstats(lifeform_t *lf, int showall) {
needredraw = B_TRUE;
cls(); wrefresh(mainwin);
needredraw = B_TRUE;
drawscreen();
wrefresh(gamewin);
wrefresh(statwin);
@ -7883,6 +8053,7 @@ void tombstone(lifeform_t *lf) {
centre(mainwin, y, "R.I.P."); y++;
//printf("%s\n",lf->name);
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);
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);
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 *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);
char askchar(char *prompt, char *validchars, char *def, int showchars);
cell_t *askcoords(char *prompt, int targettype);
@ -72,6 +72,7 @@ void drawmsg(void);
void drawscreen(void);
void drawstatus(void);
int drop(object_t *o, int count);
void dumpspells(void);
char getchoice(prompt_t *prompt);
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
int getkey(void);
@ -81,8 +82,8 @@ void doheading(WINDOW *win, int *y, int x, char *what);
void initgfx(void);
void initprompt(prompt_t *p, char *q1);
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 makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown);
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, int wantinvalid);
void more(void);
void warn(char *format, ... );
void msg(char *format, ... );
@ -95,8 +96,7 @@ void redraw(void);
int savequit(void);
void setcol(WINDOW *win, enum COLOUR col);
void unsetcol(WINDOW *win, enum COLOUR col);
void setobcolour(WINDOW *win, object_t *o);
void unsetobcolour(WINDOW *win, object_t *o);
void setobcolour(WINDOW *win, object_t *o, int set);
void showlfarmour(lifeform_t *lf);
void showlfstats(lifeform_t *lf, int showall);
void tombstone(lifeform_t *lf);

810
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 autoweild(lifeform_t *lf);
int appearsrandomly(enum RACE rid);
void awardxpfor(lifeform_t *killed, float pct);
void bleed(lifeform_t *lf);
void breakallgrabs(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 canquaff(lifeform_t *lf, object_t *o);
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 canweild(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);
int getpoisondamchance(enum POISONTYPE ptype);
char *getpoisondamverb(enum POISONTYPE ptype);
char *getpoisondesc(enum POISONTYPE ptype);
char *getpoisonname(enum POISONTYPE ptype);
int getraceclass(lifeform_t *lf);
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 *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
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);
void loseobflags(lifeform_t *lf, object_t *o, int kind);
int hasbp(lifeform_t *lf, enum BODYPART bp);
@ -191,6 +195,7 @@ int isfriendly(lifeform_t *lf);
int isgenius(lifeform_t *lf);
int isimmobile(lifeform_t *lf);
flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
int isinbattle(lifeform_t *lf);
int isingunrange(lifeform_t *lf, cell_t *where);
int isloreskill(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 isplayer(lifeform_t *lf);
flag_t *ispoisoned(lifeform_t *lf);
flag_t *ispoisonedwith(lifeform_t *lf, enum POISONTYPE pt);
int ispolymorphed(lifeform_t *lf);
int isprone(lifeform_t *lf);
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);
void losemp(lifeform_t *lf, int amt);
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 makepeaceful(lifeform_t *lf);
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);
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat);
int poisoncausesvomit(enum POISONTYPE ptype);
int poisonthreatenslife(lifeform_t *lf, flag_t *f);
void practice(lifeform_t *lf, enum SKILL skid);
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);
void sortlf(map_t *map, lifeform_t *lf);
int stone(lifeform_t *lf);
void stopeating(lifeform_t *lf);
void stopresting(lifeform_t *lf);
void stoprunning(lifeform_t *lf);
int testammo(lifeform_t *lf, object_t *o);

59
log.txt
View File

@ -4,50 +4,15 @@
====== NEW LOGFILE ====
givejob() starting.
fireat(): dam = throwdam(2) * speed(3) = 6
fireat(): dam = throwdam(2) * speed(3) = 6
fireat(): dam = throwdam(3) * speed(3) = 9
.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 }
.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 }
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
x
x
x
x
x
x
x
x
x
x
x
x

98
map.c
View File

@ -24,6 +24,10 @@ extern enum OBCLASS sortorder[];
extern enum ERROR reason;
extern enum GAMEMODE gamemode;
extern int needredraw;
cell_t *addcell(map_t *m, int x, int y) {
cell_t *cell;
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 (autogen) {
// 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
if (rnd(1,2) == 1) {
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];
int 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'
// 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) {
glyph_t tempgl;
@ -424,7 +434,6 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
if (haslos(viewer, c)) {
// show cell contents
//drawcellwithcontents(cell, x-viewx, y-viewy);
if (c->lf && cansee(viewer, c->lf)) { // lifeform here which we can see
// draw the lf's race glyph
*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
o = gettopobject(c);
if (hasobwithflag(c->obpile, F_SECRETDOOR)) {
celltype_t *ct;
ct = findcelltype(getwallcelltype(c->map->habitat));
*g = ct->glyph;
} else if (o) {
if (o) {
// return the object's glyph
*g = *(getglyph(o));
} else {
// should never happen. if it does, just show the
// first object
dblog("Warn: sorted object glyph drawing matching nothing!");
//mvwprintw(gamewin, y, x, "%c", cell->obpile->first->type->obclass->glyph);
//drawglyph(&cell->obpile->first->type->obclass->glyph, x, y);
*g = c->obpile->first->type->obclass->glyph;
// objects here, but we can't see them. draw the cell.
// otherwise just draw the cell
//*g = c->obpile->first->type->obclass->glyph;
*g = c->type->glyph;
if (!islit(c)) {
g->colour = C_BLUE;
}
}
} else {
// draw cell normally
//drawcell(cell, x, y);
*g = c->type->glyph;
if (!islit(c)) {
g->colour = C_BLUE;
}
}
} else { // can't see the cell
void *thing;
@ -533,9 +542,8 @@ object_t *gettopobject(cell_t *where) {
// draw impassable objects first...
o = hasobwithflag(where->obpile, F_IMPASSABLE);
if (o) {
// ignore secret doors
if (issecretdoor(o)) {
return NULL;
// ignore hidden traps, but not secret doors
if (hasflag(o->flags, F_SECRET) && !isdoor(o, NULL)) {
} else {
return o;
}
@ -549,9 +557,7 @@ object_t *gettopobject(cell_t *where) {
// appear first.
for (o = where->obpile->last ; o ; o = o->prev) {
if (o->type->obclass->id == sortorder[c]) {
if (issecretdoor(o)) {
return NULL;
} else {
if (!hasflag(o->flags, F_SECRET)){
return o;
}
}
@ -564,10 +570,20 @@ object_t *gettopobject(cell_t *where) {
void calclight(map_t *map) {
int x,y;
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 (x = 0; x < map->w; x++) {
c = getcellat(map, x,y);
//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;
}
}
@ -580,7 +596,7 @@ void calclight(map_t *map) {
// lit based on depth
if ((map->depth <= 5) && (c->lit != L_PERMDARK)) {
c->lit = L_PERMLIGHT;
makelit(c, L_PERMLIGHT, -1);
}
// TODO: has dark producing lf?
@ -588,21 +604,11 @@ void calclight(map_t *map) {
// has lightproducing lf? (ie.hasflag f_produceslight)
if (c->lf) {
if (lfhasflag(c->lf, F_PRODUCESLIGHT)) {
sumflags(c->lf->flags, F_PRODUCESLIGHT, &radius, NULL, NULL);
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);
radius = lfproduceslight(c->lf);
if (radius) {
makelitradius(c, radius, L_TEMP, -1);
}
}
}
}
// has light-producing object on ground?
for (o = c->obpile->first ; o ; o = o->next) {
radius = obproduceslight(o);
@ -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) {
@ -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
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce) {
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);
if (killwalls) {
@ -2090,6 +2104,16 @@ int hasobject(cell_t *c) {
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) {
if (getcelldist(src, dst) == 1) {
return B_TRUE;
@ -2403,7 +2427,7 @@ void makedoor(cell_t *cell) {
chance = rolldie(1,6) - (m->depth / 10);
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?
@ -2414,7 +2438,7 @@ void makedoor(cell_t *cell) {
// l10 = 25
// l20 = 30
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);
object_t *hasenterableobject(cell_t *c);
lifeform_t *haslf(cell_t *c);
int hasknownobject(cell_t *c);
int hasobject(cell_t *c);
int isadjacent(cell_t *src, cell_t *dst);
int isdark(cell_t *c);

119
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);
}
@ -209,7 +215,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
rdata = o;
if (error) {
if (isdoor(o, NULL)) {
if (hasflag(o->flags, F_SECRETDOOR)) {
if (hasflag(o->flags, F_SECRET)) {
*error = E_WALLINWAY;
} else {
*error = E_DOORINWAY;
@ -658,6 +664,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
getlfname(lf, lfname);
if (isplayer(lf) || cansee(player, lf)) {
needredraw = B_TRUE;
}
if (newcell->map != lf->cell->map) {
changedlev = B_TRUE;
}
@ -690,8 +700,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
newcell->lf = lf;
// update light
if (changedlev && isplayer(lf)) {
if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
calclight(lf->cell->map);
precalclos(lf);
}
if (isplayer(lf) || cansee(player, lf)) {
needredraw = B_TRUE;
}
didmsg = moveeffects(lf);
@ -806,7 +821,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// instead.
// if you walked into a new fully lit room, reveal it
if ((postroom > 0) && (postroom != preroom)) {
cell_t *c[MAXRETCELLS];
cell_t *c[MAX_MAPW*MAX_MAPH];
int ncells;
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?
if ((gamemode == GM_GAMESTARTED)) {
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.
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);
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?
if (!isairborne(lf)) {
int slip;
object_t *o,*nexto;
object_t *slipob;
slip = getslipperyness(newcell, &slipob);
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
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;
@ -1043,7 +1085,6 @@ int opendoor(lifeform_t *lf, object_t *o) {
doorcell = o->pile->where;
assert(doorcell);
getobname(o, obname, 1);
if (!isdoor(o, NULL)) {
@ -1079,15 +1120,20 @@ int opendoor(lifeform_t *lf, object_t *o) {
int openit = B_TRUE;
f = hasflag(o->flags, F_JAMMED);
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)) {
msg("You yank on the door but it holds fast.");
}
// loosen a bit
if (amt) {
f->val[0] -= amt;
if (f->val[0] <= 0) {
killflag(f);
}
}
openit = B_FALSE; // don't open the door
}
if (openit) {
@ -1099,6 +1145,8 @@ int opendoor(lifeform_t *lf, object_t *o) {
if (f) killflag(f);
f = hasflag(o->flags, F_BLOCKSVIEW);
if (f) killflag(f);
f = hasflag(o->flags, F_SECRET);
if (f) killflag(f);
if (lf) {
if (isplayer(lf)) {
@ -1223,6 +1271,10 @@ int closedoor(lifeform_t *lf, object_t *o) {
taketime(lf, getactspeed(lf));
touch(lf, o);
}
if (player && haslos(player, cell)) {
needredraw = B_TRUE;
drawscreen();
}
}
return B_FALSE;
@ -1448,7 +1500,23 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
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
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:
if (canswapwith(lf, cell->lf)) {
lifeform_t *lfinway;
cell_t *oldcell;
// otherwise swap locations.
// make lf who is there vanish temporarily...
lfinway = cell->lf;
cell->lf = NULL;
lfinway->cell = NULL;
// remember your cell
oldcell = lf->cell;
swapplaces(lf, lfinway, onpurpose);
// move you..
moveto(lf, cell, onpurpose, B_FALSE);
if (onpurpose) taketime(lf, getmovespeed(lf));
// move them...
lfinway->cell = oldcell;
oldcell->lf = lfinway;
reason = E_OK;
if (isplayer(lf)) {
char lfname[BUFLEN];
getlfname(lfinway, lfname);
@ -1769,7 +1825,6 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
//object_t *o;
iq = getiqname(getattr(lf, A_IQ), NULL);
// default
if (error) {
*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) {
// don't move if in pain
if (lfhasflag(lf, F_PAIN)) {
@ -1832,8 +1887,26 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
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;
}

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 pullnextto(lifeform_t *lf, cell_t *c);
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 trymove(lifeform_t *lf, int dir, int onpurpose);
int tryrun(lifeform_t *lf, int dir);

52
nexus.c
View File

@ -197,6 +197,19 @@ int main(int argc, char **argv) {
getchoice(&prompt);
sk = (skill_t *) prompt.result;
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
drawscreen();
@ -471,10 +487,12 @@ void donextturn(map_t *map) {
// pre-calculate line of sight for this lifeform
precalclos(who);
/*
if (isplayer(who) || cansee(player, who)) {
needredraw = B_TRUE;
drawscreen();
}
*/
// update gun targets
autotarget(who);
@ -491,6 +509,24 @@ void donextturn(map_t *map) {
int donormalmove = B_TRUE;
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?
if (donormalmove) {
f = isresting(who);
@ -503,6 +539,12 @@ void donextturn(map_t *map) {
msg("Stopped %s.",(f->id == F_TRAINING) ? "training" : "resting");
killflag(f);
} else {
if (isplayer(who)) {
if (++who->turnsskipped >= 10) {
msg("Time passes...");
who->turnsskipped = 0;
}
}
rest(who, B_TRUE);
donormalmove = B_FALSE;
}
@ -513,6 +555,12 @@ void donextturn(map_t *map) {
if (donormalmove) {
// paralyzed etc?
if (isimmobile(who)) {
if (isplayer(who)) {
if (++who->turnsskipped >= 10) {
msg("Time passes...");
who->turnsskipped = 0;
}
}
rest(who, B_FALSE);
donormalmove = B_FALSE;
}
@ -535,8 +583,10 @@ void donextturn(map_t *map) {
if (hasflag(player->flags, F_ASLEEP)) {
// ooo is this right ?
needredraw = B_FALSE;
/*
} else if (isdead(who) || cansee(player, who)) {
needredraw = B_TRUE;
*/
}
// check for death etc
@ -550,8 +600,6 @@ void donextturn(map_t *map) {
// note: can't use 'who->' below since 'who' might have died
// and been de-alloced during checkdeath() above.
timeeffectsworld(player->cell->map); // in case the player changed levels!
}
char *getdirname(int dir) {

600
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);
object_t *addob(obpile_t *where, char *name);
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);
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
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);
int isactivated(object_t *o);
int isammofor(object_t *ammo, object_t *gun);
int isbadfood(object_t *o);
int isbetterarmourthan(object_t *a, object_t *b);
int isbetterwepthan(object_t *a, object_t *b);
int isblessed(object_t *o);
@ -167,6 +168,7 @@ void makeknown(enum OBTYPE otid);
void maketried(enum OBTYPE otid);
void makewet(object_t *o, int amt);
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);
//object_t *newobeffects(object_t *o);
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 fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
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 turnon(lifeform_t *lf, object_t *o);
int uncurseob(object_t *o, int *seen);

902
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);
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
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 stopallspells(lifeform_t *lf);
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) {
if (weight >= 1) {
if (weight == 0) {
sprintf(buf, "nothing");
} else if (weight >= 1) {
if ((int)weight == weight) { // ie. is weight an integer?
sprintf(buf, "%0.0f kg",weight);
} else {