- [+] change descriptive text for nullify power.

- [+] if you burn your hands on an equipped shield, drop it autoatically
* [+] sewer stairs problem
- [+] if something redhot/flaming takes water damage, it will make
      steam.
- [+] ring of unholiness(blessed things burn you - just add undead flag?
    - [+] gods of purity/life will warn you first.
- [+] fixed crash checking for blocking attacks from adhesive lfs.
- [+] glorana cure poison doesn't work
    - [+] cancast is returning FALSE but E_OK.
    - [+] glorana isn't getting canwill ot_s_curepoison
    - [+] got it - was using getspellschool() instead of
          spellisfromschool()
- [+] giant spider not casting web
    - [+] .oO { can't cast web right now (lowiq) (mpcost=4, i have 0) }
    - [+] FIXED, and also fixed validateraces() check for this kind of
          thing.
- [+] cats are now territorial with rndhostile rather than always
      hostile
- [+] do final cursed wish scroll effect - magic
    - [+] get a suicide spell?
- [+] thornspike armour.
- [+] new slashing weapons
    - [+] new weapon: vibroblade
        - [+] short blade
        - [+] slashing 8
        - [+] extra high crit chance
    - [+] new weapon: nanoblade
        - [+] short blade
        - [+] slashing 10
        - [+] unlimited armour piercing
    - [+] laser sword
        - [+] longblade
        - [+] fast!
        - [+] not dullable
        - [+] armour piercing (not as much as nanoblade)
        - [+] high critical (not as much as vibroblade)
    - [+] gunblade
        - [+] extra explosive damage while it has charges.
- [+] glorana accepts sacrifice of weapons, instead of food.
- [+] ekrub acceps sacrifice of food.
- [+] bug in pirate description:
    - [+] Its  (). It has no left hand.
- [+] god description should show prayer results. ie. "yumi will
      respond to prayer by xxx"
- [+] if glorana likes you while you're sleeping say, "you dream of a
      choir singing" instead of "you hear".
- [+] eating garlic gives stench.
- [+] cope with "armorpierce NA" - "will not reduce damage at all"
This commit is contained in:
Rob Pearce 2012-07-03 03:53:41 +00:00
parent ff6dba534e
commit 042ade4ca6
14 changed files with 586 additions and 145 deletions

View File

@ -1484,16 +1484,22 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
f = retflag[i];
if ((f->id == F_RETALIATE) && (getcelldist(victim->cell, lf->cell) == 1)) {
int rdam;
char damstring[BUFLEN];
rdam = rolldie(f->val[0], f->val[1]);
char damstring[BUFLEN],dicetext[BUFLEN],obname[BUFLEN];
char *loctext,*p;
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(obname, p, '^');
rdam = roll(dicetext);
if (cansee(player, victim)) {
msg("^%c%s%s %s %s %s!", isplayer(lf) ? 'b' : 'n', victimname, getpossessive(victimname),
noprefix(f->text),
getattackverb(victim, NULL, f->val[2], rdam, lf->maxhp),
noprefix(obname),
getattackverb(victim, NULL, f->val[0], rdam, lf->maxhp),
attackername);
}
snprintf(damstring, BUFLEN, "%s%s %s", victimname, getpossessive(victimname), noprefix(f->text));
losehp_real(lf, rdam, f->val[2], victim, damstring, B_TRUE, NULL, B_TRUE, NULL, B_TRUE);
snprintf(damstring, BUFLEN, "%s%s %s", victimname, getpossessive(victimname), noprefix(obname));
losehp_real(lf, rdam, f->val[0], victim, damstring, B_TRUE, NULL, B_TRUE, NULL, B_TRUE);
free(loctext);
}
}
}
@ -1540,18 +1546,16 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (isplayer(lf)) {
msg("^%cYou fumble your attack!", getlfcol(lf, CC_BAD));
} else if (cansee(player, lf)) {
msg("^%c%s fumbles its attack!", attackername, getlfcol(lf, CC_BAD));
msg("^%c%s fumbles its attack!", getlfcol(lf, CC_BAD), attackername);
}
drop(wep, ALL);
wep = NULL;
}
}
// chance that ai will give up if we can't reach the victim
// high chance that ai will give up if we can't reach the victim
if (!isplayer(lf) && !canreach(lf, victim, NULL)) {
if (pctchance(90)) {
// TODO: announce this.
// the xxx loses interest
loseaitargets(lf);
if (isplayer(victim) && cansee(player, lf)) {
msg("%s seems to have lost interest in you.", attackername);
@ -1989,17 +1993,19 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
practice(victim, SK_SHIELDS, 1);
}
if (!isdeadob(shield[i])) {
flag_t *f;
f = hasflag(lf->flags, F_ADHESIVE);
if (f && !skillcheck(victim, SC_STR, f->val[0], 0)) {
if (cansee(player, lf) || cansee(player, victim)) {
char attname[BUFLEN];
getlfname(lf, attname);
msg("^%c%s%s %s %s to %s!", getlfcol(victim, CC_BAD),
victimname, getpossessive(victimname), noprefix(shname),
(shield[i]->amt == 1) ? "sticks" : "stick", attname);
if (lf) {
flag_t *f;
f = hasflag(lf->flags, F_ADHESIVE);
if (f && !skillcheck(victim, SC_STR, f->val[0], 0)) {
if (cansee(player, lf) || cansee(player, victim)) {
char attname[BUFLEN];
getlfname(lf, attname);
msg("^%c%s%s %s %s to %s!", getlfcol(victim, CC_BAD),
victimname, getpossessive(victimname), noprefix(shname),
(shield[i]->amt == 1) ? "sticks" : "stick", attname);
}
moveob(shield[i], lf->pack, shield[i]->amt);
}
moveob(shield[i], lf->pack, shield[i]->amt);
}
}
@ -2285,7 +2291,8 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
// armourpiercing valut.
pierce = hasflag(wep->flags, F_ARMOURPIERCE);
if (pierce) {
reduceamt -= pierce->val[0];
if (pierce->val[0] < 0) reduceamt = 0;
else reduceamt -= pierce->val[0];
}
if (reduceamt < 0) reduceamt = 0;
@ -2415,7 +2422,7 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, in
// use up a charge
usecharge(wep);
}
// deal extra electric damage
// deal extra damage of the given type
*(dam + *ndam) = real_roll(f->text, fordisplay);
*(damtype + *ndam) = f->val[0];
(*ndam)++;

229
data.c
View File

@ -274,7 +274,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_NOVICE, NA, NULL);
//addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
for (i = 1; i < MAXSKILLS; i++) {
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
@ -497,12 +497,13 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "nylon rope");
// initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SEWING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL);
// learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
@ -659,7 +660,7 @@ void initjobs(void) {
// 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_ATHLETICS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); // limit
addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
@ -783,7 +784,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_EXTRALUCK, 1, NA, NA, NULL);
addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young hawk");
addflag(lastjob->flags, F_MAXATTACKS, 2, 2, NA, NULL);// this is so that our hookhand works
addflag(lastjob->flags, F_INJURY, IJ_EYEDESTROYED, NA, NA, NULL);
addflag(lastjob->flags, F_INJURY, IJ_EYEDESTROYED, BP_EYES, DT_EXPLOSIVE, "right eye is destroyed^field of view halved");
// also: has a hook instead of fists.
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
@ -2556,6 +2557,7 @@ void initobjects(void) {
addot(OT_BREADGARLIC, "loaf of garlic bread", "A pungent loaf of garlic bread. Nauseates those around you and restores some health.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
addflag(lastot->flags, F_EATCONFER, F_STENCH, 1, 1, "100");
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread");
addot(OT_CAKEFRUIT, "fruit cake", "A very dense fruit cake. Restores all Stamina, Hit Points and Mana.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
@ -2609,6 +2611,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_EATCONFER, F_STENCH, 1, 1, "100");
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
addot(OT_HOTDOG, "hot dog", "A chunk of meat sandwiched between two pieces of bread. Temporarily increases strength, and provides some healing.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_RED, '%', NA, NULL);
@ -2981,9 +2984,11 @@ void initobjects(void) {
addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, 4, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
/*
addot(OT_SCR_MINDSCAN, "scroll of mind scan", "Allows you to view the world through another creature's eyes.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_LINKSPELL, OT_S_MINDSCAN, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL);
*/
addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL);
@ -4167,11 +4172,13 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
/*
addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
*/
addot(OT_S_STUN, "stun", "Stuns the target, preventing them from taking agressive action for a few seconds.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
@ -4738,6 +4745,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NEEDSGRAB, B_TRUE, NA, NA, NULL);
addot(OT_A_ENHANCEOB, "enhance item", "Combine two regular items into a single masterwork item.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_EXPLODESELF, "explode self", "Magically cause the molecules of your own body to violently explode.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, 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);
@ -5514,6 +5523,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 5, 20, NA, NULL);
addot(OT_STYPTIC, "styptic", "A medical compound designed to inhibit bleeding.", MT_METAL, 0.5, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_VALUE, 65, NA, NA, NULL);
@ -5535,7 +5545,36 @@ void initobjects(void) {
addflag(lastot->flags, F_EXPLODEONDEATH, NA, 1, NA, "10d2");
addflag(lastot->flags, F_MAKESNOISE, 33, SV_TALK, NA, "something sparking.");
addot(OT_VIBROBLADE, "vibroblade", "A futuristic blade which vibrates at ultra-high speed, adding cutting power to attacks.", MT_METAL, 1, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 8, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 50, 70, "5");
addflag(lastot->flags, F_CRITCHANCE, 25, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
// tech - l3
addot(OT_GUNBLADE, "gunblade", "A futuristic sword which (while powered) is capable of releasing controlled explosive charges at the time of impact.", MT_METAL, 1, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 6, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 70, 90, "5");
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 20, 30, NA, NULL);
addflag(lastot->flags, F_EXTRADAMWITHCHARGES, DT_EXPLOSIVE, NA, NA, "6d2");
addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_RARE, NULL);
@ -5571,6 +5610,37 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addot(OT_NANOBLADE, "nanoblade", "A monofilament blade capable of cutting through virtually any material.", MT_METAL, 1, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 10, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 60, 80, "5");
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
addot(OT_LASERSWORD, "lasersword", "A metal handle capable of extending out a blade of pure energy.", MT_METAL, 1, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 10, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 65, 85, "5");
addflag(lastot->flags, F_CRITCHANCE, 10, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURPIERCE, 5, NA, NA, "");
addot(OT_PROXMINE, "proximity mine", "An explosive charge which, once activated, is triggered by nearby motion.", MT_METAL, 2, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
@ -6517,6 +6587,16 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 15, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 95, NA, NA, NULL);
addot(OT_ARMOURTHORN, "thornspike armour", "Magical body armour which causes thorns to grow from your skin.", MT_LEATHER, 10, OC_ARMOUR, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_RETALIATE, DT_PIERCE, NA, "1d4^sharp thorns");
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 15, 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_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
@ -6828,7 +6908,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -1, NA, NULL);
@ -7175,6 +7255,21 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, "");
addflag(lastot->flags, F_EQUIPCONFER, F_STENCH, 2, 1, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_RING_UNHOLINESS, "ring of unholiness", "An evil ring which renders its wearer effectively undead.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_RARE, "");
addflag(lastot->flags, F_EQUIPCONFER, F_UNDEAD, B_TRUE, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DISEASEIMMUNE, B_TRUE, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_COLD, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISON, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_DECAY, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_NECROTIC, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_BREATHWATER, B_TRUE, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_NIGHTBOOST, 15, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DAYBOOST, -15, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addflag(lastot->flags, F_STARTBLESSED, B_CURSED, NA, NA, NULL);
addot(OT_RING_WATERBREATHING, "ring of water breathing", "Allows the wearer to breath normally while underwater.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, "");
addflag(lastot->flags, F_EQUIPCONFER, F_BREATHWATER, B_TRUE, NA, NULL);
@ -7373,7 +7468,7 @@ void initobjects(void) {
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, 90, NA, NA, "");
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL);
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 22, "1-2");
@ -7382,7 +7477,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHPARALYZE2, "strong paralyzing touch", "strong paralyzing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_ARMOURPIERCE, 90, NA, NA, "");
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL);
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "3-5");
@ -7391,7 +7486,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHPOISON, "poisonous touch", "poison touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_ARMOURPIERCE, 100, NA, NA, "");
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
@ -7566,10 +7661,9 @@ void initobjects(void) {
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 70, NA, NULL);
addflag(lastot->flags, F_ARMOURPIERCE, 8, NA, NA, "");
addflag(lastot->flags, F_ARMOURPIERCE, 6, NA, NA, "");
addflag(lastot->flags, F_DAM, DT_CHOP, 11, NA, NULL);
addflag(lastot->flags, F_ALTDAM, DT_BASH, 5, NA, "flat of blade");
addflag(lastot->flags, F_ARMOURPIERCE, 4, NA, NA, "");
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 65, 75, "10");
@ -7850,7 +7944,6 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
// long blades
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 80, NA, NULL);
@ -9612,7 +9705,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANCAST, OT_S_LIGHT, NA, NA, "pw:10;");
// may cast all life spells
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && (getspellschool(ot->id) == SS_LIFE)) {
if ((ot->obclass->id == OC_SPELL) && spellisfromschool(ot->id, SS_LIFE)) {
addflag(lastrace->flags, F_CANWILL, ot->id, NA, NA, "pw:10;");
}
}
@ -9631,6 +9724,12 @@ void initrace(void) {
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "cursing objects");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "eating pets");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "uncursing items");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "curing ailments");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "smiting evil");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "removing polymorphs");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "purifying food");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your items");
addrace(R_GODBATTLE, "Bjorn", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Bjorn the Battlelord is the god of honourable combat. He appears as a heavily built, bearded warrior clad in well-used armour.");
@ -9691,6 +9790,16 @@ void initrace(void) {
addflag(lastrace->flags, F_SACRIFICEOB, OT_SPELLBOOK, NA, 10, "OB explode#S into a shower of blood!");
addflag(lastrace->flags, F_SACRIFICEOB, OT_GRIMOIRE, NA, 10, "OB explode#S into a shower of blood!");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "restoring stamina");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "enraging you");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "enhancing your accuracy");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "hasting you");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "uncursing equipped items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "repairing items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "detecting enemies");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your weapon");
addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
@ -9729,7 +9838,7 @@ void initrace(void) {
addflag(lastrace->flags, F_GENDER, G_FEMALE, NA, NA, NULL);
// may cast all nature spells
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && (getspellschool(ot->id) == SS_NATURE)) {
if ((ot->obclass->id == OC_SPELL) && spellisfromschool(ot->id, SS_NATURE)) {
addflag(lastrace->flags, F_CANWILL, ot->id, NA, NA, "pw:10;");
}
}
@ -9746,6 +9855,18 @@ void initrace(void) {
// sacrifices
addflag(lastrace->flags, F_SACRIFICEOB, OT_CORPSE, RC_ANIMAL, 10, "Writhing vines sprout up and drag OB underground.");
addflag(lastrace->flags, F_SACRIFICEOB, OT_CORPSE, RC_DRAGON, 25, "Writhing vines sprout up and tear OB to pieces!");
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_FOOD, NA, 3, "Writhing vines sprout up and drag OB underground.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "entangling enemies");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "summoning plants");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "calling lightning");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "joining battle against dragons");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "purifying food");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "curing poison");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "healing injuries");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "sating hunger");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "providing ammo");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "mending armour");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing armour");
addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Felix is the god of Thieves, Revenge and Greed. He generally appears as an overweight glutton carrying his contraband loot around in huge sacks. Despite this, he is amazingly agile and is said to be able to steal one's soul right out of their body.");
@ -9798,6 +9919,13 @@ void initrace(void) {
// sacrifices (piety val will be overridden with value)
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_MONEY, NA, 2, "OB IS consumed in a swirl of shadowy blackness.");
addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_GEM, NA, 2, "OB IS consumed in a swirl of shadowy blackness.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "teleporting you out of danger");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "stealing from your enemies");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "turning you invisible");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "mapping your surroundings");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "unlocking doors");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "uncursing items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "identifying objects");
addrace(R_GODLIFE, "Glorana", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Glorana is the goddess of life. She appears as a pulsating orb of holy energy.");
addbodypart(lastrace, BP_BODY, "life energy");
@ -9825,7 +9953,7 @@ void initrace(void) {
addflag(lastrace->flags, F_REGENERATES, 5, NA, NA, NULL);
// may cast all life spells
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && (getspellschool(ot->id) == SS_LIFE)) {
if ((ot->obclass->id == OC_SPELL) && spellisfromschool(ot->id, SS_LIFE)) {
addflag(lastrace->flags, F_CANWILL, ot->id, NA, NA, "pw:10;");
}
}
@ -9845,7 +9973,13 @@ void initrace(void) {
addflag(lastrace->flags, F_SACRIFICEOB, OT_POT_RESTORATION, NA, 40, "OB IS consumed by a shaft of holy light.");
addflag(lastrace->flags, F_SACRIFICEOB, OT_POT_AMBROSIA, NA, 40, "OB IS consumed by a shaft of holy light.");
addflag(lastrace->flags, F_SACRIFICEOB, OT_BANDAGE, NA, 30, "OB IS consumed by a shaft of holy light.");
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_FOOD, NA, 3, "OB IS consumed by a shaft of holy light.");
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_WEAPON, NA, 2, "OB IS consumed by a shaft of holy light.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "granting heavenly armour");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "curing poison");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "sating hunger");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "healing you");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "restoring your mana");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "creating holy water");
addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of Death is garbed in a cloak made of pure shadow. and weilds an enormous scythe.");
setbodytype(lastrace, BT_HUMANOID);
@ -9878,7 +10012,7 @@ void initrace(void) {
addflag(lastrace->flags, F_FLEEONHPPCT, 10, NA, NA, NULL);
// may cast all death spells
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && (getspellschool(ot->id) == SS_DEATH)) {
if ((ot->obclass->id == OC_SPELL) && spellisfromschool(ot->id, SS_DEATH)) {
addflag(lastrace->flags, F_CANWILL, ot->id, NA, NA, "pw:10;");
}
}
@ -9895,6 +10029,11 @@ void initrace(void) {
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "casting holy spells");
// sacrifices
addflag(lastrace->flags, F_SACRIFICEOB, OT_CORPSE, NA, 2, "Bony claws rise up and drag OB underground.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "granting heavenly armour");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "flaying the flesh of your enemies");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "sending servants to aid you");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "slaying a nearby enemy");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "animating the dead");
addrace(R_GODFIRE, "Klikirak", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Klikirak is the burning god of Fire and Destruction. He is visible only as a raging inferno of fire, destroying anything in his path.");
addbodypart(lastrace, BP_BODY, "flames");
@ -9916,14 +10055,14 @@ void initrace(void) {
// god abilities
// may cast all fire spells
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && (getspellschool(ot->id) == SS_FIRE)) {
if ((ot->obclass->id == OC_SPELL) && spellisfromschool(ot->id, SS_FIRE)) {
addflag(lastrace->flags, F_CANWILL, ot->id, NA, NA, "pw:10;");
}
}
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_PRODUCESLIGHT, 6, NA, NA, NULL);
addflag(lastrace->flags, F_AUTOCREATEOB, 1, NA, NA, "large fire");
addflag(lastrace->flags, F_RETALIATE, 2, 4, DT_FIRE, "roaring flames");
addflag(lastrace->flags, F_RETALIATE, DT_FIRE, NA, NA, "2d4^roaring flames");
addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, B_TRUE, NA, NULL);
addflag(lastrace->flags, F_GODOF, NA, NA, NA, "Destruction & Fire");
addflag(lastrace->flags, F_GENDER, G_MALE, NA, NA, NULL);
@ -9936,6 +10075,8 @@ void initrace(void) {
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "using cold-based magic");
// sacrifices
addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_FLAMMABLE, NA, 2, "OB IS consumed in a burst of fire!");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "restoring frozen weapons");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "setting nearby objects on fire");
addrace(R_GODMAGIC, "Lumara", 55, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Lumara is the goddess of magic. She appears as a slender elderly woman, her expression wise with age.");
setbodytype(lastrace, BT_HUMANOID);
@ -9982,6 +10123,11 @@ void initrace(void) {
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_SCROLL, NA, 2, "OB disappear#S in a swirl of multicoloured lights.");
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_WAND, NA, 5, "OB disappear#S in a swirl of multicoloured lights.");
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_RING, NA, 10, "OB disappear#S in a swirl of multicoloured lights.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "restoring your mana");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "restoring your mana");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "uncursing items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "identifying items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "increasing your maximum mana");
addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Yumi is the goddess of Mercy and Forgiveness. She has a calm, serene face and wears simple clothing.");
@ -10029,7 +10175,12 @@ void initrace(void) {
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison");
// sacrifices
addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_WEAPON, NA, 2, "OB IS destroyed in a flash of power.");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "provide immunity to paralysis/stoning");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "put enemies to sleep");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "healing damage");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "curing poison");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "sating hunger");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "uncursing equipped items");
// monsters
@ -10179,6 +10330,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, "range:2;");
addflag(lastrace->flags, F_CANCAST, OT_S_BURNINGWAVE, NA, NA, "pw:6;");
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "unleashes its fiery breath");
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
@ -12095,11 +12247,11 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_RNDSPELLCOUNT, 2, NA, NA, NULL);
addflag(lastrace->flags, F_RNDSPELLSCHOOL, SS_NATURE, 1, 2, "pw:2;");
addflag(lastrace->flags, F_RNDSPELLSCHOOL, SS_NATURE, 1, 2, "pw:1;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures");
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 3, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "short bow");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "2-6 arrows");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "short bow");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-2 arrows");
addflag(lastrace->flags, F_STARTOB, 60, NA, NA, "cap");
addflag(lastrace->flags, F_STARTOB, 60, NA, NA, "leather shoes");
addflag(lastrace->flags, F_STARTSKILL, SK_RANGED, PR_BEGINNER, NA, NULL);
@ -12121,7 +12273,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
@ -12369,6 +12521,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, NA, NA, "range:1;");
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_SLEEP, NA, B_APPENDYOU, "throws a handful of sand");
addflag(lastrace->flags, F_TREMORSENSE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^rushing air");
@ -12527,6 +12680,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_DRILL, 5, NA, NULL);
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_DIG, NA, NA, "pw:1;");
addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "pounds its drills into the ground");
@ -13160,7 +13314,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "thorns");
addflag(lastrace->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d4^thorns");
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL);
@ -13184,7 +13338,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp spines");
addflag(lastrace->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d4^sharp spines");
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "cactus fruit");
addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL);
@ -13292,7 +13446,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "passionfruit");
addflag(lastrace->flags, F_RETALIATE, 1, 1, DT_PIERCE, "sharp spines");
addflag(lastrace->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d1^sharp spines");
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
@ -13511,8 +13665,9 @@ void initrace(void) {
addrace(R_CATCHEETAH, "cheetah", 250, 'f', C_BROWN, MT_FLESH, RC_ANIMAL, "A large cat capable of amazing running speeds. It also has unique paws which do not allow for gripping.");
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_RNDHOSTILE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_FREQUENT, NULL);
@ -13553,7 +13708,8 @@ void initrace(void) {
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RNDHOSTILE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
@ -13589,7 +13745,8 @@ void initrace(void) {
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RNDHOSTILE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
@ -13632,7 +13789,8 @@ void initrace(void) {
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RNDHOSTILE, 50, NA, NA, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_FREQUENT, NULL);
@ -13670,7 +13828,7 @@ void initrace(void) {
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
@ -14563,7 +14721,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp spines");
addflag(lastrace->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d4^sharp spines");
addflag(lastrace->flags, F_CORPSEFLAG, F_SHARP, 1, 4, NULL);
addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL, "An aggressive rodent, approximately the size of a cat.");
@ -15003,6 +15161,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_SPIDERCLIMB, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_WEB, 3, 3, "pw:1;range:4;");
addflag(lastrace->flags, F_CANWILL, OT_A_CLIMB, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
@ -15039,6 +15198,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 26, "10-20");
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 3, NA, NULL); // strong!
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_WEB, 3, 3, "pw:5;range:2;");
addflag(lastrace->flags, F_CANWILL, OT_A_CLIMB, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
@ -15077,6 +15237,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITCONFER, F_PAIN, SC_POISON, 26, "5-15");
addflag(lastrace->flags, F_HITCONFERVALS, DT_POISON, NA, NA, "1d2");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); // don't announce spellcasting
addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_WEB, 3, 3, "pw:7;range:3;");
addflag(lastrace->flags, F_CANWILL, OT_A_CLIMB, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
@ -16317,7 +16478,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
addflag(lastrace->flags, F_EXTRADAM, DT_COLD, NA, NA, "2d4");
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_RETALIATE, 2, 3, DT_COLD, "icy spikes");
addflag(lastrace->flags, F_RETALIATE, DT_COLD, NA, NA, "2d3^icy spikes");
addflag(lastrace->flags, F_SEEINDARK, 10, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
@ -16381,7 +16542,7 @@ void initrace(void) {
addbodypart(lastrace, BP_WINGS, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "razor-sharp spikes");
addflag(lastrace->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d4^razor-sharp spikes");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);

Binary file not shown.

14
defs.h
View File

@ -1819,6 +1819,7 @@ enum OBTYPE {
OT_A_DISARMLF, // disarm an opponent
OT_A_DRAGUNDERGROUND,
OT_A_ENHANCEOB,
OT_A_EXPLODESELF,
OT_A_FEIGNDEATH,
OT_A_FLIP,
OT_A_FLURRY,
@ -1934,10 +1935,14 @@ enum OBTYPE {
OT_POWERCORE,
OT_STYPTIC,
OT_TENT,
OT_VIBROBLADE,
// tech l3
OT_GUNBLADE,
OT_INFOVISOR,
OT_JETSKATES,
OT_LASERSWORD,
OT_LOCKHACKER,
OT_NANOBLADE,
OT_PORTLADDER,
OT_PROXMINE,
// tech l4
@ -2021,6 +2026,7 @@ enum OBTYPE {
OT_APRON,
OT_ARMOURDEMON,
OT_ARMOURLEATHER,
OT_ARMOURTHORN,
OT_ARMOURRING,
OT_ARMOURSCALE,
OT_ARMOURCHAIN,
@ -2130,6 +2136,7 @@ enum OBTYPE {
OT_RING_RESISTMAG,
OT_RING_SIGHT,
OT_RING_STENCH,
OT_RING_UNHOLINESS,
OT_RING_WATERBREATHING,
OT_RING_WOUNDING,
// innate / animal weapons
@ -3072,6 +3079,8 @@ enum FLAG {
F_ARMOURPENALTY, // lower your acc/ev by val0 due to cumbersome
// armour. lowered by sk_armour skill.
// v0 is accuracy penalty, v1 is evasion penalty.
// if v0 = b_true (or less than 0) it will
// pierce ALL armour
F_MINDSHIELD, // lf is immune to psionic attacks
F_MISCASTCHANCE, // lf has +v0% chance of spell failure
F_LEVRACE, // at level v0, this race is promoted to race v1
@ -3362,6 +3371,8 @@ enum FLAG {
F_GODOF, // text = what this lf is the god of. use capitals.
F_GODLIKES, // text = something this god likes (ie. incs piety)
F_GODDISLIKES, // text = something this god likes (ie. decs piety)
F_GODBATTLE, // text = what this god will do for you during battle
F_GODNOBATTLE, // text = what this god will do for you outside battle
F_GODPOISON, // v0=TRUE: god likes using poison. gain v1 piety
// v0=FALSE: god hates using poison. lose v1 piety
// for all sacrifice flags:
@ -3605,7 +3616,8 @@ enum FLAG {
F_REFLECTION, // missiles are reflected back at thrower
F_RETALIATE, // deal damage to anyone who hits you
// v0=ndice, v1=dsides, v2=damtype, text=obname
// text must have at least TWO words
// new:v0=damtype, text=dam^obname
// obname must have at least TWO words
F_RISEASGHOST, // become a ghost when you die.
F_SEEINDARK, // nightvis range is val0
F_SEEINVIS, // can see invisible things

2
flag.c
View File

@ -184,7 +184,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
} else {
// last one. insert at end of list.
f = fp->last;
f->next = malloc(sizeof(flag_t));
f->next = malloc(sizeof(flag_t)); /// <- died here!
f->next->prev = f;
f = f->next;
fp->last = f;

9
god.c
View File

@ -1634,7 +1634,9 @@ void pleasegod(enum RACE rid, int amt) {
msg("A searing heat runs through your blood.");
break;
case R_GODLIFE:
if (isdeaf(player)) {
if (isasleep(player)) {
msg("You dream of a choir singing.");
} else if (isdeaf(player)) {
msg("You have a feeling of holiness.");
} else {
msg("You hear a distance choir singing.");
@ -2066,7 +2068,10 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
if (plev >= PL_INDIFFERENT) {
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
int pow;
pow = plev + 2;
limit(&pow, 1, getspellmaxpower(OT_S_HEAVENARM));
dospelleffects(NULL, OT_S_HEAVENARM, pow, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE;
}
}

120
io.c
View File

@ -901,9 +901,14 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
getflags(c->lf->flags, retflag, &nretflags, F_RETALIATE, F_NONE);
for (i = 0; i < nretflags; i++) {
char *loctext,obname[BUFLEN],dicetext[BUFLEN],*p;
f = retflag[i];
if (strlen(extrainfo)) strcat(extrainfo, ", ");
strcat(extrainfo, f->text);
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(obname, p, '^');
strcat(extrainfo, obname);
free(loctext);
}
wep = getweapon(c->lf);
@ -1272,6 +1277,8 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
char buf[BUFLEN];
char *buf2;
char *p;
char *loctext;
char obname[BUFLEN],dicetext[BUFLEN];
poisontype_t *pt;
if (player && isdead(player)) {
@ -1603,10 +1610,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break;
case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it
msg("You are surrounded by a %s!", f->text);
msg("^%dYou are surrounded by a %s!", getlfcol(lf, CC_GOOD), f->text);
donesomething = B_TRUE;
} else {
msg("%s is surrounded by a %s!", lfname, f->text);
msg("^%d%s is surrounded by a %s!", getlfcol(lf, CC_GOOD), lfname, f->text);
donesomething = B_TRUE;
}
break;
@ -1870,9 +1877,13 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
break;
case F_RETALIATE:
msg("%s appear%s from %s%s skin.", noprefix(f->text),
(f->text[strlen(f->text)-1] == 's') ? "" : "s",
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(obname, p, '^');
msg("%s appear%s from %s%s skin.", noprefix(obname),
(obname[strlen(obname)-1] == 's') ? "" : "s",
lfname, getpossessive(lfname));
free(loctext);
donesomething = B_TRUE;
break;
case F_REGENERATES:
@ -1990,6 +2001,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
}
break;
case F_UNDEAD:
if (isplayer(lf)) {
msg("^%cAn evil taint spreads through your body!", getlfcol(lf, CC_GOOD));
donesomething = B_TRUE;
}
break;
case F_WINDSHIELD:
if (isplayer(lf)) {
msg("^gYou are surrounded by a whirling cyclone of debris!");
@ -2052,6 +2069,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
char buf[BUFLEN];
lifeform_t *lf2;
int donesomething = B_FALSE;
char *p;
char *loctext;
char obname[BUFLEN],dicetext[BUFLEN];
if (isdead(player)) {
return B_FALSE;
@ -2367,10 +2387,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break;
case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it
msg("Your %s vanishes!", f->text);
msg("^%dYour %s vanishes!", getlfcol(lf, CC_BAD), f->text);
donesomething = B_TRUE;
} else {
msg("%s%s %s vanishes!", lfname, getpossessive(lfname), f->text);
msg("^%d%s%s %s vanishes!", getlfcol(lf, CC_BAD), lfname, getpossessive(lfname), f->text);
donesomething = B_TRUE;
}
break;
@ -2555,10 +2575,14 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
break;
case F_RETALIATE:
msg("%s disappear%s from %s%s skin.", noprefix(f->text),
(f->text[strlen(f->text)-1] == 's') ? "" : "s",
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(obname, p, '^');
msg("%s disappear%s from %s%s skin.", noprefix(obname),
(obname[strlen(obname)-1] == 's') ? "" : "s",
lfname, getpossessive(lfname));
donesomething = B_TRUE;
free(loctext);
break;
case F_REGENERATES:
if (isplayer(lf)) { // don't know if monsters lose it
@ -2668,6 +2692,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
case F_TRUESTRIKE:
// no message when you lose this.
break;
case F_UNDEAD:
if (isplayer(lf)) {
msg("The evil taint leaves your body.");
donesomething = B_TRUE;
}
break;
case F_WINDSHIELD:
if (isplayer(lf) || cansee(player, lf)) {
msg("%s%s cyclonic shield vanishes.", lfname, getpossessive(lfname));
@ -3291,13 +3321,15 @@ object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, in
o = defob;
if (count) *count = defcount;
} else {
/*
if (useobletters) {
o = findobl(op, ch);
} else {
}
*/
o = NULL;
for (i = firstob ; (mylist[i] != NULL) && (y < lastline); i++) {
for (i = firstob ; (mylist[i] != NULL) && (useobletters || (y < lastline)); i++) {
if (useobletters) {
if (mylist[i]->letter == ch) {
o = mylist[i];
@ -5355,6 +5387,41 @@ char *makedesc_god(lifeform_t *god, char *retbuf) {
strcat(thisline, ".\n\n");
strncat(retbuf, thisline, HUGEBUFLEN);
sprintf(thisline, "During battle, %s will respond to prayers by ", godname);
getflags(god->flags, retflag, &nretflags, F_GODBATTLE, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (i == 0) {
strcat(thisline, f->text);
} else if (i == nretflags - 1) {
strcat(thisline, " and ");
strcat(thisline, f->text);
} else {
strcat(thisline, ", ");
strcat(thisline, f->text);
}
}
strcat(thisline, ".\n\n");
strncat(retbuf, thisline, HUGEBUFLEN);
sprintf(thisline, "Outside of battle, %s will respond to prayers by ", godname);
getflags(god->flags, retflag, &nretflags, F_GODNOBATTLE, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (i == 0) {
strcat(thisline, f->text);
} else if (i == nretflags - 1) {
strcat(thisline, " and ");
strcat(thisline, f->text);
} else {
strcat(thisline, ", ");
strcat(thisline, f->text);
}
}
strcat(thisline, ".\n\n");
strncat(retbuf, thisline, HUGEBUFLEN);
// note: we manually handle SACRIFICEOBWITHFLAG
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBBLESSED, F_SACRIFICEOBWITHFLAG,F_NONE);
if (nretflags == 0) {
@ -5618,6 +5685,8 @@ char *makedesc_ob(object_t *o, char *retbuf) {
flag_t *retflag[MAXCANDIDATES];
int nretflags;
object_t *compareob = NULL;
char *loctext,*p;
char retalname[BUFLEN],dicetext[BUFLEN];
// do we need to compare this object with an equipped on?
if (!isequipped(o)) {
@ -6493,7 +6562,11 @@ char *makedesc_ob(object_t *o, char *retbuf) {
}
f = hasflag(o->flags, F_ARMOURPIERCE);
if (f && f->known) {
sprintf(buf, "Armour will not reduce %s damage below %d.\n",OB1(o,"its","their"), f->val[0]);
if (f->val[0] < 0) {
sprintf(buf, "Armour will not reduce %s damage at all.\n",OB1(o,"its","their"));
} else {
sprintf(buf, "Armour will not reduce %s damage below %d.\n",OB1(o,"its","their"), f->val[0]);
}
strncat(retbuf, buf, HUGEBUFLEN);
}
f = hasflag(o->flags, F_BALANCE);
@ -6818,8 +6891,12 @@ char *makedesc_ob(object_t *o, char *retbuf) {
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_RETALIATE:
sprintf(buf2, "%s protects you with %s.\n", buf, f->text);
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(retalname, p, '^');
sprintf(buf2, "%s protects you with %s.\n", buf, retalname);
strncat(retbuf, buf2, HUGEBUFLEN);
free(loctext);
break;
case F_PROTALIGN:
sprintf(buf2, "%s repels attacks from %s aligned creatures.\n", buf,
@ -12287,12 +12364,19 @@ void showlfstats(lifeform_t *lf, int showall) {
f = lfhasflag(lf, F_RETALIATE);
if (f && (f->known)) {
char *loctext,retalname[BUFLEN],dicetext[BUFLEN],*p;
loctext = strdup(f->text);
p = readuntil(dicetext, loctext, '^');
readuntil(retalname, p, '^');
if (showall || (lorelev >= PR_BEGINNER)) {
wrapprint(mainwin, &y, &x, 0, "%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]));
wrapprint(mainwin, &y, &x, 0, "%s %s covered by %s (%s %s dmg to attackers). ", you(lf), is(lf), retalname,
dicetext, getdamname(f->val[0]));
} else {
wrapprint(mainwin, &y, &x, 0, "%s %s covered by %s ", you(lf), is(lf), f->text);
wrapprint(mainwin, &y, &x, 0, "%s %s covered by %s. ", you(lf), is(lf), retalname);
}
free(loctext);
}
// fleeing?
if (showall) {
@ -13471,6 +13555,12 @@ void showlfstats(lifeform_t *lf, int showall) {
y++;
}
f = hasflag_real(lf->flags, F_UNDEAD, B_TRUE, NULL, FROMRACE);
if (f) {
mvwprintw(mainwin, y, 0, "%s have been rendered undead.", you(lf));
y++;
}
f = lfhasflag(lf, F_STRIKETOKO);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s %s attacking in a non-lethal manner.", you(lf), is(lf));

93
lf.c
View File

@ -14955,6 +14955,13 @@ flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp) {
return NULL;
}
int isweaponbp(enum BODYPART bp) {
if ((bp == BP_WEAPON) || (bp == BP_SECWEAPON)) {
return B_TRUE;
}
return B_FALSE;
}
int isweaponskill(enum SKILL skid) {
switch (skid) {
case SK_AXES:
@ -15735,8 +15742,15 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
}
}
} else if (damtype == DT_WATER) {
int dosteam = B_FALSE;
if (lfhasflag(lf, F_ONFIRE) || (getlfmaterial(lf) == MT_FIRE)) {
dosteam = B_TRUE;
}
// put out fires
extinguishlf(lf);
if (dosteam) {
addob(lf->cell->obpile, "cloud of steam");
}
}
// low hitpoint warning for player
@ -16594,7 +16608,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// wake up a little
f = lfhasflag(l, F_ASLEEP);
if (f) {
if (f && (f->val[1] != ST_KO)) {
if (f->lifetime > 0) { // ie. temporary
timeeffectsflag(f, volume + rnd(1,3));
} else if (f->lifetime == PERMENANT) {
@ -16602,7 +16616,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// ie asleep rather than 'resting'
// wake up!
if (isplayer(l)) {
msg("^wA nearby noise awakens you!");
msg("^wA nearby noise %s you!", (f->val[1] == ST_MEDITATING) ? "" : "awakens" );
rv = B_TRUE;
}
killflag(f);
@ -21731,6 +21745,13 @@ int touch(lifeform_t *lf, object_t *o) {
}
// returns B_TRUE if the action which involved touching this should fail
//
// onpurpose = true means that we are actively touching the object with our hands (ie
// picking it up).
//
// onpurpose = false means that we have inadvertantly touched the object, maybe not
// with our hands (ie. we're constantl 'touching' armour while
// wearing it.)
int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
flag_t *f;
flag_t *retflag[MAXCANDIDATES];
@ -21770,12 +21791,22 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
}
}
// undead and blesed objects?
gloves = getequippedob(lf->pack, BP_HANDS);
// undead and blessed objects?
if (isundead(lf) && isblessed(o)) {
object_t *gloves;
// not wearing gloves?
gloves = getequippedob(lf->pack, BP_HANDS);
if (!gloves) {
int safe = B_FALSE;
if (gloves) {
if (onpurpose) {
// okay.
safe = B_TRUE;
} else {
if (isweaponbp(getequiploc(o))) {
safe = B_TRUE;
}
}
}
if (!safe) {
if (isplayer(lf)) {
msg("^bThe %s burn%s you as you touch %s!",noprefix(obname),
OBS1(o), OB1(o, "it", "them") ) ;
@ -21815,7 +21846,6 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
}
}
gloves = getequippedob(lf->pack, BP_HANDS);
f = hasflag(o->flags, F_SHARP);
if (f) {
@ -21899,8 +21929,8 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
dam = f->val[0];
}
losehp(lf, dam, dt, NULL, buf);
// drop the object if it's an equipped weapon
if ((o->pile->owner == lf) && isequipped(o) && isweapon(o)) {
// drop the object if it's an equipped weapon/shield
if ((o->pile->owner == lf) && isweaponbp(getequiploc(o))) {
drop(o, ALL);
}
return B_TRUE;
@ -22599,7 +22629,7 @@ int validateraces(void) {
}
if (hasflag(r->flags, F_CANCAST) && !hasflag(r->flags, F_CASTWITHOUTIQ)) {
if (getattr(lf, A_IQ) <= IQ_ANIMAL) {
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) <= IQ_ANIMAL) {
printf("ERROR in race '%s' - has F_CANCAST but iq is too low. might need f_castwithoutiq?\n", r->name);
goterror = B_TRUE;
}
@ -23202,6 +23232,7 @@ int rest(lifeform_t *lf, int onpurpose) {
int wear(lifeform_t *lf, object_t *o) {
int rv = B_FALSE,i;
char buf[BUFLEN],obname[BUFLEN];
int preknown;
flag_t *f;
enum BODYPART possbp[MAXBODYPARTS];
int nparts = 0,ncheckparts = 0;
@ -23440,6 +23471,34 @@ int wear(lifeform_t *lf, object_t *o) {
// at this point, we're going to try to wear it...
killflagsofid(lf->flags, F_HIDING);
// was the object already known?
preknown = isknown(o);
if (isplayer(lf)) {
if (o->type->id == OT_RING_UNHOLINESS) {
int protect = B_FALSE;
if (godprayedto(R_GODPURITY)) {
godsay(R_GODPURITY, B_TRUE, "Beware mortal! That ring holds the taint of impurity!");
protect = B_TRUE;
} else if (godprayedto(R_GODLIFE)) {
godsay(R_GODLIFE, B_TRUE, "Beware child! That ring is not for the living!");
protect = B_TRUE;
}
if (protect) {
char ques[BUFLEN],ch;
sprintf(ques,"Still put on %s?",obname);
ch = askchar(ques,"yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
msg("Cancelled.");
return B_TRUE;
}
// otherwise, you were warned, so count it as known...
preknown = B_TRUE;
}
}
}
// some checks first...
if (touch(lf, o)) {
taketime(lf, getactspeed(lf));
@ -23608,6 +23667,18 @@ int wear(lifeform_t *lf, object_t *o) {
makeknown(o->type->id);
}
if (isplayer(lf) && (o->type->id == OT_RING_UNHOLINESS) && preknown) {
enum RACE whichgod = R_NONE;
if (godprayedto(R_GODPURITY)) {
whichgod = R_GODPURITY;
} else if (godprayedto(R_GODLIFE)) {
whichgod = R_GODLIFE;
}
if (whichgod != R_NONE) {
angergod(whichgod, 50, GA_HERESY);
}
}
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
// set statdirty since this might have impacted your AR / EV
statdirty = B_TRUE;

1
lf.h
View File

@ -368,6 +368,7 @@ int isswimming(lifeform_t *lf);
int isunconscious(lifeform_t *lf);
int isundead(lifeform_t *lf);
flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp);
int isweaponbp(enum BODYPART bp);
int isweaponskill(enum SKILL skid);
enum FLAG iswoozy(lifeform_t *lf);
void killjob(job_t *job);

12
map.c
View File

@ -4490,7 +4490,8 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y);
if (!c->locked) {
setcelltype(c, getcellempty(c));
//setcelltype(c, getcellempty(c));
setcelltype(c, getcellsolid(c));
}
}
}
@ -4604,7 +4605,6 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
linkexits(map, map->room[i].id);
}
// replace all empty cells with slime (except the exit one)
for (i = 0; i < (map->w*map->h); i++){
c = map->cell[i];
@ -4646,8 +4646,6 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
}
}
// now move all objects out of the water
for (i = 0; i < (map->w*map->h); i++){
c = map->cell[i];
@ -4666,17 +4664,19 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
// add the exit. make sure it's next to a wall so it's possible to climb to.
// also ensure it's not over water.
c = NULL;
// infinite loop here.
while (!c || (countadjwalls(c) == 0) || getcellwaterdepth(c, NULL)) {
c = getrandomroomcell(map, ANYROOM, WE_NONE);
assert(c);
}
//////////
o = addobfast(c->obpile, OT_GRATINGROOF);
assert(o);
// have to force these stairs to go back to a different region.
f = hasflag(o->flags, F_CLIMBABLE);
assert(f);
f->val[1] = map->region->parentregion->id;
linkstairs(o, entryob);
//linkstairs(o, entryob);
}
void createstomach(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
@ -7252,7 +7252,7 @@ void initmap(void) {
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE);
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE);
addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN);
addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE);

View File

@ -3605,6 +3605,7 @@ objecttype_t *findotn(char *name) {
modname = strrep(modname, "blocks ", "block ", NULL);
modname = strrep(modname, "cans ", "can ", NULL);
modname = strrep(modname, "chunks ", "chunk ", NULL);
modname = strrep(modname, "clouds ", "cloud ", NULL);
modname = strrep(modname, "cloves ", "clove ", NULL);
modname = strrep(modname, "flasks ", "flask ", NULL);
modname = strrep(modname, "gems ", "gem ", NULL);
@ -7382,6 +7383,7 @@ int ismagicalobtype(objecttype_t *ot) {
switch (ot->id) {
case OT_SHILLELAGH:
case OT_WIZARDSTAFF:
case OT_ARMOURTHORN:
return B_TRUE;
default: break;
}
@ -10498,7 +10500,7 @@ int pour(lifeform_t *lf, object_t *o) {
for (d = DC_N; d <= DC_NW; d++) {
cell_t *c;
c = getcellindir(lf->cell, d);
if (c) {
if (c && haslos(lf, c)) {
object_t *door;
door = hasobwithflag(c->obpile, F_DOOR);
if (door) {
@ -12653,8 +12655,20 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
// water puts out fire
if (damtype == DT_WATER) {
int prehot = B_FALSE;
if (hasflag(o->flags, F_HOT) || hasflag(o->flags, F_ONFIRE) ||
hasflag(o->flags, F_FLAMESTRIKE)) {
prehot = B_TRUE;
}
extinguish(o);
makewet(o, howmuch);
if (prehot) {
cell_t *c;
c = getoblocation(o);
if (c) {
addob(c->obpile, "puff of steam");
}
}
}
// initial effects based on damage type
@ -13078,8 +13092,8 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
strcat(realthrowernamea, noprefix(realthrowername));
}
} else {
strcat(throwernamea, "something");
strcat(realthrowernamea, "something");
strcpy(throwernamea, "something");
strcpy(realthrowernamea, "something");
}
if (firearm) {
@ -13721,7 +13735,11 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
}
msg("^b%s", buf2);
}
snprintf(damstring, BUFLEN, "%s (%s by %s)",realobname,throwverbpast, realthrowernamea);
if (streq(realthrowernamea, "something")) {
snprintf(damstring, BUFLEN, "%s",realobname);
} else {
snprintf(damstring, BUFLEN, "%s (%s by %s)",realobname,throwverbpast, realthrowernamea);
}
if (dam > 0) {
@ -15316,6 +15334,15 @@ int wepdullable(object_t *o) {
if (!o) return B_FALSE;
// exceptions
switch (o->type->id) {
case OT_NANOBLADE:
case OT_LASERSWORD:
return B_FALSE;
default:
break;
}
dt = getdamtype(o);
switch (dt) {
case DT_PIERCE:
@ -15462,6 +15489,13 @@ int geteffecttime(int min, int max, enum BLESSTYPE isblessed) {
return howlong;
}
enum BODYPART getequiploc(object_t *o) {
flag_t *f;
f = isequipped(o);
if (!f) return BP_NONE;
return f->val[0];
}
// populate retob[] with all fire in the obpile
int getflamingobs(obpile_t *op, object_t **retob, int *nretobs) {
object_t *o;

View File

@ -76,6 +76,7 @@ int getcritchance(lifeform_t *lf, object_t *o, lifeform_t *victim);
int getdr(object_t *o);
int checkcritprotection(lifeform_t *lf, object_t *o);
int geteffecttime(int min, int max, enum BLESSTYPE isblessed);
enum BODYPART getequiploc(object_t *o);
int getflamingobs(obpile_t *op, object_t **retob, int *nretobs);
int getingredients(obpile_t *op, recipe_t *rec, object_t **retob, int *retcount, int *retconsume, int *nretobs, int promptformulti);
objecttype_t *getlinkspell(object_t *o);

150
spell.c
View File

@ -117,6 +117,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You can't charge while swimming!");
return B_TRUE;
} else if (isstuck(user)) {
if (isplayer(user)) msg("You can't charge while stuck!");
return B_TRUE;
}
if (!range) {
@ -1281,6 +1284,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (lfhasflag(user, F_GRABBEDBY)) {
if (isplayer(user)) msg("You can't jump while being held!");
return B_TRUE;
} else if (isstuck(user)) {
if (isplayer(user)) msg("You can't jump while stuck!");
return B_TRUE;
}
if (hasflag(user->flags, F_GRAVLESSENED)) {
@ -2159,6 +2165,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (!lfhasflagval(user, F_HASATTACK, OT_CLAWS, NA, NA, NULL)) {
if (isplayer(user)) msg("You need claws to perform a swoop attack.");
return B_TRUE;
} else if (isstuck(user)) {
if (isplayer(user)) msg("You can't swoop while stuck!");
return B_TRUE;
}
if (!targcell) {
@ -2419,6 +2428,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (lfhasflag(user, F_GRABBEDBY)) {
if (isplayer(user)) msg("You can't tumble while being held!");
return B_TRUE;
} else if (isstuck(user)) {
if (isplayer(user)) msg("You can't tumble while stuck!");
return B_TRUE;
}
if (targcell) {
@ -3026,6 +3038,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
practice(user, SK_SEWING, 1);
taketime(user, getactspeed(user));
} else if (abilid == OT_A_EXPLODESELF) {
// special case to avoid abuse
if (isplayer(user) && isimmuneto(user->flags, DT_EXPLOSIVE, B_FALSE)) {
msg("Your resistance to explosive damage prevents the use of this ability.");
return B_TRUE;
}
msg("^%c%s explode%s!", getlfcol(user, CC_VBAD), username, isplayer(user) ? "" : "s");
explodecells(user->cell, 9999, B_TRUE, NULL, 2, DT_COMPASS, B_FALSE);
} else if (abilid == OT_A_EXPOSEDSTRIKE) {
flag_t *f;
if (getweaponskill(user, getweapon(user)) < PR_BEGINNER) {
@ -4373,6 +4393,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
killflagsofid(target->flags, F_FLEEONHPPCT);
killflagsofid(target->flags, F_FLEEFROM);
killflagsofid(target->flags, F_TIMID);
killflagsofid(target->flags, F_ATTACKRANGE);
addflag(target->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
f = lfhasflag(target, F_MORALE); if (f) f->val[0] = 30;
} else if (spellid == OT_S_BURNINGFEET) {
@ -4665,7 +4686,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A relaxing aroma surrounds you.");
}
} else if (spellid == OT_S_CHAINLIGHTNING) {
cell_t *hitcell[MAXRETCELLS]; // all cells which have been hit in total
cell_t *hitcell[MAXRETCELLS*2]; // all cells which have been hit in total
cell_t *arccell[MAXRETCELLS]; // cells hit this time
cell_t *arccell2[MAXRETCELLS]; // cells hit this time
int nhitcells = 0, narccells,narccells2;
@ -5392,7 +5413,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_CUREPOISON) {
flag_t *retflag[MAXCANDIDATES];
int nretflags,i,donesomething = B_FALSE;
target = targcell->lf;
if (!target) {
target = targcell->lf;
}
if (!target) {
fizzle(caster);
return B_TRUE;
@ -7968,18 +7991,23 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_NULLIFY) {
flag_t *retflag[MAXCANDIDATES],*poss[MAXCANDIDATES],*f;
int nretflags,i,ndone = 0,nposs;
char announcebuf[BUFLEN];
int seen;
char lfname[BUFLEN];
strcpy(announcebuf, "");
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
getlfname(target, lfname);
seen = cansee(player, target);
if (isplayer(target)) {
msg("^BYou are engulfed in an anti-magic field!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
} else if (seen) {
msg("^B%s is engulfed in an anti-magic field!", lfname);
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
@ -7988,11 +8016,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
if (isplayer(target)) {
msg("Luckily, you shrug off its effects.");
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
} else if (seen) {
msg("%s seems unaffected.", lfname);
}
return B_FALSE;
}
// lose some mana
@ -8006,6 +8033,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (killflagsofid(target->flags, F_REVIVETIMER)) {
ndone++;
if (seen && !isplayer(target)) {
msg("^%c%s%s ability to regenerate is nullified!", getlfcol(target, CC_BAD), lfname, getpossessive(lfname));
}
}
// now stop active spells or abilities
@ -8023,8 +8053,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
}
if (nposs) {
stopspell(target, poss[rnd(0,nposs-1)]->val[0]);
enum OBTYPE sid;
objecttype_t *ot;
sid = (poss[rnd(0,nposs-1)])->val[0];
ot = findot(sid);
stopspell(target, sid);
ndone++;
if (seen && !isplayer(target)) {
msg("^%c%s%s active '%s' spell is nullified!", getlfcol(target, CC_BAD), lfname, getpossessive(lfname), ot->name);
}
} else {
break;
}
@ -8070,23 +8107,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
if (nposs) {
enum OBTYPE sid;
objecttype_t *ot;
f = poss[rnd(0,nposs-1)];
sid = f->val[0];
ot = findot(sid);
if (seen && !isplayer(target)) {
msg("^%c%s can no longer %s '%s'!", getlfcol(target, CC_BAD), lfname,
(f->id == F_CANCAST) ? "cast" : "use the ability", ot->name);
}
killflag(f);
ndone++;
} else {
break;
}
}
if (isplayer(target)) {
if (!ndone) {
if (!ndone) {
if (isplayer(target)) {
msg("You are unaffected.");
}
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
if (ndone) {
msg("^%c%s%s powers are nullified!", getlfcol(target, CC_BAD), lfname, getpossessive(lfname));
} else {
} else if (seen) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("%s is unaffected.", lfname);
}
}
@ -11709,7 +11750,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
flag_t *f;
if (!target) target = caster;
f = addtempflag(target->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp thorns", FROMSPELL);
f = addtempflag(target->flags, F_RETALIATE, DT_PIERCE, NA, NA, "1d4^sharp thorns", FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_TRUESTRIKE) {
flag_t *f;
@ -12469,6 +12510,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
} else if (spellid == OT_S_WINDSHIELD) {
char retaltext[BUFLEN];
flag_t *f;
// always targetted at caster
targcell = caster->cell;
@ -12476,7 +12518,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(caster->flags, F_WINDSHIELD, power, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
f = addtempflag(target->flags, F_RETALIATE, 1, power, DT_BASH, "whirling debris", FROMSPELL);
sprintf(retaltext, "1d%d^whirling debris", power);
f = addtempflag(target->flags, F_RETALIATE, DT_BASH, NA, NA, retaltext, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_WISHLIMITED) {
object_t *o = NULL;
@ -12650,41 +12694,51 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
}
}
} else if (ch == 'f') { // magic (spellbooks), bad: ???
objecttype_t *ot,*poss[MAXCANDIDATES];
int nposs = 0;
// find all castable spells (spellpower > 0)
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && getspellpower(target, ot->id)) {
poss[nposs++] = ot;
} else if (ch == 'f') { // magic (spellbooks), bad: gain 'explode self' magic
if (blessed == B_CURSED) {
flag_t *f;
f = lfhasflagval(target, F_CANWILL, OT_A_EXPLODESELF, NA, NA, NULL);
if (f) {
if (isplayer(target)) nothinghappens();
} else {
addflag(target->flags, F_CANWILL, OT_A_EXPLODESELF, 50, 50, NULL);
}
}
if (!nposs) {
// give knowledge of a random spell school plus sorcery
enum SPELLSCHOOL school;
skill_t *poss2[MAXSKILLS],*sk;
int nposs2 = 0;
for (school = SS_AIR; school < SS_LAST; school++) {
sk = findskill(getschoolskill(school));
poss2[nposs2++] = sk;
}
sk = poss2[rnd(0,nposs2-1)];
giveskill(target, sk->id);
// ... then try to find castable spells again
} else {
objecttype_t *ot,*poss[MAXCANDIDATES];
int nposs = 0;
// find all castable spells (spellpower > 0)
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && getspellpower(target, ot->id)) {
poss[nposs++] = ot;
}
}
}
if (!nposs) {
// give knowledge of a random spell school plus sorcery
enum SPELLSCHOOL school;
skill_t *poss2[MAXSKILLS],*sk;
int nposs2 = 0;
for (school = SS_AIR; school < SS_LAST; school++) {
sk = findskill(getschoolskill(school));
poss2[nposs2++] = sk;
}
sk = poss2[rnd(0,nposs2-1)];
giveskill(target, sk->id);
if (nposs) {
// pick a random spell from this list
ot = poss[rnd(0,nposs-1)];
snprintf(buf, BUFLEN, "spellbook of %s",ot->name);
} else {
strcpy(buf, "");
// ... then try to find castable spells again
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_SPELL) && getspellpower(target, ot->id)) {
poss[nposs++] = ot;
}
}
}
if (nposs) {
// pick a random spell from this list
ot = poss[rnd(0,nposs-1)];
snprintf(buf, BUFLEN, "spellbook of %s",ot->name);
} else {
strcpy(buf, "");
}
}
} else if (ch == '-') { // ie. nothing
if (isplayer(target)) {

5
text.c
View File

@ -291,6 +291,9 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
case DT_ELECTRIC:
snprintf(retbuf, BUFLEN, "^%c%s %s zapped!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
break;
case DT_EXPLOSIVE:
snprintf(retbuf, BUFLEN, "^%c%s %s blasted!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
break;
case DT_HEAT:
case DT_FIRE:
snprintf(retbuf, BUFLEN, "^%c%s %s burned!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
@ -1863,6 +1866,8 @@ char *makeplural(char *text) {
if (rv) return newtext;
newtext = strrep(newtext, "chunk ", "chunks ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "cloud ", "clouds ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "clove ", "cloves ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "flask ", "flasks ", &rv);