diff --git a/ai.c b/ai.c index 955b100..ad22a21 100644 --- a/ai.c +++ b/ai.c @@ -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)) { diff --git a/attack.c b/attack.c index b092964..f463174 100644 --- a/attack.c +++ b/attack.c @@ -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); } } diff --git a/data.c b/data.c index 2694928..5046545 100644 --- a/data.c +++ b/data.c @@ -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); diff --git a/data/hiscores.db b/data/hiscores.db index a7b90a6..453fd69 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index 5f8234b..f77ee6d 100644 --- a/defs.h +++ b/defs.h @@ -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. diff --git a/flag.c b/flag.c index 2409a5a..cf425df 100644 --- a/flag.c +++ b/flag.c @@ -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; } diff --git a/god.c b/god.c index 0f1e3dd..c7b3a9b 100644 --- a/god.c +++ b/god.c @@ -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); + } } } } diff --git a/io.c b/io.c index e23fad7..a96d65b 100644 --- a/io.c +++ b/io.c @@ -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; diff --git a/lf.c b/lf.c index 97dedaf..32fc38b 100644 --- a/lf.c +++ b/lf.c @@ -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;idxnlos = 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) { @@ -21604,6 +21654,35 @@ void startlfturn(lifeform_t *lf) { if (f) { 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)) { @@ -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); diff --git a/lf.h b/lf.h index 1174264..3b80a09 100644 --- a/lf.h +++ b/lf.h @@ -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); diff --git a/map.c b/map.c index 07f8368..f2d1b24 100644 --- a/map.c +++ b/map.c @@ -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); diff --git a/map.h b/map.h index 0ad886a..bbe7ad0 100644 --- a/map.h +++ b/map.h @@ -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); diff --git a/move.c b/move.c index 7c8a28a..12440b4 100644 --- a/move.c +++ b/move.c @@ -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? diff --git a/nexus.c b/nexus.c index b1af291..ef8876a 100644 --- a/nexus.c +++ b/nexus.c @@ -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) { diff --git a/objects.c b/objects.c index 61005ff..64f2f7d 100644 --- a/objects.c +++ b/objects.c @@ -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 diff --git a/objects.h b/objects.h index 150ce04..2502b60 100644 --- a/objects.h +++ b/objects.h @@ -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); diff --git a/save.c b/save.c index 800dcbe..9752166 100644 --- a/save.c +++ b/save.c @@ -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); diff --git a/spell.c b/spell.c index 13e0e23..7d41f17 100644 --- a/spell.c +++ b/spell.c @@ -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