From 0d663e81b39214ece1d16d05efae71b24d6dd324 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Thu, 13 Oct 2011 21:37:15 +0000 Subject: [PATCH] * [+] maybe a new weapon damage calculation.... - [+] eyes shouldn't adjust if you can seein the dark - [+] make fire spread to nearby flammable objects. - [+] issue with soldering iron - [+] shouldn't be able to weild it if we don't know what it is - [+] shouldn't be able to get stats like damage dealt ect if we dno't know what it is - [+] need technology skill to weild tech weapons?? - [+] misile damage problem - Killed by a spear (thrown by an orc warrior).(33 damage) - [+] ring of endurance - [+] make evasion checks modified by speed. - [+] bone items have higehr chance to be cursed - [+] tweak feign death check now - int check (attacker) vs wisdom (one feigning death) - [+] cursed teleportation should take you next to a monster - [+] bug: infinite loop during getrandomroomcell(map,ANYROOM) - [+] make dumprooms able to show room ids - [+] bug: i'm able to cast varpower spells which cost more mp than i have! --- ai.c | 2 +- attack.c | 48 +++++++++---- data.c | 96 ++++++++++++++++++-------- data/hiscores.db | Bin 9216 -> 9216 bytes defs.h | 18 ++++- io.c | 36 ++++++---- lf.c | 50 +++++++++++--- map.c | 174 ++++++++++++++++++++++++++++------------------- map.h | 4 +- nexus.c | 4 +- objects.c | 39 ++++++++--- objects.h | 1 + spell.c | 23 ++++++- 13 files changed, 338 insertions(+), 157 deletions(-) diff --git a/ai.c b/ai.c index 2c57301..ae29441 100644 --- a/ai.c +++ b/ai.c @@ -68,7 +68,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { penalty = (getcelldist(lf->cell, victim->cell)-1); if (penalty < 0) penalty = 0; penalty *= 3; - if (!skillcheckvs(lf, SC_WILL, -penalty, victim, SC_WILL, 5+gethitdice(victim))) { + if (!skillcheckvs(lf, SC_IQ, -penalty, victim, SC_WILL, 5+gethitdice(victim))) { dblog(".oO { attempted target fooled me with feign death. ignoring. }"); return B_TRUE; } diff --git a/attack.c b/attack.c index 618fcbc..aa2a5ab 100644 --- a/attack.c +++ b/attack.c @@ -2586,23 +2586,43 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { } if (wep && owner && victim) { + enum DRAINTYPE draintype = DR_NONE; if ((wep->type->id == OT_TEETH) && lfhasflag(owner, F_VAMPIRIC) && isbleeding(victim)) { + draintype = DR_FROMBITE; + } else if (hasflag(wep->flags, F_VAMPIRIC)) { + draintype = DR_FROMWEP; + } + + if (draintype && !isimmuneto(victim->flags, DT_NECROTIC)) { + int hpgain; // drain life! - gainhp(owner, dam); - if (isplayer(owner)) { - char lfname[BUFLEN]; - char victimname[BUFLEN]; - getlfname(owner,lfname); - getlfname(victim, victimname); - msg("You suck %s%s blood!", victimname, getpossessive(victimname)); - } else if (cansee(player, owner)) { - char lfname[BUFLEN]; - char victimname[BUFLEN]; - getlfname(owner,lfname); - getlfname(victim, victimname); - msg("%s sucks %s%s blood!", lfname, victimname, getpossessive(victimname)); + if (isresistantto(victim->flags, DT_NECROTIC)) { + hpgain = dam; + } else { + hpgain = (dam/2); + } + if (hpgain && (owner->hp < owner->maxhp)) { + gainhp(owner, hpgain); + if (draintype == DR_FROMBITE) { + if (isplayer(owner)) { + char lfname[BUFLEN]; + char victimname[BUFLEN]; + getlfname(owner,lfname); + getlfname(victim, victimname); + msg("You suck %s%s blood!", victimname, getpossessive(victimname)); + } else if (cansee(player, owner)) { + char lfname[BUFLEN]; + char victimname[BUFLEN]; + getlfname(owner,lfname); + getlfname(victim, victimname); + msg("%s sucks %s%s blood!", lfname, victimname, getpossessive(victimname)); + } + } else { + if (isplayer(owner)) { + msg("Life force surges into you!"); + } + } } } } - } diff --git a/data.c b/data.c index 06107c5..ffa3d69 100644 --- a/data.c +++ b/data.c @@ -367,6 +367,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of oil"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rubber boots"); // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_CHANNELING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_METALWORK, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); @@ -512,9 +513,9 @@ void initjobs(void) { // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 2, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); - addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, -3, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, -2, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_CON, 2, NA, NULL); - addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, -3, NA, NULL); + addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, -2, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, -4, NA, NULL); // initial objects addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet"); @@ -764,6 +765,8 @@ void initobjects(void) { addflag_real(lastbrand->flags, F_REVENGE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); addbrand(BR_SHARPNESS, "of sharpness", BP_WEAPON); addflag_real(lastbrand->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); + addbrand(BR_LIFESUCK, "of lifesucking", BP_WEAPON); + addflag_real(lastbrand->flags, F_VAMPIRIC, NA, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1); // feet addbrand(BR_LEVITATION, "of hovering", BP_FEET); @@ -1464,6 +1467,7 @@ void initobjects(void) { addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); @@ -1476,6 +1480,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); + addflag(lastot->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); @@ -3543,6 +3548,16 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 5, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addot(OT_SOLDERINGIRON, "soldering iron", "A hand tool with an electrically heated metal tip. This unit is operated by an in-built battery.", MT_METAL, 0.5, OC_TECH, SZ_TINY); + addflag(lastot->flags, F_RARITY, H_ALL, RR_UNCOMMON, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_HEAT, NA, NA, "1d6"); + addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, 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_HASHIDDENNAME, B_TRUE, NA, NA, NULL); @@ -4128,7 +4143,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_BLOCKSVIEW, 4, NA, NA, NULL); + addflag(lastot->flags, F_BLOCKSVIEW, 2, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "."); addflag(lastot->flags, F_CAUSESCOUGH, 18, NA, NA, NULL); @@ -4546,69 +4561,72 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); // rings + addot(OT_RING_ENDURANCE, "ring of endurance", "Boosts stamina regeneration.", MT_METAL, 0.1, OC_RING, SZ_MINI); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); + addflag(lastot->flags, F_EQUIPCONFER, F_STAMREGEN, NA, NA, "0.5"); addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 3, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL); addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAMP, 10, NA, NULL); addot(OT_RING_LUCK, "ring of luck", "Makes the wearer more lucky.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRALUCK, 5, NA, NULL); addot(OT_RING_PROTFIRE, "ring of fire immunity", "Grants the caster complete immunity to fire.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FIRE, NA, NULL); addot(OT_RING_PROTCOLD, "ring of cold immunity", "Grants the caster complete immunity to cold.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_COLD, NA, NULL); addot(OT_RING_STR, "ring of strength", "Increases the wearer's strength.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addot(OT_RING_IQ, "ring of intelligence", "Increases the wearer's intelligence.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addot(OT_RING_CON, "ring of fitness", "Increases the wearer's fitness.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addot(OT_RING_DEX, "ring of dexterity", "Increases the wearer's dexterity.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_AGI, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addot(OT_RING_HUNGER, "ring of hunger", "Greatly increases the metabolic rate of the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 73, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_FASTMETAB, 3, NA, NULL); addflag(lastot->flags, F_STARTBLESSED, B_CURSED, NA, NA, NULL); addot(OT_RING_WOUNDING, "ring of wounding", "Increases the damage output of the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 73, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRADAM, NA, NA, "0d0+4"); addflag(lastot->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_INVISIBLE, NA, NA, NULL); addot(OT_RING_INVULN, "ring of invulnerability", "Grants the caster complete immunity to physical harm.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_EQUIPCONFER, F_INVULNERABLE, NA, NA, NULL); addot(OT_RING_MPREGEN, "ring of recharging", "Slowly regenerates the wearer's mana.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_MPREGEN, 1, NA, NULL); addot(OT_RING_CONTROL, "ring of control", "Allows the wearer control over teleportation and polymorphic effects.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_CONTROL, NA, NA, NULL); addot(OT_RING_REGENERATION, "ring of regeneration", "Slowly regenerates the wearer's health, even when not resting.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_REGENERATES, 1, NA, NULL); addot(OT_RING_RESISTMAG, "ring of magic resistance", "Renders the wearer immune to most magical effects.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_EQUIPCONFER, F_RESISTMAG, 5, NA, NULL); addot(OT_RING_MIRACLES, "ring of miracles", "Grants a limited number of miracles to the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); - addflag(lastot->flags, F_RARITY, H_ALL, 40, NA, ""); + addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, ""); addflag(lastot->flags, F_CHARGES, 1, 3, NA, NULL); // unarmed weapons - note these damage/accuracys can be @@ -4642,6 +4660,15 @@ void initobjects(void) { addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL); + addot(OT_BEAK, "beak", "beak object", MT_BONE, 0, OC_WEAPON, SZ_TINY); + addflag(lastot->flags, F_DAM, DT_BITE, NA, NA, "1d2"); + addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); + addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "peck"); + addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2"); addflag(lastot->flags, F_ATTACKVERB, NA, 5, NA, "scratch"); @@ -4826,14 +4853,14 @@ void initobjects(void) { addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); 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_DAM, DT_CHOP, NA, NA, "1d8+1"); + addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d10+1"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL); - addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+1"); + addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "3d6"); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); @@ -4846,9 +4873,17 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); - addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM); + addot(OT_HATCHET, "hatchet", "Similar to a handaxe but weighted at the head. A fast one-handed axe, ideal for throwing.", MT_METAL, 4, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1"); + addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); + addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); + addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL); + addflag(lastot->flags, F_CRITCHANCE, 6, NA, NA, NULL); + addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); + addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "3d4"); addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 11, NA, NULL); @@ -4875,6 +4910,7 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 10, NA, NULL); + addflag(lastot->flags, F_CANBEDIFFMAT, MT_BONE, 10, NA, NULL); addot(OT_FORK, "fork", "A common kitchen fork.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d2"); @@ -5454,17 +5490,15 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, "2d6"); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_NOARMOURON, BP_BODY, NA, NA, NULL); addflag(lastrace->flags, F_NOARMOURON, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_NOARMOURON, BP_RIGHTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOARMOURON, BP_LEFTFINGER, NA, NA, NULL); // other special stuff - addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of oil"); addflag(lastrace->flags, F_BODYPARTNAME, BP_EARS, NA, NA, "audio inputs"); addflag(lastrace->flags, F_BODYPARTNAME, BP_EYES, NA, NA, "video inputs"); - addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "metal frame"); + addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "central frame"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEGS, NA, NA, "stabilisers"); addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "robotic hands"); addflag(lastrace->flags, F_BODYPARTNAME, BP_FEET, NA, NA, "lower propulsion units"); @@ -5503,6 +5537,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); // bonuses addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); // penalties addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL); @@ -7376,6 +7411,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_BEAK, NA, NA, "1d2"); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 1, NA, NA, NULL); @@ -7750,15 +7786,15 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addrace(R_SNAKETREE, "tree snake", 3, 's', C_GREEN, MT_FLESH, RC_ANIMAL, "Non-venomous snakes which leap at their prey."); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "3d4+1"); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4"); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+1"); addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "torso"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); @@ -8103,7 +8139,7 @@ void initrace(void) { addflag(lastrace->flags, F_ATTACKRANGE, 1, 2, NA, NULL); // just buzz around addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_STIRGE, "mosquitoid", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT, "Mosquitoids look like giant mosquiteos but are equipped with human-like arms, with clawed hands."); + addrace(R_STIRGE, "mosquitoid", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT, "Mosquitoids look like giant mosquitoes but are equipped with human-like arms, with clawed hands."); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); diff --git a/data/hiscores.db b/data/hiscores.db index 5fe5e3990c86dfb4e6216b8d9e8e959b88f24a15..cd06d0bb8e4e70dff4ee316910ccb374aa54049d 100644 GIT binary patch delta 1514 zcmZvceN2^g6vxjC5AO1!(&h60#DkIxg3J357~s1oP?JT>#KlD~iV#;GFRwyC+0xBQ z`pxAk|Ik{_j1q3yR`%i_HLGc9xhz*YrL>lnu@%Ew{m#W&Z9HfD?03KC{Lb&3^ZcGW zSTR_!ClOy6P5O4$0Hs3{9tXb3zwr(Jk+1S){+iG8XMCDJ_3mOeq7 zphM6qXc2S@whMX%J%VmQmtdn{gP>8+FK7@vKm%YXci5V>v>%LWk*Wlhg4Kdmf(jZ1 zW2LNC2$l<$(R*MlmDLi#V)`76MY1XvlnF}dcb)xwSaJv_=*7*jo6at;1KlcKy4~NV!wl~LmE0$@<1IhtiV*n1cvYs zq^cXU_k`%&IqK0leWe%*PACID$Gf?nvzX`$3eaxyQZYGkAGTsPT!drrBzSe$wEg=w zRawYM2cCd*bect|E``Rb1;(=u?XS@XXUf6xk=-7@TPqn_DGDk9$8D2Xj43b&+JRr- zb}r#?xPW(<%(6%|Bpyt^1W_`| zQ~V73xQwIeGQCRuw3?#vDvn_#x?lvh$`DmX(rY2u4+Uz-%uz0Lvm_}944H$JM&mk7 z9nlyKPy+s-hf%IOdPn~;?Bxd7MOB+;x5w<7Gy=GIp4Mys*M z@>tupdOfyvr+>5U>uL*1ZI;j8VCi_B%uaJFN6LsJyKlON1yVyqm&fn5t!-_d7Oz`f zOYxdL!FmeaGu2}&pUb5N=6Oxsf3$9-2yTTfZ*8)&w@)XoRmm}CdSkGN>BRZH(n3xN zjL(!+y1YHFYkCgGOcAy^H7~X%w=)=0w0g#n{|;hPv!~5(+4?3IbOiU5&zfuk#$FuM;vwgH=jKQKWYt{dIf$=0=u zuf?%VNrXfV^TtRB3m<-vDT{1XNYq4^2tf@hAQ2%dVd&8Kg(PZ*Cf@TF6W<@dynD`h zC+EF;-$30!-To{%JeK{PrC$iK6($7Tr9bF4{X|oAgTAIKbcsHtkLW{spWdOj=_I{D zuhCIDL@&_`^c?M_r)f9sq8^G-2SuofHqs-sj_RqFmQjcnQ;>XAK>3tIZgSEbvQi2G z{*8a)@Axy`!b$uFzrrta@iY7w&)^66E}p_MJb}mY7!KnBl=wXE!#&t9_s;Sb723SC9c^eqgn!^KxC6hy4{#H{g{yEGK8H`>EKCf=FUbkr@o2Y30%A-T)5&aMo?tqd zDAUfgF|AC5+03*s%}khSVjgFtFLm7pzG-0UnKjI6W))M%)G{^9N@fMKoLR(YP_nW90c%^s&g+CZh0uD0eJzKq*(E#|{CT!ayL3O2$bF)c2L3+t)hPQFDn3L6_-S zdW=d4@k>lfm*%yo3}49#ZG_~M!@X239HLCn1$u?zR8CgBhOgsJT!k*R-D9u^)`M4E z6C)z7%Kp0+SE(t=GrrdY5AhTQ)k6MeWG8E!0ni>OO%cf_UF$(F_L<2tAy3+jU}v-| z))U^A@TI9P>7r4nbN`|mZvp;_r?DR&#!R>lqp$<2z$z|^1EO +Zu9C-u?>Zd6(> zq{r<|cFc2v{$Q;c3ZV++$v%%wo_4>gl`U6uHDw(u(LEA!YTD}DnTELPfFc8dT*ecC-N`BnGNx**bz>&dKw}v?cuIyi}V`~2+LdE$gEDT zE2tFmyoC(x%(M&{7F)Q-R}wXY<-pHmbjG&Ew?%tm u(apa5+s#C=S)I0%OWS5j&B*^ti(1WuI!vmE9L}`p{)icwnM7VS(*6adLIAM< diff --git a/defs.h b/defs.h index 04bd3bc..34d3428 100644 --- a/defs.h +++ b/defs.h @@ -373,6 +373,12 @@ enum CASTTYPE { CT_EYESPIT }; +enum DRAINTYPE { + DR_NONE = 0, + DR_FROMBITE, + DR_FROMWEP +}; + enum NOISECLASS { NC_NONE = 0, NC_MOVEMENT = 1, @@ -1363,6 +1369,7 @@ enum OBTYPE { OT_INSECTICIDE, OT_LANTERNLED, OT_TENT, + OT_SOLDERINGIRON, // tech l2 OT_C4, OT_FLASHBANG, @@ -1494,6 +1501,7 @@ enum OBTYPE { OT_SHIELDLARGE, OT_SHIELDTOWER, // rings + OT_RING_ENDURANCE, OT_RING_INVIS, OT_RING_INVULN, OT_RING_LUCK, @@ -1513,6 +1521,7 @@ enum OBTYPE { OT_RING_SIGHT, OT_RING_WOUNDING, // innate / animal weapons + OT_BEAK, OT_CLAWS, OT_FISTS, OT_HOOKHAND, // for pirate @@ -1541,6 +1550,7 @@ enum OBTYPE { // axes OT_AXE, OT_HANDAXE, + OT_HATCHET, OT_BATTLEAXE, OT_GREATAXE, OT_WARAXE, @@ -2081,7 +2091,10 @@ enum FLAG { F_DEBUG, // debugging enabled F_ACCURACYMOD, // modify your accuracy by val0 F_PLAYABLE, // player can select to be this race. - F_VAMPIRIC, // successful bite attacks form this lf will heal it + F_VAMPIRIC, // when on a lf: + // successful bite attacks form this lf will heal it + // when on an object + // successful attacks with this weapon will heal lf F_VEGETARIAN, // this lf will not eat meat. F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry' F_CARNIVORE, // this lf will only eat meat. @@ -2464,6 +2477,8 @@ enum FLAG { F_SEEINVIS, // can see invisible things F_SILENTMOVE, // lf makes no noise when walking/flying F_STABILITY, // doesn't slip over + F_STAMREGEN, // boost stamina regeneration at 'text' per turn + // (this is a float) F_STENCH, // creatures within v0 gain f_nauseated = v1 F_STUNNED, // cannot attack or cast spells F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0 @@ -3263,6 +3278,7 @@ enum BRAND { BR_THINKING, BR_KNOWLEDGE, BR_LEVITATION, + BR_LIFESUCK, BR_FEATHERFALL, BR_ANTIMAG, BR_CONCEALMENT, diff --git a/io.c b/io.c index 2852f13..5ffe10c 100644 --- a/io.c +++ b/io.c @@ -1159,7 +1159,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; break; case F_MAGICARMOUR: - msg("%s %s appears around %s!",needan(f->text) ? "an" : "a", f->text, lfname); + msg("%s %s forms around %s!",needan(f->text) ? "an" : "a", f->text, lfname); donesomething = B_TRUE; break; case F_ASLEEP: @@ -4505,11 +4505,13 @@ char *makedesc_ob(object_t *o, char *retbuf) { ff->val[0], (ff->val[0] == 1) ? "" : "s", ff2->val[0], (ff2->val[0] == 1) ? "" : "s"); strncat(retbuf, buf, HUGEBUFLEN); - } else if (o->type->obclass->id == OC_WEAPON) { + } else if (isweapon(o) && isknown(o)) { flag_t *damflag; int delay; int critchance; - snprintf(buf, BUFLEN, "It is a %s weapon", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed"); + snprintf(buf, BUFLEN, "%s %s weapon", + (o->type->obclass->id == OC_WEAPON) ? "It is a" : "It can be used as a", + hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed"); damflag = hasflag(o->flags, F_DAM); if (damflag) { int bonus = 0; @@ -5311,14 +5313,16 @@ char *makedesc_ob(object_t *o, char *retbuf) { // skill type? - f = hasflag(o->flags, F_USESSKILL); - if (f && (f->val[0] != SK_NONE)) { - enum SKILLLEVEL slev; - slev = getskill(player, f->val[0]); - sprintf(buf, "It falls into the '%s' category (your skill: ",getskillname(f->val[0])); - strncat(retbuf, buf, HUGEBUFLEN); - sprintf(buf, "^%d%s^n)\n", getskilllevelcolour(slev), getskilllevelname(getskill(player, f->val[0])) ); - strncat(retbuf, buf, HUGEBUFLEN); + if (isknown(o)) { + f = hasflag(o->flags, F_USESSKILL); + if (f && (f->val[0] != SK_NONE)) { + enum SKILLLEVEL slev; + slev = getskill(player, f->val[0]); + sprintf(buf, "It falls into the '%s' category (your skill: ",getskillname(f->val[0])); + strncat(retbuf, buf, HUGEBUFLEN); + sprintf(buf, "^%d%s^n)\n", getskilllevelcolour(slev), getskilllevelname(getskill(player, f->val[0])) ); + strncat(retbuf, buf, HUGEBUFLEN); + } } if (hasflag(o->flags, F_NOBLESS)) { @@ -5396,9 +5400,10 @@ char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite) { if ((levhilite != PR_INEPT) && (slev == levhilite)) { hilitethis = B_TRUE; } - snprintf(buf, BUFLEN, "%sAt %s level%s: %s\n",hilitethis ? "^W" : "", - getskilllevelname(sk->skilldesclev[i]), sk->skilldesctext[i], - hilitethis ? "^n" : ""); + snprintf(buf, BUFLEN, "%sAt %s level%s: %s\n",hilitethis ? "^8" : "", + getskilllevelname(sk->skilldesclev[i]), + hilitethis ? "^n" : "", + sk->skilldesctext[i]); } strncat(retbuf, buf, HUGEBUFLEN); } @@ -8054,7 +8059,8 @@ void drawstatus(void) { snprintf(maxmpstr, BUFLEN, "(%d)",player->maxmp); } - if (getmaxmp(player) > 0) { + // note: not using getmaxmp() here on purpose! + if (player->maxmp > 0) { wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD); setcol(statwin, getpctcol(player->mp, getmaxmp(player))); wprintw(statwin, "%d",player->mp); diff --git a/lf.c b/lf.c index 0cddd8e..616fdca 100644 --- a/lf.c +++ b/lf.c @@ -1126,6 +1126,10 @@ int canweild(lifeform_t *lf, object_t *o) { return B_FALSE; } } + if (o && (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE))) { + reason = E_NOTKNOWN; + return B_FALSE; + } if (o && lfhasflagval(lf, F_INJURY, IJ_TENDONCUT, NA, NA, NULL)) { if ((weildloc == BP_WEAPON) || (otherloc == BP_WEAPON)) { @@ -1271,8 +1275,6 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar return B_TRUE; } } - - power = getspellpower(lf, sid); } sp = findot(sid); @@ -1289,17 +1291,26 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar snprintf(buf, BUFLEN, "Cast %s at what power level?", sp->name); initprompt(&prompt, buf); for (i = 1; i <= max; i++) { - snprintf(buf, BUFLEN, "Power %s (%d MP)", roman(i), getmpcost(lf, sid) * i); - getvarpowerspelldesc(sp->id, i, desc); - if (strlen(desc)) { - strcat(buf, "\t"); - strcat(buf, desc); - } - addchoice(&prompt, '0' + i, buf, buf, NULL, NULL); + int thiscost; + thiscost = getmpcost(lf, sid) * i; + if (lf->mp >= thiscost) { + snprintf(buf, BUFLEN, "Power %s (%d MP)", roman(i), thiscost); + getvarpowerspelldesc(sp->id, i, desc); + if (strlen(desc)) { + strcat(buf, "\t"); + strcat(buf, desc); + } + addchoice(&prompt, '0' + i, buf, buf, NULL, NULL); + } } + addchoice(&prompt, '0', "Cancel", "Cancel", NULL, NULL); ch = getchoice(&prompt); power = ch - '0'; + if (power == 0) { + msg("Cancelled."); + return B_TRUE; + } // modify cost cost *= i; } @@ -2556,7 +2567,7 @@ void do_eyesight_adjust(lifeform_t *lf) { setlosdirty(lf); //precalclos(lf); } - } else { + } else if (!lfhasflag(lf, F_SEEINDARK)) { if ((lf->cell->lit == L_NOTLIT) && (lf->eyeadjustment < MAX_EYEADJ)) { // your eyes start to adjust... lf->eyeadjustment++; @@ -6333,6 +6344,9 @@ int getstamina(lifeform_t *lf) { float getstamregen(lifeform_t *lf) { float regenrate = STAMREGEN; + flag_t *retflag[MAXCANDIDATES]; + int nretflags,i; + if (lfhasflagval(lf, F_INJURY, IJ_WINDPIPECRUSHED, NA, NA, NULL)) { regenrate = 0.2; // override everything else } else { @@ -6343,7 +6357,13 @@ float getstamregen(lifeform_t *lf) { regenrate = pctof(50, regenrate); } } + + getflags(lf->flags, retflag, &nretflags, F_STAMREGEN, F_NONE); + for (i = 0; i < nretflags; i++) { + regenrate += atof(retflag[i]->text); + } limitf(®enrate, 0, NA); + return regenrate; } @@ -13007,6 +13027,11 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r othermod += f->val[0]; } } + } else if (ct == SC_DODGE) { + if (attrib) { + // ie. -5 to 5 + othermod += (getstatmod(lf, A_AGI) / 10); + } } else if (ct == SC_SLIP) { if (lfhasflagval(lf, F_INJURY, IJ_LEGBROKEN, NA, NA, NULL)) { othermod -= 25; @@ -15768,7 +15793,7 @@ int wear(lifeform_t *lf, object_t *o) { } break; case E_NOTKNOWN: - if (isplayer(lf)) msg("You can't wear that!"); + if (isplayer(lf)) msg("You can't wear that!"); // same message as wearing non-armour break; case E_NOBP: if (isplayer(lf)) msg("You have no %s on which to wear that!", getbodypartname(lf, bp)); @@ -15926,6 +15951,9 @@ int weild(lifeform_t *lf, object_t *o) { case E_NOHANDS: msg("You do not have enough free hands to weild this weapon."); break; + case E_NOTKNOWN: + if (isplayer(lf)) msg("You can't weild that!"); // same message as wearing non-armour + break; case E_LOWCHA: msg("You are not attractive enough to use this weapon."); break; diff --git a/map.c b/map.c index cb0ffc9..dd6681e 100644 --- a/map.c +++ b/map.c @@ -1082,95 +1082,121 @@ void clearcell_exceptflags(cell_t *c, ... ) { } // returns true if something happened -int dowaterspread(cell_t *c) { +int doelementspread(cell_t *c) { float thisdepth; int i; int nsurround = 0; int db = B_FALSE; cell_t *surroundcell[8]; + object_t *fireob = NULL; - if (!c || c->type->solid || hascloseddoor(c)) { + if (!c || c->type->solid) { return B_FALSE; } // calculate depth of this cell - thisdepth = getcellwaterdepth(c, NULL); + if (!hascloseddoor(c)) { + thisdepth = getcellwaterdepth(c, NULL); - if (!thisdepth) return B_FALSE; + if (thisdepth) { - // count surrounding cells of lower depth - for (i = DC_N; i <= DC_NW; i++) { - cell_t *newc; + // count surrounding cells of lower depth + for (i = DC_N; i <= DC_NW; i++) { + cell_t *newc; - newc = getcellindir(c, i); - if (newc && !newc->type->solid && !hascloseddoor(newc)) { - float newcdepth; - int ok = B_FALSE; + newc = getcellindir(c, i); + if (newc && !newc->type->solid && !hascloseddoor(newc)) { + float newcdepth; + int ok = B_FALSE; - /* - FIX THIS CODE LATER - if (newc->type->floorheight == c->type->floorheight) { - // same height - don't include these??? - ok = B_FALSE; - //ok = B_TRUE; - } else if (newc->type->floorheight < c->type->floorheight) { - // ie. downhill. don't include these - ok = B_FALSE; - } else if (newc->type->floorheight > c->type->floorheight) { - // ie. uphill. - ok = B_TRUE; - } - */ - if (newc->type->floorheight == c->type->floorheight) { - ok = B_TRUE; - } else { - ok = B_FALSE; - } + /* + FIX THIS CODE LATER + if (newc->type->floorheight == c->type->floorheight) { + // same height - don't include these??? + ok = B_FALSE; + //ok = B_TRUE; + } else if (newc->type->floorheight < c->type->floorheight) { + // ie. downhill. don't include these + ok = B_FALSE; + } else if (newc->type->floorheight > c->type->floorheight) { + // ie. uphill. + ok = B_TRUE; + } + */ + if (newc->type->floorheight == c->type->floorheight) { + ok = B_TRUE; + } else { + ok = B_FALSE; + } - if (ok) { - newcdepth = getcellwaterdepth(newc, NULL); + if (ok) { + newcdepth = getcellwaterdepth(newc, NULL); - if (newcdepth < thisdepth) { - surroundcell[nsurround] = newc; - nsurround++; + if (newcdepth < thisdepth) { + surroundcell[nsurround] = newc; + nsurround++; + } + } } } + + + // if there were any posisble cells around us + if (nsurround) { + float newdepth; + + //newdepth = thisdepth / (pctof(nsurround,50)+1); + newdepth = thisdepth / (pctof(nsurround,55)+1); + //newdepth = thisdepth / (nsurround+1); + limitf(&newdepth,(float)DP_NONE, (float)DP_MAX); + + if (db) dblog("waterspread: cell %d,%d (%d/%s) spreads to %d cells-->%d/%s", + c->x, c->y, (int)thisdepth, getwaterdepthname((int)thisdepth), + nsurround, (int)newdepth, getwaterdepthname((int)newdepth)); + + // SET our cell to new depth + setwaterdepth(c, (int)newdepth); + + // ADD water to surrounding cells + for (i = 0; i < nsurround; i++) { + cell_t *sc; + flag_t *f; + + sc = surroundcell[i]; + + f = hasflagval(sc->map->flags, F_NEWWATERDEPTH, sc->x, sc->y, NA, NULL); + if (f) { + f->val[2] += newdepth; + } else { + addflag(sc->map->flags, F_NEWWATERDEPTH, sc->x, sc->y, (int)newdepth, NULL); + } + } + + return B_TRUE; + } } } - - - // if there were any posisble cells around us - if (nsurround) { - float newdepth; - - //newdepth = thisdepth / (pctof(nsurround,50)+1); - newdepth = thisdepth / (pctof(nsurround,55)+1); - //newdepth = thisdepth / (nsurround+1); - limitf(&newdepth,(float)DP_NONE, (float)DP_MAX); - - if (db) dblog("waterspread: cell %d,%d (%d/%s) spreads to %d cells-->%d/%s", - c->x, c->y, (int)thisdepth, getwaterdepthname((int)thisdepth), - nsurround, (int)newdepth, getwaterdepthname((int)newdepth)); - - // SET our cell to new depth - setwaterdepth(c, (int)newdepth); - - // ADD water to surrounding cells - for (i = 0; i < nsurround; i++) { - cell_t *sc; - flag_t *f; - - sc = surroundcell[i]; + // fire + fireob = hasobofmaterial(c->obpile, MT_FIRE); + if (fireob && (fireob->birthtime != curtime)) { + cell_t *retcell[MAXRETCELLS]; + int nretcells,i,nspread = 0; - f = hasflagval(sc->map->flags, F_NEWWATERDEPTH, sc->x, sc->y, NA, NULL); - if (f) { - f->val[2] += newdepth; - } else { - addflag(sc->map->flags, F_NEWWATERDEPTH, sc->x, sc->y, (int)newdepth, NULL); + // check adjacent cells for flammable stuff + getradiuscells(c, 1, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_FALSE, retcell, &nretcells, B_FALSE); + for (i = 0; i < nretcells; i++) { + object_t *oo; + for (oo = retcell[i]->obpile->first ; oo ; oo = oo->next) { + if (isflammable(oo) && !hasobofmaterial(retcell[i]->obpile, MT_FIRE)) { + ignite(oo); + // if object didn't ignite into a fire, add one. + if (!hasobofmaterial(retcell[i]->obpile, MT_FIRE)) { + addobfast(retcell[i]->obpile, fireob->type->id); + } + nspread++; + } } } - - return B_TRUE; } return B_FALSE; } @@ -3676,7 +3702,7 @@ int dirtoy(int dt, int dir) { } -void dumpmap(map_t *map) { +void dumpmap(map_t *map, int showrooms) { int x,y; cell_t *cell; char ch; @@ -3694,8 +3720,16 @@ printf("dump of map '%s' (%d x %d):\n",map->name, map->w, map->h); for (x = 0; x < map->w; x++) { cell = getcellat(map, x, y); ch = cell->type->glyph.ch; - if ((ch == '.') && cell->filled) { - ch = 'o'; + if (ch == '.') { + if (showrooms && isroom(cell)) { + ch = '0' + getroomid(cell); + } + + if (ch == '.') { + if (cell->filled) { + ch = 'o'; + } + } } dblog_nocr("%c",ch); } @@ -4455,7 +4489,7 @@ cell_t *getrandomroomcell(map_t *map, int roomid) { if (getroomid(c) == roomid) { ok = B_TRUE; } else if (roomid == ANYROOM) { - if (isroom(c) != -1) { + if (isroom(c)) { ok = B_TRUE; } } diff --git a/map.h b/map.h index 1f4ca4d..1b9a54f 100644 --- a/map.h +++ b/map.h @@ -16,7 +16,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in int cellhaslos(cell_t *c1, cell_t *dest); void clearcell(cell_t *c); void clearcell_exceptflags(cell_t *c, ...); -int dowaterspread(cell_t *c); +int doelementspread(cell_t *c); int fix_reachability(map_t *m); int fix_unreachable_cell(cell_t *badcell); void floodfill(cell_t *startcell); @@ -59,7 +59,7 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety); int dirtox(int dt, int dir); int dirtoy(int dt, int dir); -void dumpmap(map_t *map); +void dumpmap(map_t *map, int showrooms); void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre); void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce); celltype_t *findcelltype(enum CELLTYPE cid); diff --git a/nexus.c b/nexus.c index 37187f6..d34db9d 100644 --- a/nexus.c +++ b/nexus.c @@ -1470,8 +1470,8 @@ void timeeffectsworld(map_t *map, int updategametime) { } } - // water spreads... - if (dowaterspread(c) && haslos(player, c)) { + // water/fire spreads... + if (doelementspread(c) && haslos(player, c)) { needredraw = B_TRUE; } } // end if c diff --git a/objects.c b/objects.c index 8c805fd..36eb976 100644 --- a/objects.c +++ b/objects.c @@ -89,21 +89,27 @@ enum OBCLASS sortorder[] = { char *techadjective[] = { + "bizzare", "crazy", + "curious", "mysterious", "odd", + "peculiar", "strange", "weird", "", }; char *technoun[] = { + "apparatus", "contraption", "device", "doodad", "doohickey", "gadget", - "thing", + "gizmo", + "thingamajig", "object", + "widget", "", }; @@ -1080,6 +1086,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes changemat(o, wantdiffmat); } + // extra chance of bone items being cursed + if (o->type->material->id == MT_BONE) { + if (pctchance(15)) { + o->blessed = B_CURSED; + } + } + // fill in sign text if (signtext) { addflag(o->flags, F_SIGNTEXT, NA, NA, NA, signtext); @@ -5027,7 +5040,7 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth pluralname = strdup(ot->name); } - // blessed or cursed? 15% chance each way + // chance to be blessed or cursed? 15% chance each way strcpy(cursestr, ""); if (!hasflag(ot->flags, F_NOBLESS)) { int num; @@ -5298,12 +5311,12 @@ int getthrowdam(object_t *o) { if (f) { dam = f->val[0]; } else { - // base damage is = kilograms. - // ie. 1 kg object does 1 damage - // ie. 5 kg object does 5 damage - // ie. 100 kg object does 100 damage (person) - // ie. 1 tonne object does 1000 damage (car) - dam = ceil((double)getobunitweight(o)); + // base damage is = kilograms/5. + // ie. 1 kg object does 0 damage + // ie. 5 kg object does 1 damage + // ie. 100 kg object does 20 damage (person) + // ie. 1 tonne object does 200 damage (car) + dam = ceil((double)getobunitweight(o)) / 2; // missile objects do extra damage if (hasflag(o->flags, F_THROWMISSILE)) { dam *= 2; @@ -5451,6 +5464,14 @@ object_t *hasobofclass(obpile_t *op, enum OBCLASS cid) { return NULL; } +object_t *hasobofmaterial(obpile_t *op, enum MATERIAL mid) { + object_t *o; + for (o = op->first ; o ; o = o->next) { + if (o->type->material->id == mid) return o; + } + return NULL; +} + int hasobmod(object_t *o, obmod_t *om) { flag_t *omf; int found = B_TRUE; @@ -6137,6 +6158,8 @@ int isthrownmissile(object_t *o) { int isweapon(object_t *o) { if (o->type->obclass->id == OC_WEAPON) { return B_TRUE; + } else if (hasflag(o->flags, F_DAM)) { + return B_TRUE; } return B_FALSE; } diff --git a/objects.h b/objects.h index 03ce164..a101175 100644 --- a/objects.h +++ b/objects.h @@ -139,6 +139,7 @@ object_t *hasknownob(obpile_t *op, enum OBTYPE oid); object_t *hasob(obpile_t *op, enum OBTYPE oid); object_t *hasobletter(obpile_t *op, char letter); object_t *hasobofclass(obpile_t *op, enum OBCLASS cid); +object_t *hasobofmaterial(obpile_t *op, enum MATERIAL mid); int hasobmod(object_t *o, obmod_t *om); object_t *hasobmulti(obpile_t *op, enum OBTYPE *oid, int noids); object_t *hasobwithflag(obpile_t *op, enum FLAG flagid); diff --git a/spell.c b/spell.c index 18eefd1..054bb68 100644 --- a/spell.c +++ b/spell.c @@ -7621,9 +7621,23 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } if ((power < 5) || !isplayer(caster)) { - // random - while (!c || c->type->solid || haslf(c)) { - c = getrandomcell(target->cell->map); + c = NULL; + if (blessed == B_CURSED) { + lifeform_t *lf; + // next to a random monster + for (lf = target->cell->map->lf ; lf ; lf = lf->next) { + if (areenemies(lf, target)) { + c = getrandomadjcell(lf->cell, WE_WALKABLE, B_NOEXPAND); + if (c) break; + } + } + } + + if (!c) { + // random + while (!c || c->type->solid || haslf(c)) { + c = getrandomcell(target->cell->map); + } } } else if (power >= 8) { // controlled @@ -9000,6 +9014,9 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { // +/- 1 for iq power += (getstatmod(lf, A_IQ) / 50); } + + // plus your school skill + power += schoolskill; } else { // for monsters, just based on hitdice: power = gethitdice(lf);