- [+] if can WILL _and_ CAST a spell, use power level from whichever is

highest
- [+] exorcise spell - l2 summoning
    - [+] +10% chance per skill level, -5% per monster TR, +5% per
          spell power
    - [+] implement
- [+] paladins get exorcise  at l5
- [+] new purity god pray effect: 100% success exorcisms.
- [+] new perks for lore:demonology 
    - [+] nov: exorcise demons (power 1)
    - [+] skilled: summon demon
- [+]  midnight -portals open.  moongate? lunar portal? lunar gate?
      moon door?
    - [+] portals with no F_MAPLINK will create a random destinatino in
          the same map.
    - [+] makeobjecttemporary() function
    - [+] when it strikes midnight, a portal appears somewhere on the
          plaeyr's level
    - [+] the portal is temporary for 60 turns (ie. approx 1 hours)
          turns until end of midnight (calc this)
- [+] fixed crash on "w-"
- [+] during glorana's peace, striketoko is okay.
- [+] announce posion potion effects.
- [+] make dark maps just lower max vis range, isntead of not being lit
      ?
- [+] redo entire light calculation code.
    - [+] light effects:
        - [+] create "bright light" object in radius around target cell
              (it has f_produceslight)   
        - [+] at high level, light spell will increase ILLUMINATION
              level of the entire map.
    - [+] DARKNESS
        - [+] make a "magical darkness" object
        - [+] blocks view.
        - [+] at high level, light spell will increase ILLUMINATION
              level of the entire map.
    - [+] bright light objects burn/scare undead
    - [+] undead won't walk into cells with bright light power >= their
          TR
    - [+] monsters in cells with produces light which are vulnerable to
          light take damage
        - [+] cases to check for:
            - [+] vuln to light 
            - [+] migrains
        - [+] iscelllit() should return light level of cell (sum of
              f_produceslight)
    - [+] gaining/losing f_produceslight should setlosdirty
    - [+] makelit() just places light/darkness objects
    - [+] monsters in cells with produces light which have good eyes
          get blinded
        - [+] move blinding code out of spell.c and into turneffectslf
    - [+] placing light/darkness objects causes los recalc in any who
          can see them
        - [+] this shoudl happen automatically since they will have
              BLOCKSVIEW.
    - [+] islit():
        - [+] check for ot_darkness objects in the cell
        - [+] check for f_produceslight flags in the cell's lfs/objects
        - [+] return how MUCH the cell is lit
    - [+] f_produceslight flag now just lets you see further in the
          darkness
    - [+] still give light sources to monsters, but change the check to
          see whether we do this (check the map's illumnation level)
    - [+] get rid of calclight() code.
    - [+] then i can get rid of seeindark code in los checking ???
    - [+] get rid of eyesight adjustment code 
    - [+] remove enum LIGHTLEV
    - [+] CHANGE nightvisrange - it just countres the map's
          illumination level
    - [+] remove lf->eyeadjustment
    - [+] remove lf->losdark
    - [+] remove lf->nlosdark
    - [+] remove cell->lit and littime and otiglittimer and origlight
          and lastlit
        - [+] remove it
        - [+] don't save it
This commit is contained in:
Rob Pearce 2012-08-02 04:08:27 +00:00
parent c06ebff882
commit 8e3c457c01
18 changed files with 565 additions and 276 deletions

2
ai.c
View File

@ -1481,7 +1481,7 @@ int ai_premovement(lifeform_t *lf) {
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
// need light?
if (!haslos(lf, lf->cell)) {
if (!lfhasflag(lf, F_PRODUCESLIGHT) && (lf->cell->map->illumination != IL_FULLLIT)) {
object_t *lamp;
lamp = hasobwithflagval(lf->pack, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL);
if (lamp && !isactivated(lamp)) {

View File

@ -208,7 +208,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
int h,m,s;
splittime(&h,&m,&s);
if (godprayedto(R_GODLIFE) && (h == 6)) {
if (godprayedto(R_GODLIFE) && (h == 6) && !lfhasflag(lf, F_STRIKETOKO)) {
if (!warnabout("Really attack during Glorana's Peace?")) {
return B_TRUE;
}
@ -703,7 +703,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
killflagsofid(lf->flags, F_USEDPOISON);
if (isplayer(lf)) god_usepoison_response();
}
if (godprayedto(R_GODLIFE) && (h == 6)) {
if (godprayedto(R_GODLIFE) && (h == 6) && !lfhasflag(lf, F_STRIKETOKO)) {
angergodmaybe(R_GODLIFE, 30, GA_PEACEHOUR);
}
}

73
data.c
View File

@ -1239,7 +1239,7 @@ void initobjects(void) {
addflag_real(lastbrand->flags, F_ONLYFORWEPSKILL, SK_LONGBLADES, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addflag_real(lastbrand->flags, F_ONLYFORWEPSKILL, SK_SHORTBLADES, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addflag_real(lastbrand->flags, F_RACESLAY, RC_UNDEAD, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_PRODUCESLIGHT, 3, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_PRODUCESLIGHT, 4, NA, NULL, PERMENANT, B_UNKNOWN, -1);
// feet
addbrand(BR_LEVITATION, "of hovering", BP_FEET, B_CURSED, 50);
@ -1991,10 +1991,20 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_VERYRARE, NULL);
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, '^', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "portal");
addflag(lastot->flags, F_PORTAL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addot(OT_LUNARGATE, "lunar gate", "A mystical portal said to open at the stroke of midnight.", MT_MAGIC, 0, OC_EFFECT, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_BOLDCYAN, '^', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "lunar gate");
addflag(lastot->flags, F_PORTAL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, SV_TALK, NA, "a shrill humming.");
addot(OT_STOMACHEXIT, "gaping hole", "A gaping hole in an enormous creature.", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_GREY, '^', NA, NULL);
addflag(lastot->flags, F_DONTSHOWDEST, B_TRUE, NA, NA, NULL);
@ -2003,6 +2013,22 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addot(OT_MAGICLIGHT, "very bright light", "A very bright light, seemingly coming from nowhere.", MT_MAGIC, 0, OC_EFFECT, SZ_HUGE);
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
addot(OT_MAGICDARK, "unnatural darkness", "An unnattural area of pitch black darkness.", MT_MAGIC, 0, OC_EFFECT, SZ_HUGE);
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
// terrain
addot(OT_WATERDEEP, "water", "Deep water.", MT_WATER, 300, OC_TERRAIN, SZ_HUGE);
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
@ -4379,6 +4405,12 @@ void initobjects(void) {
addflag(lastot->flags, F_TARGETTEDSPELL, TT_NONE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODNATURE, 5, NA, NULL);
addot(OT_S_EXORCISE, "exorcise", "Sends a single demonic or summoned creature back to whence they came.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how powerful a creature can be affected.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l3
addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power V you can control where the monster appears.");
@ -4391,6 +4423,12 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
// l4
addot(OT_S_EXORCISEMASS, "mass exorcise", "Exorcises all demonic or summoned creatures within sight of the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how powerful a creature can be affected.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l5
addot(OT_S_CLONE, "clone", "Creates an identical clone of the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
@ -4532,12 +4570,12 @@ void initobjects(void) {
addflag(lastot->flags, F_PLEASESGOD, R_GODTHIEVES, 5, NA, NULL);
addot(OT_S_LIGHT, "light area", "Creates a temporary light source centred on the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the light appears.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power V, the light will blind creatures with night vision.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VIII, the light becomes permenant.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power V, the entire level becomes lighter.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_CREATEWATER, "create water", "Creates a large pool of shallow water.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
@ -4590,9 +4628,11 @@ void initobjects(void) {
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the darkness appears.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VIII, the darkness becomes permenant.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power V, the entire map becomes darker.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addot(OT_S_MENDING, "mending", "Repairs minor damage to objects (1d6 + ^bpower^n).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
@ -5093,8 +5133,8 @@ void initobjects(void) {
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit");
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL);
addflag(lastot->flags, F_RNDCHARGES, 200, 400, NA, NULL);
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
@ -5433,8 +5473,8 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 4, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 4, NA, IFACTIVE, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
@ -5731,7 +5771,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RNDCHARGES, 10, 30, NA, NULL);
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_FLYING, B_TRUE, NA, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
@ -6204,12 +6244,12 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_WHITE, ',', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL);
addot(OT_MOSSSUN, "patch of sun moss", "A patch of brightly glowing yellow moss.", MT_PLANT, 0.1, OC_FLORA, SZ_MINI);
addflag(lastot->flags, F_GLYPH, C_YELLOW, ',', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 4, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL);
@ -6567,7 +6607,7 @@ void initobjects(void) {
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL);
addot(OT_TORNADO, "tornado", "A large column of incredibly fast spinning air.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SPIRAL, NA, NULL);
@ -9878,9 +9918,10 @@ void initrace(void) {
addflag(lastrace->flags, F_SACRIFICEOB, OT_CORPSE, NA, 10, "OB explode#S in a shower of sparks!");
addflag(lastrace->flags, F_CANCAST, OT_S_WISHLIMITED, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANCAST, OT_S_EXORCISE, NA, NA, "pw:50;");
// likes/dislikes
addflag(lastrace->flags, F_GODPOISON, B_FALSE, 100, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "destroying the undead");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "destroying the undead or demons");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing evil creatures");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "blessing objects");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "acts of charity");
@ -9892,6 +9933,7 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "uncursing items");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "curing ailments");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "smiting evil");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "exorcising demons");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "removing polymorphs");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "purifying food");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your items");
@ -16480,7 +16522,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_EATCONFER, F_PRODUCESLIGHT, B_TRUE, NA, "100");
addflag(lastrace->flags, F_EATCONFER, F_PRODUCESLIGHT, 3, NA, "100");
addrace(R_STINKBUG, "stinkbeetle", 1, 'x', C_MAGENTA, MT_FLESH, RC_INSECT, "A dog-sized beetle with tough scales. Emits a foul odour upon death.");
setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL);
@ -17757,7 +17799,6 @@ void initrace(void) {
addflag(r->flags, F_DTIMMUNE, DT_DECAY, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
// +/- 15 accuracy during day/night
addflag(r->flags, F_NIGHTBOOST, 15, NA, NA, NULL);
addflag(r->flags, F_DAYBOOST, -15, NA, NA, NULL);
@ -18007,6 +18048,8 @@ void initskills(void) {
addskilldesc(SK_LORE_ARCANA, PR_ADEPT, "^gYou gain the 'study scrolls' ability.", B_FALSE);
addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 5);
free(lastskill->shortname); lastskill->shortname = strdup("Lore:Demons");
addskilldesc(SK_LORE_ARCANA, PR_NOVICE, "^gYou gain the 'exorcise' ability.", B_FALSE);
addskilldesc(SK_LORE_ARCANA, PR_SKILLED, "^gYou gain the 'summon demons' ability.", B_FALSE);
addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.", 5);
addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.", 5);
addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.", 5);

Binary file not shown.

28
defs.h
View File

@ -226,7 +226,7 @@
#define MAXSPELLLEV 6
#define MAXVISRANGE 10 // max visible range in full light
#define MAXVISLIMIT (MAXVISRANGE*20)
#define MAX_EYEADJ 20
//#define MAX_EYEADJ 20
#define MINCLEARINGRADIUS 4
#define MAXCLEARINGRADIUS 7
@ -341,6 +341,10 @@
#define DC_W 10
#define DC_NW 11
// light dirs
#define D_DARKER 1
#define D_LIGHTER -1
// altitude directions
#define D_UP 12
#define D_DOWN 13
@ -1410,8 +1414,11 @@ enum OBTYPE {
OT_TREEUP,
OT_TUNNELDOWN,
OT_TUNNELUP,
OT_LUNARGATE,
OT_PORTAL,
OT_STOMACHEXIT,
OT_MAGICLIGHT,
OT_MAGICDARK,
// buildings - rememebr to update MAXBUILDINGTYPES!
OT_BABAYAGAHUT,
OT_BYHUTDOOR,
@ -1777,6 +1784,8 @@ enum OBTYPE {
// -- summoning
OT_S_CLONE,
OT_S_CREATEFOOD,
OT_S_EXORCISE,
OT_S_EXORCISEMASS,
OT_S_FLOATINGDISC,
OT_S_FRIENDS,
OT_S_GLYPHWARDING,
@ -2813,6 +2822,7 @@ enum FLAG {
// OPTIONAL v1 = id of region to link to.
F_PIT, // this is a pit which we can fall down.
// v0 = up/down
F_PORTAL, // this object counts as a 'magic portal'
//F_STAIRDIR//, // val0 = direcion
F_OPPOSITESTAIRS, // val0 = opposite kind of stairs
F_MAPLINK, // val0 = map id to link to.
@ -3930,12 +3940,14 @@ enum PIETYLEV {
PL_ECSTATIC = 3,
};
/*
enum LIGHTLEV {
L_PERMDARK = -1,
L_NOTLIT = 0,
L_TEMP = 1,
L_PERMLIGHT = 2,
};
*/
// spell targets
@ -4429,12 +4441,12 @@ typedef struct cell_s {
struct room_s *room;
struct celltype_s *type;
struct obpile_s *obpile;
enum LIGHTLEV lit;
enum LIGHTLEV origlit; // for timed light
enum LIGHTLEV lastlit;
//enum LIGHTLEV lit;
//enum LIGHTLEV origlit; // for timed light
//enum LIGHTLEV lastlit;
habitat_t *habitat;
int origlittimer;
int littimer;
//int origlittimer;
//int littimer;
int hp;
char *reason;
@ -4554,14 +4566,18 @@ typedef struct lifeform_s {
int losdirty;
int nlos; // cells which we can see
cell_t **los;
/*
int nlosdark; // cells which we'd be able to see if they
cell_t **losdark; // were lit.
*/
//int *viscell;
int visw;
int visrange;
/*
int eyeadjustment; // have your eyes adjusted to the dark?
// your nightvision is increased by eyeadj / 10
// max is MAX_EYEADJ
*/
int damlastturn; // for hp bar. not saved.
int mplastturn; // for mp bar. not saved.

19
flag.c
View File

@ -59,7 +59,7 @@ 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) {
lifeform_t *lf;
flag_t *f;
map_t *redolight = NULL;
//map_t *redolight = NULL;
int redrawscreenatend = B_FALSE;
int redrawstatatend = B_FALSE;
int i;
@ -117,6 +117,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
lf = fp->owner;
/*
if (gamemode == GM_GAMESTARTED) {
if (id == F_PRODUCESLIGHT) {
if (lf && lf->cell && (lf->cell->map == player->cell->map)) {
@ -137,6 +138,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
}
}
}
*/
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
////////////////////////////////
@ -360,8 +362,10 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
}
}
if ((gamemode == GM_GAMESTARTED) && (redrawscreenatend || redrawstatatend || redolight)) {
//if ((gamemode == GM_GAMESTARTED) && (redrawscreenatend || redrawstatatend || redolight)) {
if ((gamemode == GM_GAMESTARTED) && (redrawscreenatend || redrawstatatend )) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
/*
if (redolight) {
//dblog("CALCINGLIGHT from flag\n");
if (!redrawscreenatend) redrawscreenatend = B_TRUE;
@ -373,6 +377,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
//precalclos(player);
}
*/
//dblog("DRAWINGSCREEN from flag\n");
if (redrawscreenatend) needredraw = B_TRUE;
@ -598,6 +603,7 @@ int flagcausesloscalc(enum FLAG fid) {
case F_BLOCKSVIEW:
case F_NIGHTVISRANGEMOD:
case F_PRONE:
case F_PRODUCESLIGHT:
case F_SEEINDARK:
case F_SHADOWED:
case F_AWARENESS:
@ -956,7 +962,7 @@ void killflag(flag_t *f) {
flagpile_t *pile;
lifeform_t *lf;
enum FLAG fid;
map_t *redolight = NULL;
//map_t *redolight = NULL;
cell_t *redolos = NULL;
int redostat = B_FALSE;
int redoscreen = B_FALSE;
@ -973,6 +979,7 @@ void killflag(flag_t *f) {
lf = f->pile->owner;
if (gamemode == GM_GAMESTARTED) {
/*
if (f->id == F_PRODUCESLIGHT) {
if (lf && lf->cell && (lf->cell->map == player->cell->map)) {
// someone stopped producing light
@ -990,7 +997,9 @@ void killflag(flag_t *f) {
if (lf && (isplayer(lf) || cansee(player, lf))) {
redolight = lf->cell->map;
}
} else if (f->id == F_FLEEFROM) {
} else
*/
if (f->id == F_FLEEFROM) {
if (lf && lf->cell) {
lifeform_t *fleefrom;
fleefrom = findlf(lf->cell->map, f->val[0]);
@ -1154,12 +1163,14 @@ void killflag(flag_t *f) {
}
}
}
/*
if (redolight) {
calclight(redolight);
setlosdirty(player);
//precalclos(player);
needredraw = B_TRUE;
}
*/
if (redoscreen) {
needredraw = B_TRUE;
}

13
god.c
View File

@ -1920,12 +1920,17 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
int i,nretflags;
flag_t *retflag[MAXCANDIDATES];
// smite evil
// smite evil or exorcise
for (l = lf->cell->map->lf ; l ; l = l->next) {
if (getalignment(l) == AL_EVIL) {
if ((getraceclass(l) == RC_DEMON) || (getalignment(l) == AL_EVIL)) {
if (haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL)) {
// smite them
castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell, NULL, NULL);
if (getraceclass(l) == RC_DEMON) {
// exorcise them
castspell(god, OT_S_EXORCISE, l, NULL, l->cell, NULL, NULL);
} else {
// smite them
castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell, NULL, NULL);
}
}
}
}

4
io.c
View File

@ -1852,10 +1852,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break;
case F_NAUSEATED:
if (isplayer(lf)) {
msg("^wYou are nauseated by a disgusting stench!");
msg("^%cYou are nauseated by a disgusting stench!", getlfcol(lf, CC_BAD));
donesomething = B_TRUE;
} else {
msg("%s looks very unwell.",lfname);
msg("^%c%s looks nauseous.",getlfcol(lf, CC_BAD), lfname);
donesomething = B_TRUE;
}
break;

218
lf.c
View File

@ -878,6 +878,16 @@ int caneat(lifeform_t *lf, object_t *o) {
return B_TRUE;
}
int canexorcise(lifeform_t *lf, lifeform_t *target, int modifier) {
int maxlevel;
if (lfhasflag(target, F_UNIQUE)) return B_FALSE;
maxlevel = gettr(lf) + getskill(lf, SK_LORE_DEMONS) + modifier;
if (gettr(target) <= maxlevel) {
return B_TRUE;
}
return B_FALSE;
}
int canhaverandombehaviour(lifeform_t *lf) {
if (lfhasflag(lf, F_BEHAVIOUR)) return B_FALSE;
@ -1509,35 +1519,37 @@ int canweild(lifeform_t *lf, object_t *o) {
weildloc = getweildloc(o, lf, &otherloc, NULL);
// already weilding it?
if (o && isequipped(o)) {
reason = E_ALREADYUSING;
return B_FALSE;
}
// paladin?
if (getsubjob(lf) == SJ_PALADIN) {
if (!isblessed(o) || !o->blessknown) {
reason = E_PALADIN;
if (o) {
if (isequipped(o)) {
reason = E_ALREADYUSING;
return B_FALSE;
}
}
// too heavy?
if (o && lfhasflagval(lf, F_INJURY, IJ_SHOULDERDISLOCATED, NA, NA, NULL)) {
if (isheavyweapon(o)) {
reason = E_INJURED;
// paladin?
if (getsubjob(lf) == SJ_PALADIN) {
if (!isblessed(o) || !o->blessknown) {
reason = E_PALADIN;
return B_FALSE;
}
}
// too heavy?
if (lfhasflagval(lf, F_INJURY, IJ_SHOULDERDISLOCATED, NA, NA, NULL)) {
if (isheavyweapon(o)) {
reason = E_INJURED;
return B_FALSE;
}
}
if ((gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE))) {
reason = E_NOTKNOWN;
return B_FALSE;
}
}
if (o && (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE))) {
reason = E_NOTKNOWN;
return B_FALSE;
}
if (o && lfhasflagval(lf, F_INJURY, IJ_TENDONCUT, NA, NA, NULL)) {
if ((weildloc == BP_WEAPON) || (otherloc == BP_WEAPON)) {
reason = E_INJURED;
return B_FALSE;
if (lfhasflagval(lf, F_INJURY, IJ_TENDONCUT, NA, NA, NULL)) {
if ((weildloc == BP_WEAPON) || (otherloc == BP_WEAPON)) {
reason = E_INJURED;
return B_FALSE;
}
}
}
@ -2137,6 +2149,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
return rv;
}
/*
int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange) {
int dist;
//int ambientvis;
@ -2151,14 +2164,13 @@ int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange) {
}
// outside ambient light range and beyond nightvis range
/*
ambientvis = getmapmaxvisrange(c->map);
if ((ambientvis == 0) || (dist > ambientvis)) {
if (dist >= nightvisrange) {
return B_FALSE;
}
}
*/
//ambientvis = getmapmaxvisrange(c->map);
//if ((ambientvis == 0) || (dist > ambientvis)) {
// if (dist >= nightvisrange) {
// return B_FALSE;
// }
// }
// outside the range of our light, and not lit
if ((nightvisrange != UNLIMITED) && !islit(c)) {
@ -2174,6 +2186,7 @@ int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange) {
return B_TRUE;
}
*/
int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod) {
object_t *o;
@ -3244,7 +3257,7 @@ void die(lifeform_t *lf) {
// award xp (but not if another monster killed it)
if (hasflag(lf->flags, F_KILLEDBYPLAYER)) {
awardxpfor(lf,100);
if ((getalignment(lf) == AL_EVIL) || isundead(lf)) {
if ((getalignment(lf) == AL_EVIL) || isundead(lf) || (getraceclass(lf) == RC_DEMON)) {
pleasegodmaybe(R_GODPURITY, 5);
if (isundead(lf)) pleasegodmaybe(R_GODLIFE, 10);
} else if (getalignment(lf) == AL_GOOD) {
@ -4259,6 +4272,7 @@ int digup(lifeform_t *lf, object_t *o) {
return B_FALSE;
}
/*
void do_eyesight_adjust(lifeform_t *lf) {
int i,nlitcells = 0;
int preea;
@ -4297,6 +4311,7 @@ void do_eyesight_adjust(lifeform_t *lf) {
}
}
}
*/
// dump which level random things will appear at
void dumplev(void) {
@ -8414,6 +8429,7 @@ int getnightvisrange(lifeform_t *lf) {
flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags,i;
int lightamt = 0;
f = lfhasflag(lf, F_SEEINDARK);
if (f && !isblind(lf)) {
@ -8426,10 +8442,13 @@ int getnightvisrange(lifeform_t *lf) {
f = lfhasflag(lf, F_TREMORSENSE);
if (f) {
return f->val[0];
} else {
}
/*
else {
// depends how much your eyes have adjusted
range = (lf->eyeadjustment / 10);
}
*/
}
// modifications?
getflags(lf->flags, retflag, &nretflags, F_NIGHTVISRANGEMOD, F_NONE);
@ -8440,6 +8459,9 @@ int getnightvisrange(lifeform_t *lf) {
}
}
sumflags(lf->flags, F_PRODUCESLIGHT, &lightamt, NULL, NULL);
range += lightamt;
limit(&range, 0, MAXVISRANGE);
return range;
@ -11078,6 +11100,8 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
}
// remove warrior's level abilities
killflagsofid(lf->flags, F_LEVABIL);
// instead, you get 'exorcise' at level 5
addflag(lf->flags, F_LEVABIL, 5, OT_S_EXORCISE, NA, "pw:1;");
// monster spells
if (!isplayer(lf)) {
addflag(lf->flags, F_RNDSPELLCOUNT, rnd(2,4), NA, NA, NULL);
@ -11403,6 +11427,11 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
if (!newf) {
newf = addtempflag(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL, FROMSKILL);
}
} else if (id == SK_LORE_DEMONS) {
newf = hasflagval(lf->flags, F_CANWILL, OT_S_EXORCISE, NA, NA, NULL);
if (!newf) {
newf = addtempflag(lf->flags, F_CANWILL, OT_S_EXORCISE, NA, NA, "pw:1;", FROMSKILL);
}
} else if (id == SK_LOCKPICKING) {
newf = hasflagval(lf->flags, F_CANWILL, OT_A_PICKLOCK, NA, NA, NULL);
if (!newf) {
@ -11514,6 +11543,13 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
newf = addtempflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL, FROMSKILL);
}
}
} else if (id == SK_LORE_DEMONS) {
if (f->val[1] == PR_SKILLED) {
newf = hasflagval(lf->flags, F_CANWILL, OT_S_SUMMONDEMON, NA, NA, NULL);
if (!newf) {
newf = addtempflag(lf->flags, F_CANWILL, OT_S_SUMMONDEMON, NA, NA, "pw:1;", FROMSKILL);
}
}
} else if (id == SK_LORE_NATURE) {
if (f->val[1] == PR_BEGINNER) {
if (isplayer(lf)) {
@ -13287,6 +13323,7 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
*/
}
/*
int haslosdark(lifeform_t *viewer, cell_t *dest) {
int i;
for (i = 0; i < viewer->nlosdark; i++) {
@ -13296,6 +13333,7 @@ int haslosdark(lifeform_t *viewer, cell_t *dest) {
}
return B_FALSE;
}
*/
int haslos_fast(lifeform_t *viewer, cell_t *dest) {
int i;
@ -14111,11 +14149,11 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
a->losdirty = B_TRUE;
//a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
a->los = NULL; // will be alloced in precalclos
a->losdark = NULL; // will be alloced in precalclos
//a->losdark = NULL; // will be alloced in precalclos
a->nlos = 0;
a->nlosdark = 0;
//a->nlosdark = 0;
a->eyeadjustment = 0;
//a->eyeadjustment = 0;
a->changinglev = B_FALSE;
@ -16045,7 +16083,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of fumes!", lfname);
sprintf(buf2, "^wSomething releases a cloud of fumes!");
spellcloud(lf->cell, 1, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL, B_NOCENTRE);
spellcloud(lf->cell, 2, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL, B_NOCENTRE);
}
@ -17321,7 +17359,8 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int want
return B_FALSE;
}
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid) {
// returns true on failure
int poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid) {
flag_t *f;
int found = B_FALSE,i;
enum POISONSEVERITY psev;
@ -17335,18 +17374,18 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
// special case - lycanthropy only affects players
if ((pt->id == P_LYCANTHROPY) && !isplayer(lf)) {
return;
return B_TRUE;
}
// are you immune to disease/poison?
psev = pt->severity;
switch (psev) {
case PS_POISON:
if (isimmuneto(lf->flags, DT_POISON, B_FALSE)) return;
if (isimmuneto(lf->flags, DT_POISON, B_FALSE)) return B_TRUE;
break;
case PS_DISEASE:
if (isimmuneto(lf->flags, DT_POISON, B_FALSE)) return;
if (hasflag(lf->flags, F_DISEASEIMMUNE)) return;
if (isimmuneto(lf->flags, DT_POISON, B_FALSE)) return B_TRUE;
if (hasflag(lf->flags, F_DISEASEIMMUNE)) return B_TRUE;
break;
case PS_CURSE:
default:
@ -17358,7 +17397,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
// adjust time based on first aid skill
howlong -= getskill(lf, SK_FIRSTAID);
if (howlong <= 0) {
return;
return B_TRUE;
}
}
@ -17437,6 +17476,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
}
}
return B_FALSE;
}
int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power) {
@ -17556,9 +17596,10 @@ void precalclos(lifeform_t *lf) {
int startxray,rangemod;
int maxvisrange,nightvisrange;
cell_t **los;
cell_t **losdark;
//cell_t **losdark;
int *blocker;
int nlos = 0,nlosdark = 0, i,nn;
int nlos = 0,i,nn;
//int nlosdark = 0;
flag_t *f;
int endx[MAXVISLIMIT],endy[MAXVISLIMIT];
int nendcells = 0;
@ -17578,13 +17619,15 @@ void precalclos(lifeform_t *lf) {
if (lf->los) {
free(lf->los); lf->los = NULL;
}
/*
if (lf->losdark) {
free(lf->losdark); lf->losdark = NULL;
}
*/
if (!lf->born) {
lf->nlos = 0;
lf->nlosdark = 0;
//lf->nlosdark = 0;
return;
}
@ -17604,10 +17647,10 @@ void precalclos(lifeform_t *lf) {
allocamt = MAX_MAPW * MAX_MAPH;
los = malloc( sizeof(cell_t *) * allocamt);
losdark = malloc( sizeof(cell_t *) * allocamt);
//losdark = malloc( sizeof(cell_t *) * allocamt);
blocker = malloc( sizeof(cell_t *) * allocamt);
nlos = 0;
nlosdark = 0;
//nlosdark = 0;
//maxvisrange = getvisrange(lf, B_FALSE);
maxvisrange = getvisrange(lf, B_TRUE);
@ -17694,10 +17737,12 @@ void precalclos(lifeform_t *lf) {
}
}
if (!found) {
/*
int litforus;
// is the cell lit? if it isn't, then still keep going,
// as there might be a light-producing object further on.
litforus = celllitfor(lf, c, maxvisrange, nightvisrange);
*/
if (!celltransparentfor(lf, c, &xray, &rangemod)) {
keepgoing = B_FALSE;
@ -17707,12 +17752,14 @@ void precalclos(lifeform_t *lf) {
// if keepgoing was false, still count it
// BUT then stop looking.
if (litforus) {
//if (litforus) {
los[nlos] = c;
blocker[nlos] = keepgoing ? B_FALSE : B_TRUE;
nlos++;
assert (nlos < allocamt);
} else {
//}
/*
else {
int idx,found=B_FALSE;
for (idx=0;idx<nlosdark;idx++) {
if (losdark[idx] == c) {
@ -17731,6 +17778,7 @@ void precalclos(lifeform_t *lf) {
assert (nlosdark < allocamt);
}
}
*/
}
} else { // ie. if !c
keepgoing = B_FALSE;
@ -17738,7 +17786,7 @@ void precalclos(lifeform_t *lf) {
} // end foreach cell and while keepgoing
}
assert(nlos < allocamt);
assert(nlosdark < allocamt);
//assert(nlosdark < allocamt);
// now fill in lifeform structure
if (nlos) {
@ -17751,6 +17799,7 @@ void precalclos(lifeform_t *lf) {
}
lf->nlos = nlos;
/*
if (nlosdark) {
lf->losdark = malloc(sizeof(cell_t *) * nlosdark);
for (i = 0; i < nlosdark; i++) {
@ -17760,9 +17809,10 @@ void precalclos(lifeform_t *lf) {
lf->losdark = NULL;
}
lf->nlosdark = nlosdark;
*/
free(los);
free(losdark);
//free(losdark);
free(blocker);
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
@ -21464,7 +21514,7 @@ void startlfturn(lifeform_t *lf) {
// so half it here.
dam = amt/2;
limit(&dam, 1, NA);
losehp(lf, amt, DT_LIGHT, NULL, "a migraine");
losehp(lf, dam, DT_LIGHT, NULL, "a migraine");
if (isplayer(lf)) {
char obname[BUFLEN];
if (lamp) {
@ -21605,6 +21655,35 @@ void startlfturn(lifeform_t *lf) {
applywalkdam(lf, roll(f->text), f->val[0], o);
}
f = hasflag(o->flags, F_PRODUCESLIGHT);
if (f) {
if (lfhasflag(lf, F_SEEINDARK)) {
// if you don't have eyes, your'e safe!
if (!lfhasflagval(lf, F_NOBODYPART, BP_EYES, NA, NA, NULL)) {
if (isplayer(lf)) {
msg("The bright light burns your vision-enhanced eyes!");
}
// blind for 1-3 turns
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(3,3+f->val[0]));
}
}
if (isvulnto(lf->flags, DT_LIGHT, B_FALSE)) {
int dam;
char obname[BUFLEN],damstring[BUFLEN];
// note: amt will be doubled due to light vulnerability,
// so half it here.
dam = f->val[0]/2;
limit(&dam, 1, NA);
getobnametruebase(o, obname, o->amt);
sprintf(damstring, "light from %s", obname);
if (isplayer(lf)) {
msg("Your head explodes in pain at the light from %s!", obname);
}
losehp(lf, dam, DT_LIGHT, NULL, damstring);
}
}
f = hasflag(o->flags, F_CAUSESCOUGH);
if (f && !isimmuneto(lf->flags, DT_POISONGAS, B_FALSE)) {
char obname[BUFLEN];
@ -22872,10 +22951,9 @@ void unequipeffects(lifeform_t *lf, object_t *o) {
loseobflags(lf, o, F_EQUIPCONFER);
if (obproduceslight(o)) {
calclight((getoblocation(o))->map);
//calclight((getoblocation(o))->map);
setlosdirty(lf);
//precalclos(lf);
drawscreen();
}
if (o->type->id == OT_ENERGYBLADE) {
@ -23140,8 +23218,34 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
return B_TRUE;
}
if (o->type->id == OT_PORTAL) {
if (hasflag(o->flags, F_PORTAL)) {
f = hasflag(o->flags, F_MAPLINK);
if (!f) {
int wantdepth;
object_t *dstportal;
wantdepth = rnd(1,lf->cell->map->region->rtype->maxdepth);
// generate random destination portal
dstportal = linkportal(o, wantdepth);
if (dstportal) {
flag_t *newf;
// if source portal is temporary, make the
// destination portal temporary as well.
if (hasflagval(o->flags, F_OBHPDRAIN, NA, DT_DIRECT, NA, NULL)) {
newf = hasflag(o->flags, F_OBHP);
if (newf) {
maketemporary(dstportal, newf->val[0], "vanishes");
}
}
// now update 'f' since 'o' should now have F_MAPLINK.
f = hasflag(o->flags, F_MAPLINK);
} else {
// failed to create destinaiton.
if (isplayer(lf)) msg("The portal doesn't seem to take you anywhere.");
if (onpurpose) taketime(lf, getmovespeed(lf));
return B_TRUE;
}
}
assert(f);
if (f->val[0] != NA) {
map_t *m;
m = findmap(f->val[0]);
@ -24941,7 +25045,7 @@ int weild(lifeform_t *lf, object_t *o) {
lifeform_t *g;
g = findgod(R_GODDEATH);
if (g) msg("You sense %s's approval.",g->race->name);
} else if (o->material->id == MT_WOOD) && godprayedto(R_GODNATURE)) {
} else if ((o->material->id == MT_WOOD) && godprayedto(R_GODNATURE)) {
lifeform_t *g;
g = findgod(R_GODNATURE);
if (g) msg("You sense %s's approval.",g->race->name);

7
lf.h
View File

@ -47,6 +47,7 @@ int cancook(lifeform_t *lf, recipe_t *rec, enum ERROR *reason);
int canclimb(lifeform_t *lf, enum ERROR *reason);
int candrink(lifeform_t *lf, object_t *o);
int caneat(lifeform_t *lf, object_t *o);
int canexorcise(lifeform_t *lf, lifeform_t *target, int modifier);
int canhaverandombehaviour(lifeform_t *lf);
int canhear(lifeform_t *lf, cell_t *c, int volume, int *numwalls);
int canlearn(lifeform_t *lf, enum SKILL skid);
@ -92,7 +93,7 @@ void die(lifeform_t *lf);
int digcell(lifeform_t *lf, cell_t *c, object_t *o);
int digdown(lifeform_t *lf, object_t *o);
int digup(lifeform_t *lf, object_t *o);
void do_eyesight_adjust(lifeform_t *lf);
//void do_eyesight_adjust(lifeform_t *lf);
void dumplev(void);
void dumplf(void);
void dumpmonsters(void);
@ -324,7 +325,7 @@ int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
int haslofknown(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf, int walllfsok);
int haslos(lifeform_t *viewer, cell_t *dest);
int haslosdark(lifeform_t *viewer, cell_t *dest);
//int haslosdark(lifeform_t *viewer, cell_t *dest);
int haslos_fast(lifeform_t *viewer, cell_t *dest);
void interrupt(lifeform_t *lf);
enum FLAG isairborne(lifeform_t *lf);
@ -421,7 +422,7 @@ enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
void outfitlf(lifeform_t *lf);
void petify(lifeform_t *lf, lifeform_t *owner);
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int antannounce);
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid);
int poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid);
int poisoneffects(lifeform_t *lf, enum POISONTYPE ptid, int power);
int poisoncausesvomit(enum POISONTYPE ptype);
int poisonthreatenslife(lifeform_t *lf, flag_t *f);

156
map.c
View File

@ -75,10 +75,10 @@ cell_t *addcell(map_t *m, int x, int y) {
cell->lf = NULL;
cell->room = NULL;
cell->locked = B_FALSE;
cell->lit = L_NOTLIT;
cell->origlit = L_NOTLIT;
cell->littimer = 0;
cell->origlittimer = 0;
//cell->lit = L_NOTLIT;
//cell->origlit = L_NOTLIT;
//cell->littimer = 0;
//cell->origlittimer = 0;
cell->writing = NULL;
cell->writinglifetime = -1;
cell->known = B_FALSE;
@ -961,23 +961,23 @@ void adjustcellglyph(cell_t *c, glyph_t *g) {
if ((c->x + c->y) % 2) g->colour = c->type->altcol;
}
/*
switch (c->lit) {
case L_PERMDARK:
case L_NOTLIT:
g->colour = C_BLUE;
break;
/*
case L_TEMP: // lit by a light source
if (g->colour < 8) {
g->colour = g->colour + 8; // ie. make bold
if (g->colour >= C_GREY) g->colour = C_WHITE;
}
break;
*/
//case L_TEMP: // lit by a light source
// if (g->colour < 8) {
// g->colour = g->colour + 8; // ie. make bold
// if (g->colour >= C_GREY) g->colour = C_WHITE;
// }
// break;
case L_PERMLIGHT:
default:
break;
}
*/
}
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance) {
@ -2479,6 +2479,7 @@ object_t *gettopobject(cell_t *where, int forglyph) {
return NULL;
}
/*
void calclight(map_t *map) {
int x,y;
cell_t *c;
@ -2509,27 +2510,6 @@ void calclight(map_t *map) {
int radius;
object_t *o;
/*
// lit based on depth
if (isoutdoors(map)) {
int hours,mins,secs;
splittime(&hours,&mins,&secs);
if (isnighttime()) {
// ie. nighttime, after 7pm or before 5am
} else {
// ie. daytime
makelit(c, L_PERMLIGHT, -1);
}
}
*/
//if ((map->depth <= 5) && (c->lit != L_PERMDARK)) {
/*
if ((map->illumination == IL_FULLLIT) && (c->lit != L_PERMDARK)) {
makelit(c, L_PERMLIGHT, -1);
}
*/
if (c->lit != L_PERMDARK) {
makelit(c, L_PERMLIGHT, -1);
}
@ -2575,8 +2555,8 @@ void calclight(map_t *map) {
}
}
}
*/
// if "stayclose" is non-zero, then room must be within 'stayclose' cells of another room.
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force, int stayclose) {
@ -4395,7 +4375,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
object_t *o;
c = getcellat(map, x, y);
o = hasobwithflag(c->obpile, F_CLIMBABLE);
if (o && (o->type->id != OT_PORTAL) && !getstairdestination(o, NULL) && !hasflag(o->flags, F_MAPLINK)) {
if (o && !hasflag(o->flags, F_PORTAL) && !getstairdestination(o, NULL) && !hasflag(o->flags, F_MAPLINK)) {
// this will join these stairs to existing ones on
// existing adjacent maps
if (!linkstairs(o, NULL)) {
@ -6225,7 +6205,7 @@ void finalisemap(map_t *map, object_t *entryob, int exitdir) {
}
// unlinked stairs? ie ones added from vaults. if so, link them.
if (hasflag(o->flags, F_CLIMBABLE) && !hasflag(o->flags, F_MAPLINK)) {
if (o->type->id != OT_PORTAL) {
if (!hasflag(o->flags, F_PORTAL)) {
linkstairs(o, NULL);
}
}
@ -7234,7 +7214,7 @@ cell_t *getstairdestination(object_t *o, int *madenewmap) {
dir = getstairdirection(o);
//if ((dir != D_UP) && (dir != D_DOWN)) {
if (o->type->id == OT_PORTAL) {
if (hasflag(o->flags, F_PORTAL)) {
// ie this is a portal
return NULL;
} else {
@ -7516,6 +7496,10 @@ int isadjacent(cell_t *src, cell_t *dst) {
}
int isdark(cell_t *c) {
if (hasob(c->obpile, OT_MAGICDARK)) {
return TRUE;
}
/*
switch (c->lit) {
case L_PERMDARK:
case L_NOTLIT:
@ -7523,6 +7507,7 @@ int isdark(cell_t *c) {
default:
break;
}
*/
return B_FALSE;
}
@ -7732,6 +7717,10 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
}
int islit(cell_t *c) {
int amt = 0;
object_t *o;
flag_t *f;
/*
switch (c->lit) {
case L_TEMP:
case L_PERMLIGHT:
@ -7739,7 +7728,26 @@ int islit(cell_t *c) {
default:
break;
}
return B_FALSE;
*/
for (o = c->obpile->first ; o ; o = o->next) {
if (o->type->id == OT_MAGICDARK) {
return 0;
}
f = hasflag(o->flags, F_PRODUCESLIGHT);
if (f) {
amt += f->val[0];
}
}
if (c->lf) {
for (o = c->lf->pack->first ; o ; o = o->next) {
f = hasflag(o->flags, F_PRODUCESLIGHT);
if (f) {
amt += f->val[0];
}
}
}
return amt;
}
@ -7964,7 +7972,7 @@ object_t *linkportal(object_t *srcportal, int wantdepth) {
newcell = getrandomcell(newmap);
}
// add the dst portal
dstportal = addob(newcell->obpile, "magic portal");
dstportal = addobfast(newcell->obpile, srcportal->type->id);
assert(dstportal);
// link the dst portal
@ -8127,7 +8135,7 @@ void makedoor(cell_t *cell, int openchance) {
}
/*
void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
enum LIGHTLEV origlit;
@ -8168,11 +8176,29 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
}
c->lit = how;
}
*/
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {
int x,y;
cell_t *c2;
void makelit(cell_t *c, enum OBTYPE how, int howlong, int power) {
object_t *o;
o = addobfast(c->obpile, how);
if (o) {
flag_t *f;
if (howlong != PERMENANT) {
addflag(o->flags, F_OBHP, howlong, howlong, NA, NULL);
addflag(o->flags, F_OBHPDRAIN, 1, DT_DIRECT, NA, NULL);
}
f = hasflag(o->flags, F_PRODUCESLIGHT);
if (f) {
f->val[0] = power;
}
}
}
void makelitradius(cell_t *c, int radius, enum OBTYPE how, int howlong, int power) {
int (*distfunc)(cell_t *, cell_t *);
cell_t *retcell[MAXRETCELLS];
int nretcells,i;
if (radius <= 0) return;
@ -8181,25 +8207,13 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {
} else {
distfunc = getcelldistorth;
}
for (y = c->y - radius ; y <= c->y + radius; y++) {
for (x = c->x - radius ; x <= c->x + radius; x++) {
c2 = getcellat(c->map, x, y);
if (c2 && (distfunc(c, c2) <= radius)) {
if (cellhaslos(c,c2)) {
makelit(c2, how,howlong);
}
}
getradiuscells(c, radius, DT_ORTH, B_FALSE, LOF_NEED, B_TRUE, retcell, &nretcells, 0);
for (i = 0; i < nretcells; i++) {
if (cellhaslos(c,retcell[i])) {
makelit(retcell[i], how,howlong, power);
}
}
// now setlos dirty for lfs who can see any of the cells.
// while makelit() does this as well, we need to do it
// again here because makelit also contains calls to "haslos",
// which clears lf->losdirty again. This is fine when we're only
// changing one cell's light level, but when changing multiple
// cells we need to go through again afterwards.
/*
if (gamemode == GM_GAMESTARTED) {
lifeform_t *lf;
for (lf = c->map->lf ; lf ; lf = lf->next) {
@ -8211,6 +8225,7 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {
}
}
}
*/
}
void markroomwalls(map_t *m, room_t *r) {
@ -8339,6 +8354,27 @@ void mapentereffects(map_t *m) {
}
}
void modillumination(map_t *m, int dir) {
int donesomething = B_FALSE;
if (dir > 0) {
if (m->illumination < IL_FULLDARK) {
m->illumination++;
donesomething = B_TRUE;
}
} else if (dir < 0) {
if (m->illumination > IL_FULLLIT) {
m->illumination--;
donesomething = B_TRUE;
}
}
if (donesomething) {
lifeform_t *lf;
for (lf = m->lf ; lf ; lf = lf->next) {
setlosdirty(lf);
}
}
}
void moveobtoclearcell(object_t *o) {
cell_t *c,*startcell;
startcell = getoblocation(o);

7
map.h
View File

@ -58,7 +58,7 @@ int getroomid(cell_t *c);
void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid, int includefixed);
enum TIMEPHASE gettimephase(void);
object_t *gettopobject(cell_t *where, int forglyph);
void calclight(map_t *map);
//void calclight(map_t *map);
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force, int stayclose);
int compassdir(int orthdir);
int countadjcellsoftype(cell_t *cell, enum CELLTYPE id, int dirtype);
@ -176,10 +176,11 @@ int linkholes(map_t *map);
object_t *linkportal(object_t *srcportal, int wantdepth);
int linkstairs(object_t *o, object_t *o2);
void makedoor(cell_t *cell, int openchance);
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
void makelit(cell_t *c, enum OBTYPE how, int howlong, int power);
void makelitradius(cell_t *c, int radius, enum OBTYPE how, int howlong, int power);
void markroomwalls(map_t *m, room_t *r);
void mapentereffects(map_t *m);
void modillumination(map_t *m, int dir);
void moveobtoclearcell(object_t *o);
int orthdir(int compassdir);
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum SUBJOB *wantsubjob, enum BEHAVIOUR *wantbehaviour);

16
move.c
View File

@ -1324,10 +1324,12 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (gamemode == GM_GAMESTARTED) {
// update light
/*
if ((isplayer(lf) && changedlev) || lfproduceslight(lf, NULL)) {
calclight(lf->cell->map);
setlosdirty(lf);
}
*/
//precalclos(lf);
if (isplayer(lf) || cansee(player, lf)) {
@ -1743,12 +1745,14 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
killflagsofid(lf->flags, F_DONEDARKMSG);
}
/*
// just moved into a dark area - announce it.
if (postdark && !predark && !lfhasflag(lf, F_DONEDARKMSG)) {
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;
}
*/
}
if (dontclearmsg) {
@ -3522,7 +3526,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
if (isplayer(lf)) {
statdirty = B_TRUE;
needredraw = B_TRUE;
calclight(lf->cell->map);
//calclight(lf->cell->map);
setlosdirty(lf);
//precalclos(lf);
drawscreen();
@ -3678,7 +3682,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
}
}
// look for avoided objects (because they are cursed).
// look for avoided objects (because they are cursed or otherwise).
for (o = cell->obpile->first ; o ; o = o->next) {
flag_t *f;
snprintf(buf, BUFLEN, "%ld",o->id);
@ -3694,6 +3698,14 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
}
}
if (isundead(lf)) {
f = hasflag(o->flags, F_PRODUCESLIGHT);
if (f && (f->val[0] >= gettr(lf))) {
if (error) *error = E_WONT;
return B_FALSE;
}
}
if (hasflag(o->flags, F_TRAP)) {
if (hasflag(o->flags, F_SECRET)) {
// hidden traps?

31
nexus.c
View File

@ -457,7 +457,8 @@ int main(int argc, char **argv) {
enteringmap = B_FALSE; // no time passes for lfs on a different map to the player.
// calculate initial light
calclight(player->cell->map);
//calclight(player->cell->map);
// pre-calc line-of-sight for player
//precalclos(player);
@ -503,7 +504,7 @@ int main(int argc, char **argv) {
gamemode = GM_GAMESTARTED;
// redo light and player los
calclight(player->cell->map);
//calclight(player->cell->map);
// make player face the direction which gives them the most visibility
// as we check, set all cells around us to start off known.
@ -805,11 +806,11 @@ void donextturn(map_t *map) {
startlfturn(who);
// calculate light
calclight(map);
//calclight(map);
// pre-calculate line of sight for this lifeform
//precalclos(who);
// cope with eyesight adjusting to the dark
do_eyesight_adjust(who);
//do_eyesight_adjust(who);
// update gun targets
autotarget(who);
@ -1968,13 +1969,13 @@ void timeeffectsworld(map_t *map, int updategametime) {
timeeffectsob(o);
} // end foreach object here
// expire light effects
/* // expire light effects
if (c->littimer > 0) {
c->littimer--;
if (c->littimer == 0) {
c->lit = c->origlit;
}
}
} */
// water/fire spreads...
if (doelementspread(c) && haslos(player, c)) {
@ -2045,7 +2046,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
flag_t *f;
if (h != prevhour) {
// if it's a new hour, announce the time.
// effects which occur at certain times.
if (godprayedto(R_GODLIFE)) {
if (h == 6) {
char text[BUFLEN];
@ -2068,7 +2069,23 @@ void timeeffectsworld(map_t *map, int updategametime) {
more();
}
}
// midnight
if (h == 0) {
cell_t *c;
// lunar gate appears in a random spot on the player's level
//c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
if (c) {
o = addobfast(c->obpile, OT_LUNARGATE);
if (o) {
// 60 turns is approximately 1 hour.
maketemporary(o, 60, "vanishes");
}
}
}
// if it's a new hour, announce the time.
f = lfhasflag(map->lf, F_KNOWSTIME);
if (f && !isasleep(map->lf) && !isblind(map->lf)) {
if (m <= 10) {

View File

@ -8264,6 +8264,14 @@ void makeknown(enum OBTYPE otid) {
}
}
void maketemporary(object_t *o, int howlong, char *obdietext) {
addflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_OBHP, howlong, howlong, NA, NULL);
addflag(o->flags, F_OBHPDRAIN, 1, DT_DIRECT, NA, NULL);
addflag(o->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_OBDIETEXT, B_TRUE, NA, NA, obdietext);
}
void maketried(enum OBTYPE otid, char *triedon) {
knowledge_t *k;
objecttype_t *ot;
@ -11296,7 +11304,12 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
}
break;
case OT_POT_POISON:
poison(lf, rnd(10,20), P_VENOM, 1, "a potion of poison", R_NONE);
if (isplayer(lf)) {
msg("^%cThis tastes like poison!", getlfcol(lf, CC_BAD));
}
if (poison(lf, rnd(10,20), P_VENOM, 1, "a potion of poison", R_NONE)) {
if (isplayer(lf)) msg("Luckily, it has no effect.");
}
break;
case OT_POT_POLYMORPH:
if (potblessed == B_BLESSED) {
@ -12227,12 +12240,14 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
cell_t *pos;
pos = getoblocation(src);
if (pos) {
calclight(pos->map);
//calclight(pos->map);
if (gamemode == GM_GAMESTARTED) {
setlosdirty(player);
if (haslos(player, pos)) {
setlosdirty(player);
}
//precalclos(player);
}
drawscreen();
//drawscreen();
}
}
@ -14176,9 +14191,9 @@ void timeeffectsob(object_t *o) {
glowflag = addtempflag(o->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL, FROMBLESSING);
if (haslos(player, ourcell)) {
if (!o->blessknown) o->blessknown = B_TRUE;
setlosdirty(player);
}
calclight(ourcell->map);
setlosdirty(player);
//calclight(ourcell->map);
//precalclos(player);
}
} else { // not near undead

View File

@ -242,6 +242,7 @@ lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level);
int makeduller(object_t *o, int howmuch);
void makehot(object_t *o, int howmuch, int howlong);
void makeknown(enum OBTYPE otid);
void maketemporary(object_t *o, int howlong, char *obdietext);
void maketried(enum OBTYPE otid, char *triedon);
void makewet(object_t *o, int amt);
void modifybetterwepdam(object_t *o, lifeform_t *owner, int *dam);

12
save.c
View File

@ -210,7 +210,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
fscanf(f, "sorted: %d\n",&l->sorted);
fscanf(f, "polyrevert: %d\n",&l->polyrevert);
fscanf(f, "forgettimer: %f\n",&l->forgettimer);
fscanf(f, "eyeadj: %d\n",&l->eyeadjustment);
//fscanf(f, "eyeadj: %d\n",&l->eyeadjustment);
fscanf(f, "facing: %d\n",&l->facing);
fscanf(f, "turncounter: %d\n",&l->turncounter);
fscanf(f, "rotated: %d\n",&l->rotated);
@ -388,8 +388,8 @@ map_t *loadmap(FILE *f) {
c = addcell(m, x, y);
// cell info
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
&roomid, &celltypeid, &c->known, &c->knowntime, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer,&c->locked, &temphab, &c->isroomwall);
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
&roomid, &celltypeid, &c->known, &c->knowntime, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->locked, &temphab, &c->isroomwall);
c->habitat = findhabitat(temphab);
c->room = findroom(m, roomid);
@ -975,7 +975,7 @@ int savelf(FILE *f, lifeform_t *l) {
fprintf(f, "sorted: %d\n",l->sorted);
fprintf(f, "polyrevert: %d\n",l->polyrevert);
fprintf(f, "forgettimer: %f\n",l->forgettimer);
fprintf(f, "eyeadj: %d\n",l->eyeadjustment);
//fprintf(f, "eyeadj: %d\n",l->eyeadjustment);
fprintf(f, "facing: %d\n",l->facing);
fprintf(f, "turncounter: %d\n",l->turncounter);
fprintf(f, "rotated: %d\n",l->rotated);
@ -1107,8 +1107,8 @@ int savemap(FILE *f, map_t *m) {
cell_t *c;
c = getcellat(m, x, y);
// cell info
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
c->room ? c->room->id : -1, c->type->id, c->known, c->knowntime, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer,c->locked, c->habitat->id, c->isroomwall );
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
c->room ? c->room->id : -1, c->type->id, c->known, c->knowntime, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->locked, c->habitat->id, c->isroomwall );
// cell objects
for (o = c->obpile->first ; o ; o = o->next) {
fprintf(f, "ob:%ld\n",o->id);

223
spell.c
View File

@ -544,7 +544,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
flag_t *awareness;
// process light sources for the other end (otherwise new
// maps will be dark by default and you might not see anything)
calclight(c->map);
//calclight(c->map);
// prevent announcement of the flag we're about to give
user->born = B_FALSE;
// temporarily give the player 360degree sight
@ -5594,24 +5594,22 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
} else if (spellid == OT_S_DARKNESS) {
int radius;
if (!targcell) targcell = caster->cell;
// centre on the caster
// create light objects
radius = power / 3;
limit(&radius, 1, NA);
makelitradius(targcell, radius, OT_MAGICDARK, rnd(5,10)+(power*2), power );
if (blessed || (power >= 5)) {
modillumination(targcell->map, D_DARKER);
}
if (haslos(player, targcell)) {
msg("A cloud of darkness descends!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
if (blessed) {
// permenant darkness
makelitradius(targcell, power*2, L_PERMDARK, -1);
} else {
// temporary darkness
makelitradius(targcell, power*2, L_PERMDARK, rnd(5,10) + power );
}
calclight(targcell->map);
if (targcell->map == player->cell->map) {
needredraw = B_TRUE;
drawscreen();
}
} else if (spellid == OT_S_DEATHKEEN) {
if (!isnighttime()) {
fizzle(caster);
@ -6078,6 +6076,62 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
} else if (spellid == OT_S_EXORCISE) {
if (!target) target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
if (lfhasflag(target, F_SUMMONEDBY) || (getraceclass(target) == RC_DEMON)) {
if (canexorcise(caster, target, power)) {
unsummon(target, B_TRUE);
} else {
if (isplayer(caster)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("^%c%s is too powerful for you to exorcise!", getlfcol(caster, CC_BAD), lfname);
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("%s resists the effects of an exorcism.", lfname);
}
}
} else {
if (isplayer(caster)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("%s seems unaffected.", lfname);
}
// this counts as a failure since you targetted the
// wrong kind of creature
return B_TRUE;
}
} else if (spellid == OT_S_EXORCISEMASS) {
int i,ndone = 0;
for (i = 1; i < caster->nlos; i++) {
cell_t *c;
c = caster->los[i];
if (c->lf &&
(lfhasflag(c->lf, F_SUMMONEDBY) || (getraceclass(c->lf) == RC_DEMON)) ) {
if (canexorcise(caster, c->lf, power)) {
unsummon(c->lf, B_TRUE);
ndone++;
} else {
if (!isplayer(caster) && cansee(player, target)) {
char lfname[BUFLEN];
getlfname(c->lf, lfname);
msg("%s resists the effects of an exorcism.", lfname);
}
}
}
}
if (ndone == 0) {
if (isplayer(caster)) {
msg("Your exorcism fails.");
}
return B_TRUE;
}
} else if (spellid == OT_S_EXPLODEMETAL) {
float totalmass = 0;
object_t *o, *nexto;
@ -9074,17 +9128,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
//newmap = findmapofdepth(newdepth);
// make both gates temporary
addflag(srcportal->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(srcportal->flags, F_OBHP, 6, 6, NA, NULL);
addflag(srcportal->flags, F_OBHPDRAIN, 1, DT_DIRECT, NA, NULL);
addflag(srcportal->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(srcportal->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
addflag(dstportal->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(dstportal->flags, F_OBHP, 6, 6, NA, NULL);
addflag(dstportal->flags, F_OBHPDRAIN, 1, DT_DIRECT, NA, NULL);
addflag(dstportal->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(dstportal->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
maketemporary(srcportal, 6, "vanishes");
maketemporary(dstportal, 6, "vanishes");
if (haslos(player, srccell)) {
char obname[BUFLEN];
@ -9294,10 +9339,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else if (spellid == OT_S_LIGHT) {
lifeform_t *l;
int radius;
// at power 3, you can control where the light appears
// at power 8, the light is permenant
// at power 8, increase illumination of entire map too!
if (power >= 3) {
// TODO: this actually means we can cast it through walls!!!
if (!validatespellcell(caster, &targcell,TT_NONE, spellid, power, frompot)) return B_TRUE;
@ -9305,64 +9350,36 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
targcell = caster->cell;
}
// create light objects
radius = power / 3;
limit(&radius, 1, NA);
makelitradius(targcell, radius, OT_MAGICLIGHT, rnd(5,10)+(power*2), power );
if (blessed || (power >= 5)) {
// permenant light
modillumination(targcell->map, D_LIGHTER);
}
if (haslos(player, targcell)) {
msg("The area is lit by a magical light!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
if (blessed || (power >= 8)) {
// permenant light
makelitradius(targcell, power*2, L_PERMLIGHT, -1);
} else {
// temporary light
makelitradius(targcell, power*2, L_PERMLIGHT, rnd(5,10)+(power*2) );
}
// blind anyone with nightvis who sees it
// (player last)
for (l = caster->cell->map->lf ; l ; l = l->next) {
if (!isplayer(l) && haslos(l, caster->cell)) {
if (power >= 5) {
if (lfhasflag(l, F_SEEINDARK)) {
// if you don't have eyes, your'e safe!
if (!lfhasflagval(l, F_NOBODYPART, BP_EYES, NA, NA, NULL)) {
// blind for 1-3 turns
addtempflag(l->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(3,5));
}
}
}
// undead will flee from light
if (isundead(l) && !skillcheck(l, SC_WILL, 100, 0)) {
// runs away from caster
addtempflag(l->flags, F_FLEEFROM, caster->id, NA, NA, NULL, 20);
}
if (targcell->lf) {
// undead will flee from light
if (isundead(targcell->lf) && !skillcheck(targcell->lf, SC_WILL, 100, 0)) {
// runs away from this cell
addtempflag(targcell->lf->flags, F_FLEEFROM, caster->id, NA, NA, NULL, 15+power);
}
}
if (isplayer(caster) || cansee(player, caster)) {
if (lfhasflag(player, F_SEEINDARK)) {
msg("The light burns your vision-enhanced eyes!");
// blind for 5-10 turns
addtempflag(player->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(5,10));
}
}
// anyone there glows if the spell was controlled
if (targcell->lf && (power >= 3)) {
if (power >= 8) {
// permenant!
addflag(targcell->lf->flags, F_PRODUCESLIGHT, B_TRUE, NA, NA, NULL);
} else {
addtempflag(targcell->lf->flags, F_PRODUCESLIGHT, B_TRUE, NA, NA, NULL, rnd(10,20)+(power*2) );
}
}
calclight(targcell->map);
//calclight(targcell->map);
/*
if (targcell->map == player->cell->map) {
needredraw = B_TRUE;
drawscreen();
}
*/
} else if (spellid == OT_S_LIGHTNINGBOLT) {
cell_t *retcell[MAXRETCELLS];
int nretcells;
@ -11941,7 +11958,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
successrate = power*10;
if (caster->race->raceclass->id == RC_DEMON) {
friendly = B_TRUE;
} else if (onein(4)) {
} else if (onein(3)) {
friendly = B_FALSE;
} else {
friendly = B_TRUE;
@ -13378,13 +13395,14 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf, int forcepowe
// note: doesn't matter if the lf doesn't actually have f_cancast / f_canwill,
// in this case the function will return the POTENTIAL power.
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
int power = 0;
int power = 0,willpower = 0, castpower = 0;
int spelllev;
enum SKILLLEVEL schoolskill;
enum SPELLSCHOOL school;
int db = B_FALSE;
int boost;
flag_t *f;
flag_t *willflag,*castflag;
char whatfrom[BUFLENSMALL];
if (db) {
objecttype_t *ot;
@ -13398,31 +13416,40 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
// CAN WE CAST THIS AT ALL
////////////////////////////////////
// If we can will/cast this then we might have a set
// spellpower
f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
if (f && strlen(f->text)) {
texttospellopts(f->text, "pw:", &power, NULL );
if (power > 0) {
if (db) {
dblog("-->power = %d (from canwill)", power);
}
// note that this power _can_ override max spell power
power += boost;
return power;
// spellpower. if we both will _and_ cast this,
// then use whatever power is higher.
strcpy(whatfrom, "");
willflag = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
if (willflag && strlen(willflag->text)) {
texttospellopts(willflag->text, "pw:", &willpower, NULL );
}
castflag = lfhasflagval(lf, F_CANCAST, spellid, NA, NA, NULL);
if (castflag && strlen(castflag->text)) {
texttospellopts(castflag->text, "pw:", &castpower, NULL );
}
if ((willpower > 0) && (castpower > 0)) {
if (castpower > willpower) {
power = castpower;
strcpy(whatfrom, "cancast");
} else {
power = willpower;
strcpy(whatfrom, "canwill");
}
} else {
f = lfhasflagval(lf, F_CANCAST, spellid, NA, NA, NULL);
if (f && strlen(f->text)) {
texttospellopts(f->text, "pw:", &power, NULL );
if (power > 0) {
if (db) {
dblog("-->power = %d (from cancast)", power);
}
// note that this power _can_ override max spell power
power += boost;
return power;
}
} else if (willpower > 0) {
power = willpower;
strcpy(whatfrom, "canwill");
} else if (castpower > 0) {
power = castpower;
strcpy(whatfrom, "cancast");
}
if (strlen(whatfrom)) {
if (db) {
dblog("-->power = %d (from %s)", power, whatfrom);
}
// note that this power _can_ override max spell power
power += boost;
return power;
}
// get spell details