diff --git a/ai.c b/ai.c index 4e8e78e..e6625cb 100644 --- a/ai.c +++ b/ai.c @@ -197,8 +197,27 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) { } if (ok) { - poss[nposs] = f->val[0]; - nposs++; + // lycanthropes always change to animal form at midnight. + if (gettimephase() == TP_MIDNIGHT) { + if ((f->val[0] == OT_S_SHAPESHIFT) && + lfhasflag(lf, F_LYCANTHROPE)) { + if (ispolymorphed(lf)) { + // never change to human form. + ok = B_FALSE; + } else { + // always change to animal form. + // note: this should have already happened though, + // during donextturn(); + return f->val[0]; + } + } + } + + // still ok? + if (ok) { + poss[nposs] = f->val[0]; + nposs++; + } } } } diff --git a/attack.c b/attack.c index df2c1ae..71536a7 100644 --- a/attack.c +++ b/attack.c @@ -1471,7 +1471,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (cansee(player, lf) || cansee(player, victim)) { char wepname[BUFLEN]; real_getobname(wep, wepname, 1, B_PREMODS, B_NOCONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL); - msg("^%c%s%s %s %s to %s!", getlfcol(lf, CC_BAD), + msg("^%d%s%s %s %s to %s!", getlfcol(lf, CC_BAD), attackername, getpossessive(attackername), noprefix(wepname), (wep->amt == 1) ? "sticks" : "stick", victimname); } @@ -1542,9 +1542,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (fumble) { if (wep && !isunarmed) { if (isplayer(lf)) { - msg("^%cYou fumble your attack!", getlfcol(lf, CC_BAD)); + msg("^%dYou fumble your attack!", getlfcol(lf, CC_BAD)); } else if (cansee(player, lf)) { - msg("^%c%s fumbles its attack!", getlfcol(lf, CC_BAD), attackername); + msg("^%d%s fumbles its attack!", getlfcol(lf, CC_BAD), attackername); } drop(wep, ALL); wep = NULL; @@ -2006,7 +2006,7 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da if (cansee(player, lf) || cansee(player, victim)) { char attname[BUFLEN]; getlfname(lf, attname); - msg("^%c%s%s %s %s to %s!", getlfcol(victim, CC_BAD), + msg("^%d%s%s %s %s to %s!", getlfcol(victim, CC_BAD), victimname, getpossessive(victimname), noprefix(shname), (shield[i]->amt == 1) ? "sticks" : "stick", attname); } @@ -2073,7 +2073,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, objec } else { strcpy(lfname, "Something"); } - msg("^%c%s slice%s off %s%s %s!", getlfcol(victim, CC_VBAD), + msg("^%d%s slice%s off %s%s %s!", getlfcol(victim, CC_VBAD), lfname, isplayer(lf) ? "" : "s", vname, getpossessive(vname), bpname); } // take extra damage based on number of severable limbs diff --git a/data.c b/data.c index 25afcce..4870940 100644 --- a/data.c +++ b/data.c @@ -529,12 +529,13 @@ void initjobs(void) { // 2: body control - low metabolism addflag(lastjob->flags, F_LEVSPELL, 3, OT_S_LOWERMETAB, NA, NULL); // 4: self-healing (mp), immune to haste/slow (innate) - addflag(lastjob->flags, F_LEVFLAG, 4, F_DISEASEIMMUNE, B_TRUE, NULL); - addflag(lastjob->flags, F_LEVABIL, 5, OT_A_FLURRY, NA, "pw:1;"); + addflag(lastjob->flags, F_LEVABIL, 4, OT_A_FLURRY, NA, "pw:1;"); + addflag(lastjob->flags, F_LEVFLAG, 5, F_DISEASEIMMUNE, B_TRUE, NULL); // 6: waterawlk via 'body equilibrium' (innate) - addflag(lastjob->flags, F_LEVFLAG, 7, F_TREMORSENSE, NA, NULL); + addflag(lastjob->flags, F_LEVABIL, 6, OT_A_AIMEDSTRIKE, NA, NULL); + // 7: iron fist - converts all remaining stamina to damage+knockback. // 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate) - addflag(lastjob->flags, F_LEVABIL, 8, OT_A_AIMEDSTRIKE, NA, NULL); + addflag(lastjob->flags, F_LEVFLAG, 8, F_TREMORSENSE, NA, NULL); // 9: resistance to charm, hypnosis, sleep (innate) addflag(lastjob->flags, F_LEVFLAG, 10, F_DTIMMUNE, DT_POISON, NULL); addflag(lastjob->flags, F_LEVSPELL, 11, OT_S_PSYARMOUR, NA, NULL); @@ -1772,6 +1773,7 @@ void initobjects(void) { addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "hut's door"); addflag(lastot->flags, F_OPPOSITESTAIRS, OT_BYHUTDOOR, NA, NA, NULL); killflagsofid(lastot->flags, F_SHOP); + killflagsofid(lastot->flags, F_OPERABLE); // the exit to baba yaga's hut addot(OT_BYHUTDOOR, "hut's doorway", "The front door of Baba Yaga's hut.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE); @@ -6704,7 +6706,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SHOULDERS, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_COLD, NA, NULL); addflag(lastot->flags, F_HELPSREST, 5, NA, NA, NULL); @@ -6729,7 +6731,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 15, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 60, NA, NA, NULL); @@ -6739,7 +6741,6 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 15, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 75, NA, NA, NULL); @@ -6748,7 +6749,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 15, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); @@ -6757,7 +6758,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 15, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 45, NA, NULL); @@ -6778,7 +6779,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 35, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 85, NA, NA, NULL); @@ -6786,7 +6787,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 0, 5, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_ELECTRIC, NA, NULL); @@ -6796,7 +6797,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_STABILITY, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 35, NA, NULL); @@ -6806,7 +6807,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 35, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); @@ -6852,14 +6853,14 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); addot(OT_PIRATEHAT, "tricorne", "A three cornered hat with a skull and crossbones emblem.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); @@ -6877,7 +6878,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); @@ -6885,7 +6886,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); @@ -6903,14 +6904,14 @@ void initobjects(void) { addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_HELMFOOTBALL, "football helmet", "A metal helmet with a grill in front of the face.", MT_METAL, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -1, NA, NULL); @@ -13980,7 +13981,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); @@ -14008,8 +14009,8 @@ void initrace(void) { addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_STING, 6, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_STING, 4, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:1d6;"); addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:3d3;needgrab:1;"); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); @@ -16545,6 +16546,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); + addflag(lastrace->flags, F_REVIVETIMER, 0, 50, R_LINGPARASITE, "starts moving!"); addrace(R_LINGREAPER, "ling reaper", 65, 'N', C_RED, MT_FLESH, RC_DEMON, "An evil demonic creature, covered in spikes and the bright red blood of its victims."); setbodytype(lastrace, BT_HUMANOID); diff --git a/data/hiscores.db b/data/hiscores.db index a0fbcdf..fa53271 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index dcbe787..2c72ffb 100644 --- a/defs.h +++ b/defs.h @@ -339,6 +339,22 @@ #define MAXDIR_MAP 15 +enum TIMEPHASE { + TP_SUNRISE, // 6am - 6:59 + TP_MORNING, // 7am - 9:59 + TP_MORNINGLATE, // 10 - 12 + TP_NOON, // 12:00 - 12:59 + TP_AFTERNOON, // 1pm - 4:59 + TP_DUSK, // 5pm - 5:59 + TP_SUNSET, // 6pm - 6:59 + TP_EVENING, // 7pm - 9:59, also 'dusk' + TP_NIGHT, // 10pm - 11:59 + TP_MIDNIGHT, // 0:00 - 00:59 + TP_NIGHTLATE, // 1am - 3:59 + TP_DAWN, // 4am - 4:59 + TP_TWILIGHTMORN, // 5am - 5:59 +}; + enum BEHAVIOUR { BH_NONE = 0, BH_INSANE, @@ -3160,6 +3176,7 @@ enum FLAG { F_EXTRACORPSE, // text field specifies what additional corpse // obtype to leave // v0 = pct change for this to happen. NA = 100. + F_CORPSELF, // v0 = race of lf to create when this lf dies. F_LIFEOB, // v0 = obtype of life object // OR // text field contains obid of life object @@ -3435,7 +3452,7 @@ enum FLAG { F_HUMANOID, // this race is a humanoid // (can wear armour / use weapons) F_INSECT, // this race is classed as an insect - F_LYCANTHROPE, // this race is a lycanthrope + F_LYCANTHROPE, // this race is a lycanthrope. text = what to turn into. F_UNDEAD, // this race is classed as undead F_COLDBLOOD, // this race is coldblooded F_NOBODYPART, // this race doesn't have bodypart val0 diff --git a/god.c b/god.c index 306c226..57804a4 100644 --- a/god.c +++ b/god.c @@ -1327,6 +1327,11 @@ int godgiftmaybe(enum RACE rid, int fromtemple) { o = addob(player->cell->obpile, obtogive); if (o) { char buf[BUFLEN]; + // make sure armour fits + if (hasflag(o->flags, F_MULTISIZE)) { + resizeobject(o, getlfsize(player)); + } + addflag(o->flags, F_GODGIFT, god->race->id, NA, NA, NULL); if (haslos(player, player->cell)) { getobname(o, buf, o->amt); @@ -1777,14 +1782,21 @@ int prayto(lifeform_t *lf, lifeform_t *god) { switch (god->race->id) { lifeform_t *l; + int dist; int donesomething = B_FALSE,n; cell_t *c; object_t *o; case R_GODBATTLE: - if (isinbattle(player, B_INCLUDEDISTANT, B_FALSE)) { + dist = isinbattle(player, B_INCLUDEDISTANT, B_FALSE); + if (dist) { int redo = B_TRUE; object_t *o; + // knock back nearby enemies + if (dist == 1) { + dospelleffects(god, OT_S_FORCESPHERE, 6, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL); + } + if (getstamina(player) <= pctof(25, getmaxstamina(player))) { setstamina(player, getmaxstamina(player)); msg("\"Time for your second wind!\""); diff --git a/io.c b/io.c index 463b43b..39c5759 100644 --- a/io.c +++ b/io.c @@ -12791,6 +12791,25 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } + // if the PLAYER knows the time... + if (lfhasflag(player, F_KNOWSTIME)) { + enum TIMEPHASE tp; + tp = gettimephase(); + if ((tp == TP_TWILIGHTMORN) || (tp == TP_SUNRISE)) { + if (getskill(lf, SK_SS_LIFE)) { + mvwprintw(mainwin, y, 0, "The power of %s Life magic is currently boosted because it is %s.", + your(lf), gettimephasename(tp)); + y++; + } + } else if (tp == TP_MIDNIGHT) { + if (getskill(lf, SK_SS_DEATH)) { + mvwprintw(mainwin, y, 0, "The power of %s Death magic is currently boosted because it is %s.", + your(lf), gettimephasename(tp)); + y++; + } + } + } + if (lfhasflag(lf, F_CANCAST)) { int chance; chance = getmiscastchance(lf); diff --git a/lf.c b/lf.c index c9c0dc1..7afa64d 100644 --- a/lf.c +++ b/lf.c @@ -1866,6 +1866,24 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar tempboost += retflag[i]->val[0]; killflag(retflag[i]); } + + // boost based on time? + switch (gettimephase()) { + case TP_MIDNIGHT: + if (hasflagval(sp->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL)) { + tempboost += 3; + } + break; + case TP_TWILIGHTMORN: + case TP_SUNRISE: + if (hasflagval(sp->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL)) { + tempboost += 3; + } + break; + default: + break; + } + if (tempboost) { power += tempboost; if (isplayer(lf)) { @@ -2384,7 +2402,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%cThe running water burns %s!", getlfcol(lf, CC_BAD), lfname); + msg("^%dThe running water burns %s!", getlfcol(lf, CC_BAD), lfname); } losehp(lf, roll("6d6"), DT_DIRECT, NULL, "running water"); } @@ -2406,7 +2424,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s drowns.",getlfcol(lf, CC_BAD) , lfname); + msg("^%d%s drowns.",getlfcol(lf, CC_BAD) , lfname); didsomething = B_TRUE; } addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); @@ -2423,7 +2441,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s is drowning!", getlfcol(lf, CC_VBAD), lfname); + msg("^%d%s is drowning!", getlfcol(lf, CC_VBAD), lfname); didsomething = B_TRUE; } getobnametruebase(o, obname, o->amt); @@ -2856,6 +2874,7 @@ void die(lifeform_t *lf) { int thisisplayer = B_FALSE; // for earthwyrms etc dividing enum RACE dividerace = R_NONE; + enum RACE createrace = R_NONE; cell_t *dividecell[2] = {NULL, NULL}; char dividename[BUFLEN]; int dividetr, dividehp; @@ -3184,14 +3203,14 @@ void die(lifeform_t *lf) { if (cansee(player, lf)) { getlfname(lf, buf); if (lf->lastdamtype == DT_EXPLOSIVE) { - msg("^%c%s is vaporised!",getlfcol(lf, CC_BAD), buf); + msg("^%d%s is vaporised!",getlfcol(lf, CC_BAD), buf); vaporised = B_TRUE; } else if (lf->lastdamtype == DT_MELT) { - msg("^%c%s completely melts.",getlfcol(lf, CC_BAD), buf); + msg("^%d%s completely melts.",getlfcol(lf, CC_BAD), buf); } else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) { - msg("^%c%s shatters!",getlfcol(lf, CC_BAD), buf); + msg("^%d%s shatters!",getlfcol(lf, CC_BAD), buf); } else { - msg("^%c%s dies.",getlfcol(lf, CC_BAD), buf); + msg("^%d%s dies.",getlfcol(lf, CC_BAD), buf); } } } @@ -3328,7 +3347,7 @@ void die(lifeform_t *lf) { if (isplayer(souleater)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%cYou consume %s%s soul!", getlfcol(souleater, CC_VGOOD), lfname, getpossessive(lfname)); + msg("^%dYou consume %s%s soul!", getlfcol(souleater, CC_VGOOD), lfname, getpossessive(lfname)); soulflag->known = B_TRUE; revealflagob(souleater, soulflag); @@ -3336,7 +3355,7 @@ void die(lifeform_t *lf) { char lfname[BUFLEN]; getlfname(lf, lfname); getlfname(souleater, buf); - msg("^%c%s consumes %s%s soul!", getlfcol(souleater, CC_VGOOD), buf, lfname, getpossessive(lfname)); + msg("^%d%s consumes %s%s soul!", getlfcol(souleater, CC_VGOOD), buf, lfname, getpossessive(lfname)); soulflag->known = B_TRUE; } amt = pctof( rnd(1,soulflag->val[0]), lf->maxhp); @@ -3524,7 +3543,11 @@ void die(lifeform_t *lf) { addob(corpsecell->obpile, f->text); } } - + // ...or even create new lfs when they die! + getflags(lf->flags, retflag, &nretflags, F_CORPSELF, F_NONE); + if (nretflags) { + createrace = retflag[rnd(0,nretflags-1)]->val[0]; + } } // splatter @@ -3646,8 +3669,15 @@ void die(lifeform_t *lf) { // IMPORTANT: DO NOT REFERENCE lf->xxxx AFTER THIS POINT // UNLESS WE ARE _SURE_ IT IS THE PLAYER (ie. thisisplayer = true) - - if (dividerace != R_NONE) { + if (createrace != R_NONE) { + lifeform_t *newlf; + newlf = addmonster(where, createrace, NULL, B_FALSE, 1, B_FALSE, NULL); + if (newlf) { + // no xp for killing + killflagsofid(newlf->flags, F_XPVAL); + addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL); + } + } else if (dividerace != R_NONE) { if (dividelos) { msg("^w%s divides!", dividename); } @@ -4322,6 +4352,7 @@ int eat(lifeform_t *lf, object_t *o) { corpserace = findrace(cf->val[0]); // special case if (lf->race->id == R_LINGPARASITE) { + lifeform_t *newlf; if (isplayer(lf)) { msg("You crawl inside %s.", obname); } else if (cansee(player, lf)) { @@ -4333,7 +4364,10 @@ int eat(lifeform_t *lf, object_t *o) { setlastdam(lf, "merging with a corpse"); lf->lastdamtype = DT_DIRECT; lf->hp = 0; - makezombie(o); + newlf = makezombie(o); + if (newlf) { + addflag(newlf->flags, F_CORPSELF, R_LINGPARASITE, NA, NA, NULL); + } return B_FALSE; } } @@ -7926,7 +7960,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { if (f) { if (f->val[0] != NA) acc += f->val[0]; } - } else { // ie. daytime + } else if (isdaytime()) { // ie. daytime f = lfhasflag(lf, F_DAYBOOST); if (f) { if (f->val[0] != NA) acc += f->val[0]; @@ -11735,7 +11769,7 @@ void growhydrahead(lifeform_t *lf, int announce) { getlfname(lf, vname); // regrow if (cansee(player, lf)) { - msg("^%c%s grow%s two more heads!", getlfcol(lf, CC_GOOD), vname, isplayer(lf) ? "" : "s"); + msg("^%d%s grow%s two more heads!", getlfcol(lf, CC_GOOD), vname, isplayer(lf) ? "" : "s"); } } @@ -12113,7 +12147,7 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR if (isplayer(lf)) { msg("^BYour brain is ruptured!"); } else if (cansee(player, lf)) { - msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); + msg("^%d%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); } if (lf->hp > 0) { setlastdam(lf, "a ruptured brain"); @@ -12170,7 +12204,7 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR if (isplayer(lf)) { msg("^BYour heart is pierced!"); } else if (cansee(player, lf)) { - msg("^%c%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); + msg("^%d%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); } if (lf->hp > 0) { setlastdam(lf, "a pierced heart"); @@ -13290,6 +13324,7 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp) { } +// returns distance to closest enemy. 0 = not in battle. int isinbattle(lifeform_t *lf, int includedistant, int onlyarmed) { if (includedistant) { lifeform_t *l; @@ -13297,7 +13332,7 @@ int isinbattle(lifeform_t *lf, int includedistant, int onlyarmed) { if ((l != lf) && areenemies(l, lf) && cansee(lf, l)) { if (!lfhasflag(l, F_DOESNTMOVE)) { if (!onlyarmed || getweapon(l)) { - return B_TRUE; + return getcelldist(lf->cell, l->cell); } } } @@ -13310,7 +13345,7 @@ int isinbattle(lifeform_t *lf, int includedistant, int onlyarmed) { if (c && c->lf && areenemies(lf, c->lf) && cansee(lf, c->lf)) { if (!lfhasflag(c->lf, F_DOESNTMOVE)) { if (!onlyarmed || getweapon(c->lf)) { - return B_TRUE; + return 1; } } } @@ -14423,7 +14458,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) { if (isplayer(lf) || cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s choke%s on %s!", getlfcol(lf, CC_BAD), lfname, isplayer(lf) ? "" : "s", buf); + msg("^%d%s choke%s on %s!", getlfcol(lf, CC_BAD), lfname, isplayer(lf) ? "" : "s", buf); } } else { if (isplayer(lf)) { @@ -14432,7 +14467,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) { char lfname[BUFLEN]; char buf2[BUFLEN]; getlfname(lf, lfname); - snprintf(buf2, BUFLEN, "^%c%s %ss %s!", getlfcol(lf, CC_BAD), buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname); + snprintf(buf2, BUFLEN, "^%d%s %ss %s!", getlfcol(lf, CC_BAD), buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname); msg("%s", buf2); } } @@ -16200,7 +16235,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { break; } } - msg("^%c%s %s %s!", getlfcol(lf, (amt > 0) ? CC_GOOD : CC_BAD), lfname, verb, adverb); + msg("^%d%s %s %s!", getlfcol(lf, (amt > 0) ? CC_GOOD : CC_BAD), lfname, verb, adverb); more(); } return B_FALSE; @@ -16288,7 +16323,7 @@ void modhunger(lifeform_t *lf, int amt) { char lfname[BUFLEN]; getlfname(lf, lfname); gethungername(lf, posthlev, buf); - msg("^%c%s looks %s%c", getlfcol(lf, CC_BAD), lfname, buf, (needexclam) ? '!' : '.'); + msg("^%d%s looks %s%c", getlfcol(lf, CC_BAD), lfname, buf, (needexclam) ? '!' : '.'); } if ((posthlev >= H_VHUNGRY) && (amt > 0)) { @@ -16956,11 +16991,11 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char // announce - announceflaggain won't be called // since this isn't a new flag. if (isplayer(lf)) { - msg("^%cYou feel more sick.", getlfcol(lf, CC_VBAD)); + msg("^%dYou feel more sick.", getlfcol(lf, CC_VBAD)); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s looks even more sick.", getlfcol(lf, CC_VBAD), lfname); + msg("^%d%s looks even more sick.", getlfcol(lf, CC_VBAD), lfname); } found = B_TRUE; @@ -17082,6 +17117,7 @@ int polymorphto(lifeform_t *lf, enum RACE rid, int howlong) { killflagsofid(lf->flags, F_POLYMORPHED); addtempflag(lf->flags, F_POLYMORPHED, B_TRUE, NA, NA, NULL, howlong); setrace(lf, rid, B_TRUE); + return B_FALSE; } @@ -18587,6 +18623,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { race_t *origrace = NULL; int nretflags; int reverting = B_FALSE; + lifeform_t *l; //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging newrace = findrace(rid); @@ -18959,10 +18996,14 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { while (lf->polypack->first) { moveob(lf->polypack->first, lf->pack, lf->polypack->first->amt); } - // in case something which affects our vision came out of ->polypack - setlosdirty(lf); } + // losdirty for anyone who sees it (including us again, + // in case something which affects our vision came out of + // or went in to ->polypack ) + for (l = lf->cell->map->lf ; l ; l = l->next) { + if (cansee(l, lf)) setlosdirty(l); + } //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging } @@ -19592,6 +19633,8 @@ void startlfturn(lifeform_t *lf) { int nretflags; int movedlastturn = B_FALSE; object_t *bloodamu = NULL; + enum TIMEPHASE tp; + tp = gettimephase(); map = lf->cell->map; @@ -19721,7 +19764,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s is suffocating!", getlfcol(lf, CC_VBAD), lfname); + msg("^%d%s is suffocating!", getlfcol(lf, CC_VBAD), lfname); } dam = lf->maxhp / 3; limit(&dam, 1, NA); @@ -19736,7 +19779,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%cThe sunlight burns %s!", getlfcol(lf, CC_BAD), lfname); + msg("^%dThe sunlight burns %s!", getlfcol(lf, CC_BAD), lfname); } losehp(lf, roll("6d6"), DT_DIRECT, NULL, "sunlight"); if (isdead(lf)) return; @@ -19790,6 +19833,11 @@ void startlfturn(lifeform_t *lf) { // regeneration sumflags(lf->flags, F_REGENERATES, &i, NULL, NULL); + if ((tp == TP_TWILIGHTMORN) || (tp == TP_SUNRISE)) { + if (isplayer(lf) && godprayedto(R_GODLIFE)) { + i += 1; + } + } if (i > 0) { // heal hp gainhp(lf, i); @@ -20521,7 +20569,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD), + msg("^%d%s%s spine snaps!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname)); } losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE); @@ -20556,7 +20604,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s shivers.", getlfcol(lf, CC_BAD), lfname); + msg("^%d%s shivers.", getlfcol(lf, CC_BAD), lfname); } wep = getweapon(lf); if (wep) { @@ -20604,7 +20652,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags"); + msg("^%d%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags"); } taketime(lf,getactspeed(lf)); @@ -20622,7 +20670,7 @@ void startlfturn(lifeform_t *lf) { } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("^%c%s melts a little.",getlfcol(lf, CC_BAD), lfname); + msg("^%d%s melts a little.",getlfcol(lf, CC_BAD), lfname); } } } @@ -20671,7 +20719,7 @@ void startlfturn(lifeform_t *lf) { getlfname(lf, lfname); getobname(bloodamu, obname, 1); getobname(o, bname, 1); - msg("^%c%s%s %s sucks up %s!", getlfcol(lf, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname), bname); + msg("^%d%s%s %s sucks up %s!", getlfcol(lf, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname), bname); makeknown(bloodamu->type->id); } } @@ -21104,9 +21152,9 @@ int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag) { if (op->owner) { getlfname(op->owner, targname); if (isplayer(lf)) { - msg("^%cYou steal %s from %s!", getlfcol(op->owner, CC_BAD), obname, targname); + msg("^%dYou steal %s from %s!", getlfcol(op->owner, CC_BAD), obname, targname); } else if (cansee(player, lf)) { - msg("^%c%s steals %s from %s!", getlfcol(op->owner, CC_BAD), lfname, obname, targname); + msg("^%d%s steals %s from %s!", getlfcol(op->owner, CC_BAD), lfname, obname, targname); } } else { if (isplayer(lf)) { @@ -21156,7 +21204,7 @@ int stone(lifeform_t *lf) { addflag(lf->flags, F_CORPSETYPE, B_TRUE, NA, NA, statname); if (cansee(player, lf)) { - msg("^%c%s %s to stone!", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "turn" : "turns"); + msg("^%d%s %s to stone!", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "turn" : "turns"); } setlastdam(lf, "petrification"); lf->hp = 0; @@ -22462,7 +22510,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { if (isimmuneto(lf->flags, DT_FALL, B_FALSE)) { msg("%s lands gently on the ground.", lfname); } else { - msg("^%c%s slams into the ground!", getlfcol(lf, CC_BAD), lfname); + msg("^%d%s slams into the ground!", getlfcol(lf, CC_BAD), lfname); } } // how far did you fall? @@ -22493,7 +22541,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { if (isplayer(lf)) { msg("^bYou slam into the roof!"); } else if (cansee(player, lf)){ - msg("^%c%s slams into the roof!",getlfcol(lf, CC_BAD), lfname); + msg("^%d%s slams into the roof!",getlfcol(lf, CC_BAD), lfname); } // how far did you fall? sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL); @@ -23609,7 +23657,7 @@ int wear(lifeform_t *lf, object_t *o) { } } else if (o->type->id == OT_AMU_CHOKING) { if (isplayer(lf)) { - msg("^%c%s starts to constrict around your neck!", getlfcol(lf, CC_VBAD), obname); + msg("^%d%s starts to constrict around your neck!", getlfcol(lf, CC_VBAD), obname); makeknown(o->type->id); if (!needstobreath(lf)) { msg("Luckily, you don't need to breath."); diff --git a/map.c b/map.c index 3b5f239..1ffca46 100644 --- a/map.c +++ b/map.c @@ -6090,8 +6090,12 @@ void finalisemap(map_t *map, object_t *entryob, int exitdir) { enum OBTYPE wantoid; if (exitdir == D_DOWN) { wantoid = upstairtype; - } else { + } else if (exitdir == D_UP) { wantoid = downstairtype; + } else { + objecttype_t *ot; + ot = getoppositestairs(entryob->type); + wantoid = ot->id; } for (y = 0; (y < map->h) && !linkedentry; y++) { for (x = 0; (x < map->w) && !linkedentry; x++) { @@ -7673,15 +7677,65 @@ int isnewcellok(cell_t *cell, char *err) { return B_TRUE; } + +enum TIMEPHASE gettimephase(void) { + int h,m,s; + splittime(&h, &m, &s); + if (h == 6) { + return TP_SUNRISE; + } else if ((h >= 7) && (h <= 9)) { + return TP_MORNING; + } else if ((h >= 10) && (h < 12)) { + return TP_MORNINGLATE; + } else if (h == 12) { + return TP_NOON; + } else if ((h > 12) && (h < 17)) { + return TP_AFTERNOON; + } else if (h == 17) { + return TP_DUSK; + } else if (h == 18) { + return TP_SUNSET; + } else if ((h >= 19) && (h < 22)) { + return TP_EVENING; + } else if ((h >= 22) && (h <= 23)) { + return TP_NIGHT; + } else if (h == 0) { + return TP_MIDNIGHT; + } else if ((h >= 1) && (h < 4)) { + return TP_NIGHTLATE; + } else if (h == 4) { + return TP_DAWN; + } + // ie. h == 5 + return TP_TWILIGHTMORN; +} + + + int isnighttime(void) { - int hours,mins,secs; - splittime(&hours,&mins,&secs); - if ((hours < 6) || (hours >= 20)) { - return B_TRUE; + switch (gettimephase()) { + case TP_NIGHT: + case TP_MIDNIGHT: + case TP_NIGHTLATE: + return B_TRUE; + default: break; } return B_FALSE; } +int isdaytime(void) { + switch (gettimephase()) { + case TP_MORNING: + case TP_MORNINGLATE: + case TP_NOON: + case TP_AFTERNOON: + return B_TRUE; + default: break; + } + return B_FALSE; +} + + int isonmap(map_t *map, int x, int y) { if ((x < 0) || (y < 0)) { return B_FALSE; diff --git a/map.h b/map.h index a574131..44bffe3 100644 --- a/map.h +++ b/map.h @@ -56,6 +56,7 @@ int getmapmaxvisrange(map_t *m); void getradiuscells(cell_t *centre, int radius, int dirtype, int outsideonly, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells, int scatterdensity); 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); int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force, int stayclose); @@ -157,6 +158,7 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph); int islit(cell_t *c); int isloopdirok(cell_t *cell, int dir); int isnewcellok(cell_t *cell, char *err); +int isdaytime(void); int isnighttime(void); int isonmap(map_t *map, int x, int y); int isoutdoors(map_t *m); diff --git a/move.c b/move.c index 398a334..40f966e 100644 --- a/move.c +++ b/move.c @@ -287,7 +287,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err for (o = cell->obpile->first ; o ; o = o->next) { if (wis >= AT_GTAVERAGE) { // don't walk onto crushable objects if you worship ekrub - if (isplayer(lf) && cancrush(lf, o) && !lfhasflag(lf, F_CAREFULMOVE)) { + if (isplayer(lf) && godprayedto(R_GODNATURE) && cancrush(lf, o) && !lfhasflag(lf, F_CAREFULMOVE)) { if (error) { *error = E_AVOIDOB; rdata = o; @@ -955,7 +955,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc } else { // ie door or object getobname(rdata, thing, 1); } - if (seen) msg("^%c%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing); + if (seen) msg("^%d%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing); snprintf(buf, BUFLEN, "slamming into %s", thing); // 1d6 dam per cell pushed dam = rolldie(howfar, 6); diff --git a/nexus.c b/nexus.c index f890fcc..ee170aa 100644 --- a/nexus.c +++ b/nexus.c @@ -109,6 +109,7 @@ long curtime = 0; // # current game clock (in seconds) long gamedays = 0; // # game days passed since start of game long gamesecs = 0; // # game seconds passed since start of game long timeleft = 0; // # secs remaining for which we need to process events +int prevhour = -1; // previous Hour extern int statdirty; @@ -775,6 +776,21 @@ void donextturn(map_t *map) { int donormalmove = B_TRUE; flag_t *f; + // lycanthrope in human form at midnight? + if (gettimephase() == TP_MIDNIGHT) { + flag_t *f; + f = lfhasflag(who, F_LYCANTHROPE); + if (f && !ispolymorphed(who)) { + race_t *r; + if (isplayer(who)) { + msg("You feel a change coming over your body!"); + } + r = findracebyname(f->text); + polymorphto(who, r->id, rnd(50,100)); + donormalmove = B_FALSE; + } + } + // charmed ? if (donormalmove) { f = lfhasflag(who, F_CHARMEDBY); @@ -1893,43 +1909,70 @@ void timeeffectsworld(map_t *map, int updategametime) { // if it's the player's turn, announce sun set/rise if (isplayer(map->lf)) { + int h,m,s; + splittime(&h, &m, &s); flag_t *f; - f = lfhasflag(map->lf, F_KNOWSTIME); - if (f) { - int h,m,s; - splittime(&h, &m, &s); - if (m <= 10) { - if (f->val[1] == B_TRUE) { - if (h == 6) { - msg("The sun is rising."); - } else if (h == 8) { - msg("It is now daytime."); - if (getskill(player, SK_LORE_UNDEAD) >= PR_ADEPT) { - real_warnabout("The undead will be less dangerous now.", 200, B_FALSE); - } - } else if (h == 12) { - msg("It is now Noon."); - } else if (h == 18) { - msg("The sun is setting."); - } else if (h == 20) { - msg("It is now nighttime."); - if (getskill(player, SK_LORE_UNDEAD) >= PR_ADEPT) { - real_warnabout("The undead will be more dangerous!", 200, B_FALSE); - } - } else if (h == 0) { - msg("It is now Midnight."); + + if (h != prevhour) { + // if it's a new hour, announce the time. + if (godprayedto(R_GODLIFE)) { + if (h == 6) { + char text[BUFLEN]; + switch (rnd(1,4)) { + case 1: sprintf(text, "The hour of Glorana's Peace is here."); break; + case 2: sprintf(text, "Mortal, rejoice in Glorana's Peace!"); break; + case 3: sprintf(text, "Now is the time of Glorana's Peace."); break; + case 4: sprintf(text, "Be healed my child - Glorana's Peace is upon you."); break; } - } else { - if ((h == 0) || (h == 12)) { - msg("It is now 12 o'clock."); - } else if ((h == 6) || (h == 18)) { - msg("It is now 6 o'clock."); - } else if ((h == 8) || (h == 20)) { - msg("It is now 8 o'clock."); + godsay(R_GODLIFE, B_TRUE, text); + more(); + } else if (h == 7) { + char text[BUFLEN]; + switch (rnd(1,3)) { + case 1: sprintf(text, "Glorana's Peace has come to an end for today."); break; + case 2: sprintf(text, "...and so ends Glorana's Peace."); break; + case 3: sprintf(text, "I declare Glorana's Peace ended."); break; + } + godsay(R_GODLIFE, B_TRUE, text); + more(); + } + } + + f = lfhasflag(map->lf, F_KNOWSTIME); + if (f && !isasleep(map->lf) && !isblind(map->lf)) { + if (m <= 10) { + enum TIMEPHASE tp; + tp = gettimephase(); + if (f->val[1] == B_TRUE) { + msg("It is now %d:%d (%s).", h, m, gettimephasename(tp)); + switch (tp) { + case TP_MORNING: + if (getskill(player, SK_LORE_UNDEAD) >= PR_ADEPT) { + real_warnabout("The undead will be less dangerous now.", 200, B_FALSE); + } + break; + case TP_NIGHT: + if (getskill(player, SK_LORE_UNDEAD) >= PR_ADEPT) { + real_warnabout("The undead will be more dangerous!", 200, B_FALSE); + } + break; + default: break; + } + } else { + int modh; + modh = h; + if (modh == 0) { + modh = 12; + } else if (modh > 12) { + modh -= 12; + } + + msg("It is now %d o'clock.", modh); } } } - } + } // end if h != prevhour + prevhour = h; } if (db) dblog("cur time is %ld\n",curtime); diff --git a/objects.c b/objects.c index 8e4de7d..86e37ba 100644 --- a/objects.c +++ b/objects.c @@ -501,6 +501,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum enum OBTYPE wantfountaintype = OT_NONE; enum LFSIZE wantarmsize = SZ_ANY; enum MATERIAL wantdiffmat = MT_NOTHING; + int minar = 0; // minimum AR for armour map_t *targetmap = NULL; // for portals cell_t *targetcell = NULL; // for portals int donesomething; @@ -839,6 +840,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum matchlfskills = player; } p += strlen("appropriate "); + // also make sure armour fits + if (matchlfskills) { + wantarmsize = getlfsize(matchlfskills); + } donesomething = B_TRUE; // weapon "goodness" } else if (strstarts(p, "average ")) { @@ -850,17 +855,20 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum if (onein(4)) wantblessed = B_BLESSED; p += strlen("good "); donesomething = B_TRUE; + limit(&minar, 1, NA); } else if (strstarts(p, "great ")) { wantgoodness = G_GREAT; if (onein(3)) wantblessed = B_BLESSED; if (onein(10)) dorandombrand = B_TRUE; p += strlen("great "); + limit(&minar, 2, NA); donesomething = B_TRUE; } else if (strstarts(p, "excellent ")) { wantgoodness = G_EXCELLENT; if (onein(2)) wantblessed = B_BLESSED; if (onein(4)) dorandombrand = B_TRUE; p += strlen("excellent "); + limit(&minar, 3, NA); donesomething = B_TRUE; // object names // brands @@ -1054,7 +1062,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum // want a specific rarity? rrtorarity(wantrarity, &minrarity, &maxrarity); - ot = getrandomobofclass(oc->id, minrarity, maxrarity, matchlfskills); + // want actual armour as opposed to clothing? + if ((oc->id == OC_ARMOUR) && strstr(p, "armour")) { + limit(&minar, 1, NA); + } + + ot = getrandomobofclass(oc->id, minrarity, maxrarity, matchlfskills, minar); if (ot) { found = B_TRUE; break; @@ -1070,11 +1083,11 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum // want a specific rarity? rrtorarity(wantrarity, &minrarity, &maxrarity); - ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL); + ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL, B_FALSE); if (ot) { // make sure it's not just a rock. while (!hasflag(ot->flags, F_GEM)) { - ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL); + ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL, B_FALSE); } found = B_TRUE; } @@ -1499,7 +1512,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE); // random potion type - ot = getrandomobofclass(OC_POTION, min, max, NULL); + ot = getrandomobofclass(OC_POTION, min, max, NULL, B_FALSE); if (ot) { f->val[0] = ot->id; } @@ -4484,7 +4497,7 @@ int getrandomgrimoirelev(void) { return wantlev; } -objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf) { +objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar) { objecttype_t *ot; int count = 0,sel,n; flag_t *f; @@ -4493,6 +4506,7 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) { int rarityok = B_FALSE; int skillok = B_FALSE; + int armourok = B_FALSE; // does rarity match? f = hasflag(ot->flags, F_RARITY); if (f) { @@ -4512,7 +4526,18 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity skillok = B_TRUE; } } else skillok = B_TRUE; - if (skillok && rarityok) { + + + // minar only applies if we're asking for armour + if (minar && (ocid == OC_ARMOUR)) { + flag_t *f; + f = hasflag(ot->flags, F_ARMOURRATING); + if (f && (f->val[0] > 0)) { + armourok = B_TRUE; + } + } else armourok = B_TRUE; + + if (skillok && rarityok && armourok) { count++; } } @@ -4528,6 +4553,7 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity if (f) { int rarityok = B_FALSE; int skillok = B_FALSE; + int armourok = B_FALSE; // does rarity match? f = hasflag(ot->flags, F_RARITY); if (f) { @@ -4547,7 +4573,16 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity skillok = B_TRUE; } } else skillok = B_TRUE; - if (skillok && rarityok) { + + if (minar) { + flag_t *f; + f = hasflag(ot->flags, F_ARMOURRATING); + if (f && (f->val[0] > 0)) { + armourok = B_TRUE; + } + } else armourok = B_TRUE; + + if (skillok && rarityok && armourok) { n++; if (n == sel) { return ot; @@ -11122,7 +11157,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } break; } - i = geteffecttime(5,15,potblessed); + i = geteffecttime(20,40,potblessed); if (!lfhasflagval(lf, F_INVULNERABLE, B_TRUE, NA, NA, NULL)) { addtempflag(lf->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL, i); @@ -13817,7 +13852,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp stuck = B_TRUE; if (cansee(player, target)) { if (thrower) { - msg("^%c%s sticks to %s!", getlfcol(thrower, CC_BAD), obname, targetname); + msg("^%d%s sticks to %s!", getlfcol(thrower, CC_BAD), obname, targetname); } else { msg("%s sticks to %s!", obname, targetname); } diff --git a/objects.h b/objects.h index 816e2c6..b65e406 100644 --- a/objects.h +++ b/objects.h @@ -103,7 +103,7 @@ object_t *getrandomammo(lifeform_t *lf); objecttype_t *getrandomammofor(object_t *o, int usefirst); brand_t *getrandombrandfor(objecttype_t *ot); int getrandomgrimoirelev(void); -objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf); +objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar); enum OBTYPE getrandomtrapforob(void); int getrustdampct(object_t *o); int getfirearmrange(object_t *o); diff --git a/spell.c b/spell.c index 5eac34c..faa5d88 100644 --- a/spell.c +++ b/spell.c @@ -5183,7 +5183,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_TRUE; } for (i = 0; i < power; i++) { - ot = getrandomobofclass(OC_FOOD, NA, NA, NULL); + ot = getrandomobofclass(OC_FOOD, NA, NA, NULL, B_FALSE); o = addobfast(targcell->obpile, ot->id); if (i == 0) { getobname(o, obname, o->amt); @@ -6395,13 +6395,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (isplayer(target)) { sprintf(buf, "You unleash a mighty shockwave!"); if (seenbyplayer) *seenbyplayer = B_TRUE; - animradial(caster->cell, radius, '}', C_RED, DT_COMPASS, buf, buf); + animradial(target->cell, radius, '}', C_RED, DT_COMPASS, buf, buf); } else if (cansee(player, target)) { char tname[BUFLEN]; getlfname(target, tname); sprintf(buf, "%s unleashes a mighty shockwave!", tname); if (seenbyplayer) *seenbyplayer = B_TRUE; - animradial(caster->cell, radius, '}', C_RED, DT_COMPASS, buf, buf); + animradial(target->cell, radius, '}', C_RED, DT_COMPASS, buf, buf); } // start at outside. for (n = radius; n >= 1; n--) { @@ -12814,6 +12814,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ for (i = 0; i < nretobs; i++) { char obname[BUFLEN]; o = retobs[i]; + // make sure armour fits + if (hasflag(o->flags, F_MULTISIZE)) { + resizeobject(o, getlfsize(target)); + } getobname(o, obname, o->amt); if (!hasflag(o->flags, F_IMPASSABLE) && canpickup(target, o, ALL)) { // you gain it. diff --git a/text.c b/text.c index 2e4a0cb..16410db 100644 --- a/text.c +++ b/text.c @@ -40,6 +40,11 @@ char *capitalise(char *text) { if (!(*p)) return text; // do nothing p++; // go past the colour char if (!(*p)) return text; // do nothing + while (*p && isdigit(*p)) { + p++; // go past any digits (in case this was ^12 rather than ^b) + } + if (!(*p)) return text; // do nothing + } *p = toupper(*p); } @@ -1647,6 +1652,25 @@ char *getschoolnameshort(enum SPELLSCHOOL sch) { return "unknown school"; } +char *gettimephasename(enum TIMEPHASE tp) { + switch (tp) { + case TP_SUNRISE: return "sunrise"; + case TP_MORNING: return "morning"; + case TP_MORNINGLATE: return "late morning"; + case TP_NOON: return "Noon"; + case TP_AFTERNOON: return "afternoon"; + case TP_DUSK: return "dusk"; + case TP_SUNSET: return "sunset"; + case TP_EVENING: return "evening"; + case TP_NIGHT: return "night"; + case TP_MIDNIGHT: return "Midnight"; + case TP_NIGHTLATE: return "late night"; + case TP_TWILIGHTMORN: return "morning twilight"; + case TP_DAWN: return "dawn"; + default: break; + } + return "unknown_timephase"; +} char *gettimetext(char *retbuf) { int hours,mins,secs; diff --git a/text.h b/text.h index e7bd5f0..659df71 100644 --- a/text.h +++ b/text.h @@ -40,6 +40,7 @@ char *getreldirname(int reldir); char *getsizetext(enum LFSIZE sz); char *getschoolname(enum SPELLSCHOOL sch); char *getschoolnameshort(enum SPELLSCHOOL sch); +char *gettimephasename(enum TIMEPHASE tp); char *gettimetext(char *retbuf); char *gettimetextfuzzy(char *retbuf, int wantpm); char *getwaterdepthname(enum DEPTH d);