From 804f72f5c7a492d2215e30fc4973c2d356a92e44 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Thu, 19 Jan 2012 03:42:10 +0000 Subject: [PATCH] - [+] monsters vulnerable to lightning - [+] ice sprite ? (because it's water based) - [+] sawgrass - [+] change how repair works - [+] always repair to 100% - [+] skill determiens lowest hp percentage at which you can still repair it - [+] helper obs lower rather than increase cutoffpct - [+] felix should take all gold and gems when you die. - [+] reduce javelin weight - [+] felix should accept gems as sacrifice too. - [+] don't show "nothing happens" when felix casts reveal hidden. - [+] when checking if an object will block a door from closing, use the same code as when checking whether a lf is too big. - [+] The sound of a voice: "Braaaains... awakens you! - [+] Missing the last quote! - [+] check firearm reloading times (F_RELOADTURNS) - [+] add option: "automatically relaod empty firearms" --- data.c | 50 +++++++++++++++++++++++------------- data/hiscores.db | Bin 13312 -> 13312 bytes defs.h | 3 +++ god.c | 22 ++++++++++++---- io.c | 24 ++++++++++++++--- lf.c | 41 ++++++++++++++++++++++-------- move.c | 8 +++--- objects.c | 47 +++++++++++++++++++++++++++++++--- objects.h | 4 ++- spell.c | 65 ++++++++++++++++++++--------------------------- 10 files changed, 183 insertions(+), 81 deletions(-) diff --git a/data.c b/data.c index bc7d2b0..1af6d84 100644 --- a/data.c +++ b/data.c @@ -1839,6 +1839,7 @@ void initobjects(void) { // gems addot(OT_AQUAMARINE, "aquamarine stone", "An aqua-coloured gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); @@ -1847,6 +1848,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL); addot(OT_AMETHYST, "amethyst", "A purple gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); @@ -1855,6 +1857,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 15, NA, NA, NULL); addot(OT_DIAMOND, "diamond", "A sparkling diamond.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); @@ -1863,6 +1866,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addot(OT_EMERALD, "emerald", "A deep green gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); @@ -1871,6 +1875,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 650, NA, NA, NULL); addot(OT_OPAL, "opal", "An amorphous form of silica related to quartz.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); @@ -1879,6 +1884,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 70, NA, NA, NULL); addot(OT_PEARL, "pearl", "A small pinkish-white gem.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); @@ -1887,6 +1893,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL); addot(OT_RUBY, "ruby", "A large red gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); @@ -1895,6 +1902,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 110, NA, NA, NULL); addot(OT_SAPPHIRE, "sapphire", "A brilliant blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_CYAN, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); @@ -1903,6 +1911,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 850, NA, NA, NULL); addot(OT_TOPAZ, "topaz stone", "A dull blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); + addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '*', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); @@ -6094,7 +6103,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TANGLEMISSILE, 33, 30, B_TRUE, NULL); - addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6, OC_MISSILE, SZ_MEDIUM); + addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 4, OC_MISSILE, SZ_MEDIUM); 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, ""); @@ -6253,7 +6262,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL); addflag(lastot->flags, F_ALTDAM, DT_SLASH, 4, NA, NULL); - addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); @@ -7577,8 +7586,9 @@ void initrace(void) { addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "purchasing items"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "giving away or discarding money"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "opening locked objects through force"); - // sacrifices + // 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"); 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."); @@ -9004,6 +9014,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -9289,6 +9300,7 @@ void initrace(void) { 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); + addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); // end plants // animals @@ -9902,6 +9914,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_ACIDATTACK, 11, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^slurping"); addflag(lastrace->flags, F_DTIMMUNE, DT_ACID, B_TRUE, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL); addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "puddle of acid"); addflag(lastrace->flags, F_DIESPLATTER, 3, 0, NA, "splash of acid"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); @@ -9937,6 +9950,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "puddle of slime"); addflag(lastrace->flags, F_DIESPLATTER, 3, 0, NA, "puddle of slime"); + addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL); addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL, "Common venomous snakes."); setbodytype(lastrace, BT_SNAKE); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -11421,7 +11435,7 @@ void initskills(void) { addskilldesc(SK_ATHLETICS, PR_NOVICE, "^gYou gain the 'sprint' ability.^n", B_FALSE); addskilldesc(SK_ATHLETICS, PR_ADEPT, "^gYou gain the 'tumble' ability.^n", B_FALSE); addskilldesc(SK_ATHLETICS, PR_EXPERT, "^gYou gain the 'jump' ability.^n", B_FALSE); - addskill(SK_BACKSTAB, "Backstabbing", "Lets you inflict massive damage with stabs when unseen.", 50); + addskill(SK_BACKSTAB, "Backstabbing", "Lets you inflict massive damage when unseen and using a piercing weapon.", 50); addskilldesc(SK_BACKSTAB, PR_NOVICE, "^gYour unseen attacks inflict double damage.^n", B_FALSE); addskilldesc(SK_BACKSTAB, PR_BEGINNER, "^gYour unseen attacks inflict triple damage.^n", B_FALSE); addskilldesc(SK_BACKSTAB, PR_ADEPT, "^gYour unseen attacks inflict quadruple damage.^n", B_FALSE); @@ -11495,27 +11509,29 @@ void initskills(void) { addskill(SK_LOCKPICKING, "Lockpicking", "Enhances your ability to pick locks.", 50); addskilldesc(SK_LOCKPICKING, PR_NOVICE, "^gYou gain the 'pick locks' ability.^n", B_FALSE); addskill(SK_METALWORK, "Metalwork", "Lets you repair metal objects.", 25); - addskilldesc(SK_METALWORK, PR_NOVICE, "^gYou can repair metal items up to 40% condition.^n", B_FALSE); - addskilldesc(SK_METALWORK, PR_BEGINNER, "^gYou can repair metal items up to 60% condition.^n", B_FALSE); - addskilldesc(SK_METALWORK, PR_ADEPT, "^gYou can repair metal items up to 80% condition.^n", B_FALSE); + addskilldesc(SK_METALWORK, PR_NOVICE, "^gYou can repair metal items with condition >= 80%.^n", B_FALSE); + addskilldesc(SK_METALWORK, PR_BEGINNER, "^gYou can repair metal items with condition >= 65%.^n", B_FALSE); + addskilldesc(SK_METALWORK, PR_ADEPT, "^gYou can repair metal items with condition >= 50%.^n", B_FALSE); + addskilldesc(SK_METALWORK, PR_SKILLED, "^gYou can repair metal items with condition >= 25%.^n", B_FALSE); addskilldesc(SK_METALWORK, PR_SKILLED, "^gYou can re-size metal armour (at the expense of durability).^n", B_FALSE); addskilldesc(SK_METALWORK, PR_EXPERT, "^gYou can fully repair metal items.^n", B_FALSE); addskilldesc(SK_METALWORK, PR_MASTER, "^gYou can increase an item's quality to masterwork using a duplicate.^n", B_FALSE); addskill(SK_RANGED, "Ranged Weapons", "Your ability to aim a ranged weapon like a bow or gun.", 50); - addskilldesc(SK_RANGED, PR_INEPT, "^gYour ranged accuracy decreases by 32%% per cell.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_NOVICE, "^gYour ranged accuracy decreases by 22%% per cell.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_BEGINNER, "^gYour ranged accuracy decreases by 16%% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_INEPT, "^gYour ranged accuracy decreases by 32% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_NOVICE, "^gYour ranged accuracy decreases by 22% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_BEGINNER, "^gYour ranged accuracy decreases by 16% per cell.^n", B_FALSE); addskilldesc(SK_RANGED, PR_ADEPT, "^gYou can now reload ranged weapons instantly.^n", B_TRUE); - addskilldesc(SK_RANGED, PR_ADEPT, "^gYour ranged accuracy decreases by 12%% per cell.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_SKILLED, "^gYour ranged accuracy decreases by 10%% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_ADEPT, "^gYour ranged accuracy decreases by 12% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_SKILLED, "^gYour ranged accuracy decreases by 10% per cell.^n", B_FALSE); addskilldesc(SK_RANGED, PR_EXPERT, "^gMonsters no longer block your line of fire for ranged weapons.^n", B_TRUE); - addskilldesc(SK_RANGED, PR_EXPERT, "^gYour ranged accuracy decreases by 8%% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_EXPERT, "^gYour ranged accuracy decreases by 8% per cell.^n", B_FALSE); addskilldesc(SK_RANGED, PR_MASTER, "^gYour ranged attacks now deal 50% more damage.^n", B_TRUE); - addskilldesc(SK_RANGED, PR_MASTER, "^gYour ranged accuracy decreases by 6%% per cell.^n", B_FALSE); + addskilldesc(SK_RANGED, PR_MASTER, "^gYour ranged accuracy decreases by 6% per cell.^n", B_FALSE); addskill(SK_SEWING, "Sewing", "Lets you repair cloth or leather objects.", 25); - addskilldesc(SK_SEWING, PR_NOVICE, "^gYou can repair cloth items up to 40% condition.^n", B_FALSE); - addskilldesc(SK_SEWING, PR_BEGINNER, "^gYou can repair cloth items up to 60% condition.^n", B_FALSE); - addskilldesc(SK_SEWING, PR_ADEPT, "^gYou can repair cloth items up to 80% condition.^n", B_FALSE); + addskilldesc(SK_SEWING, PR_NOVICE, "^gYou can repair cloth items with condition >= 80%.^n", B_FALSE); + addskilldesc(SK_SEWING, PR_BEGINNER, "^gYou can repair cloth items with condition >= 65%.^n", B_FALSE); + addskilldesc(SK_SEWING, PR_ADEPT, "^gYou can repair cloth items with condition >= 50%.^n", B_FALSE); + addskilldesc(SK_SEWING, PR_SKILLED, "^gYou can repair cloth items with condition >= 25%.^n", B_FALSE); addskilldesc(SK_SEWING, PR_SKILLED, "^gYou can re-size cloth armour (at the expense of durability).^n", B_FALSE); addskilldesc(SK_SEWING, PR_EXPERT, "^gYou can fully repair cloth items.^n", B_FALSE); addskilldesc(SK_SEWING, PR_MASTER, "^gYou can increase an item's quality to masterwork using a duplicate.^n", B_FALSE); diff --git a/data/hiscores.db b/data/hiscores.db index e49d4452e12f7b3355ee1c8b63790ec10ea6ad3a..df2a9fc60e959d9bb9d8775287dc50ac136d7f85 100644 GIT binary patch delta 165 zcmV;W09yZmXn<&t8Ug|Wu^hDs0WP!B2w?&N{IfI*%_J)T000pHdH@5@1DykF12qE% z0?Go00#E`K0pS6#0eS&R0T%$`0ImRf07j8P9T_wL0TU}d7jkc6Om;FLNOf&tZXi-` zXLV(h93>bFF@bvq00I*=F#=eVkr5%YZ!kLnlgu+TlaVt!lUp-3lNU2YliM;pldLi? TlXfyTlMOO5liM*eld3T>d1WuN delta 193 zcmZq3Xvml##l-k;qs&$gM)}Q`I1-r{-)=VHKC9xyWX~YT;LO0dit#oRFH;%Q8m8OK z;>^*^6PeF2Rx&y>3NbujSj|ulRN~CQpwpPo#=s=3Y0P}HC_l-k%viyrGcell->obpile->first ; o ; o = nexto) { + int i; nexto = o->next; // does the god want this? getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_NONE); - int i; for (i = 0; i < nretflags; i++) { int ok = B_FALSE; int thispiety = 0; @@ -328,6 +328,17 @@ void dooffer(void) { if (ok) { char *p; char obname[BUFLEN]; + + // override piety sometimes + if (god->race->id == R_GODTHIEVES) { + // 100 value = 1 piety. + // NOTE: this could be exploited by constantly sacrificing + // 1 gold at a time! + if ((o->type->id == OT_GOLD) || hasflag(o->flags, F_GEM)) { + thispiety = (getobvalue(o) / 100) + 1; + } + } + if (haslos(player, player->cell)) { getobname(o, obname, ALL); p = strdup(f->text); @@ -344,9 +355,10 @@ void dooffer(void) { } removeob(o, ALL); pietyplus += thispiety; + break; } - } - } + } // end for each f_sacrificexxx flag + } // end foreach ob if (pietyplus) { pleasegod(god->race->id, pietyplus); @@ -968,8 +980,8 @@ int prayto(lifeform_t *lf, lifeform_t *god) { } else { int i,first = B_TRUE; msg("\"Allow me to reveal your surroundings...\""); - dospelleffects(lf, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); - dospelleffects(lf, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); // unlock doors for (i = 0; i < player->nlos; i++) { cell_t *c; diff --git a/io.c b/io.c index 29d772b..203d4f7 100644 --- a/io.c +++ b/io.c @@ -585,7 +585,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src if (targettype & TT_IMPASSABLE) { object_t *o; for (o = c->obpile->first ; o ; o = o->next) { - if (isimpassableob(o, player)) { + if (isimpassableob(o, player, getlfsize(player))) { valid = B_TRUE; break; } @@ -2269,7 +2269,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; break; case F_REFLECTION: - msg("^%cThe negative gravity around %s vanishes!", lfname); + msg("^%cThe negative gravity around %s vanishes!", getlfcol(lf, CC_BAD), lfname); donesomething = B_TRUE; break; case F_RETALIATE: @@ -4757,7 +4757,7 @@ char *makedesc_god(lifeform_t *god, char *retbuf) { strcat(thisline, ".\n\n"); strncat(retbuf, thisline, HUGEBUFLEN); - // TODO: manually handle SACRIFICEOBWITHFLAG + // note: we manually handle SACRIFICEOBWITHFLAG getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBBLESSED, F_NONE); if (nretflags == 0) { sprintf(thisline, "%s does not accept sacrifices.\n", godname); @@ -4801,6 +4801,24 @@ char *makedesc_god(lifeform_t *god, char *retbuf) { } strncat(retbuf, thisline, HUGEBUFLEN); } + getflags(god->flags, retflag, &nretflags, F_SACRIFICEOBWITHFLAG, F_NONE); + for (i = 0; i < nretflags; i++) { + if (i == 0) { + sprintf(thisline, "%s accepts the sacrifice of:\n", godname); + strncat(retbuf, thisline, HUGEBUFLEN); + } + strcpy(thisline, ""); + switch (retflag[i]->val[0]) { + case F_GEM: + sprintf(thisline, "- gems\n"); + break; + default: + break; + } + if (strlen(thisline)) { + strncat(retbuf, thisline, HUGEBUFLEN); + } + } } return retbuf; diff --git a/lf.c b/lf.c index 85432d4..df7ae34 100644 --- a/lf.c +++ b/lf.c @@ -906,7 +906,7 @@ int canpickup(lifeform_t *lf, object_t *o, int amt) { reason = E_NOPICKUP; return B_FALSE; } - if (isimpassableob(o, lf)) { + if (isimpassableob(o, lf, getlfsize(lf))) { reason = E_TOOBIG; return B_FALSE; } @@ -2425,9 +2425,21 @@ void die(lifeform_t *lf) { msg("Bony claws rise up and drag your corpse underground."); more(); break; case R_GODPURITY: msg("Your spirit ascends to the heavens."); more(); break; - case R_GODTHIEVES: - msg("All your possessions suddenly vanish!"); more(); - godsay(god->race->id, B_TRUE, "Yoink!"); more(); + case R_GODTHIEVES: // lose all gold / gems + if (countmoney(player->pack)) { + int taken = B_FALSE; + if (killobsofid(player->pack, OT_GOLD, B_TRUE)) { + taken = B_TRUE; + msg("All your gold suddenly vanishes!"); more(); + } + if (killobswithflag(player->pack, F_GEM, B_TRUE)) { + taken = B_TRUE; + msg("All your gems suddenly vanish!"); more(); + } + if (taken) { + godsay(god->race->id, B_TRUE, "Yoink!"); more(); + } + } break; case R_GODMERCY: if (onein(10)) { @@ -4113,12 +4125,13 @@ int fall_from_air(lifeform_t *lf) { // make 'lf' respond to damage void fightback(lifeform_t *lf, lifeform_t *attacker) { - interrupt(lf); + if (isdead(lf)) return; if (lfhasflag(lf, F_FEIGNINGDEATH) || lfhasflagval(lf, F_ASLEEP, NA, ST_KO, NA, NULL)) { // don't respond. return; } + interrupt(lf); // special cases if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) { @@ -12915,7 +12928,7 @@ int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *pctmod) { myval = getattr(lf, att); diff = myval - valneeded; - limit(&diff,-20, 15); + limit(&diff,-20, 20); // for firearms or scaleamt == 0, you MUST meet the requirement. if (diff < 0) { @@ -12935,7 +12948,7 @@ int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *pctmod) { if (pctmod) { // for each 5 points you are over/under the requirement, adjust "scaleamt" percent. - *pctmod = (diff/5) * scaleamt; + *pctmod = (diff/10) * scaleamt; } @@ -13009,7 +13022,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { statdirty = B_TRUE; } // already at max/min? - if ((amt > 0) && (lf->att[attr] >= 18)) { + if ((amt > 0) && (lf->att[attr] >= MAX_ATTRIBVAL)) { return B_TRUE; } if ((amt < 0) && (lf->att[attr] <= 0)) { @@ -13024,7 +13037,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { } // enforce limits - limit(&lf->att[attr], 0, 18); + limit(&lf->att[attr], 0, MAX_ATTRIBVAL); if (lf->born && (gamemode == GM_GAMESTARTED) && (amt != 0) && (isplayer(lf) || cansee(player, lf))) { char lfname[BUFLEN], verb[BUFLEN], adverb[BUFLEN]; @@ -13483,9 +13496,17 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, // wake up! if (isplayer(l)) { char wakenoise[BUFLEN]; + char *punc; assert(text); strcpy(wakenoise, text); - wakenoise[strlen(wakenoise)-1] = '\0'; // omit punctuation + // omit punctuation + punc = &(wakenoise[strlen(wakenoise)-1]); + switch (*punc) { + case '"': break; + default: + *punc = '\0'; + break; + } //msg("A nearby noise awakens you!"); msg("^wThe sound of %s awakens you!", wakenoise); rv = B_TRUE; diff --git a/move.c b/move.c index 084420c..a3ac940 100644 --- a/move.c +++ b/move.c @@ -409,7 +409,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) { } for (o = cell->obpile->first ; o ; o = o->next) { - if (isimpassableob(o, lf)) { + if (isimpassableob(o, lf, SZ_ANY)) { if (lf) { enum MATERIAL mid; mid = getlfmaterial(lf); @@ -1592,7 +1592,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { if (getlfmaterial(lf) == MT_GAS) { char obname[BUFLEN]; for (o = newcell->obpile->first ; o ; o = o->next) { - if (isimpassableob(o, lf) && !hasflag(o->flags, F_REALLYIMPASSABLE)) { + if (isimpassableob(o, lf, getlfsize(lf)) && !hasflag(o->flags, F_REALLYIMPASSABLE)) { getobname(o, obname, o->amt); if (isplayer(lf)) { msg("You seep around %s.", obname); @@ -1604,7 +1604,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { } else if (getlfmaterial(lf) == MT_SLIME) { char obname[BUFLEN]; for (o = newcell->obpile->first ; o ; o = o->next) { - if (isimpassableob(o, lf)) { + if (isimpassableob(o, lf, getlfsize(lf))) { getobname(o, obname, o->amt); if (isplayer(lf)) { msg("You seep under %s.", obname); @@ -2043,7 +2043,7 @@ int closedoor(lifeform_t *lf, object_t *o) { // any solid object other than the door? for (oo = cell->obpile->first ; oo ; oo = oo->next) { - if ((oo != o) && (getmaterialstate(oo->material->id) == MS_SOLID) && (getobsize(o) >= SZ_SMALL)) { + if ((oo != o) && (getmaterialstate(oo->material->id) == MS_SOLID) && isimpassableob(o, NULL, getobsize(o))) { if (lf && isplayer(lf)) { char inwayname[BUFLEN]; getobname(oo, inwayname, oo->amt); diff --git a/objects.c b/objects.c index ee83131..194929f 100644 --- a/objects.c +++ b/objects.c @@ -830,6 +830,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes createmap(targetmap, dlev, c->map->region, NULL, D_NONE, NULL); } targetcell = getrandomroomcell(targetmap, ANYROOM); + if (!targetcell) targetcell = getrandomcell(targetmap); while (!cellwalkable(NULL, targetcell, NULL)) { targetcell = getrandomadjcell(targetcell, WE_WALKABLE, B_ALLOWEXPAND); } @@ -6700,15 +6701,20 @@ int isidentified(object_t *o) { return B_TRUE; } -int isimpassableob(object_t *o, lifeform_t *lf) { +int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) { flag_t *f; f = hasflag(o->flags, F_IMPASSABLE); if (f) { enum LFSIZE lfsize; enum LFSIZE blockmin, blockmax; - if (!lf) return B_TRUE; - lfsize = getlfsize(lf); + if (!lf && (forcesize == SZ_ANY)) return B_TRUE; + + if (forcesize != SZ_ANY) { + lfsize = forcesize; + } else { + lfsize = getlfsize(lf); + } blockmin = f->val[0]; blockmax = f->val[1]; @@ -7168,6 +7174,7 @@ void killob(object_t *o) { } } + void killobmod(obmod_t *om) { obmod_t *nextone, *lastone; @@ -7200,6 +7207,40 @@ void killobpile(obpile_t *op) { free(op); } +// returns # killed +int killobsofid(obpile_t *op, enum OBTYPE oid, int includecontainers) { + object_t *o,*nexto; + int count = 0; + for (o = op->first ; o ; o = nexto) { + nexto = o->next; + if (o->contents && includecontainers) { + count += killobsofid(o->contents, oid, includecontainers); + } else if (o->type->id == oid) { + killob(o); + count++; + continue; + } + } + return count; +} + +// returns # killed +int killobswithflag(obpile_t *op, enum FLAG fid, int includecontainers) { + int count = 0; + object_t *o,*nexto; + for (o = op->first ; o ; o = nexto) { + nexto = o->next; + if (o->contents && includecontainers) { + count += killobswithflag(o->contents, fid, includecontainers); + } else if (hasflag(o->flags, fid)) { + killob(o); + count++; + continue; + } + } + return count; +} + void killoc(objectclass_t *oc) { objectclass_t *nextone, *lastone; int i; diff --git a/objects.h b/objects.h index 660ffe6..6a1a9cf 100644 --- a/objects.h +++ b/objects.h @@ -189,7 +189,7 @@ int isknown(object_t *o); int isknownot(objecttype_t *ot); int isheavyweapon(object_t *o); int isidentified(object_t *o); -int isimpassableob(object_t *o, lifeform_t *lf); +int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize); int ismagical(object_t *o); int ismeleeweapon(object_t *o); int ismetal(enum MATERIAL mat); @@ -217,6 +217,8 @@ void killmaterial(material_t *m); void killob(object_t *o); void killobmod(obmod_t *om); void killobpile(obpile_t *o); +int killobsofid(obpile_t *op, enum OBTYPE oid, int includecontainers); +int killobswithflag(obpile_t *op, enum FLAG fid, int includecontainers); void killobtype(object_t *o); void killoc(objectclass_t *oc); void killot(objecttype_t *ot); diff --git a/spell.c b/spell.c index 1c1f82b..a941279 100644 --- a/spell.c +++ b/spell.c @@ -1308,7 +1308,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // did you land on something impassable? for (o = targcell->obpile->first ; o ; o = o->next) { - if (isimpassableob(o, user)) { + if (isimpassableob(o, user, getlfsize(user))) { char obname[BUFLEN]; getobname(o, obname, o->amt); if (isplayer(user)) { @@ -1415,7 +1415,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else if (abilid == OT_A_REPAIR) { object_t *o,*helpob = NULL; enum MATERIAL repairablemats[MAXCANDIDATES]; - int repaircutoff = 0; int cutoffpct[MAXCANDIDATES]; int nmats = 0; int i; @@ -1442,10 +1441,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef float pct; f = hasflag(o->flags, F_OBHP); pct = ((float)f->val[0] /(float) f->val[1]) * 100; - if (pct < cutoff) { + if (pct >= cutoff) { char buf[BUFLEN],desc[BUFLEN]; getobname(o, buf, o->amt); - sprintf(desc, "%s (-> %d%%)",buf, cutoff); + sprintf(desc, "%s",buf); // we can repair this object addchoice(&prompt, o->letter, desc, desc, o, NULL); } @@ -1475,16 +1474,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_FALSE; } - // select cutoff hp - repaircutoff = 0; - for (i = 0; i < nmats; i++) { - if (o->material->id == repairablemats[i]) { - repaircutoff = cutoffpct[i]; - break; - } - } - assert(repaircutoff != 0); - // get helper ob helpob = getworkhelpob(user->pack, o->material->id); if (helpob) { @@ -1493,25 +1482,23 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef strcpy(helpobname, ""); } - // repair it! + // fully repair it. f = hasflag(o->flags, F_OBHP); - f->val[0] = pctof(repaircutoff, f->val[1]); + f->val[0] = f->val[1]; if (isplayer(user)) { char buf[BUFLEN],withbuf[BUFLEN]; real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE); if (helpob) sprintf(withbuf, " (with %s)", helpobname); else strcpy(withbuf, ""); - msg("You %srepair your %s%s.", (f->val[0] == f->val[1]) ? "" : "partially ", - noprefix(buf), withbuf); + msg("You repair your %s%s.", noprefix(buf), withbuf); } else { char buf[BUFLEN],withbuf[BUFLEN]; real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE); if (helpob) sprintf(withbuf, " with %s", helpobname); else strcpy(withbuf, ""); - msg("%s %s repairs %s%s.", username, (f->val[0] == f->val[1]) ? "completely" : "partially", - buf, withbuf); + msg("%s repairs %s%s.", username, buf, withbuf); } practice(user, SK_METALWORK, 1); @@ -6821,7 +6808,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int x,y; int range; map_t *m; - m = caster->cell->map; + if (!target) target = caster; + m = target->cell->map; if (power == 10) { range = UNLIMITED; } else { @@ -6834,15 +6822,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ c = getcellat(m, x, y); if (c) { if (range == UNLIMITED) { - setcellknown(c, MAXOF(PR_ADEPT, getskill(caster, SK_CARTOGRAPHY))); + setcellknown(c, MAXOF(PR_ADEPT, getskill(target, SK_CARTOGRAPHY))); } else if (getcelldist(caster->cell, c) <= range) { - setcellknown(c, MAXOF(PR_ADEPT, getskill(caster, SK_CARTOGRAPHY))); + setcellknown(c, MAXOF(PR_ADEPT, getskill(target, SK_CARTOGRAPHY))); } } } } - if (isplayer(caster)) { + if (isplayer(target)) { msg("An image of your surroundings appears in your mind!"); if (seenbyplayer) *seenbyplayer = B_TRUE; needredraw = B_TRUE; @@ -8669,11 +8657,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_REVEALHIDDEN) { int i; int seen = B_FALSE; - for (i = 0 ; i < caster->nlos; i++ ){ - targcell = caster->los[i]; + if (!target) target = caster; + for (i = 0 ; i < target->nlos; i++ ){ + targcell = target->los[i]; if (targcell) { object_t *o; - if (isplayer(caster)) { + if (isplayer(target)) { // reveal secret doors/obs/etc for (o = targcell->obpile->first ; o ; o = o->next) { flag_t *f; @@ -8697,7 +8686,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if ((f->lifetime > 0) || (f->lifetime == PERMENANT)) { killflag(f); // player can see whoever just appeared, and the caster? - if (cansee(player, targcell->lf) && cansee(player, caster)) { + if (cansee(player, targcell->lf) && cansee(player, target)) { char tname[BUFLEN]; seen = B_TRUE; getlfname(targcell->lf, tname); @@ -8705,10 +8694,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } } else if ( (f->id == F_HIDING) && - !lfhasflagval(caster, F_SPOTTED, targcell->lf->id, NA, NA, NULL)) { - addflag(caster->flags, F_SPOTTED, targcell->lf->id, NA, NA, NULL); + !lfhasflagval(target, F_SPOTTED, targcell->lf->id, NA, NA, NULL)) { + addflag(target->flags, F_SPOTTED, targcell->lf->id, NA, NA, NULL); // player can see whoever just appeared, and the caster? - if (cansee(player, targcell->lf) && cansee(player, caster)) { + if (cansee(player, targcell->lf) && cansee(player, target)) { char tname[BUFLEN]; seen = B_TRUE; getlfname(targcell->lf, tname); @@ -11202,12 +11191,12 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair slev = getskill(lf, skid); switch (slev) { - case PR_NOVICE: cutoff = 40; break; - case PR_BEGINNER: cutoff = 60; break; - case PR_ADEPT: cutoff = 80; break; - case PR_SKILLED: cutoff = 80; break; - case PR_EXPERT: cutoff = 100; break; - case PR_MASTER: cutoff = 100; break; + case PR_NOVICE: cutoff = 80; break; + case PR_BEGINNER: cutoff = 65; break; + case PR_ADEPT: cutoff = 50; break; + case PR_SKILLED: cutoff = 25; break; + case PR_EXPERT: cutoff = 0; break; + case PR_MASTER: cutoff = 0; break; default: cutoff = 0; break; } if (skid == SK_METALWORK) { @@ -11215,7 +11204,7 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair } else if (skid == SK_SEWING) { helpob = getworkhelpob(lf->pack, MT_CLOTH); } - if (helpob) cutoff += 15; + if (helpob) cutoff -= 15; if (cutoff) { if (skid == SK_METALWORK) {