diff --git a/data.c b/data.c index 97684da..50613b8 100644 --- a/data.c +++ b/data.c @@ -998,6 +998,10 @@ void initobjects(void) { addbrand(BR_LIFESUCK, "of lifesucking", BP_WEAPON, B_UNCURSED, 0); addflag_real(lastbrand->flags, F_VAMPIRIC, NA, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); + addbrand(BR_REFLECTION, "of reflection", BP_SECWEAPON, B_UNCURSED, 0); + addflag_real(lastbrand->flags, F_ONLYFOROBWITHFLAG, F_SHIELD, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); + addflag_real(lastbrand->flags, F_EQUIPCONFER, F_REFLECTION, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1); + addbrand(BR_SLAY_ANIMAL, "of butchering", BP_WEAPON, B_UNCURSED, 0); addflag_real(lastbrand->flags, F_ONLYFORDAMTYPE, DT_SLASH, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_RACESLAY, RC_ANIMAL, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); @@ -1013,7 +1017,7 @@ void initobjects(void) { addflag_real(lastbrand->flags, F_ONLYFORWEPSKILL, SK_LONGBLADES, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_ONLYFORWEPSKILL, SK_SHORTBLADES, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_RACESLAY, RC_UNDEAD, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); - addflag_real(lastbrand->flags, F_EQUIPCONFER, F_PRODUCESLIGHT, 3, NA, NULL, PERMENANT, B_KNOWN, -1); + addflag_real(lastbrand->flags, F_EQUIPCONFER, F_PRODUCESLIGHT, 3, NA, NULL, PERMENANT, B_UNKNOWN, -1); // feet addbrand(BR_LEVITATION, "of hovering", BP_FEET, B_CURSED, 50); @@ -5824,7 +5828,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_DETECTLIFE, 5, NA, NULL); addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); - addot(OT_RING_REFLECTION, "ring of reflection", "Bounces any projectiles which hit the wearer back to their source.", MT_METAL, 0.1, OC_RING, SZ_MINI); + addot(OT_RING_REFLECTION, "ring of missile turning", "Bounces any projectiles which hit the wearer back to their source.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_REFLECTION, B_TRUE, NA, NULL); addflag(lastot->flags, F_VALUE, 350, NA, NA, NULL); @@ -10732,7 +10736,7 @@ void initrace(void) { addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addrace(R_GIANTBLOWFLY, "giant urgnat", 2, 'i', C_GREY, MT_FLESH, RC_INSECT, "Large, more solid versions of giant gnats. These can actually cause damage, albeit rarely."); + addrace(R_GIANTBLOWFLY, "giant ur-gnat", 2, 'i', C_GREY, MT_FLESH, RC_INSECT, "Large, more solid versions of giant gnats. These can actually cause damage, albeit rarely."); setbodytype(lastrace, BT_BIRD); lastrace->baseid = R_GIANTFLY; addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); diff --git a/defs.h b/defs.h index 99afb4b..2e57ca5 100644 --- a/defs.h +++ b/defs.h @@ -2042,6 +2042,7 @@ enum FLAG { // monetary value) // for object brands F_ONLYFOROBTYPE, // brand can only go on obtype v0 + F_ONLYFOROBWITHFLAG, // brand can only go on obs with flag v0 F_ONLYFORDAMTYPE, // brand can only go on obs with damtype v0 F_ONLYFORWEPSKILL, // brand can only go on obclass v0 // weapon/armour flags @@ -3829,6 +3830,7 @@ enum BRAND { BR_SHARPNESS, BR_PYROMANIA, BR_REVENGE, + BR_REFLECTION, BR_SHADOWS, BR_SLOTH, BR_SPEED, diff --git a/objects.c b/objects.c index 4d25eee..1a3c24b 100644 --- a/objects.c +++ b/objects.c @@ -4702,7 +4702,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan } else if ((o->type->id == OT_MAP) && isknown(o)) { flag_t *f; f = hasflag(o->flags, F_MAPTO); - if (f && getskill(player, SK_CARTOGRAPHY)) { + if (f && getskill(player, SK_CARTOGRAPHY) && isidentified(o)) { snprintf(basename, BUFLEN, "map to %s", f->text); } else { strcpy(basename, "map"); @@ -7913,7 +7913,9 @@ enum DAMTYPE oblastdamtype(object_t *o) { } int brandappliesto(brand_t *br, objecttype_t *ot) { - flag_t *f; + flag_t *f,*f2; + flag_t *retflag[MAXCANDIDATES]; + int i,nretflags = 0; if (br->bp == BP_WEAPON) { if (ot->obclass->id != OC_WEAPON) { @@ -7932,35 +7934,40 @@ int brandappliesto(brand_t *br, objecttype_t *ot) { return B_FALSE; } } - if (hasflag(br->flags, F_ONLYFORDAMTYPE)) { - enum DAMTYPE dt; - f = hasflag(ot->flags, F_DAM); - if (!f) { - return B_FALSE; - } - dt = f->val[0]; - if (!hasflagval(br->flags, F_ONLYFORDAMTYPE, dt, NA, NA, NULL)) { - return B_FALSE; - } - } - if (hasflag(br->flags, F_ONLYFORWEPSKILL)) { - enum SKILL skid; - f = hasflag(ot->flags, F_USESSKILL); - if (!f) { - return B_FALSE; - } - skid = f->val[0]; - if (!hasflagval(br->flags, F_ONLYFORWEPSKILL, skid, NA, NA, NULL)) { - return B_FALSE; + getflags(br->flags, retflag, &nretflags, F_ONLYFOROBWITHFLAG, F_ONLYFORDAMTYPE, F_ONLYFORWEPSKILL, F_NONE); + for (i = 0; i < nretflags; i++) { + f2 = retflag[i]; + if (f2->id == F_ONLYFOROBWITHFLAG) { + if (!hasflag(ot->flags, f2->val[0])) return B_FALSE; + } else if (f2->id == F_ONLYFORDAMTYPE) { + enum DAMTYPE dt; + f = hasflag(ot->flags, F_DAM); + if (!f) { + return B_FALSE; + } + dt = f->val[0]; + if (!hasflagval(br->flags, F_ONLYFORDAMTYPE, dt, NA, NA, NULL)) { + return B_FALSE; + } + } else if (f2->id == F_ONLYFORWEPSKILL) { + enum SKILL skid; + + f = hasflag(ot->flags, F_USESSKILL); + if (!f) { + return B_FALSE; + } + skid = f->val[0]; + + if (!hasflagval(br->flags, F_ONLYFORWEPSKILL, skid, NA, NA, NULL)) { + return B_FALSE; + } } } return B_TRUE; } - - int obmatchescondition(object_t *o, long opts) { int ok; @@ -11331,8 +11338,6 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) { addflag(o->flags, F_LASTDAMTYPE, damtype, NA, NA, NULL); } - - real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE); getobconditionname(o, predamname); hpflag = hasflag(o->flags, F_OBHP); @@ -12482,14 +12487,23 @@ void timeeffectsob(object_t *o) { if (f->id == F_OBHPDRAIN) { enum DAMTYPE damtype; + int doit = B_TRUE; //takedamage(o, f->val[0] * firstlftime, DT_DIRECT); if (f->val[1] == NA) { damtype = DT_DIRECT; } else { damtype = f->val[1]; } - takedamage(o, f->val[0], damtype); - if (hasflag(o->flags, F_DEAD)) return; + // special case + if (o->type->id == OT_CORPSE) { + if (hasobofmaterial(o->pile, MT_ICE)) { + doit = B_FALSE; + } + } + if (doit) { + takedamage(o, f->val[0], damtype); + if (hasflag(o->flags, F_DEAD)) return; + } } // corpses rot away... diff --git a/shops.c b/shops.c index 7cc8abd..151442a 100644 --- a/shops.c +++ b/shops.c @@ -242,6 +242,7 @@ void shop(lifeform_t *lf, object_t *vm) { case 3: snprintf(buf, BUFLEN, "Sweet dreams!"); break; } msg("\"%s\"", buf); + more(); } else if (npurchased > ndonated) { switch (rnd(1,2)) { case 1: snprintf(buf, BUFLEN, "Pleasure doing business with you!"); break; @@ -852,8 +853,8 @@ enum SHOPRETURN shoprest(lifeform_t *lf, object_t *vm, int starty, char *toptext sprintf(obid, "%ld", vm->id); addflag(lf->flags, F_RESTINGINMOTEL, amt*60, 0, NA, obid); addflag(lf->flags, F_RESTUNTILBETTER, B_TRUE, NA, NA, NULL); + breakaitargets(lf, B_FALSE); startresting(lf, B_FALSE); more(); - breakaitargets(lf, B_FALSE); return SR_QUIT; } diff --git a/spell.c b/spell.c index 7a28aaa..4bb304f 100644 --- a/spell.c +++ b/spell.c @@ -1272,7 +1272,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef maxrange++; } - if (!targcell) { snprintf(buf, BUFLEN, "Jump where (max distance %d)?", maxrange); while (!targcell) { @@ -1306,6 +1305,19 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } + + // did you land on something impassable? + for (o = targcell->obpile->first ; o ; o = o->next) { + if (isimpassableob(o, user)) { + char obname[BUFLEN]; + getobname(o, obname, o->amt); + if (isplayer(user)) { + msg("There %s %s in the way!", (o->amt == 1) ? "is" : "are", obname); + } + return B_TRUE; + } + } + // we now have a cell - go there! taketime(user, getactspeed(user)); origcell = user->cell; @@ -1379,31 +1391,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef msg("%s dodges out of the way!", victimname); } } else { - /* - int dam = 0; - int diff; - diff = getlfsize(user) - getlfsize(victim); - if (diff > 0) { // user was larger - // victim takes damage based on the jumper's weight - // 1hp per 25 kg - dam = getlfweight(user, B_WITHOBS) / 25; - } else { - // user was same size or smaller - dam = 0; - } - if (dam > 0) { - if (lfhasflag(user, F_EXTRAINFO) || lfhasflag(user, F_OMNIPOTENT)) { - msg("[%s takes %d damage]",victimname,dam); - } - snprintf(buf, BUFLEN, "a falling %s", user->race->name); - losehp(victim, dam, DT_BASH, user, buf); - } - */ // both victim and attacker fall if (!isdead(victim)) fall(victim, NULL, B_TRUE); fall(user, NULL, B_TRUE); } } + + practice(user, SK_ATHLETICS, 1); } else if (abilid == OT_A_PICKLOCK) { lockpick(user, NULL, NULL, NULL); @@ -6945,15 +6939,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("^w%s is engulfed in an anti-magic field!", lfname); if (seenbyplayer) *seenbyplayer = B_TRUE; } + + // lose all mana + if (target->mp > 0) { + losemp(target, target->mp); + ndone++; + } + while (ndone < power) { - // get a list of flags which could be destroyed - nposs = 0; // for player: // remove memorised spells // for monsters: // remove racial spells AND abilities // // abilities/spells conferred by objects are not affected. + nposs = 0; getflags(target->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE); for (i = 0; i < nretflags; i++) { int ok = B_TRUE;