From 38a788ca5f2749e4319289428799a220c09cd76b Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Wed, 5 Dec 2012 05:00:54 +0000 Subject: [PATCH] - [+] pour poison potion on weapon should poison it. - [+] coldness shoudl reduce object heat and heat should add f_hot - [+] novice engineering should let you make arrows. - [+] hunter shouhld have novice engineering. - [+] BUG: during the game: i nvalid racename 'piranha' in vault pool_room - [+] this happened because more than 1 appeared. - [+] disallow minions/numapepar in vaults. --- ai.c | 4 +- attack.c | 10 +-- data.c | 26 ++++---- data/hiscores.db | Bin 17408 -> 17408 bytes defs.h | 1 + god.c | 10 ++- io.c | 22 +++---- lf.c | 128 ++++++++++++++++++++++++++---------- objects.c | 120 +++++++++++++++++++++++++++++----- objects.h | 1 + spell.c | 166 +++++++++++++++++++++++++++++------------------ spell.h | 1 + text.c | 11 ++-- 13 files changed, 352 insertions(+), 148 deletions(-) diff --git a/ai.c b/ai.c index a22f76c..b5fc136 100644 --- a/ai.c +++ b/ai.c @@ -126,7 +126,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { sayphrase(lf, SP_ALLY_ATTACKUNSEEN, SV_SHOUT, NA, text, victim); } } else { - makenoise(lf, N_GETANGRY); + if (!lfhasflag(lf, F_HIDING)) makenoise(lf, N_GETANGRY); } // become hostile? @@ -2977,7 +2977,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG int found = B_FALSE,i; // must be a corpse in sight for (i = 0; i < lf->nlos; i++) { - if (hasob(lf->los[0]->obpile, OT_CORPSE)) { + if (hasob(lf->los[i]->obpile, OT_CORPSE)) { found = B_TRUE; break; } diff --git a/attack.c b/attack.c index 28705d8..5bd75dd 100644 --- a/attack.c +++ b/attack.c @@ -33,10 +33,10 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty int damtaken = 0; // first of all, only apply some of the damage - //dam /= 2; - //if (dam == 0) { -// return 0; -// } + dam /= 2; + if (dam == 0) { + return 0; + } // special case - missiles always hit flak jacket if (damtype == DT_PROJECTILE) { @@ -2271,7 +2271,7 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da if (pctchance(fullchance)) { blocked = B_TRUE; } - } + } // did we block with this object? if (!blocked && skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i])) { blocked = B_TRUE; diff --git a/data.c b/data.c index c327e29..1361512 100644 --- a/data.c +++ b/data.c @@ -599,6 +599,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ENGINEERING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LISTEN, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); @@ -614,8 +615,8 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_EVASION, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_ENGINEERING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, PR_ADEPT, NA, NULL); // limit + addflag(lastjob->flags, F_CANLEARN, SK_ENGINEERING, PR_ADEPT, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_LORE_HUMANOID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_DRAGONS, NA, NA, NULL); // abilities @@ -3147,7 +3148,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHLARGE, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addot(OT_ASHLARGE, "large pile of ash", "A large pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); @@ -3157,7 +3158,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHHUGE, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_ASH, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); @@ -3168,7 +3169,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_SHRINKSTO, OT_ASH, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); @@ -3179,7 +3180,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); @@ -3192,7 +3193,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addot(OT_ASHINVIS, "pile of prankster's dust", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); @@ -3203,7 +3204,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); @@ -3215,7 +3216,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); - addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK, SZ_TINY); @@ -3613,6 +3614,7 @@ void initobjects(void) { addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "0"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addot(OT_SANDWICHCHEESE, "cheese sandwich", "A tasty cheese sandwich. Filling, and restores all stamina plus some health.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_LIGHTBROWN, '%', NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); @@ -6135,6 +6137,7 @@ void initobjects(void) { addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder. Said to be highly unstable.", MT_METAL, 0.5, OC_TOOLS, SZ_TINY); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of black powder"); + addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); @@ -9177,7 +9180,7 @@ void initobjects(void) { addot(OT_COMBATKNIFE, "combat knife", "A sharp, lightweight knife designed for military use.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 65, NA, NULL); - addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL); + addflag(lastot->flags, F_OBATTACKDELAY, 65, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 4, NA, NULL); addflag(lastot->flags, F_ALTDAM, DT_PIERCE, 3, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -20418,12 +20421,13 @@ void initskills(void) { addskill(SK_ENGINEERING, "Engineering", "Your construction knowledge and skill with devices like traps.", 25); addskilldesc(SK_ENGINEERING, PR_INEPT, "Each level increases damage dealt to doors/walls by +2.", B_FALSE); addskillabil(SK_ENGINEERING, PR_NOVICE, OT_A_DISARM, NA, NULL, B_TRUE); + addskillabil(SK_ENGINEERING, PR_NOVICE, OT_A_BUILD, NA, NULL, B_TRUE); addskilldesc(SK_ENGINEERING, PR_NOVICE, "You receive extra knowledge about walls/floors.", B_FALSE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now 'see' the remaining hit points of walls.", B_FALSE); addskillabil(SK_ENGINEERING, PR_BEGINNER, OT_A_DISMANTLE, NA, NULL, B_TRUE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now detect hollow spaces.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now identify trap types.", B_TRUE); - addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now create barricades and basic traps.", B_TRUE); + //addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now create barricades and basic traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now dismantle doors and made-made walls.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_SKILLED, "You now automatically detect traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_SKILLED, "Your speed at dismantling walls is doubled.", B_TRUE); diff --git a/data/hiscores.db b/data/hiscores.db index e58d5e260f8f7ed35dd14edb91e3348b24ef766d..913609c775a9654cd3969c5c9135298287158bd7 100644 GIT binary patch delta 358 zcmZqZU~K4MoFL6;wo&E1EUj&a0C$! zAi^F**lj+~Wy&kW&bX9;c>}W-(|e}bOrDHi8JBJ>>}Qnnb7Es)5;n|dbSuhF@+mV? z@F>kq%u{g7ESmgILyRRSH8pwiLQNTyAV)R^Mq$IsSafBnxrynio_Wccd8tK-C8;S2 zNtFtT3OR{I>8X<)#T4WM9Kae&nZOzi5$1z6PX4GQI(e?Syh)Hf#C&^F%%32w;1FrY z4)lP2BP-JquvQa=;MAPF{34)5c_pbu!8wVUc@Q_H=jG?*C}eFCB01p02P^S7XSbN delta 89 zcmZqZU~K4MoFL6;xKZW>JF_j*`N`}YHJlYpH<)#pc$n2T_i$)2Nir}oX0kE^$s91L l0U{ZW1If+jxlDOEn3%m7m^UzcZ7jUXG_fIbvzPQX4FHu$6r}(F diff --git a/defs.h b/defs.h index 860b1a4..90c917b 100644 --- a/defs.h +++ b/defs.h @@ -489,6 +489,7 @@ enum CELLCONDITION { CC_READABLE, CC_SPECIFIED, // hard - does retlist contain this ?? CC_WEARABLE, + CC_WEILDABLE, CC_WEAPON, CC_WEPSK }; diff --git a/god.c b/god.c index 30b8b41..acaf590 100644 --- a/god.c +++ b/god.c @@ -555,6 +555,8 @@ void askforworship(enum RACE rid) { msg("\"%s\"", getflagtext(god->flags, F_GODDECLINE)); more(); } } + // make god vanish + castspell(god, OT_S_PLANESHIFT, god, NULL, god->cell, NULL, NULL); } void checkgodbonus(enum RACE rid, enum PIETYLEV newlev, enum PIETYLEV oldlev) { @@ -737,7 +739,7 @@ void dooffer(void) { if ((god->race->id == R_GODNATURE) && (o->type->obclass->id == OC_FLORA) && newcell) { - addmonster(player->cell, R_BUTTERFLY, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL); + addmonster(newcell, R_BUTTERFLY, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL); } if (o->type->obclass->id == OC_FLORA) { @@ -2006,7 +2008,11 @@ void pleasegod(enum RACE rid, int amt) { if (!prayedtoany() && !lfhasflag(player, F_GODOFFERDONE)) { if ((newplev > oldplev) && (newplev >= PL_PLEASED)) { - askforworship(rid); + if ((rid == R_GODDEATH) && (getalignment(player) == AL_GOOD)) { + } else if ((rid == R_GODLIFE) && (getalignment(player) == AL_EVIL)) { + } else { + askforworship(rid); + } } } } diff --git a/io.c b/io.c index c1b840d..5e1614d 100644 --- a/io.c +++ b/io.c @@ -1249,7 +1249,7 @@ char askdir(char *prompt, int maycancel, int usedrunk) { // retbuf must already be allocated // "def" is optional -char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def) { +char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def) { char buf[BUFLEN],msghistbuf[BUFLEN]; char *ending; @@ -1271,7 +1271,7 @@ char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def) mvwprintw(msgwin, 0, 0, buf); wrefresh(msgwin); echo(); - wgetnstr(msgwin, retbuf, retBUFLEN); + wgetnstr(msgwin, retbuf, retbuflen); noecho(); clearmsg(); if (def && (strlen(retbuf) == 0)) { @@ -5513,7 +5513,7 @@ int doweild(obpile_t *op) { int rv; condset_t cs; // include _anything_ which could be weilded, even if not neccesarily a weapon. - initcondv(&cs, CC_HASFLAG, B_TRUE, F_DAM, + initcondv(&cs, CC_WEILDABLE, B_TRUE, NA, CC_NONE); o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', &cs, B_TRUE); if (o) { @@ -9828,7 +9828,7 @@ int drop(object_t *o, int count) { } } */ - } else { + } else if (!isdeadob(o)) { // tell the player why! if (isplayer(op->owner)) { switch (reason) { @@ -10503,21 +10503,21 @@ int getkey(int escseqok) { enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev) { switch (slev) { case PR_INEPT: - return C_RED; + return C_DARKGREY; case PR_NOVICE: return C_BROWN; case PR_BEGINNER: - return C_GREY; + return C_LIGHTYELLOW; case PR_ADEPT: - return C_GREEN; + return C_LIGHTGREEN; case PR_SKILLED: - return C_BLUE; + return C_LIGHTBLUE; case PR_EXPERT: - return C_CYAN; + return C_LIGHTCYAN; case PR_MASTER: - return C_MAGENTA; + return C_LIGHTMAGENTA; } - return C_GREY; + return C_DARKGREY; } void handle_ctrl_y(int arg) { diff --git a/lf.c b/lf.c index ea2838c..c4532be 100644 --- a/lf.c +++ b/lf.c @@ -596,68 +596,98 @@ int canattack(lifeform_t *lf) { } // need ob is populated with with the obejcttype needed. +// returns TRUE if we can build it. int canbuild(lifeform_t *lf, objecttype_t *ot, char *needtext, enum OBTYPE *needob, int *numneed) { char requiretext[BUFLEN]; objecttype_t *tempot; + int i; char *template = " (required %d x %s)"; + enum OBTYPE localneed = OT_NONE; + enum OBTYPE altob[MAXCANDIDATES]; + int localnum = 0,nalt = 0; object_t *o; - *needob = OT_NONE; - if (needtext) sprintf(needtext, "%s", ot->name); + for (i = 0; i < MAXCANDIDATES; i++) { + altob[i] = OT_NONE; + } + + if (needtext) { + sprintf(needtext, "%s", ot->name); + } switch (ot->id) { + case OT_ARROW: + localneed = OT_WOODSHARD; + localnum = 1; + altob[0] = OT_STICK; + nalt = 1; + break; case OT_BARRICADE: - *needob = OT_IRONSTAFF; - *numneed = 2; + localneed = OT_IRONSTAFF; + localnum = 2; break; case OT_RUBBLE: - *needob = OT_STONE; - *numneed = 20; + localneed = OT_STONE; + localnum = 20; break; case OT_FENCEWOOD: - *needob = OT_WOODPLANK; - *numneed = 1; + localneed = OT_WOODPLANK; + localnum = 1; break; case OT_TRAPDOORFALL: - *needob = OT_NONE; - *numneed = 0; + localneed = OT_NONE; + localnum = 0; break; case OT_TRAPNEEDLEP: - *needob = OT_NEEDLE; - *numneed = 1; + localneed = OT_NEEDLE; + localnum = 1; break; case OT_TRAPFIRE: - *needob = OT_POT_RUM; - *numneed = 1; + localneed = OT_POT_RUM; + localnum = 1; break; case OT_TRAPMINE: - *needob = OT_GRENADE; - *numneed = 1; + localneed = OT_GRENADE; + localnum = 1; break; case OT_TRAPARROW: - *needob = OT_ARROW; - *numneed = 1; + localneed = OT_ARROW; + localnum = 1; break; case OT_TRAPROCK: - *needob = OT_STONE; - *numneed = 1; + localneed = OT_STONE; + localnum = 1; break; case OT_TRAPTRIP: - *needob = OT_ROPE; - *numneed = 1; + localneed = OT_ROPE; + localnum = 1; break; default: break; } - if (*needob == OT_NONE) { + if (needob) *needob = localneed; + if (numneed) *numneed = localnum; + + if (localneed == OT_NONE) { return B_TRUE; } - o = hasob(lf->pack, *needob); - if (o && (o->amt >= *numneed)) { - tempot = findot(*needob); - sprintf(requiretext, template, *numneed, tempot->name); + o = hasob(lf->pack, localneed); + if (!o && nalt) { + int i; + for (i = 0; i < nalt; i++ ){ + o = hasob(lf->pack, altob[i]); + if (o) { + localneed = altob[i]; + if (needob) *needob = localneed; + break; + } + } + } + if (o && (o->amt >= localnum)) { + tempot = findot(localneed); + sprintf(requiretext, template, localnum, tempot->name); if (needtext) strcat(needtext, requiretext); return B_TRUE; } @@ -3829,7 +3859,7 @@ void die(lifeform_t *lf) { f = hasflag(corpse->flags, F_CORPSEOF); if (f) { - f->val[1] = lf->level; + f->val[1] = gettr(lf); } // some corpses will regenerate... @@ -5201,7 +5231,7 @@ int eat(lifeform_t *lf, object_t *o) { } } } - if (fid != F_NONE) { + if ((fid != F_NONE) && f->id == F_EATMUTATE) { // lose half your max hp! losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL, "the shock of mutation", @@ -12386,6 +12416,10 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { enum LFSIZE maxobsize = SZ_MAX; int isshop = B_FALSE; int depthmod2 = 0; + cell_t fakecell; + map_t fakemap; + + createfakes(&fakemap, &fakecell); if (targob) { cell_t *c; @@ -12455,7 +12489,9 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { for (i = 0; i < nposs; i++) { char thisdesc[BUFLEN]; int dam,acc; + int ok = B_TRUE; enum DAMTYPE dt; + object_t *o = NULL; flag_t *vf; f2 = hasflag(poss[i]->flags, F_ACCURACY); @@ -12468,9 +12504,27 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { // don't allow this if the player is vulnerable to it! vf = lfhasflagval(lf, F_MATVULN, poss[i]->material->id, NA, NA, NULL); - if (!vf || (vf->val[2] <= 0)) { + if (vf && (vf->val[2] > 0)) { + ok = B_FALSE; + } + + if (ok) { + o = addobfast(fakecell.obpile, poss[i]->id); + if (!o) { + ok = B_FALSE; + } + } + if (ok) { + if (!canpickup(lf, o, 1)) { + ok = B_FALSE; + } + } + + if (ok) { addchoice(&prompt, ch++, thisdesc, NULL, poss[i], NULL); } + + if (o) killob(o); } if (prompt.nchoices == 1) { @@ -12506,6 +12560,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { } } // end if lf && selectweapon + killfakes(&fakemap, &fakecell); // give start objects and id them for (f = fp->first ; f ; f = f->next) { @@ -19752,7 +19807,8 @@ void spot_hiding_lf(lifeform_t *lf, lifeform_t *hider) { // announce if (isplayer(lf)) { char hidername[BUFLEN]; - getlfname(hider, hidername); + getlfnamea(hider, hidername); + needredraw = B_TRUE; msg("^wYou spot %s!", hidername); } else if (isplayer(hider) && cansee(hider, lf)) { if (getlorelevel(hider, lf->race->raceclass->id)) { @@ -23520,10 +23576,12 @@ void startlfturn(lifeform_t *lf) { meltdam = roll("2d6"); break; } - if (!skillcheck(lf, SC_CON, (exlimbs*coldmult), 0)) { - poison(lf, coldtime, P_COLD, 0, "the cold", R_NONE, B_FALSE); - } else if (!skillcheck(lf, SC_CON, (exlimbs*shivermult), 0)) { - shiver(lf); + if ((temp < T_NORMAL) && !isimmuneto(lf->flags, DT_COLD, B_FALSE) && !isresistantto(lf->flags, DT_COLD, B_FALSE)) { + if (!skillcheck(lf, SC_CON, (exlimbs*coldmult), 0)) { + poison(lf, coldtime, P_COLD, 0, "the cold", R_NONE, B_FALSE); + } else if (!skillcheck(lf, SC_CON, (exlimbs*shivermult), 0)) { + shiver(lf); + } } // chance to melt if you are frozen or made of ice diff --git a/objects.c b/objects.c index f0315fd..04aed08 100644 --- a/objects.c +++ b/objects.c @@ -504,6 +504,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum enum OBTYPE wantfountaintype = OT_NONE; enum LFSIZE wantarmsize = SZ_ANY; enum MATERIAL wantdiffmat = MT_NOTHING; + int wantoriginal = B_FALSE; int minar = NA; // minimum AR for armour int mindr = NA,maxdr = NA; // minimum DR for weapons map_t *targetmap = NULL; // for portals @@ -887,6 +888,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum wantarmsize = getlfsize(matchlfskills); } donesomething = B_TRUE; + } else if (strstarts(p, "original ")) { + // don't give different material etc + p += strlen("original "); + wantoriginal = B_TRUE; + donesomething = B_TRUE; + // weapon "goodness" } else if (strstarts(p, "average ")) { wantgoodness = G_AVERAGE; @@ -1362,15 +1369,17 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum wantdiffmat = MT_NOTHING; } - // chance of being a different material based on ob flags - if ((gamemode != GM_GAMESTARTED) && isplayer(where->owner)) { - // ...but not in player's initial starting equipment - } else { - if ((wantdiffmat == MT_NOTHING) && (gamemode != GM_CHARGEN)) { - getflags(ot->flags, retflag, &nretflags, F_CANBEDIFFMAT, F_NONE); - for (i = 0; i < nretflags; i++) { - if (pctchance(retflag[i]->val[1])) { - wantdiffmat = retflag[i]->val[0]; break; + if (!wantoriginal) { + // chance of being a different material based on ob flags + if ((gamemode != GM_GAMESTARTED) && isplayer(where->owner)) { + // ...but not in player's initial starting equipment + } else { + if ((wantdiffmat == MT_NOTHING) && (gamemode != GM_CHARGEN)) { + getflags(ot->flags, retflag, &nretflags, F_CANBEDIFFMAT, F_NONE); + for (i = 0; i < nretflags; i++) { + if (pctchance(retflag[i]->val[1])) { + wantdiffmat = retflag[i]->val[0]; break; + } } } } @@ -7851,6 +7860,7 @@ int isfirearm(object_t *o) { } int isflammable(object_t *o) { + if (hasflag(o->flags, F_IMPORTANT)) return B_FALSE; if (hasflag(o->flags, F_WET)) { return B_FALSE; } @@ -8710,6 +8720,28 @@ lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) { return newlf; } +void makecool(object_t *o, int howmuch, int howlong) { + flag_t *f; + f = hasflag(o->flags, F_HOT); + if (f) { + int newlife,newpower; + + newpower = f->val[0] - howmuch; + if (newpower <= 0) { + killflag(f); + return; + } + + if (f->lifetime > 0) { + newlife = f->lifetime - howlong; + if (newlife <= 0) { + killflag(f); + return; + } + } + } +} + // returns true if something hapepned int makeduller(object_t *o, int howmuch) { char obname[BUFLEN]; @@ -8754,10 +8786,20 @@ int makeduller(object_t *o, int howmuch) { void makehot(object_t *o, int howmuch, int howlong) { flag_t *f; int seen = B_FALSE; - f = addtempflag(o->flags, F_HOT, howmuch, NA, NA, "1d2", howlong); - if (isequipped(o) && o->pile->owner) { - if (isplayer(o->pile->owner) || cansee(player, o->pile->owner)) { - seen = B_TRUE; + f = hasflag(o->flags, F_HOT); + if (f) { + if (howmuch > f->val[0]) { + f->val[0] = howmuch; + } + if (f->lifetime < howlong) { + f->lifetime = howlong; + } + } else { + f = addtempflag(o->flags, F_HOT, howmuch, NA, NA, "1d2", howlong); + if (isequipped(o) && o->pile->owner) { + if (isplayer(o->pile->owner) || cansee(player, o->pile->owner)) { + seen = B_TRUE; + } } } // you only know an object is hot if you notice the effects on the @@ -9499,9 +9541,11 @@ void obdie(object_t *o) { if (hasflag(o->flags, F_CONTAINER)) { + object_t *oo, *nextoo; // dump object's contents into parent container - while (o->contents->first) { - moveob(o->contents->first, o->pile, ALL); + for (oo = o->contents->first ; oo ; oo = nextoo) { + nextoo = oo->next; + moveob(oo, o->pile, ALL); } } @@ -9805,6 +9849,9 @@ int obmeetscondition(object_t *o, enum CELLCONDITION cond, int arg, int value) { case CC_WEARABLE: if (iswearable(o)) check = B_TRUE; break; + case CC_WEILDABLE: + if (isweapon(o) || isfirearm(o)) check = B_TRUE; + break; case CC_WEAPON: if (isweapon(o)) check = B_TRUE; break; @@ -10026,6 +10073,7 @@ int obmatchescondition(object_t *o, long opts) { int obproduceslight(object_t *o) { flag_t *f; int amt = 0; + if (isdeadob(o)) return B_FALSE; f = hasflag(o->flags, F_PRODUCESLIGHT); if (f) { int thisamt = 0; @@ -11946,6 +11994,9 @@ int pour(lifeform_t *lf, object_t *o) { if (isplayer(lf)) { angergodmaybe(R_GODPURITY, 25, GA_HERESY); } + } else if ((o->type->id == OT_POT_POISON) && canbepoisoned(dst->type->id)) { + applyobmod(dst, findobmod(OM_POISONED)); + msg("Your %s is now covered with a layer of venom.", noprefix(dstname)); } else if (o->type->id == OT_POT_INVULN) { flag_t *f; f = hasflag(dst->flags, F_DAMAGABLE); @@ -13402,6 +13453,7 @@ int readsomething(lifeform_t *lf, object_t *o) { object_t *relinkob(object_t *src, obpile_t *dst) { if (!obfits(src, dst)) return NULL; + if (isdeadob(src)) return NULL; if (src->pile->owner) { // previous owner loses all flags conferred by this object @@ -13421,6 +13473,11 @@ object_t *relinkob(object_t *src, obpile_t *dst) { if (src->pile->owner) { unequipeffects(src->pile->owner, src); + // this might have killed the object - eg. unequipping + // a summoned energy blade. + if (isdeadob(src)) { + return NULL; + } } // adjust letter... @@ -14996,9 +15053,18 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp // an actual physical shield? if (thrower != target) { + int dist; + dist = getcelldist(srcloc, where); sprintf(attackname, "%s", obname); difficulty = 60 + (speed*10); - if (check_for_block(thrower, target, getthrowdam(o) + speed, DT_PROJECTILE, difficulty, attackname, B_RANGED)) { + // harder the closer the projectile was shot from. + if (dist <= 1) { + difficulty += 40; + } else if (dist == 2) { + difficulty += 10; + } + if (check_for_block(thrower, target, getthrowdam(o) + speed, + DT_PROJECTILE, difficulty, attackname, B_RANGED)) { announcedmiss = B_TRUE; youhit = B_FALSE; missiledam += ((speed*2)+rnd(1,4)); @@ -15728,6 +15794,28 @@ void timeeffectsob(object_t *o) { } } } + + // affect hot + i = isheatable(o); + if (i) { + switch (temp) { + case T_VCOLD: + makecool(o, 1, 3); + break; + case T_COLD: + makecool(o, 1, 1); + break; + case T_HOT: + makehot(o, i, 10); + break; + case T_VHOT: + makehot(o, pctof(150,i), 20); + break; + default: break; + } + } + + if ((o->type->material->id == MT_WATER) || (o->type->id == OT_SPLASHWATER)) { if (location->type->absorbent) { if (haslos(player, location)) { diff --git a/objects.h b/objects.h index 906ad25..2bc303f 100644 --- a/objects.h +++ b/objects.h @@ -246,6 +246,7 @@ void killoc(objectclass_t *oc); void killot(objecttype_t *ot); int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher); lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level); +void makecool(object_t *o, int howmuch, int howlong); int makeduller(object_t *o, int howmuch); void makehot(object_t *o, int howmuch, int howlong); void makeknown(enum OBTYPE otid); diff --git a/spell.c b/spell.c index 622ebe9..e94c6f2 100644 --- a/spell.c +++ b/spell.c @@ -110,12 +110,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } if (abilid == OT_A_BUILD) { - char tempname[BUFLEN]; objecttype_t *tempot = NULL; int dir; char ch = 'a'; cell_t *c; object_t *o; + int numtobuild = 1; enum SKILLLEVEL slev; enum OBTYPE needob = OT_NONE; int numneed = 0; @@ -137,61 +137,61 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } slev = getskill(user, SK_ENGINEERING); - dir = askdir("Build something in which direction (- to cancel)", B_TRUE, B_TRUE); - if (dir < 0) { + dir = askdir("Build something in which direction (. for self, - to cancel)", B_TRUE, B_TRUE); + if (dir == D_MYSELF) { + c = NULL; + initprompt(&prompt, "What will you build?"); + if (slev >= PR_NOVICE) { + addbuildchoice(&prompt, user, OT_ARROW, &ch); + } + } else if (dir < 0) { msg("Cancelled."); return B_TRUE; - } - c = getcellindir(user->cell, dir); + } else { + c = getcellindir(user->cell, dir); - if (c->lf || c->type->solid) { - msg("There is no space to build anything there!"); - return B_TRUE; - } - // what can we build? - initprompt(&prompt, "What will you build?"); - if (hasdoor(c)) { - - if (slev >= PR_BEGINNER) { - // collapsing door - tempot = findot(OT_TRAPDOORFALL); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) { - addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); + if (c->lf || c->type->solid) { + msg("There is no space to build anything there!"); + return B_TRUE; + } + // what can we build? + initprompt(&prompt, "What will you build?"); + if (hasdoor(c)) { + if (slev >= PR_BEGINNER) { + // collapsing door + addbuildchoice(&prompt, user, OT_TRAPDOORFALL, &ch); + } + + if (slev >= PR_EXPERT) { + // other door traps + addbuildchoice(&prompt, user, OT_TRAPNEEDLEP, &ch); + addbuildchoice(&prompt, user, OT_TRAPFIRE, &ch); + addbuildchoice(&prompt, user, OT_TRAPMINE, &ch); } } - - if (slev >= PR_EXPERT) { - // other door traps - tempot = findot(OT_TRAPNEEDLEP); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_TRAPFIRE); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_TRAPMINE); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); + // floor traps? + if (cellwalkable(NULL, c, NULL)) { + if (slev >= PR_BEGINNER) { + addbuildchoice(&prompt, user, OT_TRAPTRIP, &ch); + addbuildchoice(&prompt, user, OT_BARRICADE, &ch); + addbuildchoice(&prompt, user, OT_RUBBLE, &ch); + addbuildchoice(&prompt, user, OT_FENCEWOOD, &ch); + } + if (slev >= PR_ADEPT) { + addbuildchoice(&prompt, user, OT_TRAPARROW, &ch); + } + if (slev >= PR_EXPERT) { + addbuildchoice(&prompt, user, OT_TRAPROCK, &ch); + } } - } - // floor traps? - if (cellwalkable(NULL, c, NULL)) { - if (slev >= PR_BEGINNER) { - tempot = findot(OT_TRAPTRIP); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_BARRICADE); // diff50 - need 2 metal poles - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_RUBBLE); // diff70 - need 20 stones - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_FENCEWOOD); // diff80 - need 1 plank of wood - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - } - if (slev >= PR_EXPERT) { - tempot = findot(OT_TRAPARROW); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - tempot = findot(OT_TRAPROCK); - if (!haschoicedata(&prompt, tempot) && canbuild(user, tempot, tempname, &needob, &numneed)) addchoice(&prompt, ch++, tempname, NULL, tempot, NULL); - } - } + } if (prompt.nchoices <= 0) { - msg("There is nothing that you can build there."); + if (c) { + msg("There is nothing that you can build there."); + } else { + msg("There is nothing that you can currently build."); + } return B_TRUE; } prompt.maycancel = B_TRUE; @@ -206,30 +206,63 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (needob != OT_NONE) { o = hasob(user->pack, needob); if (o && (o->amt >= numneed)) { - removeob(o, numneed); + if (c) { + // just build it + removeob(o, numneed); + } else { + int npossible; + npossible = (o->amt / numneed); + // ask how many + if (npossible >= 2) { + char ptext[BUFLEN],buf[BUFLEN]; + char *p; + p = makeplural(tempot->name); + sprintf(ptext, "How many %s will you build (max %d)", p, npossible); + free(p); + askstring(ptext, '?', buf, BUFLEN, "1"); + numtobuild = atoi(buf); + if (numtobuild <= 0) { + msg("Cancelled."); + return B_TRUE; + } + } + removeob(o, numneed*numtobuild); + } } else { msg("You don't have the required components to build that."); return B_TRUE; } } - // create the trap/obstacle/whatever - o = hasdoor(c); - if (o) { - addflag(o->flags, F_TRAPPED, tempot->id, NA, B_TRUE, NULL); - o = NULL; - } else { - o = addobfast(c->obpile, tempot->id); + if (c) { + // create the trap/obstacle/whatever + o = hasdoor(c); if (o) { - killflagsofid(o->flags, F_SECRET); + addflag(o->flags, F_TRAPPED, tempot->id, NA, B_TRUE, NULL); + o = NULL; } else { - msg("For some reason, you can't build there."); - return B_TRUE; + o = addobfast(c->obpile, tempot->id); + if (o) { + killflagsofid(o->flags, F_SECRET); + } else { + msg("For some reason, you can't build there."); + return B_TRUE; + } } + } else { + char buf[BUFLEN]; + sprintf(buf, "%d original %s", numtobuild, tempot->name); + o = addob(user->pack, buf); } taketime(user, getactspeed(user)*2); - setlosdirty(user); - msg("You build %s %s.", needan(tempot->name) ? "an" : "a", tempot->name); + if (c) { + setlosdirty(user); + msg("You build %s %s.", needan(tempot->name) ? "an" : "a", tempot->name); + } else { + char obname[BUFLEN]; + getobname(o, obname, o->amt); + msgnocap("%c - %s", o->letter, obname); + } } else if (abilid == OT_A_CHARGE) { cell_t *adjcell = NULL,*origcell; @@ -3921,7 +3954,15 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_FALSE; } - +void addbuildchoice(prompt_t *p, lifeform_t *lf, enum OBTYPE oid, char *ch) { + objecttype_t *tempot; + char tempname[BUFLEN]; + tempot = findot(oid); + if (!haschoicedata(p, tempot) && canbuild(lf, tempot, tempname, NULL, NULL)) { + addchoice(p, *ch, tempname, NULL, tempot, NULL); + (*ch)++; + } +} // returns TRUE on error @@ -5813,6 +5854,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int pickagain = B_TRUE; flag_t *f; while (pickagain) { + pickagain = B_FALSE; ot = getrandomobofclass(OC_FOOD, NA, NA, NULL, NULL); if (hasflag(ot->flags, F_VENOMSAC)) { pickagain = B_TRUE; diff --git a/spell.h b/spell.h index ddbba16..39e6515 100644 --- a/spell.h +++ b/spell.h @@ -3,6 +3,7 @@ #include "defs.h" int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag); +void addbuildchoice(prompt_t *p, lifeform_t *lf, enum OBTYPE oid, char *ch); int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob); objecttype_t *findspelln(char *buf); enum SPELLSCHOOL findspellschoolbyname(char *buf); diff --git a/text.c b/text.c index f3ffaf5..71e6b02 100644 --- a/text.c +++ b/text.c @@ -353,11 +353,14 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam needfree = B_TRUE; } - if (victim && isplayer(victim) && !nodam) { - col = C_YELLOW; + if (victim) { + if (isplayer(victim) && !nodam) { + col = C_YELLOW; + } else { + col = chartocol(getlfcol(victim, CC_BAD)); + } } else { - //col = C_GREY; - col = chartocol(getlfcol(victim, CC_BAD)); + col = C_GREY; } strcpy(adjective, "");