diff --git a/attack.c b/attack.c index 1e55df5..33a8756 100644 --- a/attack.c +++ b/attack.c @@ -215,6 +215,12 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { attackedpeaceful = B_TRUE; } + if (!force && isplayer(lf) && lfhasflag(lf, F_HASNEWLEVEL)) { + if (!warnabout(TEXT_WARN_ATTACK_NOXP)) { + return B_TRUE; + } + } + // player walked into someone who was feigning death? if (isplayer(lf) && lfhasflag(c->lf, F_FEIGNINGDEATH) && !force) { char vicname[BUFLEN]; diff --git a/data.c b/data.c index 07dbf3c..169ce03 100644 --- a/data.c +++ b/data.c @@ -4426,6 +4426,13 @@ void initobjects(void) { addflag(lastot->flags, F_STARTOB, 50, NA, NA, "good armour"); addflag(lastot->flags, F_STARTOB, 50, NA, NA, "great armour"); + addot(OT_BED, "wooden bed", "Standard sleep-enhancing apparatus.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "_"); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL); + addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "\\"); @@ -6451,7 +6458,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL); addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); - addflag(lastrace->flags, F_ENHANCESMELL, 2, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // penalties addflag(lastrace->flags, F_PENDESC, 0, NA, NA, "Below average Strength and low Wisdom, and slightly low Hit Points."); addflag(lastrace->flags, F_PENDESC, 1, NA, NA, "Carnivorous (only eats meat)."); @@ -7542,6 +7549,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLEEONHPPCT, 30, NA, NA, ""); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_TROGLODYTE, "troglodyte", 20, 'z', C_GREY, MT_FLESH, RC_HUMANOID, "Troglodytes are smaller, stunted lizardmen who at outcast at birth. They linger on the outskirts of society, scavenging garbage and living in their own filth."); setbodytype(lastrace, BT_HUMANOID); @@ -7571,6 +7579,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_LEPRECHAUN, "leprechaun", 35, 'n', C_GREEN, MT_FLESH, RC_HUMANOID, "Leprechauns are tiny Irish humans, with a love for gold and practical jokes. Known for their supernatural luck."); setbodytype(lastrace, BT_HUMANOID); @@ -7657,6 +7666,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID, "Large, cruel, monstrous and hideous humanoid monsters. Ogres have a raging temper and hunger for flesh."); @@ -7690,6 +7700,7 @@ void initrace(void) { addflag(lastrace->flags, F_MINIONS, 20, 1, 2, "orc warrior"); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_OGREWARHULK, "warhulk", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID, "Warhulks are huge ogres, even angrier than their comrades."); setbodytype(lastrace, BT_HUMANOID); @@ -7723,6 +7734,7 @@ void initrace(void) { addflag(lastrace->flags, F_MINIONS, 25, 1, 8, "orc"); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "orc warrior"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_ORC, "orc", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID, "Orcs are fierce humanoid monsters with green skin and grotesque features."); setbodytype(lastrace, BT_HUMANOID); @@ -7897,6 +7909,7 @@ void initrace(void) { addflag(lastrace->flags, F_AUTOCREATEOB, 1, NA, NA, "puff of smoke"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puff of smoke"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of grey ooze. Grey, acidic ooze."); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pool of slime"); @@ -7997,6 +8010,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL, "Xats are wild pigs with the claws of a dog."); setbodytype(lastrace, BT_QUADRAPED); @@ -8014,6 +8028,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "snorts^a snort"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // fish addrace(R_CRAB, "giant crab", 150, ';', C_ORANGE, MT_FLESH, RC_AQUATIC, "A massive orange crab with sharp pincers."); @@ -8260,6 +8275,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d4;"); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_YELLOW, MT_FLESH, RC_ANIMAL, "A large angry bear."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_BEAR; @@ -8287,6 +8303,7 @@ void initrace(void) { addflag(lastrace->flags, F_BLEEDABIL, OT_A_RAGE, NA, NA, NULL); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub"); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL, "Cute little baby bears. Still dangerous though."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_BEAR; @@ -8310,6 +8327,7 @@ void initrace(void) { addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "Giant ants are enormous (for an ant, anyway), and keen to take avenge their smaller ancestors who were crushed by small children."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_ANT; @@ -8377,6 +8395,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL, "A common farm-yard chicken."); setbodytype(lastrace, BT_BIRD); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -8422,6 +8441,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_DOGBLINK, "blink dog", 35, 'd', C_YELLOW, MT_FLESH, RC_ANIMAL, "Magical canines who can teleport small distances at will."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -8448,6 +8468,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Possessed evil canines who thrive on death and destruction."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -8477,6 +8498,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL, "Canines bred for war."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -8502,6 +8524,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 40, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A young baby hawk."); // 'A' for Avian setbodytype(lastrace, BT_BIRD); @@ -8532,6 +8555,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 30, NA, NA, NULL); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_HAWK, "hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A large bird of prey."); // 'A' for Avian setbodytype(lastrace, BT_BIRD); @@ -8561,6 +8585,7 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_HAWKBLOOD, "blood hawk", 1, 'A', C_RED, MT_FLESH, RC_ANIMAL, "A stronger version of a hawk."); // 'A' for Avian setbodytype(lastrace, BT_BIRD); @@ -8588,6 +8613,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_HAWKFROST, "frost hawk", 1, 'A', C_CYAN, MT_FLESH, RC_ANIMAL, "A hark imbued with the power of ice. Frost hawks can release a powerufl blast of freezing air when threatened."); // 'A' for Avian setbodytype(lastrace, BT_BIRD); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -8615,6 +8641,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_LEECH, "giant leech", 10, 'j', C_MAGENTA, MT_FLESH, RC_ANIMAL, "A boneless blood-sucking creature. Quite dangerous until it eats it becomes satiated with blood, at which point it will slither off and fall asleep."); addbodypart(lastrace, BP_BODY, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -8695,6 +8722,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL, "Common venomous snakes."); setbodytype(lastrace, BT_SNAKE); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -8955,6 +8983,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Highly intelligent members of the canine family."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -8980,6 +9009,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_MORALE, 7, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); // end animals // dragons @@ -9028,6 +9058,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONBLUEY, "young blue dragon", 150, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue dragons are massive reptilian creatures who can (and will) consume almost any living creature."); setbodytype(lastrace, BT_HUMANOID); @@ -9075,6 +9107,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONBLUEA, "ancient blue dragon", 600, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue dragons are massive reptilian creatures who can (and will) consume almost any living creature."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -9127,6 +9161,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONRED, "red dragon", 400, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); @@ -9175,6 +9211,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONREDY, "young red dragon", 150, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -9217,6 +9255,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONREDA, "ancient red dragon", 600, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -9265,6 +9305,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONWHITE, "white dragon", 400, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); @@ -9311,6 +9353,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONWHITEY, "young white dragon", 150, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -9351,6 +9395,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_DRAGONWHITEA, "ancient white dragon", 600, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -9399,6 +9445,8 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 45, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); // end dragons // insects @@ -9451,6 +9499,8 @@ 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); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_GIANTBLOWFLY, "giant blowfly", 2, 'i', C_GREY, MT_FLESH, RC_INSECT, "Large, more solid versions of giant flies. These can actually cause damage, albeit rarely."); setbodytype(lastrace, BT_BIRD); lastrace->baseid = R_GIANTFLY; @@ -9479,6 +9529,8 @@ 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); + 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_BROWN, 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); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); @@ -9503,6 +9555,8 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:1d4;"); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT, "Giant centipedes are long, many-legged creatures with a poisonous bite."); addbodypart(lastrace, BP_EYES, NULL); @@ -9713,6 +9767,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TOUCHPARALYZE2, 1, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); @@ -9766,6 +9821,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 8, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHPARALYZE, 1, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); diff --git a/defs.h b/defs.h index ff68721..8b38a19 100644 --- a/defs.h +++ b/defs.h @@ -11,6 +11,9 @@ #define ONEIN_FOUNTAINDRYUP 3 #define PCTCH_PILLAR 5 +// Text +#define TEXT_WARN_ATTACK_NOXP "You cannot gain experience until you train. Really attack?" + // Defaults #define DEF_AIFOLLOWTIME (50) // if target lf is out of view // for this many turns, abandon chase @@ -1486,6 +1489,7 @@ enum OBTYPE { // none yet. // furniture OT_ARMOURRACK, + OT_BED, OT_BOOKSHELF, OT_CANDELABRUM, OT_COFFIN, @@ -2578,6 +2582,7 @@ enum FLAG { // optional v1 is colour for casttype-based animations // (ie. spit spells) F_CAFFEINATED, // can't sleep. + F_CANEATRAW, // lf can eat raw food with no issues F_CANCAST, // can cast the spell val0 (need MP) F_CANHEARLF, // you can hear lifeform id v0 (show their glyph) // this flag does not get announced. diff --git a/doc/glyphs.txt b/doc/glyphs.txt index fec682c..f99f629 100644 --- a/doc/glyphs.txt +++ b/doc/glyphs.txt @@ -24,7 +24,6 @@ o = orc O = ogre p = sPirit c = cockatricoe -x = small creature/monster q = quadraped Q = large quadraped r = rodent @@ -36,6 +35,8 @@ H = large humanoid U = unearthly/horrific creature w = worm V = vampire +x = small creature/monster +X = unknown thing! y/Y = air related creatures like clouds of gas, air elemental z = lizard-like creature Z = undead diff --git a/io.c b/io.c index 4f7d66c..571e57e 100644 --- a/io.c +++ b/io.c @@ -1241,7 +1241,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { } else { char restobname[BUFLEN]; getobname(restob, restobname, 1); - msg("You start %s (in your %s)...",meditating ? "meditating" : "resting", noprefix(restobname)); + + if (restob->pile->owner == lf) { + msg("You start %s (in your %s)...",meditating ? "meditating" : "resting", noprefix(restobname)); + } else { + msg("You start %s (in %s)...",meditating ? "meditating" : "resting", restobname); + } } } else { msg("You start %s (on the ground)...", meditating ? "meditating" : "resting" ); @@ -3101,8 +3106,10 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { val = B_TRUE; } for (i = 0 ; (mylist[i] != NULL) ; i++) { - selected[i] = val; - selcount[i] = mylist[i]->amt; + if (!hasflag(mylist[i]->flags, F_NOPICKUP)) { + selected[i] = val; + selcount[i] = mylist[i]->amt; + } } } else if (ch == 10) { // enter // construct list to return @@ -10531,6 +10538,10 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s %s a vegetarian (will not eat meat).", you(lf), is(lf)); y++; } + if (lfhasflag(lf, F_CANEATRAW)) { + mvwprintw(mainwin, y, 0, "%s can digest raw meat.", you(lf)); + y++; + } // damage desistances/vulnerabilities // resistances diff --git a/lf.c b/lf.c index 4c4e1a0..a1dfedf 100644 --- a/lf.c +++ b/lf.c @@ -745,9 +745,9 @@ int caneat(lifeform_t *lf, object_t *o) { } } - // ai lifeforms won't eat tainted food + // ai lifeforms won't eat tainted food unless they can handle it if (!isplayer(lf)) { - if (hasflag(o->flags, F_TAINTED)) { + if (hasflag(o->flags, F_TAINTED) && !lfhasflag(lf, F_CANEATRAW)) { reason = E_WONT; return B_FALSE; } @@ -2975,7 +2975,7 @@ int eat(lifeform_t *lf, object_t *o) { // uncooked meat? if (iscorpse(o) && isplayer(lf)) { - if (!hasflag(o->flags, F_PREPARED)) { + if (!hasflag(o->flags, F_PREPARED) && !lfhasflag(lf, F_CANEATRAW)) { if (!lfhasflag(lf, F_EATING) && getskill(lf, SK_COOKING)) { int ch; char ques[BUFLEN]; @@ -3686,6 +3686,8 @@ void enhanceskills(lifeform_t *lf) { if (lf->xp >= getxpforlev(lf->level + 1)) { gainlevel(lf); // this will increment 'newlevel' } + + killwarningtext(TEXT_WARN_ATTACK_NOXP); } // end if gainedxplev } @@ -7245,6 +7247,17 @@ object_t *getrestob(lifeform_t *lf) { if (o) return o; } + for (o = lf->cell->obpile->first ; o ; o = o->next) { + f = hasflag(o->flags, F_HELPSREST); + if (f && !isarmour(o)) { + if (!bestob || (f->val[0] > bestval)) { + bestval = f->val[0]; + bestob = o; + } + } + } + + for (o = lf->pack->first; o ; o = o->next) { f = hasflag(o->flags, F_HELPSREST); if (f) { @@ -7253,9 +7266,8 @@ object_t *getrestob(lifeform_t *lf) { if (isarmour(o) && !armourfits(lf, o, NULL)) { valid = B_FALSE; } - if (valid) { - if (!bestob && (f->val[0] > bestval)) { + if (!bestob || (f->val[0] > bestval)) { bestval = f->val[0]; bestob = o; } @@ -14704,6 +14716,18 @@ void startlfturn(lifeform_t *lf) { } } + if (onein(3) && hasbp(lf, BP_TAIL)) { + cell_t *c; + c = getcellindir(lf->cell, diropposite(lf->facing)); + if (c && c->lf) { + if (isplayer(lf)) { + warn("^WYour tail brushes up against something behind you!"); + } else { + turntoface(lf, c); + } + } + } + if (hasactivespell(lf, OT_S_SUMMONWEAPON) && !hasobwithflagval(lf->pack, F_CREATEDBYSPELL, OT_S_SUMMONWEAPON, NA, NA, NULL)) { stopspell(lf, OT_S_SUMMONWEAPON); } diff --git a/map.c b/map.c index fe2582a..a077c0a 100644 --- a/map.c +++ b/map.c @@ -4997,6 +4997,18 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) { *thing = c->lf; return TT_MONSTER; } + if (lfhasflagval(player, F_GRABBEDBY, c->lf->id, NA, NA, NULL)) { + if (glyph) { + glyph->ch = 'X'; + glyph->colour = C_GREY; + } + *thing = c->lf; + if (desc) { + getlfname(c->lf, desc); + strcat(desc, " (holding you)"); + } + return TT_MONSTER; + } } f = lfhasflag(player, F_DETECTMETAL); diff --git a/move.c b/move.c index 70013d5..a56e09d 100644 --- a/move.c +++ b/move.c @@ -2347,7 +2347,11 @@ void standup(lifeform_t *lf) { msg("%s stands up.",lfname); } killflagsofid(lf->flags, F_PRONE); - killflagsofid(lf->flags, F_FEIGNINGDEATH); + if (killflagsofid(lf->flags, F_FEIGNINGDEATH)) { + // have to redraw the screen so that the corpse glyph will + // change into the lf's glyph + if (cansee(player, lf)) needredraw = B_TRUE; + } // monsters don't take time to stand up if they were feigning death! if (!isplayer(lf) && lfhasflag(lf, F_FEIGNINGDEATH)) { } else { diff --git a/nexus.c b/nexus.c index 850b3b2..602e3b1 100644 --- a/nexus.c +++ b/nexus.c @@ -1141,6 +1141,12 @@ void killwarning(warning_t *w) { } } +void killwarningtext(char *text) { + warning_t *w; + w = findwarning(text); + if (w) killwarning(w); +} + int limit(int *what, int min, int max) { int limited = B_FALSE; if (min != NA) { diff --git a/nexus.h b/nexus.h index 2cc5629..db8fc13 100644 --- a/nexus.h +++ b/nexus.h @@ -20,6 +20,7 @@ void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, in void initbresnham(int x1, int y1, int x2, int y2, int *xinc1, int *yinc1, int *dinc1, int *xinc2, int *yinc2, int *dinc2, int *numpixels, int *d); int isplayerturn(void); void killwarning(warning_t *w); +void killwarningtext(char *text); int limit(int *what, int min, int max); int limitf(float *what, float min, float max); int limitd(double *what, double min, double max);