From 0c5f7ad05b3488cfd1a007b5830aae0f0550c868 Mon Sep 17 00:00:00 2001 From: fluffymormegil Date: Sat, 17 Mar 2012 10:39:05 +0000 Subject: [PATCH] Prerelease snapshot --- Makefile | 2 +- cavechop.h | 23 ++--- display.c | 18 +++- main.c | 101 +++++++++++++-------- map.c | 64 ++++++++++--- monsters.c | 21 +++++ objects.c | 170 ++++++++++++++++++++++++++++++++-- permobj.c | 301 ++++++++++++++++++++++++++++++++----------------------------- permons.c | 12 +-- u.c | 85 ++++++++++------- 10 files changed, 534 insertions(+), 263 deletions(-) diff --git a/Makefile b/Makefile index 310a6f8..b2dded5 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ archive: clean rm -r $(ARCHIVEDIR) clean: - -rm -f *.o $(GAME) cavechop.log cavechop.sav.gz + -rm -f *.o $(GAME) cavechop.log cavechop.sav.gz *.tgz display.o: display.c cavechop.h diff --git a/cavechop.h b/cavechop.h index 510222d..60db0b9 100644 --- a/cavechop.h +++ b/cavechop.h @@ -33,7 +33,7 @@ #include /* change WIZARD_MODE to 1 if you want the wizard mode commands. */ -#define WIZARD_MODE 0 +#define WIZARD_MODE 1 #define is_vowel(ch) (((ch) == 'a') || ((ch) == 'e') || ((ch) == 'i') || ((ch) == 'o') || ((ch) == 'u')) @@ -63,11 +63,10 @@ enum terrain_num { }; /* XXX enum death */ -/* Sadly, there are not yet 52 kinds of way to die, only four: killed by - * an arbitrary string, killed by a monster, drained of body by an arbitrary - * string, and drained of agility by an arbitrary string. */ +/* Sadly, there are not 52 kinds of way to die. */ enum death { - DEATH_KILLED, DEATH_KILLED_MON, DEATH_BODY, DEATH_AGILITY + DEATH_KILLED, DEATH_KILLED_MON, DEATH_BODY, DEATH_AGILITY, + DEATH_LASH, DEATH_RIBBONS }; /* XXX enum poclass_num */ @@ -178,6 +177,7 @@ enum Permobj_nums { // weapons PO_DAGGER=0, PO_LONG_SWORD, PO_MACE, PO_RUNESWORD, PO_BOW, PO_CROSSBOW, + PO_TORMENTORS_LASH, PO_STAFF_OF_FIRE, // potions PO_POT_HEAL, PO_POT_BODY, PO_POT_AGILITY, PO_POT_RESTORATION, // flasks @@ -192,10 +192,10 @@ enum Permobj_nums PO_RING_REGEN, PO_RING_FIRE, PO_RING_VAMPIRE, PO_RING_FROST, PO_RING_TELEPORT, // food - PO_IRON_RATION, PO_DRIED_FRUIT, PO_ELVEN_BREAD + PO_IRON_RATION, PO_DRIED_FRUIT, PO_ELVEN_BREAD, PO_DEVIL_SPLEEN }; #define PO_FIRST_WEAPON PO_DAGGER -#define PO_LAST_WEAPON PO_CROSSBOW +#define PO_LAST_WEAPON PO_STAFF_OF_FIRE #define PO_FIRST_POTION PO_POT_HEAL #define PO_LAST_POTION PO_POT_RESTORATION #define PO_FIRST_FLASK PO_FLASK_POISON @@ -207,7 +207,7 @@ enum Permobj_nums #define PO_FIRST_RING PO_RING_REGEN #define PO_LAST_RING PO_RING_TELEPORT #define PO_FIRST_FOOD PO_IRON_RATION -#define PO_LAST_FOOD PO_ELVEN_BREAD +#define PO_LAST_FOOD PO_DEVIL_SPLEEN #define NUM_OF_PERMOBJS ((PO_LAST_FOOD) + 1) struct permobj { @@ -307,8 +307,7 @@ extern void populate_level(void); extern void inject_player(void); extern void explore_around(int y, int x); -/* For now, I can't be arsed with a mapcell structure */ -#define LEVGEN_WALK_STEPS 600 +#define LEVGEN_WALK_CELLS 600 #define DUN_WIDTH 42 #define DUN_HEIGHT 42 #define ROOM_HT_DELTA 4 @@ -342,7 +341,9 @@ extern void attempt_pickup(void); extern int po_is_stackable(int po); extern void damage_obj(int obj); extern int evasion_penalty(int obj); - +extern int magic_ring(void); +extern int emanate_armour(void); +extern int zap_weapon(void); /* XXX rng.c data and funcs */ #define RNG_MAX 0xFFFFFFFFu diff --git a/display.c b/display.c index 8b12b17..f94cc1d 100644 --- a/display.c +++ b/display.c @@ -105,6 +105,10 @@ static chtype terrain_char(enum terrain_num terrain_type) return '#' | colour_attrs[wall_colour]; case DOOR: return '+'; + case WATER: + return '{' | colour_attrs[DBCLR_BLUE]; + case LAVA: + return '{' | colour_attrs[DBCLR_RED]; default: return '*'; } @@ -490,7 +494,7 @@ enum game_cmd get_command(void) return GET_ITEM; case 'd': return DROP_ITEM; - case 'D': + case '@': return DUMP_CHARA; case 'S': return SAVE_GAME; @@ -644,18 +648,24 @@ void print_help(void) print_msg("R remove a ring\n"); print_msg("W wear armour\n"); print_msg("T take off armour\n"); + print_msg("w wield a weapon\n"); print_msg("t throw a flask\n"); print_msg("r read a scroll\n"); - print_msg("w wield a weapon\n"); print_msg("q quaff a potion\n"); + print_msg("e eat something edible\n"); print_msg("g pick up an item (also 0 or comma)\n"); print_msg("d drop an item\n"); - print_msg("e eat something edible\n"); print_msg("> go down stairs\n"); print_msg("5 do nothing (wait until next action)\n"); print_msg(". do nothing (wait until next action)\n"); print_msg("\nPress any key to continue...\n"); wgetch(message_window); + print_msg("ACTIONS (continued)\n"); + print_msg("z activate your weapon's magical power (if any)\n"); + print_msg("m activate your ring's magical power (if any)\n"); + print_msg("E activate your armour's magical power (if any)\n"); + print_msg("\nPress any key to continue...\n"); + wgetch(message_window); print_msg("OTHER COMMANDS\n"); print_msg("S save and exit\n"); print_msg("X quit without saving\n"); @@ -663,7 +673,7 @@ void print_help(void) print_msg("I examine an item you are carrying\n"); print_msg("# show underlying terrain of occupied squares\n"); print_msg("\\ list all recognised items\n"); - print_msg("D dump your character's details to .dump\n"); + print_msg("@ dump your character's details to .dump\n"); print_msg("? print this message\n"); print_msg("\nPress any key to continue...\n"); wgetch(message_window); diff --git a/main.c b/main.c index 667e9ca..c7bc1ab 100644 --- a/main.c +++ b/main.c @@ -265,28 +265,53 @@ int do_command(enum game_cmd cmd) { u.armour = u.inventory[i]; recalc_defence(); - print_msg("Wearing "); - print_obj_name(u.armour); - print_msg(".\n"); + if (objects[u.armour].obj_id == PO_RIBBONS) + { + print_msg("You grit your teeth, trying to get used to the tingle of\nthe ribbons' magic against your skin.\n"); + } + else + { + print_msg("Wearing "); + print_obj_name(u.armour); + print_msg(".\n"); + } return 1; } return 0; case EMANATE_ARMOUR: - print_msg("internal error: armour emanation not supported\n"); - return 0; + if (u.armour == -1) + { + print_msg("You are not wearing any armour.\n"); + return 0; + } + return emanate_armour(); case ZAP_WEAPON: - print_msg("internal error: weapon zapping not supported\n"); - return 0; + if (u.weapon == -1) + { + print_msg("You have no weapon in hand.\n"); + return 0; + } + return zap_weapon(); case MAGIC_RING: - print_msg("internal error: ring magicking not supported\n"); - return 0; + if (u.weapon == -1) + { + print_msg("You are not wearing a ring.\n"); + return 0; + } + return magic_ring(); case TAKE_OFF_ARMOUR: if (u.armour != -1) { + if ((u.resistances[DT_FIRE] == RESIST_ARMOUR) && + (terrain[u.y][u.x] == LAVA)) + { + print_msg("Your armour is your only current source of fire\nresistance; removing it here would incinerate you.\n"); + return 0; + } u.armour = -1; recalc_defence(); print_msg("You take off your armour.\n"); @@ -374,34 +399,36 @@ int do_command(enum game_cmd cmd) print_msg("You have no ring to remove!\n"); return 0; } - else if (objects[u.ring].obj_id == PO_RING_FROST) - { - if (terrain[u.y][u.x] == WATER) - { - print_msg("Since you don't know how to swim, removing that ring here\nwould result in your death by drowning.\n"); - return 0; - } - } - else - { - print_msg("You remove your ring.\n"); - u.ring = -1; - } - return 1; + else if ((terrain[u.y][u.x] == LAVA) && (u.resistances[DT_FIRE] == RESIST_RING)) + { + print_msg("That ring is your only current source of fire resistance. Removing\nit here would incinerate you.\n"); + return 0; + } + else if ((objects[u.ring].obj_id == PO_RING_FROST) && (terrain[u.y][u.x] == WATER)) + { + print_msg("Since nobody ever taught you to swim, removing that ring\nhere would result in your death by drowning.\n"); + return 0; + } + else + { + print_msg("You remove your ring.\n"); + u.ring = -1; + } + return 1; case PUT_ON_RING: - if (u.ring != -1) - { - print_msg("You are already wearing a ring.\n"); - return 0; - } - i = inv_select(POCLASS_RING, "put on", 0); - if (i >= 0) - { - u.ring = u.inventory[i]; - print_msg("You put on "); - print_obj_name(u.ring); - print_msg(".\n"); - return 1; + if (u.ring != -1) + { + print_msg("You are already wearing a ring.\n"); + return 0; + } + i = inv_select(POCLASS_RING, "put on", 0); + if (i >= 0) + { + u.ring = u.inventory[i]; + print_msg("You put on "); + print_obj_name(u.ring); + print_msg(".\n"); + return 1; } return 0; case INSPECT_ITEM: @@ -523,7 +550,7 @@ void main_loop(void) enum game_cmd cmd; int i; int action_speed; - print_msg("Welcome to Cave Chop.\n"); + print_msg("Welcome to Cave Chop, Princess %s.\n", u.name); print_msg("Press '?' for help.\n"); while (!game_finished) { diff --git a/map.c b/map.c index 4876233..5b73c2c 100644 --- a/map.c +++ b/map.c @@ -80,18 +80,13 @@ void put_stairs(void) terrain[y][x] = STAIRS; } -void build_level(void) +static void run_random_walk(int oy, int ox, enum terrain_num write, enum terrain_num *overwrite, int overwrite_length, int cells) { int i; - int y, x; - /* Snapshot the running RNG state, so that we can rebuild the map from - * the saved RNG state at game reload. */ - memcpy(saved_state, rng_state, sizeof saved_state); - /* Run a random walk from the centre of the map. Any time it would go - * off the edge, resume from the middle. Don't stop until we've excavated - * the desired amount. */ - for ((i = 0), (y = DUN_HEIGHT / 2), (x = DUN_WIDTH / 2); - i < LEVGEN_WALK_STEPS; ) + int j; + int y = oy; + int x = ox; + for (i = 0; i < cells; ) { if (zero_die(2)) { @@ -114,12 +109,55 @@ void build_level(void) x = DUN_WIDTH - 3; } } - if (terrain[y][x] != FLOOR) + for (j = 0; j < overwrite_length; ++j) { - ++i; - terrain[y][x] = FLOOR; + if (terrain[y][x] == overwrite[j]) + { + ++i; + terrain[y][x] = write; + break; + } } } +} + +void build_level(void) +{ + int y = DUN_HEIGHT / 2; + int x = DUN_WIDTH / 2; + enum terrain_num pool_flavour = FLOOR; + int num_pools; + enum terrain_num overwrite_array[2] = { WALL, FLOOR }; + /* Snapshot the running RNG state, so that we can rebuild the map from + * the saved RNG state at game reload. */ + memcpy(saved_state, rng_state, sizeof saved_state); + run_random_walk(y, x, FLOOR, overwrite_array, 1, LEVGEN_WALK_CELLS); + if ((depth > 20) && !zero_die(4)) + { + num_pools = inclusive_flat(1, 4); + pool_flavour = LAVA; + } + else if ((depth > 10) && !zero_die(3)) + { + num_pools = inclusive_flat(1, 4); + pool_flavour = WATER; + } + else + { + num_pools = 0; + } + while (num_pools > 0) + { + int pool_size = inclusive_flat(9, 36); + + do + { + y = exclusive_flat(1, DUN_HEIGHT - 2); + x = exclusive_flat(1, DUN_WIDTH - 2); + } while (terrain[y][x] != FLOOR); + run_random_walk(y, x, pool_flavour, overwrite_array, 2, pool_size); + --num_pools; + } /* Add the stairs */ put_stairs(); } diff --git a/monsters.c b/monsters.c index eb1fb77..e7dbbe9 100644 --- a/monsters.c +++ b/monsters.c @@ -211,6 +211,18 @@ void death_drop(int mon) create_obj(PO_RUNESWORD, 1, 0, y, x); } break; + case PM_DEMON: + if (!zero_die(100)) + { + create_obj(PO_DEVIL_SPLEEN, 1, 0, y, x); + } + break; + case PM_DEFILER: + if (!zero_die(50)) + { + create_obj(PO_DEVIL_SPLEEN, 1, 0, y, x); + } + break; default: break; } @@ -241,6 +253,15 @@ int mon_can_pass(int mon, int y, int x) { return 0; } + if ((terrain[y][x] == LAVA) && + !pmon_resists_fire(monsters[mon].mon_id)) + { + return 0; + } + if (terrain[y][x] == WATER) + { + return 0; + } return 1; } diff --git a/objects.c b/objects.c index 4f3077a..d9cef31 100644 --- a/objects.c +++ b/objects.c @@ -63,7 +63,7 @@ int read_scroll(int obj) break; case PO_SCR_FIRE: print_msg("The scroll explodes in flames!\n"); - if (u.ring != -1) + if (u.resistances[DT_FIRE]) { if (objects[u.ring].obj_id == PO_RING_FIRE) { @@ -71,15 +71,24 @@ int read_scroll(int obj) break; } } - i = damage_u(dice(4, 10), DEATH_KILLED, "searing flames"); - if (!i) + else { - print_msg("That hurt!\n"); + i = damage_u(dice(4, 10), DEATH_KILLED, "searing flames"); + if (!i) + { + print_msg("That hurt!\n"); + } } for (i = 0; i < MONSTERS_IN_PLAY; ++i) { if (mon_visible(i)) { + if (!pmon_resists_fire(monsters[i].mon_id)) + { + print_mon_name(i, 3); + print_msg(" is burned.\n"); + damage_mon(i, dice(4, 10), 1); + } } } break; @@ -160,7 +169,19 @@ int eat_food(int obj) print_msg("Error: attempt to eat non-food (%d)!\n", optr->obj_id); return -1; } - if (u.food < 0) + if (optr->obj_id == PO_DEVIL_SPLEEN) + { + print_msg("Vile power suffuses your body as you devour the devil\nspleen.\n"); + if (zero_die(2)) + { + gain_body(1, 1); + } + else + { + gain_agility(1, 1); + } + } + else if (u.food < 0) { print_msg("You ravenously devour your food!\n"); } @@ -186,9 +207,11 @@ int quaff_potion(int obj) gain_agility(1, 1); break; case PO_POT_HEAL: - /* Heal player; if hit points brought to max, gain one - * hit point. */ - heal_u(dice(3, 12), 1, 1); + { + int healpercent = inclusive_flat(30, 50); + int healamount = (healpercent * ((u.hpmax > 60) ? u.hpmax : 60)) / 100; + heal_u(healamount, 1, 1); + } break; case PO_POT_RESTORATION: print_msg("This potion makes you feel warm all over.\n"); @@ -575,6 +598,43 @@ void damage_obj(int obj) else { objects[obj].durability--; + if (objects[obj].durability == 0) + { + switch (objects[obj].obj_id) + { + case PO_RIBBONS: + if (u.food < 500) + { + int shortfall = (u.food < 0) ? 500 : 500 - u.food; + int damage = (shortfall + 24) / 25; + u.food = (u.food < 0) ? u.food : 0; + print_msg("Blood trickles from your nose as the ribbons drain your\nstrength repair themselves.\n"); + damage_u(damage, DEATH_RIBBONS, ""); + } + else + { + print_msg("You gasp as the ribbons drain your strength to repair\nthemselves.\n"); + u.food -= 500; + } + break; + + case PO_TORMENTORS_LASH: + if (u.food < 500) + { + int shortfall = (u.food < 0) ? 500 : 500 - u.food; + int damage = (shortfall + 24) / 25; + u.food = (u.food < 0) ? u.food : 0; + print_msg("Pain explodes through your arm as the lash resotres\nitself!\n"); + damage_u(damage, DEATH_LASH, ""); + } + else + { + print_msg("A pins-and-needles sensation washes over you as the lash\nrestores itself.\n"); + u.food -= 500; + } + break; + } + } } } @@ -597,6 +657,7 @@ int evasion_penalty(int obj) case PO_LEATHER_ARMOUR: case PO_DRAGON_ARMOUR: + case PO_BATTLE_BALLGOWN: return 10; case PO_CHAINMAIL: @@ -612,6 +673,7 @@ int evasion_penalty(int obj) return 0; case PO_ROBE_SHADOWS: + case PO_RIBBONS: return -15; /* This is a bonus. */ default: @@ -622,4 +684,96 @@ int evasion_penalty(int obj) } } +int magic_ring(void) +{ + struct obj *optr = objects + u.ring; + switch (optr->obj_id) + { + case PO_RING_TELEPORT: + if (u.food >= 50) + { + u.food -= 50; + print_msg("You activate your ring's power of teleportation.\n"); + teleport_u(); + return 1; + } + return 0; + default: + print_msg("Your current ring has no activatable power.\n"); + return 0; + } +} + +int emanate_armour(void) +{ + struct obj *optr = objects + u.armour; + switch (optr->obj_id) + { + case PO_RIBBONS: + if (optr->durability < OBJ_MAX_DUR) + { + if (u.food < 5 * (OBJ_MAX_DUR - optr->durability)) + { + print_msg("You are too hungry to willingly let the ribbons draw on\nyour strength.\n"); + return 0; + } + else + { + print_msg("You gasp as the ribbons draw on your strength to\nrepair themselves.\n"); + u.food -= 5 * (OBJ_MAX_DUR - optr->durability); + optr->durability = OBJ_MAX_DUR; + return 1; + } + } + return 1; + default: + print_msg("Your current attire has no activatable powers.\n"); + break; + } + return 0; +} + +int zap_weapon(void) +{ + struct obj *optr = objects + u.weapon; + switch (optr->obj_id) + { + case PO_STAFF_OF_FIRE: + if (u.food > 150) + { + int y, x; + u.food -= 150; + print_msg("You unleash the fiery powers of your staff!\n"); + for (y = u.y - 1; y <= u.y + 1; ++y) + { + if ((y < 0) || (y >= DUN_HEIGHT)) + { + continue; + } + for (x = u.x - 1; x <= u.x + 1; ++x) + { + if ((x < 0) || (x >= DUN_WIDTH)) + { + continue; + } + if (mapmonster[y][x] != -1) + { + struct mon *mptr = monsters + mapmonster[y][x]; + if (!pmon_resists_fire(mptr->mon_id)) + { + print_mon_name(mapmonster[y][x], 3); + print_msg(" is engulfed in roaring flames.\n"); + damage_mon(mapmonster[y][x], dice(4, 10), 1); + } + } + } + } + damage_obj(u.weapon); + } + default: + print_msg("Your current weapon has no activatable powers.\n"); + return 0; + } +} + /* objects.c */ diff --git a/permobj.c b/permobj.c index 7d51c8c..cfddcbe 100644 --- a/permobj.c +++ b/permobj.c @@ -28,150 +28,163 @@ #include "cavechop.h" struct permobj permobjs[NUM_OF_PERMOBJS] = { - [PO_DAGGER] = - { - "dagger", "daggers", "A long knife, designed for stabbing.", POCLASS_WEAPON, 25, ')', 4, 1, 1 - }, - [PO_LONG_SWORD] = - { - "long sword", "long swords", "A steel sword of simple but sturdy construction; the\nblade is three feet long.", POCLASS_WEAPON, 30, ')', 10, 1, 4 - }, - [PO_MACE] = - { - "mace", "maces", "A flanged lump of iron on an iron haft.", POCLASS_WEAPON, 30, ')', 7, 1, 2 - }, - [PO_RUNESWORD] = - { - "runesword", "runeswords", "An eerily glowing sword engraved with many strange\nrunes.", POCLASS_WEAPON, 80, ')', 20, 1, 12 - }, - [PO_BOW] = - { - "bow", "bows", "A recurve composite bow.", POCLASS_WEAPON, 45, '(', 8, 1, 1 - }, - [PO_CROSSBOW] = - { - "crossbow", "crossbows", "A crossbow.", POCLASS_WEAPON, 70, '(', 16, 1, 6 - }, - [PO_POT_HEAL] = - { - "healing potion", "healing potions", "This magic elixir restores some lost hit points.", POCLASS_POTION, 10, '!', 0, 1, 1 - }, - [PO_POT_BODY] = - { - "body potion", "body potions", "This magic elixir will improve your physique.", POCLASS_POTION, 70, '!', 0, 1, 5 - }, - [PO_POT_AGILITY] = - { - "agility potion", "agility potions", "This magic elixir will sharpen your reflexes.", POCLASS_POTION, 70, '!', 0, 1, 5 - }, - [PO_POT_RESTORATION] = - { - "restoration potion", "restoration potions", "This magic elixir cures temporary damage to one's\nabilities.", POCLASS_POTION, 70, '!', 0, 1, 1 - }, - [PO_FLASK_POISON] = - { - "poison flask", "poison flask", "This fragile bottle is full of contact poison.", POCLASS_FLASK, 10, '~', 0, 1, 1 - }, - [PO_FLASK_FIRE] = - { - "fire flask", "fire flasks", "The volatile, phosphorus-laced liquid in this sealed\nflask will ignite spontaneously when exposed to the air.", POCLASS_FLASK, 40, '~', 0, 1, 20 - }, - [PO_FLASK_WEAKNESS] = - { - "weakness flask", "weakness flasks", "Dousing the living in this vile liquid causes immediate\nand severe physical degeneration.", POCLASS_FLASK, 40, '~', 0, 1, 20 - }, - [PO_SCR_TELEPORT] = - { - "teleport scroll", "teleport scrolls", "Reading this scroll will teleport you to a random\nlocation.", POCLASS_SCROLL, 40, '?', 0, 1, 1 - }, - [PO_SCR_FIRE] = - { - "fire scroll", "fire scrolls", "Reading this scroll will engulf all nearby creatures\n(including you) in flames.", POCLASS_SCROLL, 30, '?', 0, 1, 1 - }, - [PO_SCR_PROTECTION] = - { - "protection scroll", "protection scrolls", "Reading this scroll will dispel any curses afflicting\nyou and protect you from curses for a time.", POCLASS_SCROLL, 80, '?', 0, 1, 8 - }, - [PO_LEATHER_ARMOUR] = - { - "leather armour", "suits of leather armour", "A heavy leather jerkin and breeches, providing some\nprotection.", POCLASS_ARMOUR, 25, '[', 3, 1, 1 - }, - [PO_CHAINMAIL] = - { - "chainmail", "suits of chainmail", "A suit of interlocking metal rings, providing better\nprotection than leather.", POCLASS_ARMOUR, 30, '[', 6, 1, 3 - }, - [PO_PLATE_ARMOUR] = - { - "plate armour", "suits of plate armour", "A suit of steel plates, providing better protection than\nchainmail.", POCLASS_ARMOUR, 40, '[', 10, 1, 6 - }, - [PO_MAGE_ARMOUR] = - { - "mage armour", "suits of mage armour", "A suit of glowing steel plates bearing enchantments of\ndefence.", POCLASS_ARMOUR, 70, '[', 15, 1, 12 - }, - [PO_ROBE] = - { - "mundane robe", "mundane robes", "A simple woolen robe. It's better protection than your\nskin, but not by much.", POCLASS_ARMOUR, 50, '[', 2, 1, 1 - }, - [PO_ROBE_SWIFTNESS] = - { - "robe of swiftness", "robes of swiftness", "A simple woolen robe that bears a potent enchantment,\nprotecting the wearer and making him unnaturally swift.", POCLASS_ARMOUR, 70, '[', 8, 1, 8 - }, - [PO_ROBE_SHADOWS] = - { - "robe of shadows", "robes of shadows", "A simple woolen robe that bears an awesome enchantment,\nprotecting the wearer better than steel plate.", POCLASS_ARMOUR, 90, '[', 14, 1, 18 - }, - [PO_DRAGON_ARMOUR] = - { - "dragonhide armour", "suits of dragonhide armour", "The skin of a dragon, formed into a jerkin and breeches;\nit turns blows like steel plate and turns away\nflames.", POCLASS_ARMOUR, 90, '[', 12, 1, 21 - }, - [PO_METEOR_ARMOUR] = - { - "meteoric plate armour", "suits of meteoric plate armour", "This plate armour has been forged out of metal taken from\na fallen star.", POCLASS_ARMOUR, 90, '[', 18, 1, 27 - }, - [PO_SACRED_MAIL] = - { - "sacred chainmail", "suits of sacred chainmail", "This suit of interlocking rings has been consecrated to\nthe gods of the Light.", POCLASS_ARMOUR, 90, '[', 15, 1, 24 - }, - [PO_BATTLE_BALLGOWN] = - { - "battle ballgown", "battle ballgowns", "This armoured dress is a beloved heirloom of\nyour house.", POCLASS_ARMOUR, 100, '[', 3, 1, 1 - }, - [PO_RIBBONS] = - { - "set of ribbons", "sets of ribbons", "These ribbons, arranged as if to form an alleged\ngarment, make your fingers tingle with magic.", POCLASS_ARMOUR, 90, '[', 15, 1, 27 - }, - [PO_RING_REGEN] = - { - "regeneration ring", "regeneration rings", "This magical ring increases the wearer's healing rate,\nbut also increases the rate at which they must consume\nfood.", POCLASS_RING, 70, '=', 0, 1, 1 - }, - [PO_RING_FIRE] = - { - "fire ring", "fire rings", "This magical ring protects the wearer from mundane and\nmagical fire, and imbues their blows in combat with the\npower of fire.", POCLASS_RING, 50, '=', 0, 1, 1 - }, - [PO_RING_VAMPIRE] = - { - "vampire ring", "vampire rings", "This magical ring protects the wearer from necromantic\nenergies, and imbues their blows in combat with such\nenergies as well.", POCLASS_RING, 90, '=', 0, 1, 12 - }, - [PO_RING_FROST] = - { - "frost ring", "frost rings", "This magical ring protects the wearer from mundane and\nmagical cold, and imbues their blows in combat with the\npower of cold.", POCLASS_RING, 40, '=', 0, 1, 1 - }, - [PO_RING_TELEPORT] = - { - "teleport ring", "teleport rings", "This magical ring allows the wearer to teleport for a\nmodest cost in nutrition.", POCLASS_RING, 70, '=', 0, 1, 1 - }, - [PO_IRON_RATION] = - { - "iron ration", "iron rations", "A parcel of hardtack and beef jerky. Dull but nutritious.", POCLASS_FOOD, 75, '%', 0, 1, 1 - }, - [PO_DRIED_FRUIT] = - { - "parcel of dried fruit", "parcels of dried fruit", "A parcel of mixed dried fruit. It sure beats hardtack\nand beef jerky.", POCLASS_FOOD, 75, '%', 0, 1, 1 - }, - [PO_ELVEN_BREAD] = - { - "round of elven waybread", "rounds of elven waybread", "A tasty, filling, nutritious piece of elven waybread.", POCLASS_FOOD, 85, '%', 0, 1, 1 - } + [PO_DAGGER] = + { + "dagger", "daggers", "A long knife, designed for stabbing.", POCLASS_WEAPON, 25, ')', 4, 1, 1 + }, + [PO_LONG_SWORD] = + { + "long sword", "long swords", "A steel sword of simple but sturdy construction; the\nblade is three feet long.", POCLASS_WEAPON, 30, ')', 10, 1, 4 + }, + [PO_MACE] = + { + "mace", "maces", "A flanged lump of iron on an iron haft.", POCLASS_WEAPON, 30, ')', 7, 1, 2 + }, + [PO_RUNESWORD] = + { + "runesword", "runeswords", "An eerily glowing sword engraved with many strange\nrunes.", POCLASS_WEAPON, 80, ')', 20, 1, 12 + }, + [PO_BOW] = + { + "bow", "bows", "A recurve composite bow.", POCLASS_WEAPON, 45, '(', 8, 1, 1 + }, + [PO_CROSSBOW] = + { + "crossbow", "crossbows", "A crossbow.", POCLASS_WEAPON, 70, '(', 16, 1, 6 + }, + [PO_TORMENTORS_LASH] = + { + "tormentor's lash", "tormentor's lash", "A bone-handled whip that crackles with malefic energies.", POCLASS_WEAPON, 80, ')', 20, 1, 30 + }, + [PO_STAFF_OF_FIRE] = + { + "staff of fire", "staff of fire", "A jet-black staff with a glowing ruby in its headpiece.", POCLASS_WEAPON, 80, ')', 10, 1, 20 + }, + [PO_POT_HEAL] = + { + "healing potion", "healing potions", "This magic elixir restores some lost hit points.", POCLASS_POTION, 10, '!', 0, 1, 1 + }, + [PO_POT_BODY] = + { + "body potion", "body potions", "This magic elixir will improve your physique.", POCLASS_POTION, 70, '!', 0, 1, 5 + }, + [PO_POT_AGILITY] = + { + "agility potion", "agility potions", "This magic elixir will sharpen your reflexes.", POCLASS_POTION, 70, '!', 0, 1, 5 + }, + [PO_POT_RESTORATION] = + { + "restoration potion", "restoration potions", "This magic elixir cures temporary damage to one's\nabilities.", POCLASS_POTION, 70, '!', 0, 1, 1 + }, + [PO_FLASK_POISON] = + { + "poison flask", "poison flask", "This fragile bottle is full of contact poison.", POCLASS_FLASK, 10, '~', 0, 1, 1 + }, + [PO_FLASK_FIRE] = + { + "fire flask", "fire flasks", "The volatile, phosphorus-laced liquid in this sealed\nflask will ignite spontaneously when exposed to the air.", POCLASS_FLASK, 40, '~', 0, 1, 20 + }, + [PO_FLASK_WEAKNESS] = + { + "weakness flask", "weakness flasks", "Dousing the living in this vile liquid causes immediate\nand severe physical degeneration.", POCLASS_FLASK, 40, '~', 0, 1, 20 + }, + [PO_SCR_TELEPORT] = + { + "teleport scroll", "teleport scrolls", "Reading this scroll will teleport you to a random\nlocation.", POCLASS_SCROLL, 40, '?', 0, 1, 1 + }, + [PO_SCR_FIRE] = + { + "fire scroll", "fire scrolls", "Reading this scroll will engulf all nearby creatures\n(including you) in flames.", POCLASS_SCROLL, 30, '?', 0, 1, 1 + }, + [PO_SCR_PROTECTION] = + { + "protection scroll", "protection scrolls", "Reading this scroll will dispel any curses afflicting\nyou and protect you from curses for a time.", POCLASS_SCROLL, 80, '?', 0, 1, 8 + }, + [PO_LEATHER_ARMOUR] = + { + "leather armour", "suits of leather armour", "A heavy leather jerkin and breeches, providing some\nprotection.", POCLASS_ARMOUR, 25, '[', 3, 1, 1 + }, + [PO_CHAINMAIL] = + { + "chainmail", "suits of chainmail", "A suit of interlocking metal rings, providing better\nprotection than leather.", POCLASS_ARMOUR, 30, '[', 6, 1, 3 + }, + [PO_PLATE_ARMOUR] = + { + "plate armour", "suits of plate armour", "A suit of steel plates, providing better protection than\nchainmail.", POCLASS_ARMOUR, 40, '[', 10, 1, 6 + }, + [PO_MAGE_ARMOUR] = + { + "mage armour", "suits of mage armour", "A suit of glowing steel plates bearing enchantments of\ndefence.", POCLASS_ARMOUR, 70, '[', 15, 1, 12 + }, + [PO_ROBE] = + { + "mundane robe", "mundane robes", "A simple woolen robe. It's better protection than your\nskin, but not by much.", POCLASS_ARMOUR, 50, '[', 2, 1, 1 + }, + [PO_ROBE_SWIFTNESS] = + { + "robe of swiftness", "robes of swiftness", "A simple woolen robe that bears a potent enchantment,\nprotecting the wearer and making him unnaturally swift.", POCLASS_ARMOUR, 70, '[', 8, 1, 8 + }, + [PO_ROBE_SHADOWS] = + { + "robe of shadows", "robes of shadows", "A simple woolen robe that bears an awesome enchantment,\nprotecting the wearer better than steel plate.", POCLASS_ARMOUR, 90, '[', 14, 1, 18 + }, + [PO_DRAGON_ARMOUR] = + { + "dragonhide armour", "suits of dragonhide armour", "The skin of a dragon, formed into a jerkin and breeches;\nit turns blows like steel plate and turns away\nflames.", POCLASS_ARMOUR, 90, '[', 12, 1, 21 + }, + [PO_METEOR_ARMOUR] = + { + "meteoric plate armour", "suits of meteoric plate armour", "This plate armour has been forged out of metal taken from\na fallen star.", POCLASS_ARMOUR, 90, '[', 18, 1, 27 + }, + [PO_SACRED_MAIL] = + { + "sacred chainmail", "suits of sacred chainmail", "This suit of interlocking rings has been consecrated to\nthe gods of the Light.", POCLASS_ARMOUR, 90, '[', 15, 1, 24 + }, + [PO_BATTLE_BALLGOWN] = + { + "battle ballgown", "battle ballgowns", "This lightly armoured dress is a beloved heirloom of\nyour house.", POCLASS_ARMOUR, 100, '[', 3, 1, 1 + }, + [PO_RIBBONS] = + { + /* inspired by DoomRL's Necroarmor and my own creepiness. */ + "set of ribbons", "sets of ribbons", "These ribbons, arranged as if to form an alleged\ngarment, make your fingers tingle with magic.", POCLASS_ARMOUR, 90, '[', 15, 1, 27 + }, + [PO_RING_REGEN] = + { + "regeneration ring", "regeneration rings", "This magical ring increases the wearer's healing rate,\nbut also increases the rate at which they must consume\nfood.", POCLASS_RING, 70, '=', 0, 1, 1 + }, + [PO_RING_FIRE] = + { + "fire ring", "fire rings", "This magical ring protects the wearer from mundane and\nmagical fire, and imbues their blows in combat with the\npower of fire.", POCLASS_RING, 50, '=', 0, 1, 1 + }, + [PO_RING_VAMPIRE] = + { + "vampire ring", "vampire rings", "This magical ring protects the wearer from necromantic\nenergies, and imbues their blows in combat with such\nenergies as well.", POCLASS_RING, 90, '=', 0, 1, 12 + }, + [PO_RING_FROST] = + { + "frost ring", "frost rings", "This magical ring protects the wearer from mundane and\nmagical cold, and imbues their blows in combat with the\npower of cold. Rumour suggests it might also allow walking\non water.\n", POCLASS_RING, 40, '=', 0, 1, 1 + }, + [PO_RING_TELEPORT] = + { + "teleport ring", "teleport rings", "This magical ring allows the wearer to teleport for a\nmodest cost in nutrition.", POCLASS_RING, 70, '=', 0, 1, 1 + }, + [PO_IRON_RATION] = + { + "iron ration", "iron rations", "A parcel of hardtack and beef jerky. Dull but nutritious.", POCLASS_FOOD, 75, '%', 0, 1, 1 + }, + [PO_DRIED_FRUIT] = + { + "parcel of dried fruit", "parcels of dried fruit", "A parcel of mixed dried fruit. It sure beats hardtack\nand beef jerky.", POCLASS_FOOD, 75, '%', 0, 1, 1 + }, + [PO_ELVEN_BREAD] = + { + "round of elven waybread", "rounds of elven waybread", "A tasty, filling, nutritious piece of elven waybread.", POCLASS_FOOD, 85, '%', 0, 1, 1 + }, + [PO_DEVIL_SPLEEN] = + { + "devil spleen", "devil spleens", "A weirdly pulsing organ ripped from the torso of a devil.", POCLASS_FOOD, 100, '%', 0, 1, 1 + } }; /* permobj.c */ diff --git a/permons.c b/permons.c index 967ad90..b9f5bb7 100644 --- a/permons.c +++ b/permons.c @@ -27,16 +27,6 @@ #define PERMONS_C #include "cavechop.h" -/* This array is no longer necessarily defined in sequential order. Instead, - * it has been defined in order of increasing power within "monster groups", - * as follows: - * Wild Animals - * Evil Men - * Evil Humanoids - * Undead - * Demonkind - * Supernatural Beasts - */ struct permon permons[NUM_OF_PERMONS] = { [PM_NEWT] = { @@ -62,7 +52,7 @@ struct permon permons[NUM_OF_PERMONS] = { }, [PM_GOON] = { - "goon", "goons", 't', DBCLR_YELLOW, 20, 3, 20, 6, -1, 10, -1, DT_PHYS, "", 8, 10, 1, 0 + "goon", "goons", 't', DBCLR_YELLOW, 20, 3, 15, 6, -1, 7, -1, DT_PHYS, "", 8, 10, 1, 0 }, [PM_HUNTER] = { diff --git a/u.c b/u.c index c6f3d42..fb79395 100644 --- a/u.c +++ b/u.c @@ -66,6 +66,7 @@ void recalc_defence(void) switch (objects[u.ring].obj_id) { case PO_RING_FIRE: + print_msg("gaining fire resistance from ring\n"); u.resistances[DT_FIRE] |= RESIST_RING; break; case PO_RING_FROST: @@ -85,35 +86,39 @@ int move_player(int dy, int dx) if ((u.y + dy < 0) || (u.y + dy >= DUN_HEIGHT) || (u.x + dx < 0) || (u.x + dx >= DUN_WIDTH)) { - print_msg("Attempted move out of bounds.\n"); - return 0; /* No movement. */ + print_msg("Attempted move out of bounds.\n"); + return 0; /* No movement. */ } if (mapmonster[u.y + dy][u.x + dx] != -1) { - if (u.weapon != -1) - { - if ((objects[u.weapon].obj_id == PO_BOW) || - (objects[u.weapon].obj_id == PO_CROSSBOW)) - { - print_msg("You can't use that weapon in melee!\n"); - return 0; - } - } - return player_attack(dy, dx); + if (u.weapon != -1) + { + if ((objects[u.weapon].obj_id == PO_BOW) || + (objects[u.weapon].obj_id == PO_CROSSBOW)) + { + print_msg("You can't use that weapon in melee!\n"); + return 0; + } + } + return player_attack(dy, dx); } switch (terrain[u.y + dy][u.x + dx]) { case WALL: - print_msg("You cannot go there.\n"); - return 0; + print_msg("You cannot go there.\n"); + return 0; case FLOOR: case DOOR: case STAIRS: - reloc_player(u.y + dy, u.x + dx); - return 1; + reloc_player(u.y + dy, u.x + dx); + return 1; case LAVA: if (u.resistances[DT_FIRE]) { + if (terrain[u.y][u.x] != LAVA) + { + print_msg("You walk on the lava.\n"); + } reloc_player(u.y + dy, u.x + dx); return 1; } @@ -123,20 +128,19 @@ int move_player(int dy, int dx) return 0; } case WATER: - if (u.ring != -1) + if ((u.ring != -1) && (objects[u.ring].obj_id == PO_RING_FROST)) { - if (objects[u.weapon].obj_id == PO_RING_FROST) + if (terrain[u.y][u.x] != WATER) { - if (terrain[u.y][u.x] != WATER) - { - print_msg("You walk on the water.\n"); - } - return 1; - } - else - { - print_msg("The idiot who raised you never taught you to swim.\n"); + print_msg("You walk on the water.\n"); } + reloc_player(u.y + dy, u.x + dx); + return 1; + } + else + { + print_msg("The idiot who raised you never taught you to swim.\n"); + return 0; } } return 0; @@ -297,7 +301,7 @@ void heal_u(int amount, int boost, int loud) status_updated = 1; if (loud) { - /* Tell the player how much better he feels. */ + /* Tell the player how much better they feel. */ if (u.hpcur == u.hpmax) { print_msg("You feel great.\n"); @@ -337,7 +341,6 @@ int do_death(enum death d, const char *what) { fp = fopen("cavechop.log", "a"); } - fprintf(fp, "%s, ", u.name); print_msg("THOU ART SLAIN!\n"); game_finished = 1; switch (d) @@ -346,34 +349,48 @@ int do_death(enum death d, const char *what) print_msg("You were killed by %s.\n", what); if (!wizard_mode) { - fprintf(fp, "you were killed by %s.\n", what); + fprintf(fp, "%s was killed by %s.\n", u.name, what); } break; case DEATH_KILLED_MON: print_msg("You were killed by a nasty %s.\n", what); if (!wizard_mode) { - fprintf(fp, "you were killed by a nasty %s.\n", what); + fprintf(fp, "%s was killed by a nasty %s.\n", u.name, what); } break; case DEATH_BODY: print_msg("Your heart was stopped by %s.\n", what); if (!wizard_mode) { - fprintf(fp, "your heart was stopped by %s.\n", what); + fprintf(fp, "%s's heart was stopped by %s.\n", u.name, what); } break; case DEATH_AGILITY: print_msg("Your nerves were destroyed by %s.\n", what); if (!wizard_mode) { - fprintf(fp, "your nerves were destroyed by %s.\n", what); + fprintf(fp, "%s's nerves were destroyed by %s.\n", u.name, what); } break; + case DEATH_LASH: + print_msg("You tasted the lash one time too many.\n"); + if (!wizard_mode) + { + fprintf(fp, "%s tasted the lash one time too many.\n", u.name); + } + break; + case DEATH_RIBBONS: + print_msg("You looked good in ribbons.\n"); + if (!wizard_mode) + { + fprintf(fp, "%s looked good in ribbons.\n", u.name); + } + break; } if (!wizard_mode) { - fprintf(fp, "You died after %d ticks, with %d XP, on dungeon level %d.\n\n", game_tick, u.experience, depth); + fprintf(fp, " %s died after %d ticks, with %d XP, on dungeon level %d.\n\n", u.name, game_tick, u.experience, depth); fflush(fp); fclose(fp); } -- 2.11.0