diff --git a/ai.c b/ai.c index ae29441..d799b44 100644 --- a/ai.c +++ b/ai.c @@ -1778,6 +1778,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) { specificcheckok = B_FALSE; } + if (ot->id == OT_A_DISARM) { + if (!getweapon(victim)) { + specificcheckok = B_FALSE; + } + } if ((ot->id == OT_S_DISPERSAL) && (lf->race->raceclass->id == RC_GOD)) { specificcheckok = B_FALSE; } @@ -1889,6 +1894,13 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG specificcheckok = B_FALSE; } } + + if ((ot->id == OT_A_TUMBLE) || (ot->id == OT_A_JUMP)) { + if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) || isairborne(lf)) { + specificcheckok = B_FALSE; + } + } + if ((ot->id == OT_S_WARPWOOD)) { specificcheckok = B_FALSE; if (victim) { diff --git a/attack.c b/attack.c index aa2a5ab..4f198c1 100644 --- a/attack.c +++ b/attack.c @@ -183,7 +183,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { // anyone there? if so just attack. if (c->lf) { - if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) { + if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT) && cansee(lf, c->lf)) { char ch; char victimname[BUFLEN]; char buf[BUFLEN]; @@ -718,19 +718,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // a little extra damage dam[0] = (int) ( (float)dam[0] * 1.25 ); } - // modify for strength - if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { - dam[0] = (int)((float)dam[0] * getstrdammod(lf)); - } - // modify for injuries - getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE); - for (i = 0; i < nretflags; i++) { - switch (retflag[i]->val[0]) { - case IJ_TORSOBRUISEDBAD: dam[0] = pctof(90, dam[0]); break; - } - } - + applylfdammod(&dam[0], lf, wep); // modify for size modifyforsize(&dam[0], lf, victim, 5, M_PCT); @@ -750,16 +739,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } - // extra damage for being skilled? - if (wepsk) { - slev = getskill(lf, wepsk->id); - if (slev > 1) { - float pctextra; - pctextra = ((slev - 1) * 10); - dam[0] += pctof(pctextra, dam[0]); - } - } - // target asleep? if (lfhasflag(victim, F_ASLEEP)) { dam[0] *= 2; @@ -862,7 +841,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // armour doesn't reduce damage for backstabs or critical hits. // BUT in the case of a critical hit, the armour might get // damaged during criticalhit() - if (!backstab && !critical) { + if (!backstab && !critical && ismeleedam(damtype[i])) { // modify for defender's armour reduceamt = getarmourdamreduction(victim, wep, dam[i], damtype[i]); @@ -1153,8 +1132,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } - // if victim was flying and took >= 25% of its hit points, it drops to the ground. - if (isphysicaldam(damtype[i]) && (dam[i] >= pctof(25, lf->maxhp))) { + // if victim was flying and took >= 40% of its hit points, it drops to the ground. + if (isphysicaldam(damtype[i]) && (dam[i] >= pctof(40, lf->maxhp))) { int willfall = B_FALSE,willinjure = B_FALSE,n; getflags(victim->flags, retflag, &nretflags, F_FLYING, F_LEVITATING, F_NONE); for (n = 0; n < nretflags; n++) { @@ -1439,6 +1418,7 @@ enum DAMTYPE basedamagetype(enum DAMTYPE dt) { void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) { object_t *o,*armour; + int protected = B_FALSE; char lfname[BUFLEN],victimname[BUFLEN],obname[BUFLEN]; // replace some dam types if (damtype == DT_UNARMED) damtype = DT_BASH; @@ -1473,17 +1453,10 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d } } if ((armour = getarmour(victim, BP_BODY)) != NULL) { - getobname(armour, obname, armour->amt); - if (isplayer(victim)) { - msg("Your %s protects you.", noprefix(obname)); - } else if (cansee(player, victim)) { - getlfname(victim, victimname); - msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname)); - } + protected = checkcritprotection(victim,armour); takedamage(armour, dam, damtype); - } else { - injure(victim, BP_BODY, damtype); - } + } + if (!protected) injure(victim, BP_BODY, damtype); break; case BP_HEAD: if (pctchance(80)) fall(victim, lf, B_TRUE); @@ -1519,17 +1492,10 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d break; case BP_HANDS: if ((armour = getarmour(victim, BP_HANDS)) != NULL) { - getobname(armour, obname, armour->amt); - if (isplayer(victim)) { - msg("Your %s protects you.", noprefix(obname)); - } else if (cansee(player, victim)) { - getlfname(victim, victimname); - msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname)); - } + protected = checkcritprotection(victim,armour); takedamage(armour, dam, damtype); - } else { - injure(victim, BP_HANDS, damtype); - } + } + if (!protected) injure(victim, BP_HANDS, damtype); if (onein(2)) { // drop your weapon! @@ -1557,27 +1523,20 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d } } else if (damtype == DT_SLASH) { if ((armour = getarmour(victim, hitpos)) != NULL) { - getobname(armour, obname, armour->amt); - if (isplayer(victim)) { - msg("Your %s protects you.", noprefix(obname)); - } else if (cansee(player, victim)) { - getlfname(victim, victimname); - msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname)); - } + protected = checkcritprotection(victim,armour); takedamage(armour, dam, damtype); - } else { - injure(victim, hitpos, damtype); - } + } + if (!protected) injure(victim, hitpos, damtype); } else if (damtype == DT_EXPLOSIVE) { if ((armour = getarmour(victim, hitpos)) != NULL) { int min,max; + protected = checkcritprotection(victim,armour); max = getobmaxhp(o); min = max / 2; limit(&min, 1, NA); takedamage(armour, rnd(min,max), DT_EXPLOSIVE); - } else { - injure(victim, hitpos, damtype); - } + } + if (!protected) injure(victim, hitpos, damtype); } if (lf) { @@ -2388,7 +2347,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { } victim = where->lf; - getflags(fp, retflag, &nretflags, F_DISARMATTACK, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_REVENGE, F_TRIPATTACK, F_NONE); + getflags(fp, retflag, &nretflags, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_REVENGE, F_NONE); for (i = 0; i < nretflags; i++) { f = retflag[i]; if (f->id == F_FLAMESTRIKE) { @@ -2443,53 +2402,6 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { } // end if dampct > 50 } } - } else if ((f->id == F_DISARMATTACK) && victim && owner && !isdead(victim)) { - object_t *victimwep; - skill_t *sk; - int skillmod; - - victimwep = getweapon(victim); - if (victimwep) { - sk = getobskill(wep); - if (sk) { - skillmod = getskill(owner, sk->id); - if (skillmod == 0) skillmod = -5; - } else { - skillmod = 0; - } - - if (skillcheckvs(owner, SC_DEX, skillmod, victim, SC_SLIP, 0)) { - char lfname[BUFLEN]; - char victimname[BUFLEN]; - getlfname(owner,lfname); - getlfname(victim, victimname); - if (cansee(player, owner)) { - msg("^w%s disarm%s %s!",lfname, isplayer(owner) ? "" : "s", victimname); - } - drop(victimwep, ALL); - } - } - } else if ((f->id == F_TRIPATTACK) && victim && owner && !isdead(victim)) { - int skillmod; - skill_t *sk; - sk = getobskill(wep); - if (sk) { - skillmod = getskill(owner, sk->id); - if (skillmod == 0) skillmod = -5; - } else { - skillmod = 0; - } - - if (skillcheckvs(owner, SC_DEX, skillmod, victim, SC_SLIP, 0)) { - char lfname[BUFLEN]; - char victimname[BUFLEN]; - getlfname(owner,lfname); - getlfname(victim, victimname); - if (cansee(player, owner)) { - msg("^w%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname); - } - fall(victim, NULL, B_TRUE); - } } else if ((f->id == F_HEAVYBLOW) && victim && owner) { int dir; // knock back victim diff --git a/data.c b/data.c index 81b4bb8..39b6ecf 100644 --- a/data.c +++ b/data.c @@ -129,7 +129,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather gloves"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "graph paper"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "magic map"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "a digital watch"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 blessed scrolls of create monster"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 blessed potions of experience"); @@ -273,6 +273,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_SS_NATURE, PR_NOVICE, NA, NULL); // learnable skills addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); @@ -310,9 +311,11 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_EXOTICWEPS, PR_NOVICE, NA, NULL); // learnable skills addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); @@ -383,6 +386,55 @@ void initjobs(void) { // abilities addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); + addjob(J_NINJA, "Ninja", "A dark warrior dedicated to the art of ninjutsu. Ninjas are skilled with long blades, and gain special martial arts abilities at higher levels."); + // stats + addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 1, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, -1, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, -1, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_CON, 1, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, -1, NA, NULL); + // initial objects + //addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "balaclava"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "katana"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "balaclava"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of leather shoes"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 shurikens"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 smoke grenades"); + // shuriken + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_EXOTICWEPS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_SKILLED, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_THROWING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_ARMOUR, PR_NOVICE, NA, NULL); // limit + addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); + // abilities + // gained abilities + addflag(lastjob->flags, F_LEVABIL, 2, OT_A_DISARMLF, NA, NULL); + addflag(lastjob->flags, F_LEVABIL, 4, OT_A_TRIPLF, NA, NULL); + addflag(lastjob->flags, F_LEVABIL, 6, OT_A_FLIP, NA, NULL); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); + + addjob(J_PRINCE, "Prince", "Princes have lived a life of leisure and privilege. Their time is generally spent either hunting (making them quite fit and skilled with a bow) or reading (giving them knowledge about the world around them). As they normally travel with a pack of bodyguards though, their weapons are more for show than actually useful."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, 4, NA, NULL); @@ -544,6 +596,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_AXES, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LONGBLADES, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL); @@ -1708,7 +1761,7 @@ void initobjects(void) { addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 84, RR_UNCOMMON, NULL); - addot(OT_GRAPHPAPER, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); + addot(OT_GRAPHPAPER, "magic map", "Paper containing a set of grid-lines, which automatically draws a map of its surroundings.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); @@ -3024,8 +3077,13 @@ void initobjects(void) { addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); - addot(OT_A_DISARM, "disarm", "Attempt to disable a known trap.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addot(OT_A_DISARM, "disable trap", "Attempt to disable a known trap.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_DISARMLF, "disarm", "Attempt to knock your opponent's weapon out of their hands.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); addot(OT_A_FEIGNDEATH, "feign death", "Pretend to be dead.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addot(OT_A_FLIP, "flip", "Flip your opponent over your head.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); @@ -3081,7 +3139,7 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances. This will quickly reduce your stamina.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL); @@ -3101,7 +3159,12 @@ void initobjects(void) { addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_A_TRAIN, "train skills", "Start training to gain a new experience level or enhance skill.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addot(OT_A_TRIPLF, "trip", "Attempt to trip your opponent over.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); + addot(OT_A_TRAIN, "training", "Start training to gain a new experience level or enhance skill.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addot(OT_A_TUMBLE, "tumble", "You can tumble across the ground.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); @@ -3239,7 +3302,7 @@ void initobjects(void) { addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit"); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, 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"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); @@ -3278,7 +3341,7 @@ void initobjects(void) { addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_RNDCHARGES, 200, 400, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 400, 700, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); @@ -3290,7 +3353,7 @@ void initobjects(void) { 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_RNDCHARGES, 300, 500, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 500, 900, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); @@ -3527,6 +3590,23 @@ void initobjects(void) { addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); + addot(OT_GRENADESMOKE, "smoke grenade", "A device which once activated, will explode into a cloud of smoke upon impact.", MT_METAL, 1, OC_TECH, SZ_TINY); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, 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_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CHARGES, 2, 2, NA, NULL); + addflag(lastot->flags, F_DONTSHOWCHARGES, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "cloud of smoke"); + addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "explodes"); + addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "explode"); + addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addot(OT_C4, "block of c4", "An extremely explosive plastic which explodes a medium time after activation.", MT_PLASTIC, 1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, RR_UNCOMMON, NULL); @@ -4248,6 +4328,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 33, NA, NA, NULL); addot(OT_ARMOURLEATHER, "leather armour", "Body armour created from soft leather.", MT_LEATHER, 10, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4255,6 +4336,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 95, NA, NA, NULL); addot(OT_ARMOURRING, "suit of ring mail", "Body armour formed by a series of metallic rings sewn to a leather foundation.", MT_METAL, 15, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4262,6 +4344,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 20, 20, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_ARMOURSCALE, "suit of scale armour", "Body armour consisting of many small scales attached to leather.", MT_METAL, 20, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4269,6 +4352,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 30, 30, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_OBHP, 35, 35, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_ARMOURCHAIN, "suit of chainmail", "Heavy body armour consisting of tightly meshed metal rings.", MT_METAL, 25, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4276,6 +4360,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 40, 40, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_OBHP, 45, 45, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_ARMOURSPLINT, "suit of splint mail", "Heavy armour, consisting of strips of metal attached to a leather backing.", MT_METAL, 35, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4283,6 +4368,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 50, 50, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 11, NA, NULL); addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_ARMOURPLATE, "suit of plate mail", "Heavy armour with embedded metal plates.", MT_METAL, 40, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_RARE, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); @@ -4290,6 +4376,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 60, 60, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_FLAKJACKET, "flak jacket", "Heavy metal body armour. Designed to stop a bullet, but ineffective against melee attacks.", MT_METAL, 30, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); @@ -4298,12 +4385,14 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_OVERALLS, "pair of overalls", "Well-made, brightly coloured workman overalls.", MT_CLOTH, 1, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 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_ATTREQ, A_AGI, 7, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 85, NA, NA, NULL); addot(OT_SILKSHIRT, "silk shirt", "A lightweight, comfortable white silk shirt.", MT_SILK, 0.5, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); @@ -4311,16 +4400,19 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 50, NA, NA, NULL); addot(OT_ROBE, "robe", "A plain robe.", MT_CLOTH, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 70, NA, NA, NULL); addot(OT_VELVETROBE, "velvet robe", "A luxurious velvet robe.", MT_CLOTH, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 75, NA, NA, NULL); // armour - shoulders addot(OT_CLOAK, "cloak", "A standard leather cloak.", MT_LEATHER, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); @@ -4344,6 +4436,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 60, NA, NA, NULL); addot(OT_RIDINGTROUSERS, "pair of riding trousers", "A fitted pair of leather trousers.", MT_LEATHER, 2, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4351,12 +4444,14 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 75, NA, NA, NULL); addot(OT_COMBATPANTS, "pair of combat pants", "An lightly-armoured pair of camoflauged trousers.", MT_CLOTH, 2, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); addot(OT_GREAVES, "set of greaves", "A set of heavy metal greaves.", MT_METAL, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); @@ -4365,6 +4460,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 15, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); // armour - feet addot(OT_SANDALS, "pair of sandals", "Comfortable pair of open leather sandals.", MT_LEATHER, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); @@ -4372,6 +4468,7 @@ void initobjects(void) { addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 30, NA, NA, NULL); addot(OT_SHOESLEATHER, "pair of leather shoes", "Cheap and rather uncomfortable leather shoes.", MT_LEATHER, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4379,6 +4476,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 7, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 85, NA, NA, NULL); addot(OT_BOOTSRUBBER, "pair of rubber boots", "A waterproof (but somewhat cumbersome) pair of rubber boots.", MT_RUBBER, 6, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); @@ -4387,6 +4485,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_ELECTRIC, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 95, NA, NA, NULL); addot(OT_BOOTSSPIKED, "pair of spiked boots", "A plain pair of leather boots with spikes on the bottom.", MT_LEATHER, 3, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); @@ -4394,6 +4493,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_STABILITY, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 7, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); addot(OT_BOOTSLEATHER, "pair of leather boots", "A stout pair of leather boots.", MT_LEATHER, 4, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4401,6 +4501,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 7, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); addot(OT_BOOTSMETAL, "pair of metal boots", "A strong pair of metal boots.", MT_METAL, 5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_RARE, NULL); @@ -4408,6 +4509,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 7, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); // armour - gloves addot(OT_GLOVESCLOTH, "pair of cloth gloves", "A pair of soft cloth gloves.", MT_CLOTH, 0.15, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); @@ -4416,12 +4518,14 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 70, NA, NA, NULL); addot(OT_GLOVESLEATHER, "pair of leather gloves", "A pair of coarse leather gloves.", MT_LEATHER, 0.25, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 90, NA, NA, NULL); addot(OT_GAUNTLETS, "pair of gauntlets", "A durable pair of metal gauntlets.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); @@ -4429,6 +4533,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 5, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 3, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); // armour - head addot(OT_SUNHAT, "sun hat", "Wide-brimmed hat made for working in the sun.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); @@ -4444,6 +4549,12 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addot(OT_BALACLAVA, "balaclava", "A form of cloth headgear that covers the whole head, exposing only the eyes.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); + addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4460,11 +4571,13 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 65, NA, NA, NULL); addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 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_OBHP, 20, 20, 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_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); @@ -4472,11 +4585,13 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -1, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_GOLDCROWN, "golden crown", "A heavy gold crown, encrusted with jewels.", MT_GOLD, 5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 25, RR_RARE, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 33, NA, NA, NULL); addot(OT_HELMBONE, "bone helmet", "Scary-looking helmet made from the bones of an animal (?).", MT_BONE, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); @@ -4484,6 +4599,7 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_POINTYHAT, "wizard hat", "A foot-long brimmed conical hat, inscribed with strange symbols.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); @@ -4491,6 +4607,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pointy hat"); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); // armour - ears addot(OT_EARPLUGS, "set of earplugs", "A pair of cloth plugs designed to give the wearer a peaceful night's sleep. ", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL); @@ -4508,6 +4625,7 @@ void initobjects(void) { 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_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_SPECTACLES, "pair of spectacles", "Eyewear with special lenses to enhance your vision.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4516,6 +4634,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_SUNGLASSES, "pair of sunglasses", "Tinted eyewear to protect against sunlight.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); @@ -4526,6 +4645,7 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_NIGHTVISRANGEMOD, -1, NA, NULL); addflag(lastot->flags, F_TINTED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); @@ -4533,7 +4653,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL); - + addflag(lastot->flags, F_CRITPROTECTION, 50, NA, NA, NULL); // armour - shields addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL); @@ -4744,6 +4864,12 @@ void initobjects(void) { addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); + addot(OT_TOUCHCHILL, "chilling touch", "chilling touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); + addflag(lastot->flags, F_DAM, DT_COLD, NA, NA, "1d1"); + addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); + addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); + addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addot(OT_TOUCHPARALYZE, "paralyzing touch", "paralyzing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_DAM, DT_TOUCH, NA, NA, "1d1"); @@ -4850,6 +4976,13 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); + addot(OT_SHURIKEN, "shuriken", "A sharpened star-shaped piece of metal, made for throwing.", MT_METAL, 1, OC_MISSILE, SZ_SMALL); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); + addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); + addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, ""); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); + addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); + addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL); // axes addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); @@ -4959,9 +5092,9 @@ void initobjects(void) { addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); - addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); - addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 10, NA, NULL); addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); @@ -5003,6 +5136,14 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL); + addot(OT_KATANA, "katana", "A long, finely balanced blade. Less raw power then a standard longsword, but its weight gives it a higher critical chance.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); + addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6"); + addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_AGI, 10, NA, NULL); + addflag(lastot->flags, F_CRITCHANCE, 10, NA, NA, NULL); + addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL); addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8"); @@ -5045,7 +5186,7 @@ void initobjects(void) { addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL); addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); - addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_TRIPLF, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4"); @@ -5057,7 +5198,7 @@ void initobjects(void) { addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL); - addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_TRIPLF, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+2"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); @@ -5076,7 +5217,7 @@ void initobjects(void) { addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL); addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); - addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "2d4"); @@ -5214,10 +5355,10 @@ void initobjects(void) { addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); - addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6+1"); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); - addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 10, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL); addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON, SZ_MEDIUM); @@ -5462,6 +5603,7 @@ void initrace(void) { // bonuses addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_VISRANGEMOD, 1, NA, NA, NULL); // penalties addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); @@ -7151,7 +7293,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT, "Razor sharp metallic grass with serrated edges. This plant sense vibrations in the air around it and slashes out with its sharp fronds."); + addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT, "Razor sharp metallic grass with serrated edges. This plant senses vibrations in the air around it and lashes out with its sharp fronds."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7454,7 +7596,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL, "Magical canines who can teleport small distances at will."); + addrace(R_DOGBLINK, "blink dog", 35, 'd', C_YELLOW, MT_FLESH, RC_ANIMAL, "Magical canines who can teleport small distances at will."); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 2, 4, NA, ""); @@ -8398,6 +8540,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, NA, NA, "1d4"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+2"); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -8798,6 +8941,7 @@ void initskills(void) { // weaponry addskill(SK_AXES, "Axes", "Helps you use chopping weapons like axes.", 50); addskill(SK_CLUBS, "Clubs", "Helps you use bashing weapons like maces or clubs.", 50); + addskill(SK_EXOTICWEPS, "Exotic Weapons", "Helps you use nunchaku, sais, etc.", 50); addskill(SK_LONGBLADES, "Long Blades", "Helps you use long swords, scimitars, etc.", 50); addskill(SK_POLEARMS, "Polearms", "Helps you use long bladed weapons like halberds.", 50); addskill(SK_SHORTBLADES, "Short Blades", "Helps you use daggers, short swords, etc.", 50); diff --git a/data/hiscores.db b/data/hiscores.db index 75df3b8..7734772 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index 2c309d1..0151ca6 100644 --- a/defs.h +++ b/defs.h @@ -458,6 +458,7 @@ enum SKILL { // weaponry SK_AXES, SK_CLUBS, + SK_EXOTICWEPS, SK_LONGBLADES, SK_POLEARMS, SK_SHORTBLADES, @@ -480,7 +481,7 @@ enum SKILL { SK_SS_TRANSLOCATION, SK_SS_WILD, }; -#define MAXSKILLS 52 +#define MAXSKILLS 53 // proficiency levels enum SKILLLEVEL { @@ -911,6 +912,7 @@ enum JOB { J_DRUID, J_MECHANIC, J_MONK, + J_NINJA, J_PIRATE, J_PRINCE, J_ROGUE, @@ -1288,7 +1290,8 @@ enum OBTYPE { OT_A_CHECKSTAIRS, OT_A_COOK, OT_A_DARKWALK, - OT_A_DISARM, + OT_A_DISARM, // disarm a trap + OT_A_DISARMLF, // disarm an opponent OT_A_FEIGNDEATH, OT_A_FLIP, OT_A_FLURRY, @@ -1307,6 +1310,7 @@ enum OBTYPE { OT_A_STINGACID, // need to define dam in f_canwill OT_A_SUCKBLOOD, OT_A_SWOOP, + OT_A_TRIPLF, // trip an opponent OT_A_EMPLOY, OT_A_HEAVYBLOW, OT_A_HIDE, @@ -1376,6 +1380,7 @@ enum OBTYPE { OT_C4, OT_FLASHBANG, OT_GRENADE, + OT_GRENADESMOKE, OT_MOTIONSCANNER, OT_NVGOGGLES, OT_STYPTIC, @@ -1483,6 +1488,7 @@ enum OBTYPE { OT_SUNHAT, OT_PIRATEHAT, OT_POINTYHAT, + OT_BALACLAVA, OT_CAP, OT_HELM, OT_GASMASK, @@ -1537,6 +1543,7 @@ enum OBTYPE { OT_ZAPPER, // monster weapons OT_ACIDATTACK, + OT_TOUCHCHILL, OT_TOUCHPARALYZE, OT_TOUCHPARALYZE2, // missiles / ammo @@ -1549,6 +1556,7 @@ enum OBTYPE { OT_JAVELIN, OT_BULLET, OT_RUBBERBULLET, + OT_SHURIKEN, // axes OT_AXE, OT_HANDAXE, @@ -1571,6 +1579,7 @@ enum OBTYPE { // long swords OT_FALCHION, OT_GREATSWORD, + OT_KATANA, OT_LONGSWORD, OT_ORNSWORD, OT_SCIMITAR, @@ -1982,14 +1991,13 @@ enum FLAG { //F_DAMTYPE, // val0 = damage type //F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod F_CRITCHANCE, // v0 = %chance of critical hit with this weapon + F_CRITPROTECTION, // v0 = %chance of preventing critical hits F_DAM, // v0 = damtype, text = 1d1+1 F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier) F_ACCURACY, // 100 - val0 = modify to tohit% (ie. higher is better) F_UNARMEDWEP, // this is not a real weapon, ie. claws, teeth etc F_ARMOURPIERCE, // goes through armour F_TWOHANDED, // weapon uses two hands to weild - F_TRIPATTACK, // weapon can trip the victim - F_DISARMATTACK, // weapon can disarm the victim // gun flags F_FIREARM, // this weapon is equipped in bp_secweapon, not _weapon. F_FIRESPEED, // how fast this weapon shoots projectiles @@ -2614,6 +2622,7 @@ enum INJURY { IJ_NONE, // bashing IJ_ANKLESWOLLEN, + IJ_HANDSWOLLEN, IJ_BLACKEYE, IJ_CONCUSSION, IJ_FINGERBROKEN, @@ -3051,6 +3060,7 @@ typedef struct lifeform_s { float stamina; int alive; char *lastdam; + char *killverb; struct material_s *material; enum DAMTYPE lastdamtype; diff --git a/god.c b/god.c index 6087500..9a7b5e5 100644 --- a/god.c +++ b/god.c @@ -257,7 +257,7 @@ void dooffer(void) { flag_t *retflag[MAXCANDIDATES]; int nretflags,pietyplus = 0; // which god? - god = askgod("To whom will you sacrifice?"); + god = askgod("To whom will you sacrifice?", B_TRUE); if (!god) { msg("Cancelled."); return; @@ -516,14 +516,23 @@ int godgiftmaybe(enum RACE rid) { flag_t *f; object_t *wep; rollagain = B_FALSE; - switch (rnd(1,5)) { + switch (rnd(1,6)) { case 1: - snprintf(obtogive, BUFLEN, "3-5 cursed potions of water"); + if (lfhasflag(player, F_SEEINDARK)) { + rollagain = B_TRUE; + } else { + msg("\"Henceforth the night shall be your ally!\""); + f = addtempflag(player->flags, F_SEEINDARK, 4, NA, NA, NULL, FROMGODGIFT); + f->obfrom = god->race->id; + } break; case 2: + snprintf(obtogive, BUFLEN, "3-5 cursed potions of water"); + break; + case 3: snprintf(obtogive, BUFLEN, "cursed branded weapon"); break; - case 3: // poison your weapon + case 4: // poison your weapon wep = getweapon(player); if (wep && canbepoisoned(wep->type->id)) { applyobmod(wep, findobmod(OM_POISONED)); @@ -532,7 +541,7 @@ int godgiftmaybe(enum RACE rid) { rollagain = B_TRUE; } break; - case 4: // resistant/immune to necrotic + case 5: // resistant/immune to necrotic if (lfhasflagval(player, F_DTRESIST, DT_NECROTIC, NA, NA, NULL)) { if (lfhasflagval(player, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL)) { rollagain = B_TRUE; @@ -545,7 +554,7 @@ int godgiftmaybe(enum RACE rid) { f->obfrom = god->race->id; } break; - case 5: + case 6: msg("\"Go forth and kill in my name!\""); setrace(player, R_VAMPIRE, B_TRUE); // ie. don't set origrace! break; @@ -820,7 +829,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { case R_GODDEATH: msg("\"Behold, the power of death!\""); for (l = lf->cell->map->lf ; l ; l = l->next) { - if ((l != lf) && lfhasflagval(l, F_TARGETLF, lf->id, NA, NA, NULL)) { + if ((l != lf) && haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL)) { if (isundead(l)) { makepeaceful(l); } else { diff --git a/io.c b/io.c index 5ffe10c..8994d89 100644 --- a/io.c +++ b/io.c @@ -2374,7 +2374,7 @@ int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname) { return B_TRUE; } -lifeform_t *askgod(char *prompttext) { +lifeform_t *askgod(char *prompttext, int onlyprayed) { lifeform_t *lf = NULL; int i; char *longdesc; @@ -2386,6 +2386,11 @@ lifeform_t *askgod(char *prompttext) { flag_t *f; char godof[BUFLEN],buf[BUFLEN]; lf = godlf[i]; + + if (onlyprayed && !lfhasflag(lf, F_PRAYEDTO)) { + continue; + } + real_getlfname(lf, buf, B_FALSE); f = hasflag(lf->flags, F_GODOF); snprintf(godof, BUFLEN, " (%s of %s)", (f->val[0] == B_FEMALE) ? "goddess" : "god", f->text); @@ -2398,8 +2403,15 @@ lifeform_t *askgod(char *prompttext) { free(longdesc); - getchoice(&prompt); - lf = (lifeform_t *)prompt.result; + if (prompt.nchoices == 0) { + msg("You are not worshipping any gods."); + return NULL; + } else if (prompt.nchoices == 1) { + lf = (lifeform_t *)prompt.choice[0].data; + } else { + getchoice(&prompt); + lf = (lifeform_t *)prompt.result; + } return lf; } @@ -3198,6 +3210,7 @@ void describegod(lifeform_t *god) { void describeob(object_t *o) { char buf[BIGBUFLEN]; char *buf2; + int x,y; cls(); // title @@ -3210,7 +3223,10 @@ void describeob(object_t *o) { buf2 = malloc(HUGEBUFLEN * sizeof(char)); makedesc_ob(o, buf2); - textwithcol(mainwin, buf2); + //textwithcol(mainwin, buf2); + x = 0; y = 2; + getyx(mainwin, y, x); + wrapprint(mainwin, &y, &x, "%s", buf2); free(buf2); wrefresh(mainwin); @@ -3882,7 +3898,7 @@ void doeat(obpile_t *op) { // edible objects here? for (o = player->cell->obpile->first; o ; o = o->next) { - if (caneat(player, o) && canpickup(player, o, 1)) { + if (caneat(player, o)) { getobname(o, obname, o->amt); snprintf(buf, BUFLEN, "There %s %s here. Eat %s", (o->amt == 1) ? "is" : "are", @@ -4654,16 +4670,6 @@ char *makedesc_ob(object_t *o, char *retbuf) { strncat(retbuf, buf, HUGEBUFLEN); } - f = hasflag(o->flags, F_DISARMATTACK); - if (f) { - sprintf(buf, " A skilled weilder can disarm opponents with it.\n"); - strncat(retbuf, buf, HUGEBUFLEN); - } - f = hasflag(o->flags, F_TRIPATTACK); - if (f) { - sprintf(buf, " A skilled weilder can trip opponents with it.\n"); - strncat(retbuf, buf, HUGEBUFLEN); - } f = hasflag(o->flags, F_ARMOURPIERCE); if (f && f->known) { sprintf(buf, " Armour will not reduce %s damage.\n",(o->amt == 1) ? "its" : "their"); @@ -4752,6 +4758,32 @@ char *makedesc_ob(object_t *o, char *retbuf) { } } + // critical protection chance + f = hasflag(o->flags, F_GOESON); + if (f) { + int critprotchance; + critprotchance = getcritprotection(o); + snprintf(buf, BUFLEN, "It has a %d%% chance of preventing critical hits to your %s", + critprotchance, getbodypartname(player, f->val[0])); + + if (compareob) { + int diff,comparechance = 0; + + comparechance = getcritprotection(compareob); + diff = critprotchance - comparechance; + if (diff == 0) { + strcpy(buf2, " (=)"); + } else { + // higher protchance is better + snprintf(buf2, BUFLEN, " %s(%c%d)^n", (diff > 0) ? "^g" : "^B", + (diff > 0) ? '+' : '-', abs(diff)); + } + strncat(buf, buf2, HUGEBUFLEN); + } + strcat(buf, ".\n"); + strncat(retbuf, buf, HUGEBUFLEN); + } + if (hasflag(o->flags, F_DAMAGABLE) && isarmour(o) ) { int showfullhp = B_FALSE; char hpbuf[BUFLEN]; @@ -5352,8 +5384,9 @@ char *makedesc_ob(object_t *o, char *retbuf) { strncat(retbuf, buf, HUGEBUFLEN); for (oo = o->contents->first ;oo ; oo = oo->next) { - getobname(oo, buf, oo->amt); - sprintf(buf, " - %s\n", buf); + char contentname[BUFLEN]; + getobname(oo, contentname, oo->amt); + sprintf(buf, " - %s\n", contentname); strncat(retbuf, buf, HUGEBUFLEN); } } @@ -5461,14 +5494,19 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) { strncat(retbuf, buf, BUFLEN); } - i = getmpcost(NULL, ot->id); - if (i > 0) { - if (hasflag(ot->flags, F_ONGOING)) { - sprintf(buf, "It takes %d MP to keep active - this is an ongoing cost.\n",i); - } else { - sprintf(buf, "It costs %d MP to cast.\n",i); - } + if (getmpcost(player, ot->id) == 0) { + sprintf(buf, "You can use this %s at will.\n", (ot->obclass->id == OC_ABILITY) ? "ability" : "spell"); strncat(retbuf, buf, BUFLEN); + } else { + i = getmpcost(NULL, ot->id); + if (i > 0) { + if (hasflag(ot->flags, F_ONGOING)) { + sprintf(buf, "It takes %d MP to keep active - this is an ongoing cost.\n",i); + } else { + sprintf(buf, "It costs %d MP to cast.\n",i); + } + strncat(retbuf, buf, BUFLEN); + } } f = hasflag(ot->flags, F_CASTINGTIME); @@ -6008,7 +6046,7 @@ void dohelp(char helpmode) { cls(); if (helpmode == '?') { initprompt(&prompt, "What would you like help with (ESC when done)?"); - addchoice(&prompt, '?', "Keyboard Commands", NULL, NULL, NULL); + addchoice(&prompt, 'k', "Keyboard Commands", NULL, NULL, NULL); addchoice(&prompt, 'r', "Race Descriptions", NULL, NULL, NULL); addchoice(&prompt, 's', "Skill Descriptions", NULL, NULL, NULL); addchoice(&prompt, 'g', "God Descriptions", NULL, NULL, NULL); @@ -6016,13 +6054,12 @@ void dohelp(char helpmode) { prompt.maycancel = B_TRUE; ch = getchoice(&prompt); switch (ch) { - case '?': - case 'g': - case 's': - helpmode = ch; + case '-': + case '\0': + done = B_TRUE; break; default: - done = B_TRUE; + helpmode = ch; break; } } else if (helpmode == 'c') { @@ -6082,7 +6119,7 @@ void dohelp(char helpmode) { centre(mainwin,C_WHITE, 0, "GOD REFERENCE"); y = 2; - god = askgod("Describe which god (ESC when done)?"); + god = askgod("Describe which god (ESC when done)?", B_FALSE); if (!god) { done = B_TRUE; } else { @@ -7152,9 +7189,11 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) { } if (strlen(prompt->choice[validchoice].longdesc)) { int dummy; + int x = 0; if (showall) y++; wmove(mainwin, y, 0); - textwithcol(mainwin, prompt->choice[validchoice].longdesc); + //textwithcol(mainwin, prompt->choice[validchoice].longdesc); + wrapprint(mainwin, &y, &x, "%s", prompt->choice[validchoice].longdesc); getyx(mainwin, descendy, dummy); // remember bottom of description } } else if (descendy != -1) { @@ -7392,12 +7431,13 @@ void handleinput(void) { // certain objects will stop us from running. for (o = player->cell->obpile->first ; o ; o = o->next) { - if (!hasflag(o->flags, F_NOPICKUP) || + if ( !hasflag(o->flags, F_NOPICKUP) || hasflag(o->flags, F_CLIMBABLE) ) { stopnow = B_TRUE; break; } } + if (countadjcellswithflag(player->cell, F_DOOR, DT_COMPASS)) { stopnow = B_TRUE; } @@ -8994,11 +9034,8 @@ void showlfstats(lifeform_t *lf, int showall) { mindam += bonus; maxdam += bonus; - // apply damage mod for strength - if (!hasflag(w[i]->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { - mindam = (int)((float)mindam * dammod); - maxdam = (int)((float)maxdam * dammod); - } + applylfdammod(&mindam, lf, w[i]); + applylfdammod(&maxdam, lf, w[i]); if (mindam < 0) mindam = 0; if (maxdam < 0) maxdam = 0; @@ -9141,7 +9178,7 @@ void showlfstats(lifeform_t *lf, int showall) { char hungerbar[11]; float pct; enum COLOUR col; - doheadingsmall(mainwin, y2, x2, ftext, "Hunger"); + doheadingsmall(mainwin, y2, x2, ftext, "Satiation"); // select colour for hungerbar // hunger can be from -(const*2) up to (const*5) @@ -9171,7 +9208,10 @@ void showlfstats(lifeform_t *lf, int showall) { } + ///////////////////////////////////////////////////////// // now show bottom information. + // NOTE: all text is wrapped, so make sure to end every bit of text with a space. + ///////////////////////////////////////////////////////// if (y2 > y) { y = y2 + 1; } @@ -9233,33 +9273,33 @@ void showlfstats(lifeform_t *lf, int showall) { if (hitstokillit == hitstokillyou) { if (hitstokillit) { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "You could both kill each other in %d hit%s.", hitstokillit, + wrapprint(mainwin, &y, &x, "You could both kill each other in %d hit%s. ", hitstokillit, (hitstokillit == 1) ? "" : "s"); unsetcol(mainwin, lorecol); } else { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "Neither of you would be able to kill the other."); + wrapprint(mainwin, &y, &x, "Neither of you would be able to kill the other. "); unsetcol(mainwin, lorecol); } } else { if (hitstokillit) { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "You could kill it in %d hit%s.", hitstokillit, + wrapprint(mainwin, &y, &x, "You could kill it in %d hit%s. ", hitstokillit, (hitstokillit == 1) ? "" : "s"); unsetcol(mainwin, lorecol); } else { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "You would never be able to kill it."); + wrapprint(mainwin, &y, &x, "You would never be able to kill it. "); unsetcol(mainwin, lorecol); } if (hitstokillyou) { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "It could kill you in %d hit%s.", hitstokillyou, + wrapprint(mainwin, &y, &x, "It could kill you in %d hit%s. ", hitstokillyou, (hitstokillyou == 1) ? "" : "s"); unsetcol(mainwin, lorecol); } else { setcol(mainwin, lorecol); - wrapprint(mainwin, &y, &x, "It would never be able to kill you."); + wrapprint(mainwin, &y, &x, "It would never be able to kill you. "); unsetcol(mainwin, lorecol); } } @@ -9287,7 +9327,7 @@ void showlfstats(lifeform_t *lf, int showall) { snprintf(buf, BUFLEN, "It is EXTREMELY dangerous to you."); } //mvwprintw(mainwin, y, 0, "Threat rating: %0.1f",comparelfs(player, lf)); - wrapprint(mainwin, &y, &x, "%s", buf); + wrapprint(mainwin, &y, &x, "%s ", buf); unsetcol(mainwin, lorecol); y++; } @@ -9306,7 +9346,7 @@ void showlfstats(lifeform_t *lf, int showall) { case ST_KO: strcpy(sleepname, "unconscious"); break; } - wrapprint(mainwin, &y, &x, "%s %s %s.", you(lf), is(lf), sleepname); + wrapprint(mainwin, &y, &x, "%s %s %s. ", you(lf), is(lf), sleepname); } f = lfhasknownflag(lf, F_ATTACHEDTO); if (f && (f->known)) { @@ -9319,27 +9359,27 @@ void showlfstats(lifeform_t *lf, int showall) { strcpy(grabeename, "something"); } snprintf(buf, BUFLEN,"%s %s attached to %s.",you(lf), is(lf), grabeename); - wrapprint(mainwin, &y, &x, buf); + wrapprint(mainwin, &y, &x, "%s ", buf); } f = lfhasknownflag(lf, F_FASTMETAB); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s metabolic rate has been increased.", your(lf), getpossessive(you(lf))); + wrapprint(mainwin, &y, &x, "%s metabolic rate has been increased. ", your(lf), getpossessive(you(lf))); } f = lfhasknownflag(lf, F_FEIGNINGDEATH); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s pretending to be dead.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s pretending to be dead. ", you(lf), is(lf)); } f = lfhasknownflag(lf, F_FLYING); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s flying.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s flying. ", you(lf), is(lf)); } f = lfhasknownflag(lf, F_PRONE); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s lying on the ground.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s lying on the ground. ", you(lf), is(lf)); } f = lfhasflag(lf, F_FROZEN); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s been turned to ice, and %s slowly melting.", you(lf), isplayer(lf) ? "have" : "has", + wrapprint(mainwin, &y, &x, "%s %s been turned to ice, and %s slowly melting. ", you(lf), isplayer(lf) ? "have" : "has", is(lf)); } f = lfhasknownflag(lf, F_GRABBEDBY); @@ -9353,7 +9393,7 @@ void showlfstats(lifeform_t *lf, int showall) { strcpy(grabbername, "something"); } snprintf(buf, BUFLEN,"%s %s being held by %s.",you(lf), is(lf), grabbername); - wrapprint(mainwin, &y, &x, buf); + wrapprint(mainwin, &y, &x, "%s ",buf); } f = lfhasknownflag(lf, F_GRABBING); if (f && (f->known)) { @@ -9366,11 +9406,11 @@ void showlfstats(lifeform_t *lf, int showall) { strcpy(grabeename, "something"); } snprintf(buf, BUFLEN,"%s %s holding on to %s.",you(lf), is(lf), grabeename); - wrapprint(mainwin, &y, &x, buf); + wrapprint(mainwin, &y, &x, "%s ", buf); } f = lfhasknownflag(lf, F_HIDING); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s hiding.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s hiding. ", you(lf), is(lf)); } getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE); for (i = 0; i < nretflags; i++) { @@ -9379,40 +9419,40 @@ void showlfstats(lifeform_t *lf, int showall) { f = retflag[i]; p = readuntil(injname, f->text, '^'); readuntil(injdesc, p, '^'); - wrapprint(mainwin, &y, &x, "^%c%s %s (%s).", getlfcol(lf, CC_VBAD), your(lf), injname, injdesc); + wrapprint(mainwin, &y, &x, "^%c%s %s (%s). ", getlfcol(lf, CC_VBAD), your(lf), injname, injdesc); } f = lfhasknownflag(lf, F_INVISIBLE); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s invisible.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s invisible. ", you(lf), is(lf)); } f = lfhasknownflag(lf, F_LEVITATING); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s levitating.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s levitating. ", you(lf), is(lf)); } f = lfhasflag(lf, F_NONCORPOREAL); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s %s noncorporeal and can walk through walls.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s noncorporeal and can walk through walls. ", you(lf), is(lf)); } f = lfhasflag(lf, F_PRODUCESLIGHT); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s produce%s light.", you(lf), isplayer(lf) ? "" : "s"); + wrapprint(mainwin, &y, &x, "%s produce%s light. ", you(lf), isplayer(lf) ? "" : "s"); } f = lfhasknownflag(lf, F_SLOWMETAB); if (f && (f->known)) { - wrapprint(mainwin, &y, &x, "%s metabolic rate has been decreased.", your(lf), getpossessive(you(lf))); + wrapprint(mainwin, &y, &x, "%s metabolic rate has been decreased. ", your(lf), getpossessive(you(lf))); } f = lfhasknownflag(lf, F_SPRINTING); if (f) { - wrapprint(mainwin, &y, &x, "%s %s sprinting.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s sprinting. ", you(lf), is(lf)); } if (!getstamina(lf)) { - wrapprint(mainwin, &y, &x, "%s %s exhausted.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s exhausted. ", you(lf), is(lf)); } f = lfhasknownflag(lf, F_UNDEAD); if (f) { - wrapprint(mainwin, &y, &x, "%s %s undead.", you(lf), is(lf)); + wrapprint(mainwin, &y, &x, "%s %s undead. ", you(lf), is(lf)); } // non-intrinsic effecst like polymorph, eye shading @@ -9423,11 +9463,11 @@ void showlfstats(lifeform_t *lf, int showall) { snprintf(buf2, BUFLEN, " [%d left]", f->lifetime); strcat(buf, buf2); // } - wrapprint(mainwin, &y, &x, "%s", buf); + wrapprint(mainwin, &y, &x, "%s ", buf); } if (!canuseweapons(lf)) { - wrapprint(mainwin, &y, &x, "%s cannot use weapons.", you(lf)); + wrapprint(mainwin, &y, &x, "%s cannot use weapons. ", you(lf)); } nmissingbp = 0; @@ -9472,16 +9512,16 @@ void showlfstats(lifeform_t *lf, int showall) { } } strcat(buf, "."); - wrapprint(mainwin, &y, &x, "%s", buf); + wrapprint(mainwin, &y, &x, "%s ", buf); } f = lfhasflag(lf, F_RETALIATE); if (f && (f->known)) { if (showall || (lorelev >= PR_BEGINNER)) { - wrapprint(mainwin, &y, &x, "%s %s covered by %s (%dd%d %s dmg to attackers).", you(lf), is(lf), f->text, + wrapprint(mainwin, &y, &x, "%s %s covered by %s (%dd%d %s dmg to attackers). ", you(lf), is(lf), f->text, f->val[0], f->val[1], getdamname(f->val[2])); } else { - wrapprint(mainwin, &y, &x, "%s %s covered by %s", you(lf), is(lf), f->text); + wrapprint(mainwin, &y, &x, "%s %s covered by %s ", you(lf), is(lf), f->text); } } @@ -9493,7 +9533,7 @@ void showlfstats(lifeform_t *lf, int showall) { lf2 = findlf(NULL, f->val[0]); if (lf2) { getlfname(lf2, buf); - wrapprint(mainwin, &y, &x, "%s %s fleeing from %s.", you(lf), is(lf), buf); + wrapprint(mainwin, &y, &x, "%s %s fleeing from %s. ", you(lf), is(lf), buf); } } } @@ -9503,7 +9543,7 @@ void showlfstats(lifeform_t *lf, int showall) { if (getlfmaterial(lf) != MT_FLESH) { material_t *mt; mt = findmaterial(getlfmaterial(lf)); - wrapprint(mainwin, &y, &x, "%s %s made out of %s.",you(lf), is(lf), mt->name); + wrapprint(mainwin, &y, &x, "%s %s made out of %s. ",you(lf), is(lf), mt->name); } } else if (mode == 'a') { @@ -10581,6 +10621,10 @@ void showlfstats(lifeform_t *lf, int showall) { } void textwithcol(WINDOW *win, char *buf) { + textwithcol_real(win, buf, B_TRUE); +} + +void textwithcol_real(WINDOW *win, char *buf, int resetcolatend) { char *p; enum COLOUR col; int done = B_FALSE; @@ -10618,9 +10662,11 @@ void textwithcol(WINDOW *win, char *buf) { if (done) break; waddch(win, *p); } - // back to default colour - if (col != C_NONE) { - unsetcol(win, col); + if (resetcolatend) { + // back to default colour + if (col != C_NONE) { + unsetcol(win, col); + } } } @@ -10653,7 +10699,7 @@ void tombstone(lifeform_t *lf) { centre(mainwin, C_GREY, y, "Died on level %d of %s.", player->cell->map->depth, buf); y++; } - makekillertext(killer, lf->lastdam, B_TRUE); + makekillertext(killer, lf->killverb, lf->lastdam, B_TRUE); p = readuntil(buf, killer, '\n'); while (strlen(buf)) { @@ -10713,27 +10759,67 @@ void tombstone(lifeform_t *lf) { } void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) { - char buf[BUFLEN]; + char word[HUGEBUFLEN],buf[HUGEBUFLEN]; + char *p; va_list args; - int w; + int w,nspaces = 0; + int first = B_TRUE; va_start(args, format); - vsnprintf( buf, BUFLEN, format, args ); + vsnprintf( buf, HUGEBUFLEN, format, args ); va_end(args); - strncat(buf, " ", BUFLEN); - w = getmaxx(win); - if (*x != 0) { - if (*x + strlen(buf) + 2 >= w) { - (*y)++; - *x = 0; + // remember the amount of spaces at the end + p = buf + strlen(buf) - 1; + while (*p == ' ') { + nspaces++; + p--; + } + // add on spaces at the end + //strncat(buf, " ", HUGEBUFLEN); + + // new code: print it word by word. + p = readuntil(word, buf, ' '); // get first word + //while (strlen(word)) { + while (strlen(p) || strlen(word)) { + // if this word won't fit, put it on the next line. + w = getmaxx(win); + if (*x != 0) { + if (*x + strlen(word) >= w) { + (*y)++; + *x = 0; + } + } + wmove(win, *y, *x); + if (first) { + first = B_FALSE; + } else if (*x != 0) { + textwithcol_real(win, " ", B_FALSE); + } + textwithcol_real(win, word, B_FALSE); + //(*x) += strlen(buf); + getyx(win, *y, *x); + + p = readuntil(word, p, ' '); // get next word + } + + if (*x + nspaces >= w) { + // if we're at the end of the line, just go to the next one. + (*y)++; + *x = 0; + wmove(win, *y, *x); + } else { + int i; + // otherwise print the trailing spaces + for (i = 0;i < nspaces; i++) { + textwithcol_real(win, " ", B_FALSE); } } - wmove(win, *y, *x); - textwithcol(win, buf); - //(*x) += strlen(buf); + // return colour to normal now + wattroff(mainwin, A_BOLD); + setcol(mainwin, C_GREY); getyx(win, *y, *x); } diff --git a/io.h b/io.h index f79b0ed..c9aec39 100644 --- a/io.h +++ b/io.h @@ -18,7 +18,7 @@ int announceobflaggain(object_t *o, flag_t *f); void announceobflagloss(object_t *o, flag_t *f); int confirm_badfeeling(object_t *o); int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname); -lifeform_t *askgod(char *prompt); +lifeform_t *askgod(char *prompt, int onlyprayed); object_t *askobject(obpile_t *op, char *title, int *count, long opts); object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag); object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...); @@ -125,6 +125,7 @@ int showhiscoreline(void *hilitescore, int ncols, char **argv, char **colname); void showlfarmour(lifeform_t *lf); void showlfstats(lifeform_t *lf, int showall); void textwithcol(WINDOW *win, char *buf); +void textwithcol_real(WINDOW *win, char *buf, int resetcolatend); void tombstone(lifeform_t *lf); void updatestatus(void); int updateviewfor(cell_t *cell); diff --git a/lf.c b/lf.c index 97c97c0..aad3034 100644 --- a/lf.c +++ b/lf.c @@ -1027,7 +1027,11 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) { reason = E_IMPOSSIBLE; return B_FALSE; } - // too heavy? + // injuries? + if ((where == BP_HANDS) && lfhasflagval(lf, F_INJURY, IJ_HANDSWOLLEN, NA, NA, NULL)) { + reason = E_INJURED; + return B_FALSE; + } if ((where == BP_FEET) && lfhasflagval(lf, F_INJURY, IJ_ANKLESWOLLEN, NA, NA, NULL)) { reason = E_INJURED; return B_FALSE; @@ -1211,6 +1215,15 @@ int cantakeoff(lifeform_t *lf, object_t *o) { reason = E_CURSED; return B_FALSE; } + // injuries? + if (isequippedon(o, BP_HANDS) && lfhasflagval(lf, F_INJURY, IJ_HANDSWOLLEN, NA, NA, NULL)) { + reason = E_INJURED; + return B_FALSE; + } + if (isequippedon(o, BP_FEET) && lfhasflagval(lf, F_INJURY, IJ_ANKLESWOLLEN, NA, NA, NULL)) { + reason = E_INJURED; + return B_FALSE; + } return B_TRUE; } @@ -1406,7 +1419,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } } else { // player can't see them - if ((targlf == player) || (targcell = player->cell)) { + if ((targlf == player) || (targcell == player->cell)) { if (!lfhasflag(player, F_ASLEEP)) { msg("Something casts a spell at you."); } @@ -2162,7 +2175,7 @@ void die(lifeform_t *lf) { } break; } - if (lfhasflag(lf, F_BEHEADED)) { + if (lfhasflag(lf, F_BEHEADED) && !lfhasflag(lf, F_CORPSETYPE)) { strcat(corpseprefix, "headless "); } @@ -6053,7 +6066,10 @@ float getmaxpushweight(lifeform_t *lf) { float getmaxstamina(lifeform_t *lf) { int stam = 0; - stam = (getattr(lf, A_CON) / 3) * (getskill(lf, SK_ATHLETICS) + 1); + int slev; + slev = getskill(lf, SK_ATHLETICS); + limit(&slev, 1, NA); + stam = (getattr(lf, A_CON) / 3) * (slev); if (lfhasflagval(lf, F_INJURY, IJ_LUNGCOLLAPSED, NA, NA, NULL)) { limit(&stam, NA, 2); } @@ -7584,8 +7600,14 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) { f = hasflag(o->flags, F_EQUIPPED); // make sure it's equipped in the right place - ie. weilded rings don't // do anything. - if (f && hasflagval(o->flags, F_GOESON, f->val[0], NA, NA, NULL)) { - equipped = B_TRUE; + if (f) { + if (hasflagval(o->flags, F_GOESON, f->val[0], NA, NA, NULL)) { + equipped = B_TRUE; + } else if ((f->val[0] == BP_WEAPON) || (f->val[0] == BP_SECWEAPON)) { + if (isweapon(o)) { + equipped = B_TRUE; + } + } } } if (held && hasflag(o->flags, F_ACTIVATED)) { @@ -7732,10 +7754,10 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { // special effects based on skill level if (id == SK_ATHLETICS) { if (f->val[1] == PR_ADEPT) { - newf = addflag(lf->flags, F_CANWILL, OT_A_TUMBLE, 2, 2, NULL); + newf = addflag(lf->flags, F_CANWILL, OT_A_TUMBLE, NA, NA, NULL); newf->lifetime = FROMSKILL; } else if (f->val[1] == PR_EXPERT) { - newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL); + newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL); newf->lifetime = FROMSKILL; } } else if (id == SK_CARTOGRAPHY) { @@ -7817,7 +7839,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { } } else if (id == SK_TWOWEAPON) { if (f->val[1] == PR_EXPERT) { - addflag(lf->flags, F_CANWILL, OT_A_FLURRY, 3, 3, "pw:1;"); + addflag(lf->flags, F_CANWILL, OT_A_FLURRY, NA, NA, "pw:1;"); } } else if (id == SK_SS_ALLOMANCY) { // give all allomantic spells @@ -8242,11 +8264,13 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { } break; case BP_HANDS: - switch (rnd(1,2)) { + switch (rnd(1,3)) { case 1: inj = IJ_FINGERBROKEN; desc = strdup("finger is broken^-2 accuracy"); break; case 2: inj = IJ_SHOULDERDISLOCATED; desc = strdup("shoulder is dislocated^-4 accuracy, cannot weild heavy weapons"); break; + case 3: + inj = IJ_HANDSWOLLEN; desc = strdup("hand is swollen^cannot wear/remove gloves"); break; } break; case BP_HEAD: @@ -8451,6 +8475,11 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { if (damtype == DT_SLASH) bleed(lf, B_SPLATTER); switch (inj) { + case IJ_BLACKEYE: + case IJ_EYELIDSCRAPED: + case IJ_EYEDESTROYED: + if (isplayer(lf)) setlosdirty(lf); + break; case IJ_HAMSTRUNG: fall(lf, NULL, B_TRUE); break; @@ -9539,6 +9568,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { a->alive = B_TRUE; a->lastdam = strdup("nothing"); a->lastdamtype = DT_NONE; + a->killverb = strdup("Killed"); if ((gamemode == GM_GAMESTARTED) && a->prev) { a->timespent = a->prev->timespent + 1; } else { @@ -10045,6 +10075,32 @@ void age(lifeform_t *lf, int pct) { } } +void applylfdammod(int *dam, lifeform_t *lf, object_t *wep) { + flag_t *retflag[MAXCANDIDATES]; + int nretflags = 0,i; + enum SKILLLEVEL slev; + // modify for strength + if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { + *dam = (int)((float)*dam * getstrdammod(lf)); + } + // modify for injuries + getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE); + for (i = 0; i < nretflags; i++) { + switch (retflag[i]->val[0]) { + case IJ_TORSOBRUISEDBAD: *dam = pctof(90, *dam); break; + } + } + + // extra damage for being skilled? + slev = getweaponskill(lf, wep); + if (slev > 1) { + float pctextra; + pctextra = ((slev - 1) * 10); + *dam += pctof(pctextra, *dam); + } +} + + void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) { flag_t *fromlfflag; lifeform_t *fromlf = NULL; @@ -10317,6 +10373,7 @@ int isweaponskill(enum SKILL skid) { switch (skid) { case SK_AXES: case SK_CLUBS: + case SK_EXOTICWEPS: case SK_LONGBLADES: case SK_POLEARMS: case SK_SHORTBLADES: @@ -10778,6 +10835,14 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml setlastdam(lf, buf); + switch (damtype) { + case DT_CRUSH: setkillverb(lf, "Crushed"); break; + case DT_ELECTRIC: setkillverb(lf, "Electrocuted"); break; + case DT_FIRE: setkillverb(lf, "Incinerated"); break; + case DT_MELT: setkillverb(lf, "Melted"); break; + default: break; + } + // special case if (lf->race->id == R_DREAMFUNGUS) { @@ -12650,6 +12715,13 @@ void setguntarget(lifeform_t *lf, lifeform_t *targ) { } } +void setkillverb(lifeform_t *lf, char *buf) { + if (lf->killverb) { + free(lf->killverb); + } + lf->killverb = strdup(buf); +} + void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { flag_t *f,*nextf; int i,retainhp = B_FALSE; @@ -12889,6 +12961,7 @@ void setlastdam(lifeform_t *lf, char *buf) { free(lf->lastdam); } lf->lastdam = strdup(buf); + setkillverb(lf, "Killed"); // default } @@ -14133,7 +14206,7 @@ void startlfturn(lifeform_t *lf) { if ((f->id == F_INJURY) && (f->val[2] == DT_SLASH)) { object_t *arm; arm = getequippedob(lf->pack, f->val[1]); - if (arm && !hasobmod(arm, OM_BLOODSTAINED) && pctchance(5)) applyobmod(arm, OM_BLOODSTAINED); + if (arm && !hasobmod(arm, findobmod(OM_BLOODSTAINED)) && pctchance(5)) applyobmod(arm, findobmod(OM_BLOODSTAINED)); } if (f->id == F_STABBEDBY) { @@ -14484,6 +14557,11 @@ int takeoff(lifeform_t *lf, object_t *o) { msg("You are not wearing that!"); } break; + case E_INJURED: + if (isplayer(lf)) { + msg("Your injury prevents you from removing your %s.", noprefix(obname)); + } + break; default: if (isplayer(lf)) { msg("For some reason, you cannot remove your %s!", noprefix(obname)); @@ -15811,13 +15889,13 @@ int wear(lifeform_t *lf, object_t *o) { // take offending item off first - this takes extra time. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(buf)); while (!ch) { - ch = askchar(buf2, "yn?","y", B_TRUE, B_FALSE); + ch = askchar(buf2, "ynd?","y", B_TRUE, B_FALSE); if (ch == '?') { describeob(o); ch = '\0'; } } - if (ch == 'y') { + if ((ch == 'y') || (ch == 'd')) { if (isarmour(inway)) { if (!takeoff(player, inway)) { // took it off! @@ -15829,6 +15907,9 @@ int wear(lifeform_t *lf, object_t *o) { errresolved = B_TRUE; } } + if (errresolved && (ch == 'd')) { + drop(inway, inway->amt); + } } } } @@ -15893,7 +15974,7 @@ int wear(lifeform_t *lf, object_t *o) { addflag(o->flags, F_EQUIPPED, bp, -1, -1, NULL); taketime(lf, getactspeed(lf)); - maketried(o->type->id); + if (isplayer(lf)) maketried(o->type->id); // when you wear armour, you find out // its bonuses. @@ -16099,7 +16180,7 @@ int weild(lifeform_t *lf, object_t *o) { // prompt before taking it off. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(inwayname)); while (!ch) { - ch = askchar(buf2, "yn?","y", B_TRUE, B_FALSE); + ch = askchar(buf2, "ynd?","y", B_TRUE, B_FALSE); if (ch == '?') { describeob(o); ch = '\0'; @@ -16109,7 +16190,7 @@ int weild(lifeform_t *lf, object_t *o) { } else { ch = 'y'; } - if (ch == 'y') { + if ((ch == 'y') || (ch == 'd')) { if (isarmour(oo)) { if (takeoff(lf, oo)) { // if we can't remove it, stop. @@ -16121,6 +16202,9 @@ int weild(lifeform_t *lf, object_t *o) { return B_TRUE; } } + if (ch == 'd') { + drop(oo, oo->amt); + } } else { return B_TRUE; } @@ -16202,7 +16286,7 @@ int weild(lifeform_t *lf, object_t *o) { taketime(lf, getactspeed(lf)); - maketried(o->type->id); + if (isplayer(lf)) maketried(o->type->id); if ((gamemode == GM_GAMESTARTED) && lf->created && (lf->race->id != R_DANCINGWEAPON)) { if (isplayer(lf)) { diff --git a/lf.h b/lf.h index f421f56..06ff3e4 100644 --- a/lf.h +++ b/lf.h @@ -11,6 +11,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype); void adjustspeedforwater(lifeform_t *lf, int *speed); void age(lifeform_t *lf, int pct); +void applylfdammod(int *dam, lifeform_t *lf, object_t *wep); void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o); int areallies(lifeform_t *lf1, lifeform_t *lf2); int areenemies(lifeform_t *lf1, lifeform_t *lf2); @@ -350,6 +351,7 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val); int setfacing(lifeform_t *lf, int dir); void setfollowdistance(lifeform_t *lf, int min, int max); void setguntarget(lifeform_t *lf, lifeform_t *targ); +void setkillverb(lifeform_t *lf, char *buf); void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph); void setlastdam(lifeform_t *lf, char *buf); //void setlftarget(lifeform_t *lf, lifeform_t *victim); diff --git a/map.c b/map.c index a92f4c8..2a0a38b 100644 --- a/map.c +++ b/map.c @@ -1555,12 +1555,16 @@ void calclight(map_t *map) { } // did any lit values within player's los change? if (gamemode == GM_GAMESTARTED) { + int dolos = B_FALSE; for (i = 0; i < player->nlos; i++) { if (player->los[i]->lastlit != player->los[i]->lit) { - needredraw = B_TRUE; + dolos = B_TRUE; break; } } + if (dolos) { + setlosdirty(player); + } } } @@ -5468,7 +5472,7 @@ void setcellknown(cell_t *cell, int forcelev) { } if (slev == PR_INEPT) { - cell->knowntime = getattr(player, A_IQ)*3; + cell->knowntime = getattr(player, A_IQ)*5; } else { cell->knowntime = PERMENANT; } diff --git a/move.c b/move.c index cfeacf4..ea284e0 100644 --- a/move.c +++ b/move.c @@ -307,6 +307,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) { // must check for lf before checking for impassable objects, // so that we are able to attack monsters embedded in walls. if (cell->lf && (cell->lf != lf)) { + rdata = cell->lf; // usually can't attack while swimming if (lf && isswimming(lf) && (getskill(lf, SK_SWIMMING) <= PR_EXPERT)) { if (!lfhasflag(lf, F_AQUATIC)) { diff --git a/nexus.c b/nexus.c index d34db9d..3d7c66e 100644 --- a/nexus.c +++ b/nexus.c @@ -265,6 +265,7 @@ int main(int argc, char **argv) { exit(1); } real_addlf(where, startrace->id, 1, C_PLAYER); // this will assign 'player' + addflag(player->flags, F_CANWILL, OT_A_CHECKSTAIRS, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL); ///////// diff --git a/objects.c b/objects.c index cca6f09..16fa685 100644 --- a/objects.c +++ b/objects.c @@ -2357,6 +2357,23 @@ int changemat(object_t *o, enum MATERIAL mat) { return B_FALSE; } +// returns true if the object protected you +int checkcritprotection(lifeform_t *lf, object_t *o) { + if (pctchance(getcritprotection(o))) { + char obname[BUFLEN]; + getobname(o, obname, o->amt); + if (isplayer(lf)) { + msg("Your %s protects you.", noprefix(obname)); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s%s %s protects it.", lfname, getpossessive(lfname), noprefix(obname)); + } + return B_TRUE; + } + return B_FALSE; +} + int checkobnames(char *haystack, char *needle) { char *pluralname; int db = B_FALSE; @@ -5783,7 +5800,7 @@ int isdangerousob(object_t *o, lifeform_t *lf, int onlyifknown) { // undead won't touch blessed things - don't worry about // onlyifknown, they can sense this. - if (hasflag(lf->flags, F_UNDEAD) && isblessed(o)) { + if (isundead(lf) && isblessed(o)) { return B_TRUE; } return B_FALSE; @@ -7330,7 +7347,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { taketime(lf, getactspeed(lf)); // mark obejct as tried - maketried(o->type->id); + if (isplayer(lf)) maketried(o->type->id); // trapped? if (doobtraps(o, lf)) { @@ -8304,7 +8321,7 @@ void quaff(lifeform_t *lf, object_t *o) { realobid = o->type->id; } - maketried(realobid); + if (isplayer(lf)) maketried(realobid); if (touch(lf, o)) { return; @@ -8788,7 +8805,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE case OT_POT_WATER: switch (potblessed) { case B_BLESSED: - if (hasflag(lf->flags, F_UNDEAD)) { + if (isundead(lf)) { if (isplayer(lf)) { msg("This tastes like water, but burns like acid!"); } else if (cansee(player, lf)) { @@ -8894,7 +8911,7 @@ int readsomething(lifeform_t *lf, object_t *o) { } taketime(lf, readtime); - maketried(o->type->id); + if (isplayer(lf)) maketried(o->type->id); // some checks first... if (touch(lf, o)) { @@ -9730,7 +9747,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { is(target)); } - if (hasflag(target->flags, F_UNDEAD) && isblessed(o)) { + if (isundead(target) && isblessed(o)) { if (isplayer(target)) { msg("The water burns like acid!"); } else if (cansee(player, target)) { @@ -10605,7 +10622,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, } // doesn't matter wheter you hit or not... - if (lfhasflag(target, F_UNDEAD) && isblessed(o)) { + if (isundead(target) && isblessed(o)) { if (seen) { msg("%s recoils in fear!", targetname); } @@ -10616,11 +10633,14 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, if (youhit && lfhasflag(target, F_NONCORPOREAL)) { - youhit = B_FALSE; - willcatch = B_FALSE; - if (seen) { - msg("%s passes straight through %s.", obname, targetname); - announcedmiss = B_TRUE; + if (isvulnto(target->flags, DT_HOLY) && isblessed(o)) { + } else { + youhit = B_FALSE; + willcatch = B_FALSE; + if (seen) { + msg("%s passes straight through %s.", obname, targetname); + announcedmiss = B_TRUE; + } } } @@ -10823,7 +10843,7 @@ void timeeffectsob(object_t *o) { for (x = ourcell->x - 2; x <= ourcell->x + 2; x++) { cell_t *c; c = getcellat(ourcell->map, x, y); - if (c && haslf(c) && hasflag(c->lf->flags, F_UNDEAD)) { + if (c && haslf(c) && isundead(c->lf)) { nearundead = B_TRUE; break; } @@ -11762,6 +11782,13 @@ int getcritchance(lifeform_t *lf, object_t *o, lifeform_t *victim) { return chance; } +int getcritprotection(object_t *o) { + flag_t *f; + f = hasflag(o->flags, F_CRITPROTECTION); + if (f) return f->val[0]; + return 0; +} + // determine how long a conferred effect should last, based on its blessed/cursed status. // blessed: always max // uncursed: random number between min & max diff --git a/objects.h b/objects.h index 98693d4..a8b3535 100644 --- a/objects.h +++ b/objects.h @@ -33,6 +33,7 @@ int canseeob(lifeform_t *lf, object_t *o); object_t *canstackob(obpile_t *op, object_t *match); object_t *canstacknewot(obpile_t *op, objecttype_t *match); int changemat(object_t *o, enum MATERIAL mat); +int getcritprotection(object_t *o); int checkobnames(char *haystack, char *needle); void colourmatchob(object_t *o, lifeform_t *lf); void copyobprops(object_t *dst, object_t *src); @@ -62,6 +63,7 @@ object_t *getbestcontainer(obpile_t *op); int getchargeinfo(object_t *o, int *cur, int *max); int getcharges(object_t *o); int getcritchance(lifeform_t *lf, object_t *o, lifeform_t *victim); +int checkcritprotection(lifeform_t *lf, object_t *o); int geteffecttime(int min, int max, enum BLESSTYPE isblessed); objecttype_t *getlinkspell(object_t *o); enum COLOUR getmaterialcolour(enum MATERIAL mat ); diff --git a/save.c b/save.c index 5f4d13e..ff232ae 100644 --- a/save.c +++ b/save.c @@ -1111,7 +1111,7 @@ int writehiscore(lifeform_t *lf, int *rank) { capitalise(racename); snprintf(jobname, BUFLEN, "Lv%d %s %s", player->level, racename, j->name); - makekillertext(killedby, lf->lastdam, B_FALSE); + makekillertext(killedby, lf->killverb, lf->lastdam, B_FALSE); if (!lfhasflag(lf, F_NOSCORE)) { asprintf(&cmd, "insert into 'hiscores' (score,name,job,killedby) VALUES (%ld, '%s', '%s', '%s')", score, pname, jobname, killedby); diff --git a/spell.c b/spell.c index f8b03af..507dbd1 100644 --- a/spell.c +++ b/spell.c @@ -662,14 +662,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef char buf[BUFLEN]; if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { - if (isplayer(user)) msg("You can't disarm traps while swimming!"); + if (isplayer(user)) msg("You can't disable traps while swimming!"); return B_TRUE; } // ask for direction if (!targcell) { int dirch; - dirch = askchar("Disarm trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); + dirch = askchar("Disable trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if ((dirch == '-') || !dirch) { if (isplayer(user)) msg("Cancelled."); return B_TRUE ; @@ -734,9 +734,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef getobname(trapob, buf, 1); // get name AFTER killing the flag! } if (isplayer(user)) { - msg("You disarm %s.",buf); + msg("You disable %s.",buf); } else if (cansee(player, user)) { - msg("%s disarms %s.",username, buf); + msg("%s disables %s.",username, buf); } if (isplayer(user) && hasjob(user, J_ROGUE)) { @@ -772,12 +772,81 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else { getobname(trapob, buf, 1); if (isplayer(user)) { - msg("You fail to disarm %s.",buf); + msg("You fail to disable %s.",buf); } else if (cansee(player, user)) { - msg("%s fails to disarm %s.",username, buf); + msg("%s fails to disable %s.",username, buf); } } } + } else if (abilid == OT_A_DISARMLF) { + object_t *wep,*targetwep; + int skillmod = 0,targetskillmod = 0; + // ask for direction + if (!targcell) { + char dirch; + dirch = askchar("Disarm in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); + if (dirch == '.') { + if (isplayer(user)) msg("You can't disarm yourself!"); + return B_TRUE; + } else { + int dir; + dir = chartodir(dirch); + if (dir == D_NONE) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE ; + } else { + targcell = getcellindir(user->cell, dir); + } + } + } + + if (!haslos(user, targcell)) { + if (isplayer(user)) msg("You can't see there!"); + return B_TRUE; + } + + target = targcell->lf; + if (!target) { + if (isplayer(user)) msg("There is nobody there to disarm!"); + return B_TRUE; + } + getlfname(target, targetname); + targetwep = getweapon(target); + if (!targetwep) { + targetwep = getequippedob(target->pack, BP_SECWEAPON); + if (!targetwep) { + if (isplayer(user)) msg("%s has no weapon!", targetname); + return B_TRUE; + } + } + + wep = getweapon(user); + + // try to disarm them... + taketime(user, getactspeed(user)); + + if (wep) { + skillmod = getweaponskill(user, wep); + if (isplayer(user) && (skillmod == 0)) skillmod = -5; + } else { + skillmod = getskill(user, SK_UNARMED); + } + + targetskillmod = getweaponskill(target, targetwep); + if (isplayer(target) && (targetskillmod == 0)) targetskillmod = -5; + + if (skillcheckvs(user, SC_DEX, skillmod, target, SC_DEX, targetskillmod)) { + if (cansee(player, user)) { + msg("^w%s disarm%s %s!",username, isplayer(user) ? "" : "s", targetname); + } + drop(targetwep, ALL); + } else { + if (isplayer(user)) { + msg("You try to disarm %s, but fail.",targetname); + } else if (cansee(player, user)) { + msg("%s tries to disarm %s, but fail.",username, targetname); + } + } } else if (abilid == OT_A_FEIGNDEATH) { lifeform_t *lf; if (hasflag(user->flags, F_FEIGNINGDEATH)) { @@ -1075,6 +1144,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else if (hasflag(user->flags, F_GRAVBOOSTED)) { if (isplayer(user)) msg("You can't jump with gravity boosted around you!"); return B_TRUE; + } else if (lfhasflag(user, F_GRABBING)) { + if (isplayer(user)) msg("You can't jump while being held!"); + return B_TRUE; + } else if (lfhasflag(user, F_GRABBEDBY)) { + if (isplayer(user)) msg("You can't jump while holding someone!"); + return B_TRUE; } if (hasflag(user->flags, F_GRAVLESSENED)) { @@ -1738,6 +1813,64 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // do the first one right away rest(user, B_TRUE); } + } else if (abilid == OT_A_TRIPLF) { + object_t *wep; + int skillmod = 0; + // ask for direction + if (!targcell) { + char dirch; + dirch = askchar("Trip in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); + if (dirch == '.') { + if (isplayer(user)) msg("You can't trip yourself!"); + return B_TRUE; + } else { + int dir; + dir = chartodir(dirch); + if (dir == D_NONE) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE ; + } else { + targcell = getcellindir(user->cell, dir); + } + } + } + + if (!haslos(user, targcell)) { + if (isplayer(user)) msg("You can't see there!"); + return B_TRUE; + } + + target = targcell->lf; + if (!target) { + if (isplayer(user)) msg("There is nobody there to trip!"); + return B_TRUE; + } + getlfname(target, targetname); + + wep = getweapon(user); + + // try to disarm them... + taketime(user, getactspeed(user)); + + if (wep) { + skillmod = getweaponskill(user, wep); + if (isplayer(user) && (skillmod == 0)) skillmod = -5; + } else { + skillmod = getskill(user, SK_UNARMED); + } + + if (skillcheckvs(user, SC_DEX, skillmod, target, SC_SLIP, 0)) { + if (cansee(player, user)) { + msg("^w%s trip%s %s.",username, isplayer(user) ? "" : "s", targetname); + } + fall(target, NULL, B_TRUE); + } else { + if (isplayer(user)) { + msg("You try to trip %s, but fail.",targetname); + } else if (cansee(player, user)) { + msg("%s tries to trip %s, but fail.",username, targetname); + } + } } else if (abilid == OT_A_TUMBLE) { cell_t *origcell,*c; cell_t *retcell[MAXRETCELLS]; @@ -1752,6 +1885,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else if (isairborne(user)) { if (isplayer(user)) msg("You can't tumble while airbourne!"); return B_TRUE; + } else if (lfhasflag(user, F_GRABBING)) { + if (isplayer(user)) msg("You can't tumble while being held!"); + return B_TRUE; + } else if (lfhasflag(user, F_GRABBEDBY)) { + if (isplayer(user)) msg("You can't tumble while holding someone!"); + return B_TRUE; } if (targcell) { @@ -1837,7 +1976,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // run into a person, wall or impassable object? if (i >= 1) { enum ERROR why; - if (!cellwalkable(user, c, &why)) { + if (!cellwalkable(user, c, &why)) { // this will set "rdata" // stop in previous cell strcpy(stopverb, "bump"); targcell = retcell[i-1]; @@ -1937,7 +2076,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef initprompt(&prompt, "To whom will you pray?"); prompt.maycancel = B_TRUE; - lf = askgod("To whom will you pray?"); + lf = askgod("To whom will you pray?", B_FALSE); if (!lf) { msg("Cancelled."); return B_TRUE; diff --git a/text.c b/text.c index 78f075c..b4b2edf 100644 --- a/text.c +++ b/text.c @@ -599,14 +599,14 @@ int isvowel (char c) { return B_FALSE; } -char *makekillertext(char *retbuf, char *lastdam, int wantextra) { +char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra) { char *p, *dummy; p = strtok_r(lastdam,"^", &dummy); if (p) { if (!strcmp(p, "you")) { strcpy(retbuf, "Committed suicide."); } else { - snprintf(retbuf, BUFLEN, "Killed by %s.",p); + snprintf(retbuf, BUFLEN, "%s by %s.",killverb, p); } if (wantextra) { p = strtok_r(NULL, "^", &dummy); @@ -618,7 +618,7 @@ char *makekillertext(char *retbuf, char *lastdam, int wantextra) { } } } else { - strcpy(retbuf, "Killed by something unknown."); + sprintf(retbuf, "%s by something unknown.", killverb); } return retbuf; } diff --git a/text.h b/text.h index cdbc31b..3060e0a 100644 --- a/text.h +++ b/text.h @@ -30,7 +30,7 @@ char *getwaterdepthname(enum DEPTH d); char *getweighttext(float weight, char *buf, int shortfmt); char *is(lifeform_t *lf); int isvowel(char c); -char *makekillertext(char *retbuf, char *lastdam, int wantextra); +char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra); char *makeplural(char *text); char *makeuppercase(char *text); int needses(char *text);