From c839387b84f2078ee4eb1f77beb170d532422443 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Sun, 2 Dec 2012 21:15:40 +0000 Subject: [PATCH] - [+] dog should ahve covet for ot_stick - [+] fix crash in wouldgivepenalty(); - [+] shouldn't be able to inflict poison on a plant! - [+] fix monster casting of airblast - [+] you now CAN knock out robots. - [+] don't lower god piety while training. - [+] mesmerat (mental rat) - [+] random psionic spells - [+] tempest moth - [+] no base attack but... - [+] airblast - [+] sleet storm - [+] homonculus - [+] 'n' - [+] miniature human. 2 hd? - [+] bite. low damage, but inflicts sleep. - [+] dodge like goblin - [+] scorpion. sting. inflict strong poison. - [+] spider swarm - [+] F_SWARM - [+] has lots of attacks. - [+] as it loses hp, it loses attacks too. - [+] no corpse. - [+] dietext: "the swarm disperses" --- ai.c | 14 ++-- attack.c | 2 + data.c | 189 ++++++++++++++++++++++++++++++++++++++--------- data/hiscores.db | Bin 17408 -> 17408 bytes defs.h | 10 +++ io.c | 7 ++ lf.c | 78 ++++++++++--------- lf.h | 4 +- nexus.c | 3 +- objects.c | 56 +++++++++----- spell.c | 29 ++++---- text.c | 18 +++-- 12 files changed, 296 insertions(+), 114 deletions(-) diff --git a/ai.c b/ai.c index 1816065..1631e63 100644 --- a/ai.c +++ b/ai.c @@ -611,6 +611,7 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l // if not, check for the most recent scent/footprints first if (!trailcell) { c = NULL; + lf->loslock = B_TRUE; for (i = 0; i < lf->nlos; i++) { if (hastrailof(lf->los[i]->obpile, target, NA, &tflag, lf)) { if (tflag->lifetime > besttime) { @@ -620,6 +621,7 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l } } } + lf->loslock = B_FALSE; if (bestflag && c) { if (lastx) *lastx = c->x; if (lasty) *lasty = c->y; @@ -2930,9 +2932,9 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG specificcheckok = B_TRUE; if (ot->id == OT_S_AIRBLAST) { // target must be in a straight compass dir from us - if ((victim->x != lf->x) || - (victim->y != lf->y) || - (abs(victim->x - lf->x) != abs(victim->y - lf->y)) ) { + if ((victim->cell->x != lf->cell->x) || + (victim->cell->y != lf->cell->y) || + (abs(victim->cell->x - lf->cell->x) != abs(victim->cell->y - lf->cell->y)) ) { } else { specificcheckok = B_FALSE; } @@ -3380,8 +3382,10 @@ int lookforobs(lifeform_t *lf) { } // look around for objects which we want, if we don't already have a targetcell. + // CRASH in here! if (!hasflag(lf->flags, F_TARGETCELL)) { if (db) dblog(".oO { no targetcell, so looking for remote objects }"); + if (lf->losdirty) precalclos(lf); lf->loslock = B_TRUE; for (i = 0 ; i < lf->nlos; i++) { int gothere = B_FALSE; @@ -3547,8 +3551,8 @@ int lookforobs(lifeform_t *lf) { } } - } - } + } // end if looting sleeping lfs + } // end foreach los cell lf->loslock = B_FALSE; } if (db) dblog(".oO { didn't find any obs i want }"); diff --git a/attack.c b/attack.c index ecbc730..8614989 100644 --- a/attack.c +++ b/attack.c @@ -3462,6 +3462,8 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu } poison(victim, howlong, ptype, ppower, frombuf, owner ? owner->race->id : R_NONE, B_FALSE); + } else if (fid == F_ASLEEP) { + fallasleep(victim, ST_ASLEEP, howlong); } else { // flag values if (valflag) { diff --git a/data.c b/data.c index 779bddb..fd0f014 100644 --- a/data.c +++ b/data.c @@ -2495,10 +2495,8 @@ void initobjects(void) { // baba yaga's hut addot(OT_BABAYAGAHUT, "wooden hut", "A small wooden cabin on the ground, two chicken's legs folded underneath it.", MT_DRAGONWOOD, 1000, OC_BUILDING, SZ_LARGE); addflag(lastot->flags, F_NOKO, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WOOD, '_', NA, NULL); addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "hut's door"); addflag(lastot->flags, F_OPPOSITESTAIRS, OT_BYHUTDOOR, NA, NA, NULL); @@ -3650,7 +3648,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_VALUE, 45, NA, NA, NULL); addot(OT_POT_JUICE, "potion of fruit juice", "Tasty (but not very fresh) fruit juice! Sates hunger and restores a little stamina.", MT_GLASS, 1, OC_POTION, SZ_TINY); - addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_VALUE, 10, NA, NA, NULL); addot(OT_POT_CANINETRACKING, "potion of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); @@ -3659,12 +3657,12 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL); addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY); - addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL); addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION, SZ_TINY); - addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); - addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water"); modflag(lastot->flags, F_HASHIDDENNAME, NA, NA, NA, "clear potion"); addflag(lastot->flags, F_VALUE, 5, NA, NA, NULL); @@ -3687,7 +3685,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_VALUE, 10, NA, NA, NULL); addot(OT_POT_RUM, "potion of rum", "Strong liqour which is sure to make you tipsy. This will make you unsteady and lower your accuracy, but also let you ignore pain, minor damage, and many mental attacks.", MT_GLASS, 1, OC_POTION, SZ_TINY); - addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_FLAMMABLE, 1, NA, NA, "medium fire"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); @@ -4025,7 +4023,7 @@ void initobjects(void) { addflag(lastot->flags, F_RANGE, 2, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODDEATH, 1, NA, NULL); - addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating undead zombies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many corpses are affected."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many hit points the zombies have."); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); @@ -4658,8 +4656,7 @@ void initobjects(void) { addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); - addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); - addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_NORANDOM, B_TRUE, NA, NA, NULL); addot(OT_S_ICECRUST, "ice crust", "Encrusts your weapon with a layer of sharp ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the enchantment will remain."); @@ -6860,6 +6857,7 @@ void initobjects(void) { addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL); addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL); addot(OT_FORK, "fork", "A common kitchen fork.", MT_METAL, 0.2, OC_MISC, SZ_SMALL); + addflag(lastot->flags, F_GLYPH, C_METAL, ')', NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL); @@ -7628,7 +7626,7 @@ void initobjects(void) { addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement and deals minor cold damage.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_CYAN, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); - addflag(lastot->flags, F_TEMPMOD, -10, NA, NA, NULL); + addflag(lastot->flags, F_TEMPMOD, -5, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); @@ -10378,6 +10376,8 @@ void initrace(void) { addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "wooden hut"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL); + addflag(lastrace->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat"); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); @@ -12881,6 +12881,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_ATTACKRANGE, 2, 5, NA, NULL); // maintain distance addrace(R_GOBLINHEXER, "goblin witchdoctor", 20, 'g', C_DARKYELLOW, MT_FLESH, RC_HUMANOID, "When a goblin develops an affinity for magic, they become known as witchdoctor. Shamans aim to weaken their foes with hexs, providing easy kills for their comrades."); setbodytype(lastrace, BT_HUMANOID); @@ -13158,6 +13159,32 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 7, NA, NA, NULL); + addrace(R_HOMUNCULUS, "homunculus", 5, 'n', C_FLESH, MT_STONE, RC_MAGIC, "A diminutive humanoid form, crafted out of clay then infused with magic."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "10-20 stones"); + addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_FREQUENT, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); + addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); + addflag(lastrace->flags, F_HITCONFER, F_ASLEEP, SC_CON, 140, "10-30"); + addflag(lastrace->flags, F_HITCONFERVALS, NA, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_RESISTMAG, 50, NA, NA, NULL); + addrace(R_HYDRA, "hydra", 300, 'W', C_LIGHTGREEN, MT_FLESH, RC_DRAGON, "A four legged serpentine reptile, resembling a wyrm except for its many extra heads."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -13937,6 +13964,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL); + addrace(R_PIXIE, "pixie", 5, 'n', C_MAGENTA, MT_FLESH, RC_MAGIC, "A small magical woodland creature, flying around on moth-like wings."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -15815,7 +15843,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 7, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL); @@ -15988,6 +16016,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 2, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_WANTS, OT_STICK, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, B_BLINDABLE, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "barks^barking"); @@ -16524,6 +16553,7 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_SONIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addrace(R_NEWT, "giant newt", 4, ':', C_DARKYELLOW, MT_FLESH, RC_ANIMAL, "An abnormally large example of the lizard family."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -16642,45 +16672,39 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^squeaking"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 1, NA, "squeaks^squeaking"); - addrace(R_RATMIND, "mesmerat", 3, 'r', C_PINK, MT_FLESH, RC_ANIMAL, "Glowing, irradiated rats which exhibit amazing mental powers."); + addrace(R_RATMIND, "mesmerat", 3, 'r', C_PINK, MT_FLESH, RC_ANIMAL, "Glowing, irradiated rats which have developed amazing intellects and mental powers."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); addflag(lastrace->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); + addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL); - addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_FREQUENT, NULL); - addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL); - addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL); + addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_VERYRARE, NULL); + addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 1, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); - addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 60, "5-20"); - addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); - addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;"); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTRESIST, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle"); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^squeaking"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 1, NA, "squeaks^squeaking"); - addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_FILLPOT, OT_POT_POISON, BLOODFORPOT, NA, NULL); - addflag(lastrace->flags, F_GERMS, NA, NA, NA, NULL); + addflag(lastrace->flags, F_RNDSPELLCOUNT, 5, NA, NA, NULL); + addflag(lastrace->flags, F_RNDSPELLSCHOOL, SS_MENTAL, 1, 2, NULL); + addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100"); addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run."); setbodytype(lastrace, BT_QUADRAPED); @@ -16758,6 +16782,33 @@ void initrace(void) { addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_DWARF, NA, NA, NULL); + addrace(R_SCORPION, "giant scorpion", 25, 'x', C_LIGHTMAGENTA, MT_FLESH, RC_ANIMAL, "A large, venomous scorpion."); + setbodytype(lastrace, BT_QUADRAPED); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_STING, 3, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); + addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); + addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 150, "30-50"); + addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); + addrace(R_SLUG, "acid slug", 150, 'P', C_GREY, MT_FLESH, RC_ANIMAL, "While acid slugs lack the protective shell of their snail cousings, their rubbery flesh is extremely resilient. Their acid-based attacks also make them much more dangerous."); addbodypart(lastrace, BP_BODY, NULL); addbodypart(lastrace, BP_HEAD, NULL); @@ -17183,6 +17234,34 @@ void initrace(void) { addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep"); addflag(lastrace->flags, F_FILLPOT, OT_POT_POISON, BLOODFORPOT, NA, NULL); + addrace(R_SPIDERSWARM, "swarm of spiders", 10, UNI_SWARM, C_DARKGREY, MT_FLESH, RC_HUMANOID, "A fast-moving swarm of deadly spiders."); + addbodypart(lastrace, BP_BODY, "swarm"); + addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "disperse"); + addflag(lastrace->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOGIVECRITS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); + addflag(lastrace->flags, F_MAXATTACKS, 7, 7, NA, NULL); + addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SWARM, NA, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); + addrace(R_SPIDERTOMB, "tomb spider", 5, 'S', C_DARKBLUE, MT_FLESH, RC_ANIMAL, "Tomb spiders are truly nightmarish beings. Their skin can absorb light itself, and they can boost their own life force by consuming the flesh of their victims."); setbodytype(lastrace, BT_SPIDER); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); @@ -18080,7 +18159,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "vibrates"); addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_INSECT, "A harmless, colourful butterfly."); - setbodytype(lastrace, BT_BIRD); + setbodytype(lastrace, BT_FLYINGINSECT); //addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXLOW, NA, NULL); @@ -18107,7 +18186,7 @@ void initrace(void) { addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TIMID, B_TRUE, NA, NA, NULL); addrace(R_GIANTFLY, "giant gnat", 1, 'i', C_GREY, MT_FLESH, RC_INSECT, "Giant gnats buzz around the places, feeding on corpses. Usually no more than a nuisance."); - setbodytype(lastrace, BT_BIRD); + setbodytype(lastrace, BT_FLYINGINSECT); lastrace->baseid = R_GIANTFLY; addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -18143,7 +18222,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_GIANTBLOWFLY, "giant ur-gnat", 2, 'i', C_GREY, MT_FLESH, RC_INSECT, "Large, more solid versions of giant gnats. These can actually cause damage, albeit rarely."); - setbodytype(lastrace, BT_BIRD); + setbodytype(lastrace, BT_FLYINGINSECT); lastrace->baseid = R_GIANTFLY; addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -18179,7 +18258,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_STIRGE, "mosquitoid", 10, 'i', C_DARKYELLOW, MT_FLESH, RC_INSECT, "Mosquitoids look like giant dog-sized mosquitoes but are equipped with human-like arms and clawed hands."); - setbodytype(lastrace, BT_BIRD); + setbodytype(lastrace, BT_FLYINGINSECT); 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_STR, AT_LTAVERAGE, NA, NULL); @@ -18371,6 +18450,43 @@ void initrace(void) { addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 2, DT_ELECTRIC, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_ELECTRIC, NA, "5"); + + addrace(R_MOTHTEMP, "tempest moth", 10, 'i', C_PINK, MT_FLESH, RC_INSECT, "This pink-ish moth is almsot as large as an adult human. Arcs of electricity run up and down its wings, and a sheen of moisture covers its body."); + setbodytype(lastrace, BT_FLYINGINSECT); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_CANCAST, OT_S_AIRBLAST, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANCAST, OT_S_GUSTOFWIND, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANCAST, OT_S_SLEETSTORM, 20, 20, "pw:2;"); + addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_AIRBLAST, F_AICASTTOATTACK, ST_VICTIM, NULL); + addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_GUSTOFWIND, F_AICASTTOATTACK, ST_VICTIM, NULL); + addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SLEETSTORM, F_AICASTTOATTACK, ST_VICTIM, NULL); + addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CASTCHANCE, 90, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "flutters its wings"); + addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL); + addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); + addflag(lastrace->flags, F_ATTACKRANGE, 3, 5, NA, NULL); // maintain distance + addrace(R_STINKBUG, "stinkbeetle", 1, 'x', C_MAGENTA, MT_FLESH, RC_INSECT, "A dog-sized beetle with tough scales. Emits a foul odour upon death."); setbodytype(lastrace, BT_QUADRAPED); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); @@ -18821,7 +18937,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_HITCONFER, F_REVIVETIMER, SC_POISON, 165, NULL); - addflag(lastrace->flags, F_HITCONFERVALS, 0, 5, R_ZOMBIECON, "twists and morphs into a zombie!"); + addflag(lastrace->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie"); addrace(R_SKELETON, "skeleton", 20, 'Z', C_BONE, MT_BONE, RC_UNDEAD, "A walking set of bones, animated through the use of necromancy. Due to their lack of soft flesh, they have little to fear from edged weapons."); setbodytype(lastrace, BT_HUMANOID); @@ -19696,6 +19812,7 @@ void initrace(void) { addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_INSECT) { addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_DRAGON) { // wyrms hate hydras if (r->id != R_HYDRA) { diff --git a/data/hiscores.db b/data/hiscores.db index 432e00340bad964ab170535193095a330fa1ec1f..2eed152baec73d7eb97d8d501f47d5b787afddcc 100644 GIT binary patch delta 449 zcmZqZU~K4MoFL6>zyJX(K#F6d#vNuMR_5m*A$I29%-@(lGQVMdzFCarA~P#cjL&-V z8+Hk18>TCh**WsLm|ieFX1d38lj+Ll296LWNfu@XMjH@e4I->Sge8cu*!-4DijkEa zXae_U9-gn@PDy){42wiO4}&TL^B(3rW3(ckLgRIyXn1uB!S#E>P zFjnv=1v*6`Jh7-KGrtIn0YHs8nfZANK$MeOmYSnrXrPdvrcjcRs*qBem!6uRrx#(# z4)mpdBda#lT@W(^5_1w$GV?rh3lejnj>?-H#-`8ZYXNeDaW+HWGTyv;QiRq(LGU7Y?7<><^5VTkMD!wvyPKfa8F(|y%zMB0|4)4b);Hj0totHp z4ar@O?OgbT`z3tf9rfU!_y_)q58#L9fV7VT7BRF{aUc)k3_28Yh;`sP{)jF31mAAf zL-QyK5O^2B0Kr*5j(QQibz}3e<0K4(+^TZ3tLuAb0`CGD762^3*GNKn^bGyN^X}Zm zPyft4umBde%Hw^LcY^>OPiMgIpj3bm7&#x~f@rm1{h2P#2`E6H1B}GYqmuIoBCKUm*swij_6SRlM)TYe`)bL#OyeKh+8LD`hK9^l| z?zb@E9_@(6cEkTV=zp8bHEG4xxa(bs(1#)%jELS71Cc=ci`#;4@~W?iCUV_b9`f<;1V`JQh diff --git a/defs.h b/defs.h index edd29f5..d84d85d 100644 --- a/defs.h +++ b/defs.h @@ -78,6 +78,7 @@ #define UNI_SHADEDARK 0x2593 #define UNI_SPIRAL 0x2202 #define UNI_SUN 0x203B +#define UNI_SWARM 0x2026 #define UNI_CHAIR 0x2441 #define UNI_CLOUD 0x203B //#define UNI_SOLID '#' @@ -1306,6 +1307,7 @@ enum RACE { R_HIPPOGRIFF, R_HOBGOBLIN, R_HOBGOBLINWAR, + R_HOMUNCULUS, R_HYDRA, R_KOBOLD, R_LEPRECHAUN, @@ -1423,8 +1425,10 @@ enum RACE { R_PORCUPINE, R_RAT, R_RATDIRE, + R_RATMIND, R_RATPLAGUE, R_ROC, + R_SCORPION, R_SLUG, R_SNAIL, R_SNAKE, @@ -1437,6 +1441,7 @@ enum RACE { R_SPIDER, R_SPIDERFUNNELWEB, R_SPIDERREDBACK, + R_SPIDERSWARM, R_SPIDERTOMB, R_SWAN, R_WOLFYOUNG, @@ -1468,6 +1473,7 @@ enum RACE { R_GIANTBLOWFLY, R_LIZARDBATB, R_LIZARDBAT, + R_MOTHTEMP, R_STINKBUG, R_STIRGE, // demons @@ -3458,6 +3464,8 @@ enum FLAG { // v0 = max time allowed to rest before checkout // v1 = total time rested // text = obid of hotel + F_SWARM, // this lf is a swarm, its maxattacks are reduced + // based on its remaining hp pct. F_SWIMEVASION, // +v0 evasion if swimming F_ALIGNMENT, // v0 = al_good, al_neutral, al_evil. default neutral. // if al_none is selected for the player, they @@ -4144,6 +4152,7 @@ enum FLAG { // new:v0=damtype, text=dam^obname // obname must have at least TWO words F_RISEASGHOST, // become a ghost when you die. + F_SEEWITHOUTEYES, // doesn't need eyes to see F_SEEINDARK, // nightvis range is val0 // if v1 is B_BLINDABLE, then bright light will // blind us. @@ -4604,6 +4613,7 @@ enum BODYTYPE { BT_BIRD, BT_FISH, BT_HUMANOID, + BT_FLYINGINSECT, BT_QUADRAPED, BT_SNAKE, BT_SPIDER, diff --git a/io.c b/io.c index fbd6bc2..3bdb590 100644 --- a/io.c +++ b/io.c @@ -12683,6 +12683,13 @@ void showlfstats(lifeform_t *lf, int showall) { } // obvious physical effects here. + + f = lfhasknownflag(lf, F_SWARM); + if (f) { + wrapprint(mainwin, &y, &x, 0, "%s %s a swarm, gaining EV and losing strength as its health drops.", + you(lf), is(lf) ); + } + f = lfhasknownflag(lf, F_ASLEEP); if (f) { char sleepname[BUFLEN]; diff --git a/lf.c b/lf.c index e22c6bd..c77157a 100644 --- a/lf.c +++ b/lf.c @@ -4869,7 +4869,7 @@ int eat(lifeform_t *lf, object_t *o) { setlastdam(lf, "merging with a corpse"); lf->lastdamtype = DT_DIRECT; lf->hp = 0; - newlf = makezombie(o, 0); + newlf = makezombie(o, 0, "rises from the dead"); if (newlf) { addflag(newlf->flags, F_CORPSELF, R_LINGPARASITE, NA, NA, NULL); } @@ -8016,6 +8016,12 @@ int getevasion(lifeform_t *lf) { //if (f && (isairborne(lf) == F_FLYING)) { // ev += f->val[0]; // } + if (lfhasflag(lf, F_SWARM)) { + int pct; + pct = gethppct(lf); + ev = pctof(100-pct,ev); + limit(&ev, 0, NA); + } ////////////////////////////////////////////////// // now negative modifiers @@ -9539,6 +9545,19 @@ int getattacks(lifeform_t *lf, int *min, int *max) { maxattacks++; } + if (lfhasflag(lf, F_SWARM)) { + int pct,origmin; + pct = gethppct(lf); + origmin = minattacks; + + minattacks = pctof(pct,minattacks); + maxattacks = pctof(pct,maxattacks); + if (origmin >= 1) { + limit(&minattacks, 1, NA); + } + limit(&maxattacks, minattacks, NA); + } + if (min) *min = minattacks; if (max) *max = maxattacks; nattacks = rnd(minattacks,maxattacks); @@ -13475,7 +13494,6 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR int lfcanbekod(lifeform_t *lf) { if (isundead(lf)) return B_FALSE; switch (getraceclass(lf)) { - case RC_ROBOT: case RC_GOD: case RC_SLIME: case RC_PLANT: @@ -14193,7 +14211,7 @@ flag_t *isblind(lifeform_t *lf) { } f = lfhasflagval(lf, F_NOBODYPART, BP_EYES, NA, NA, NULL); if (f) { - if (!lfhasflag(lf, F_TREMORSENSE)) { + if (!lfhasflag(lf, F_TREMORSENSE) && !lfhasflag(lf, F_SEEWITHOUTEYES)) { return f; } } @@ -15050,7 +15068,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { -race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc) { +race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc) { race_t *a; assert(!findrace(id)); @@ -15455,7 +15473,7 @@ void makepeaceful(lifeform_t *who, lifeform_t *causedby) { // 'power' is 0-10, determines how poewrful the zombie is. // if 0, don't do any special changes. -lifeform_t *makezombie(object_t *o, int power) { +lifeform_t *makezombie(object_t *o, int power, char *description) { flag_t *f; race_t *r; lifeform_t *lf; @@ -15559,7 +15577,7 @@ lifeform_t *makezombie(object_t *o, int power) { if (haslos(player, where)) { needredraw = B_TRUE; drawscreen(); - msg("%s rises from the dead!", obname); + msg("^W%s %s!", obname, description); } return lf; @@ -18603,6 +18621,11 @@ int poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char * return B_TRUE; } + if (getraceclass(lf) == RC_PLANT) { + return B_TRUE; + } + + // are you immune to disease/poison? psev = pt->severity; switch (psev) { @@ -18986,33 +19009,10 @@ void precalclos(lifeform_t *lf) { // if keepgoing was false, still count it // BUT then stop looking. - //if (litforus) { - los[nlos] = c; - blocker[nlos] = keepgoing ? B_FALSE : B_TRUE; - nlos++; - assert (nlos < allocamt); - //} - /* - else { - int idx,found=B_FALSE; - for (idx=0;idxdarklos) - // that way we can check for these to determine whether we need to recalc our los - // when light changes. - losdark[nlosdark] = c; - nlosdark++; - assert (nlosdark < allocamt); - } - } - */ + los[nlos] = c; + blocker[nlos] = keepgoing ? B_FALSE : B_TRUE; + nlos++; + assert (nlos < allocamt); } // high engineering lets you detect hollow walls. ie. @@ -20451,6 +20451,14 @@ void setbodytype(race_t *r, enum BODYTYPE bt) { addbodypart(r, i, NULL); } break; + case BT_FLYINGINSECT: + addbodypart(r, BP_EYES, NULL); + addbodypart(r, BP_HEAD, NULL); + addbodypart(r, BP_BODY, NULL); + addbodypart(r, BP_LEGS, NULL); + addbodypart(r, BP_WINGS, NULL); + addflag(r->flags, F_SEEWITHOUTEYES, B_TRUE, NA, NA, NULL ); + break; case BT_QUADRAPED: addbodypart(r, BP_EYES, NULL); addbodypart(r, BP_EARS, NULL); @@ -22332,7 +22340,9 @@ void startlfturn(lifeform_t *lf) { piety = getpiety(godlf[i]->race->id); if ((piety < 100) || (piety > 199)) { int dir,chance; - if (piety < 100) { + if (lfhasflag(player, F_TRAINING)) { + chance = 0; + } else if (piety < 100) { dir = 1; chance = piety; limit(&chance, 10, 100); diff --git a/lf.h b/lf.h index b430b2d..7dd49b5 100644 --- a/lf.h +++ b/lf.h @@ -6,7 +6,7 @@ lifeform_t *addlf(cell_t *cell, enum RACE rid, int level); lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller); poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *contracttext, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime); job_t *addjob(enum JOB id, char *name, char *desc, enum JOBCATEGORY category); -race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); +race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime); void addskillabil(enum SKILL id, enum SKILLLEVEL lev, enum OBTYPE abilid, int timeout, char *text, int announce); @@ -433,7 +433,7 @@ int makelearnable(lifeform_t *lf, enum SKILL skid); int makenauseated(lifeform_t *lf, int amt, int howlong, enum ERROR *why); void makenoise(lifeform_t *lf, enum NOISETYPE nid); void makepeaceful(lifeform_t *lf, lifeform_t *causedby); -lifeform_t *makezombie(object_t *o, int power); +lifeform_t *makezombie(object_t *o, int power, char *description); void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how, int overridepower); int meetsallattreqs(lifeform_t *lf, object_t *o); int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *modpct); diff --git a/nexus.c b/nexus.c index 05653b7..d847dc9 100644 --- a/nexus.c +++ b/nexus.c @@ -848,7 +848,6 @@ void cleanup(void) { free(raceposs); fclose(logfile); - cleanupgfx(); // free commands & options while (firstcommand) killcommand(firstcommand); @@ -886,6 +885,8 @@ void cleanup(void) { // behaviours while (firstbehaviour) killbehaviour(firstbehaviour); //WriteMemLeak(); + + cleanupgfx(); } void dbtimestartlf(lifeform_t *lf) { diff --git a/objects.c b/objects.c index fb964c5..d16e124 100644 --- a/objects.c +++ b/objects.c @@ -1225,7 +1225,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum if (db) dblog("DB: FOUND: ot->name = '%s'", ot->name ); // trying to place object on a solid cell? - if ((gamemode == GM_GAMESTARTED) && where->where) { + if ((gamemode > GM_LOADING) && where->where) { if (where->where->type->solid) { // doors are okay - clear the solid cell first. if (hasflag(ot->flags, F_DOOR)) { @@ -14959,12 +14959,14 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp } // an actual physical shield? - sprintf(attackname, "%s", obname); - difficulty = 60 + (speed*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)); + if (thrower != target) { + sprintf(attackname, "%s", obname); + difficulty = 60 + (speed*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)); + } } } @@ -15997,14 +15999,32 @@ void timeeffectsob(object_t *o) { if (lfloc) { char *revivetext; revivetext = strdup(f->text); - // revive! - lf = addmonster(lfloc, f->val[2], NULL, B_FALSE, 1, B_FALSE, NULL); - // gain flags form corpse - copyflag(lf->flags, o->flags, F_CANWILL); - copyflag(lf->flags, o->flags, F_CANCAST); - copyflag(lf->flags, o->flags, F_JOB); - // corpse vanishes - removeob(o, o->amt); + if ((f->val[2] == R_ZOMBIE) || (f->val[2] == R_ZOMBIECON)) { + int contagious = B_FALSE; + if (f->val[2] == R_ZOMBIECON) { + contagious = B_TRUE; + } + // turn into a zombified version of itself. + lf = makezombie(o, 10, revivetext); + if (lf && contagious) { + addflag(lf->flags, F_HITCONFER, F_REVIVETIMER, SC_POISON, 165, NULL); + addflag(lf->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie!"); + } + addflag(lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL); + } else { + // revive! + lf = addmonster(lfloc, f->val[2], NULL, B_FALSE, 1, B_FALSE, NULL); + // gain flags form corpse + copyflag(lf->flags, o->flags, F_CANWILL); + copyflag(lf->flags, o->flags, F_CANCAST); + copyflag(lf->flags, o->flags, F_JOB); + // no more xp. + killflagsofid(lf->flags, F_XPVAL); + addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL); + + // corpse vanishes + removeob(o, o->amt); + } // announce if (haslos(player, lfloc) || haslos(player, obloc)) { msg("^W%s %s!^n", obname, revivetext); @@ -17417,12 +17437,12 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob } int wouldgivepenalty(lifeform_t *lf, flagpile_t *fp) { - flag_t *retflag[MAXCANDIDATES],*f; + flag_t *retflag[MAXCANDIDATES]; int nretflags,i,pen = 0; getflags(lf->flags, retflag, &nretflags, F_ARMOURPENALTY, F_SHIELDPENALTY, F_NONE); for (i = 0; i < nretflags; i++) { - pen += adjustarmourpenalty(lf, f->val[0]); - pen += adjustarmourpenalty(lf, f->val[1]); + pen += adjustarmourpenalty(lf, retflag[i]->val[0]); + pen += adjustarmourpenalty(lf, retflag[i]->val[1]); } if (pen) return B_TRUE; return B_FALSE; diff --git a/spell.c b/spell.c index a77e509..c556762 100644 --- a/spell.c +++ b/spell.c @@ -4273,10 +4273,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // if it was a lifeform which stopped us... if (nextc->lf) { + // knock them back as well targcell = nextc; - target = targcell->lf; + target = nextc->lf; knockback(target, dir, power, caster, 0, B_DOANNOUNCE, B_DODAM); - real_fall_from_air(targcell->lf, SZ_HUMAN + (power/4)); + real_fall_from_air(target, SZ_HUMAN + (power/4)); } else if (firstobcell) { // objects for (o = firstobcell->obpile->first ;o ; o = nexto) { @@ -4385,7 +4386,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int sel,n; sel = rnd(0,nposs-1); o = poss[sel]; - newlf = makezombie(o, power); + newlf = makezombie(o, power, "rises from the dead"); if (newlf) { petify(newlf, target); donesomething = B_TRUE; @@ -6368,21 +6369,23 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int newdir; // make them face a random (different) direction newdir = getdiraway(targcell, caster->cell, NULL, B_FALSE, DT_ORTH, B_FALSE); + + // announce - do this before turning in case it makes the + // caster be out of sight. + if (isplayer(target)) { + msg("You are twisted around to face %s!", getdirname(target->facing)); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } else if (cansee(player, target)) { + char tname[BUFLEN]; + getlfname(target, tname); + msg("%s spins around to face %s!", tname, getdirname(target->facing)); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } setfacing(target, newdir); // ai loses target info loseaitargets(target); - // announce - if (isplayer(target)) { - msg("You spin around to face %s.", getdirname(target->facing)); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } else if (cansee(player, target)) { - char tname[BUFLEN]; - getlfname(target, tname); - msg("%s spins around to face %s.", tname, getdirname(target->facing)); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } } } else if (spellid == OT_S_DETECTLIFE) { if (!target) { diff --git a/text.c b/text.c index b1cc098..db6a2e5 100644 --- a/text.c +++ b/text.c @@ -263,7 +263,9 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam needfree = B_TRUE; } else if (fatal) { verb = getkillverb(victim, wep, damtype, dam, maxhp); - if (strstr(verb, "knock out") && !isplayer(victim)) knownnodam = B_TRUE; + if (!isplayer(victim)) { + if (strstr(verb, "knock out") || strstr(verb, "disable")) knownnodam = B_TRUE; + } } else { if (!victim || // atacking an object (getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) || // know about the race @@ -354,7 +356,8 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam if (victim && isplayer(victim) && !nodam) { col = C_YELLOW; } else { - col = C_GREY; + //col = C_GREY; + col = chartocol(getlfcol(victim, CC_BAD)); } strcpy(adjective, ""); @@ -1348,11 +1351,16 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d } if (!isunconscious(victim) && lfcanbekod(victim)) { + int willko = B_FALSE; if (wep && hasflag(wep->flags, F_MERCIFUL)) { - return "knock out"; + willko = B_TRUE; } - if (wep && wep->pile->owner && lfhasflag(wep->pile->owner, F_STRIKETOKO)) { - return "knock out"; + if (!willko && wep && wep->pile->owner && lfhasflag(wep->pile->owner, F_STRIKETOKO)) { + willko = B_TRUE; + } + if (willko) { + if (getraceclass(victim) == RC_ROBOT) return "disable"; + else return "knock out"; } }