From d44003fe93d63fb4304621b52814e585159f2551 Mon Sep 17 00:00:00 2001 From: fluffymormegil Date: Fri, 16 Mar 2012 22:23:32 +0000 Subject: [PATCH] Checkpointing various innovations that I got bored of giving separate commits to --- combat.c | 83 +++++-- combat.h | 7 +- display.c | 56 +++-- main.c | 126 +++++----- map.c | 437 ++++++-------------------------- misc.c | 2 +- mon2.c | 113 +++------ monsters.c | 100 +++----- objects.c | 827 +++++++++++++++++++++++-------------------------------------- permobj.c | 110 ++++---- permons.c | 240 +++++++++--------- pmon2.c | 31 ++- rng.c | 69 +++--- u.c | 178 ++++++------- 14 files changed, 921 insertions(+), 1458 deletions(-) diff --git a/combat.c b/combat.c index 6ff9e4c..53085fd 100644 --- a/combat.c +++ b/combat.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dunbash.h" +#include "cavechop.h" #include "combat.h" #include "monsters.h" @@ -52,7 +52,6 @@ int uhitm(int mon) struct obj *wep; struct permobj *pwep; struct obj *ring; - struct permobj *pring; int tohit; int damage; int healing; @@ -79,16 +78,11 @@ int uhitm(int mon) if (u.ring != -1) { ring = objects + u.ring; - pring = permobjs + ring->obj_id; switch (ring->obj_id) { case PO_RING_FIRE: if (!pmon_resists_fire(mp->mon_id)) { - if (!pring->known) - { - pring->known = 1; - } print_msg("Your ring burns "); print_mon_name(mon, 1); print_msg("!\n"); @@ -98,10 +92,6 @@ int uhitm(int mon) case PO_RING_VAMPIRE: if (!pmon_is_undead(mp->mon_id)) { - if (!pring->known) - { - pring->known = 1; - } print_msg("Your ring drains "); print_mon_name(mon, 1); print_msg("!\n"); @@ -113,10 +103,6 @@ int uhitm(int mon) case PO_RING_FROST: if (!pmon_resists_cold(mp->mon_id)) { - if (!pring->known) - { - pring->known = 1; - } print_msg("Your ring freezes "); print_mon_name(mon, 1); print_msg("!\n"); @@ -245,7 +231,6 @@ test_unaffected: if (unaffected & RESIST_RING) { print_msg("Your ring flashes red.\n"); - permobjs[PO_RING_FIRE].known = 1; } break; case DT_COLD: @@ -253,14 +238,12 @@ test_unaffected: if (unaffected & RESIST_RING) { print_msg("Your ring flashes blue.\n"); - permobjs[PO_RING_FROST].known = 1; } break; case DT_NECRO: print_msg("Its touch makes you feel no deader.\n"); if (objects[u.ring].obj_id == PO_RING_VAMPIRE) { - permobjs[PO_RING_VAMPIRE].known = 1; print_msg("Your ring shrieks.\n"); } break; @@ -369,8 +352,6 @@ int mshootu(int mon) unaffected = player_resists_dtype(dtype); if (unaffected) { - /* For now, resistant armours are always known, so - * we only need to check for identification of rings. */ if (unaffected & RESIST_RING) { switch (dtype) @@ -378,21 +359,18 @@ int mshootu(int mon) case DT_COLD: if (objects[u.ring].obj_id == PO_RING_FROST) { - permobjs[PO_RING_FROST].known = 1; print_msg("Your ring flashes blue.\n"); } break; case DT_FIRE: if (objects[u.ring].obj_id == PO_RING_FIRE) { - permobjs[PO_RING_FIRE].known = 1; print_msg("Your ring flashes red.\n"); } break; case DT_NECRO: if (objects[u.ring].obj_id == PO_RING_VAMPIRE) { - permobjs[PO_RING_VAMPIRE].known = 1; print_msg("Your ring shrieks.\n"); } break; @@ -465,4 +443,63 @@ int mshootu(int mon) return 0; } +int throw_flask(int obj, int sy, int sx) +{ + int i; + int y, x; + for (i = 0, y = u.y, x = u.x; i < 10; ++i) + { + y += sy; + x += sx; + if ((mapmonster[y][x] != -1) && + (monsters[mapmonster[y][x]].used)) + { + struct mon *mptr = monsters + mapmonster[y][x]; + switch (objects[obj].obj_id) + { + case PO_FLASK_WEAKNESS: + if (!pmon_is_undead(mptr->mon_id)) + { + print_msg("Your foe shrivels and twists horribly.\n"); + mptr->hpmax = (mptr->hpmax + 1) / 2; + mptr->hpcur = (mptr->hpcur + 1) / 2; + } + else + { + print_msg("What does not live cannot degenerate.\n"); + } + break; + case PO_FLASK_POISON: + print_msg("Your foe is drenched in contact poison.\n"); + if (!pmon_resists_poison(mptr->mon_id)) + { + damage_mon(mptr - monsters, inclusive_flat((mptr->hpmax + 5) / 6, (mptr->hpmax + 2) / 3), 1); + } + else + { + print_msg("... to little effect.\n"); + } + break; + case PO_FLASK_FIRE: + print_msg("Your foe is drenched in burning oil.\n"); + if (!pmon_resists_fire(mptr->mon_id)) + { + damage_mon(mptr - monsters, 15 + dice(5, 4), 1); + } + else + { + print_msg("... to little effect.\n"); + } + break; + default: + print_msg("internal error: attempt to throw non-flask.\n"); + return 0; + } + consume_obj(obj); + return 1; + } + } + return 1; +} + /* combat.c */ diff --git a/combat.h b/combat.h index 45e41f9..6c21e8d 100644 --- a/combat.h +++ b/combat.h @@ -1,6 +1,6 @@ /* combat.h * - * Copyright 2005 Martin Read + * Copyright 2005-2012 Martin Read * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +27,15 @@ #ifndef COMBAT_H #define COMBAT_H -#ifndef DUNBASH_H -#include "dunbash.h" +#ifndef CAVECHOP_H +#include "cavechop.h" #endif #include "monsters.h" #define agility_modifier() (u.withering ? (u.agility / 10) : (u.agility / 5)) /* XXX combat.c data and funcs */ +extern int throw_flask(int obj, int sy, int sx); extern int player_attack(int dy, int dx); extern int mhitu(int mon, enum damtyp dtyp); extern int uhitm(int mon); diff --git a/display.c b/display.c index d5c81bf..33e4f89 100644 --- a/display.c +++ b/display.c @@ -25,7 +25,7 @@ */ #define DISPLAY_C -#include "dunbash.h" +#include "cavechop.h" #include "monsters.h" #include #include @@ -86,7 +86,6 @@ static void draw_status_line(void) mvwprintw(status_window, 0, 17, "HP: %03d/%03d", u.hpcur, u.hpmax); mvwprintw(status_window, 0, 30, "XL: %d", u.level); mvwprintw(status_window, 0, 47, "Body: %02d/%02d", u.body - u.bdam, u.body); - mvwprintw(status_window, 0, 62, "Gold: %d", u.gold); mvwprintw(status_window, 1, 0, "Defence: %02d", u.defence); mvwprintw(status_window, 1, 15, "Food: %06d", u.food); mvwprintw(status_window, 1, 30, "Depth: %d", depth); @@ -302,25 +301,6 @@ void print_msg(const char *fmt, ...) display_update(); } -void show_discoveries(void) -{ - int i, j; - print_msg("You recognise the following items:\n"); - for (i = 0, j = 1; i < PO_REAL_COUNT; i++) - { - if (permobjs[i].known) - { - print_msg("%s\n", permobjs[i].name); - j++; - } - if (j == 19) - { - press_enter(); - j = 0; - } - } -} - void print_inv(enum poclass_num filter) { int i; @@ -524,8 +504,6 @@ enum game_cmd get_command(void) return EXAMINE_MONSTER; case '#': return SHOW_TERRAIN; - case '\\': - return SHOW_DISCOVERIES; case '\x12': return RNG_TEST; case '4': @@ -556,22 +534,30 @@ enum game_cmd get_command(void) return QUAFF_POTION; case 'r': return READ_SCROLL; + case 'e': + return EAT_FOOD; + case 't': + return THROW_FLASK; case 'w': return WIELD_WEAPON; + case 'z': + return ZAP_WEAPON; case 'W': return WEAR_ARMOUR; case 'T': return TAKE_OFF_ARMOUR; + case 'E': + return EMANATE_ARMOUR; case 'P': return PUT_ON_RING; case 'R': return REMOVE_RING; + case 'm': + return MAGIC_RING; case '?': return GIVE_HELP; case '>': return GO_DOWN_STAIRS; - case 'e': - return EAT_FOOD; case '5': case '.': return STAND_STILL; @@ -698,4 +684,24 @@ void print_help(void) print_msg("\nThis is all the help you get. Good luck!\n"); } +void touch_one_screen(int y, int x) +{ + int y2, x2; + for (y2 = y - 10; y2 <= y + 10; y2++) + { + if ((y2 < 0) || (y2 >= DUN_HEIGHT)) + { + continue; + } + for (x2 = x - 10; x2 <= x + 10; x2++) + { + if ((x2 < 0) || (x2 >= DUN_WIDTH)) + { + continue; + } + newsym(y2, x2); + } + } +} + /* display.c */ diff --git a/main.c b/main.c index 47c4d8f..610901b 100644 --- a/main.c +++ b/main.c @@ -24,9 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dunbash.h" +#include "cavechop.h" #include "combat.h" #include +#include +#include #include #include #include @@ -81,7 +83,7 @@ unsigned int convert_range(int dy, int dx) void save_game(void) { FILE *fp; - fp = fopen("dunbash.sav", "wb"); + fp = fopen("cavechop.sav", "wb"); /* Write out the snapshot we took of the RNG before generating the * current level. */ fwrite(saved_state, sizeof saved_state, 1, fp); @@ -92,8 +94,6 @@ void save_game(void) /* Write out the permanent object data. This is hideously * wasteful (and guarantees savefile breakage at version-up), but * it makes handling flavours much easier... */ - /* FIX: We no longer write out the permons data, since none of it - * changes at the moment. */ fwrite(permobjs, 100, sizeof (struct permobj), fp); /* Write out the dynamic monster/object arrays. */ fwrite(monsters, 100, sizeof (struct mon), fp); @@ -108,7 +108,7 @@ void save_game(void) fflush(fp); fclose(fp); /* Compress! */ - system("gzip dunbash.sav"); + system("gzip cavechop.sav"); game_finished = 1; return; } @@ -116,10 +116,9 @@ void save_game(void) void load_game(void) { FILE *fp; - system("gunzip dunbash.sav"); - fp = fopen("dunbash.sav", "rb"); + system("gunzip cavechop.sav"); + fp = fopen("cavechop.sav", "rb"); fread(rng_state, sizeof rng_state, 1, fp); - room_reset(); build_level(); fread(mapflags, DUN_HEIGHT, DUN_WIDTH * sizeof (int), fp); fread(permobjs, 100, sizeof (struct permobj), fp); @@ -131,7 +130,7 @@ void load_game(void) fread(&u, 1, sizeof u, fp); fread(&game_tick, 1, sizeof game_tick, fp); fclose(fp); - unlink("dunbash.sav"); + unlink("cavechop.sav"); touch_back_buffer(); status_updated = 1; map_updated = 1; @@ -265,7 +264,6 @@ int do_command(enum game_cmd cmd) if (i >= 0) { u.armour = u.inventory[i]; - permobjs[objects[u.armour].obj_id].known = 1; recalc_defence(); print_msg("Wearing "); print_obj_name(u.armour); @@ -273,6 +271,19 @@ int do_command(enum game_cmd cmd) return 1; } return 0; + + case EMANATE_ARMOUR: + print_msg("internal error: armour emanation not supported\n"); + return 0; + + case ZAP_WEAPON: + print_msg("internal error: weapon zapping not supported\n"); + return 0; + + case MAGIC_RING: + print_msg("internal error: ring magicking not supported\n"); + return 0; + case TAKE_OFF_ARMOUR: if (u.armour != -1) { @@ -291,19 +302,6 @@ int do_command(enum game_cmd cmd) print_help(); return 0; - case READ_SCROLL: - i = inv_select(POCLASS_SCROLL, "read", 0); - if (i >= 0) - { - j = read_scroll(u.inventory[i]); - if (j) - { - u.inventory[i] = -1; - } - return 1; - } - return 0; - case GO_DOWN_STAIRS: if (terrain[u.y][u.x] == STAIRS) { @@ -319,6 +317,19 @@ int do_command(enum game_cmd cmd) case STAND_STILL: return 1; + case READ_SCROLL: + i = inv_select(POCLASS_SCROLL, "read", 0); + if (i >= 0) + { + j = read_scroll(u.inventory[i]); + if (j) + { + u.inventory[i] = -1; + } + return 1; + } + return 0; + case EAT_FOOD: i = inv_select(POCLASS_FOOD, "eat", 0); if (i >= 0) @@ -345,38 +356,31 @@ int do_command(enum game_cmd cmd) } return 0; + case THROW_FLASK: + i = inv_select(POCLASS_FLASK, "throw", 0); + if (i >= 0) + { + j = select_dir(&sy, &sx); + if (j != -1) + { + return throw_flask(i, sy, sx); + } + } + return 0; + case REMOVE_RING: if (u.ring == -1) { print_msg("You have no ring to remove!\n"); return 0; } - if (objects[u.ring].obj_id == PO_RING_DOOM) + else if (objects[u.ring].obj_id == PO_RING_FROST) { - int dmg; - print_msg("You remove your ring.\n"); - print_msg("It exacts vengeance!\n"); - drain_body(one_die(4), "a ring of doom", 1); - drain_agility(one_die(4), "a ring of doom", 1); - dmg = one_die(20); - damage_u(dmg, DEATH_KILLED, "a ring of doom"); - u.hpmax -= dmg; - status_updated = 1; - u.ring = -1; - display_update(); - } - else if (objects[u.ring].obj_id == PO_RING_TELEPORT) - { - i = zero_die(u.level); - if (i < 4) - { - print_msg("You lack the willpower to remove it.\n"); - } - else - { - print_msg("You manage to pull the ring off.\n"); - u.ring = -1; - } + 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 { @@ -410,9 +414,6 @@ int do_command(enum game_cmd cmd) case EXAMINE_MONSTER: print_msg("Monster examination not implemented yet.\n"); return 0; - case SHOW_DISCOVERIES: - show_discoveries(); - return 0; case SHOW_TERRAIN: show_terrain = 1; map_updated = 1; @@ -558,27 +559,10 @@ void main_loop(void) { break; } - /* If you're wearing a ring of doom, zap you. */ - if (objects[u.ring].obj_id == PO_RING_DOOM) - { - print_msg("Your ring pulses uncleanly.\n"); - damage_u(1, DEATH_KILLED, "a ring of doom"); - display_update(); - permobjs[PO_RING_DOOM].known = 1; - } - else if (objects[u.ring].obj_id == PO_RING_TELEPORT) - { - if (!zero_die(75)) - { - print_msg("Your ring flares white!\n"); - permobjs[PO_RING_TELEPORT].known = 1; - teleport_u(); - } - } } for (i = 0; i < 100; i++) { - if (monsters[i].used == 0) + if (!monsters[i].used) { /* Unused monster */ continue; @@ -608,8 +592,10 @@ int main(void) struct stat s; int i; display_init(); + memset(mapobject, -1, sizeof mapobject); + memset(mapmonster, -1, sizeof mapmonster); /* Do we have a saved game? */ - i = stat("dunbash.sav.gz", &s); + i = stat("cavechop.sav.gz", &s); if (!i) { /* Yes! */ diff --git a/map.c b/map.c index aa75fbe..4876233 100644 --- a/map.c +++ b/map.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dunbash.h" +#include "cavechop.h" #include "monsters.h" #include @@ -32,181 +32,10 @@ int mapobject[DUN_HEIGHT][DUN_WIDTH]; int mapmonster[DUN_HEIGHT][DUN_WIDTH]; enum terrain_num terrain[DUN_HEIGHT][DUN_WIDTH]; int mapflags[DUN_HEIGHT][DUN_WIDTH]; -int roomnums[DUN_HEIGHT][DUN_WIDTH]; int depth = 1; -int roomlinkage[MAX_ROOMS][MAX_ROOMS]; -int roombounds[MAX_ROOMS][4]; -int stairs_room = -1; -int zoo_room = -1; -static int segsused[MAX_ROOMS]; static int get_levgen_mon_floor(int *y, int *x); -static void add_random_room(int yseg, int xseg); -static void link_rooms(int r1, int r2); static void put_stairs(void); -static void generate_zoo(void); - -void room_reset(void) -{ - int i; - memset((void *) &(roombounds[0][0]), 0, sizeof roombounds); - memset((void *) &(roomlinkage[0][0]), 0, sizeof roomlinkage); - memset((void *) segsused, 0, sizeof segsused); - zoo_room = -1; - stairs_room = -1; - for (i = 0; i < MAX_ROOMS; i++) - { - roomlinkage[i][i] = 3; - } - memset(mapobject, -1, sizeof mapobject); - memset(mapmonster, -1, sizeof mapmonster); - memset(terrain, 0, sizeof terrain); - memset(mapflags, 0, sizeof mapflags); - memset(roomnums, -1, sizeof roomnums); -} - -static void add_random_room(int yseg, int xseg) -{ - int roomidx = (yseg * 3) + xseg; - int ycen, xcen; - int y1, y2, x1, x2; - int y, x; - ycen = (DUN_HEIGHT - 2) / 6 + yseg * ((DUN_HEIGHT - 2) / 3); - xcen = (DUN_WIDTH - 2) / 6 + xseg * ((DUN_WIDTH - 2) / 3); - y1 = ycen - one_die(ROOM_HT_DELTA) - 1; - x1 = xcen - one_die(ROOM_WD_DELTA) - 1; - y2 = ycen + one_die(ROOM_HT_DELTA) + 1; - x2 = xcen + one_die(ROOM_WD_DELTA) + 1; - for (y = y1 + 1; y < y2; y++) - { - for (x = x1 + 1; x < x2; x++) - { - terrain[y][x] = FLOOR; - roomnums[y][x] = roomidx; - } - } - for (y = y1; y <= y2; y++) - { - roomnums[y][x1] = roomidx; - roomnums[y][x2] = roomidx; - } - for (x = x1; x <= x2; x++) - { - roomnums[y1][x] = roomidx; - roomnums[y2][x] = roomidx; - } - roombounds[roomidx][0] = y1; - roombounds[roomidx][1] = y2; - roombounds[roomidx][2] = x1; - roombounds[roomidx][3] = x2; - segsused[yseg * 3 + xseg] = 1; -} - -static void link_rooms(int r1, int r2) -{ - int i; - int y, x; - int y1, y2, y3, y4; - int x1, x2, x3, x4; - /* First rule: CORRIDORS ARE STRAIGHT! This makes the AI easier. */ - /* Second rule: Don't pass in bogus numbers to this function; it - * has no error-checking of its own. */ - /* Update the linkage matrix. */ - roomlinkage[r1][r2] = 1; - roomlinkage[r2][r1] = 1; - for (i = 0; i < MAX_ROOMS; i++) - { - if ((i == r1) || (i == r2)) - { - continue; - } - if ((roomlinkage[r1][i] > 0) && !roomlinkage[r2][i]) - { - roomlinkage[r2][i] = 2; - roomlinkage[i][r2] = 2; - } - if ((roomlinkage[r2][i] > 0) && !roomlinkage[r1][i]) - { - roomlinkage[r1][i] = 2; - roomlinkage[i][r1] = 2; - } - } - y1 = roombounds[r1][0]; - y2 = roombounds[r2][0]; - y3 = roombounds[r1][1]; - y4 = roombounds[r2][1]; - x1 = roombounds[r1][2]; - x2 = roombounds[r2][2]; - x3 = roombounds[r1][3]; - x4 = roombounds[r2][3]; - /* Now generate the corridor. */ - if ((r1 % 3) == (r2 % 3)) - { - /* same xseg; north-south linkage */ - if (x4 < x3) - { - x3 = x4; - } - if (x2 > x1) - { - x1 = x2; - } - x = exclusive_flat(x1, x3); - if (y3 < y2) - { - /* go south from r1 */ - terrain[y3][x] = DOOR; - terrain[y2][x] = DOOR; - for (y = y3 + 1; y < y2; y++) - { - terrain[y][x] = FLOOR; - } - } - else if (y4 < y1) - { - /* go south from r2 */ - terrain[y4][x] = DOOR; - terrain[y1][x] = DOOR; - for (y = y4 + 1; y < y1; y++) - { - terrain[y][x] = FLOOR; - } - } - } - else - { - /* same yseg; east-west linkage */ - if (y4 < y3) - { - y3 = y4; - } - if (y2 > y1) - { - y1 = y2; - } - y = exclusive_flat(y1, y3); - if (x3 < x2) - { - /* go south from r1 */ - terrain[y][x3] = DOOR; - terrain[y][x2] = DOOR; - for (x = x3 + 1; x < x2; x++) - { - terrain[y][x] = FLOOR; - } - } - else if (x4 < x1) - { - /* go south from r2 */ - terrain[y][x4] = DOOR; - terrain[y][x1] = DOOR; - for (x = x4 + 1; x < x1; x++) - { - terrain[y][x] = FLOOR; - } - } - } -} void leave_level(void) { @@ -215,7 +44,6 @@ void leave_level(void) memset(mapmonster, -1, sizeof mapmonster); memset(terrain, 0, sizeof terrain); memset(mapflags, 0, sizeof mapflags); - memset(roomnums, -1, sizeof roomnums); for (i = 0; i < 100; i++) { /* Throw away each monster */ @@ -233,7 +61,6 @@ void leave_level(void) void make_new_level(void) { - room_reset(); build_level(); populate_level(); inject_player(); @@ -245,184 +72,75 @@ void put_stairs(void) { int y; int x; - stairs_room = zero_die(MAX_ROOMS); - y = exclusive_flat(roombounds[stairs_room][0], roombounds[stairs_room][1]); - x = exclusive_flat(roombounds[stairs_room][2], roombounds[stairs_room][3]); + do + { + y = exclusive_flat(0, DUN_HEIGHT - 1); + x = exclusive_flat(0, DUN_WIDTH - 1); + } while (terrain[y][x] != FLOOR); terrain[y][x] = STAIRS; } -int edge_rooms[4] = { 1, 3, 5, 7 }; -int corners[4][2] = { { 0, 2 }, { 0, 6 }, { 2, 8 }, { 6, 8 } }; void build_level(void) { 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); - /* Add rooms */ - for (i = 0; i < MAX_ROOMS; i++) - { - add_random_room(i / 3, i % 3); - } - /* Add corridors */ - /* Link the centre room to an edge room. */ - link_rooms(4, edge_rooms[zero_die(4)]); - /* And to another; if we're already linked, don't bother. */ - i = zero_die(4); - if (roomlinkage[4][edge_rooms[i]] == 0) - { - link_rooms(4, edge_rooms[i]); - } - /* Link each edge room to one of its corner rooms. */ - for (i = 0; i < 4; i++) - { - link_rooms(edge_rooms[i], corners[i][zero_die(2)]); - } - /* At this point, 1-2 edge rooms and their attached corner rooms - * have linkage to the centre. */ - /* Link each edge room to its unlinked corner if it is not 2-linked - * to the centre. */ - for (i = 0; i < 4; i++) - { - if (!roomlinkage[4][edge_rooms[i]]) - { - if (roomlinkage[edge_rooms[i]][corners[i][0]]) - { - link_rooms(edge_rooms[i], corners[i][1]); - } - else - { - link_rooms(edge_rooms[i], corners[i][0]); - } - } - - } - /* Link each corner room to its unlinked edge if that edge is not - * 2-linked to the centre. If we still haven't got centre - * connectivity for the edge room, connect the edge to the centre. */ - for (i = 0; i < 4; i++) - { - if (!roomlinkage[4][edge_rooms[i]]) - { - if (!roomlinkage[edge_rooms[i]][corners[i][0]]) - { - link_rooms(edge_rooms[i], corners[i][0]); - } - if (!roomlinkage[edge_rooms[i]][corners[i][1]]) - { - link_rooms(edge_rooms[i], corners[i][1]); - } - } - if (!roomlinkage[4][edge_rooms[i]]) - { - link_rooms(edge_rooms[i], 4); - } - } - /* Just for safety's sake: Now we know all edges are attached, - * make sure all the corners are. (Previously, it was possible - * for them not to be. I know, because I met such a level :) */ - for (i = 3; i > -1; i--) - { - if (!roomlinkage[4][corners[i][0]]) - { - link_rooms(edge_rooms[i], corners[i][0]); - } - if (!roomlinkage[4][corners[i][1]]) - { - link_rooms(edge_rooms[i], corners[i][1]); - } + /* 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; ) + { + if (zero_die(2)) + { + y += (zero_die(2) ? -1 : 1); + if ((y == 0) || (y == DUN_HEIGHT - 1)) + { + y = DUN_HEIGHT / 2; + x = DUN_WIDTH / 2; + } + } + else + { + x += (zero_die(2) ? -1 : 1); + if (x == 0) + { + x = 2; + } + else if (x == DUN_WIDTH - 1) + { + x = DUN_WIDTH - 3; + } + } + if (terrain[y][x] != FLOOR) + { + ++i; + terrain[y][x] = FLOOR; + } } /* Add the stairs */ put_stairs(); } -static void generate_zoo(void) -{ - int mons; - int items; - int tries; - int index; - int y, x; - zoo_room = zero_die(MAX_ROOMS); - if (zoo_room == stairs_room) - { - zoo_room = -1; - return; - } - /* A treasure zoo should get nine monsters and nine items. */ - for (mons = 0; mons < 9; mons++) - { - for (tries = 0; tries < 200; tries++) - { - y = exclusive_flat(roombounds[zoo_room][0], roombounds[zoo_room][1]); - x = exclusive_flat(roombounds[zoo_room][2], roombounds[zoo_room][3]); - if (mapmonster[y][x] == -1) - { - index = create_mon(-1, y, x); - if (index != -1) - { - break; - } - } - } - } - for (items = 0; items < 9; items++) - { - for (tries = 0; tries < 200; tries++) - { - y = exclusive_flat(roombounds[zoo_room][0], roombounds[zoo_room][1]); - x = exclusive_flat(roombounds[zoo_room][2], roombounds[zoo_room][3]); - if (mapobject[y][x] == -1) - { - index = create_obj(-1, 1, 0, y, x); - if (index != -1) - { - break; - } - } - } - } -} - - -int get_room_y(int room) -{ - return exclusive_flat(roombounds[room][0], roombounds[room][1]); -} - -int get_room_x(int room) -{ - return exclusive_flat(roombounds[room][2], roombounds[room][3]); -} - int get_levgen_mon_floor(int *y, int *x) { /* Get a vacant floor cell that isn't in the treasure zoo. */ - int room_try; int cell_try; int ty, tx; - int room; - for (room_try = 0; room_try < (MAX_ROOMS * 2); room_try++) - { - room = zero_die(MAX_ROOMS); - if (room == zoo_room) - { - continue; - } - for (cell_try = 0; cell_try < 200; cell_try++) - { - ty = get_room_y(room); - tx = get_room_x(room); - if ((terrain[ty][tx] != FLOOR) || - (mapmonster[ty][tx] != -1)) - { - ty = -1; - tx = -1; - continue; - } - break; - } - break; + for (cell_try = 0; cell_try < 200; cell_try++) + { + ty = exclusive_flat(0, DUN_HEIGHT - 1); + tx = exclusive_flat(0, DUN_WIDTH - 1); + if ((terrain[ty][tx] != FLOOR) || + (mapmonster[ty][tx] != -1)) + { + ty = -1; + tx = -1; + continue; + } + break; } if (ty == -1) { @@ -440,10 +158,6 @@ void populate_level(void) int y, x; int ic; /* Check for a "treasure zoo" */ - if (!zero_die(10) && (depth > 2)) - { - generate_zoo(); - } /* Generate some random monsters */ for (i = 0; i < 10; i++) { @@ -467,40 +181,53 @@ void populate_level(void) if (j == -1) { continue; - } - create_obj(-1, 1, 0, y, x); + } + create_obj(-1, 1, 0, y, x); } } void inject_player(void) { - int i; - int room_try; int cell_try; - for (room_try = 0; room_try < (MAX_ROOMS * 2); room_try++) + for (cell_try = 0; cell_try < 200; cell_try++) + { + u.y = exclusive_flat(0, DUN_HEIGHT - 1); + u.x = exclusive_flat(0, DUN_WIDTH - 1); + if (terrain[u.y][u.x] != FLOOR) + { + continue; + } + if (mapmonster[u.y][u.x] != -1) + { + continue; + } + break; + } + reloc_player(u.y, u.x); +} + +void explore_around(int y, int x) +{ + int y2, x2; + for (y2 = y - 10; y2 <= y + 10; y2++) { - i = zero_die(MAX_ROOMS); - if (i == zoo_room) + if ((y2 < 0) || (y2 >= DUN_HEIGHT)) { continue; } - if (i == stairs_room) + for (x2 = x - 10; x2 <= x + 10; x2++) { - continue; - } - for (cell_try = 0; cell_try < 200; cell_try++) - { - u.y = exclusive_flat(roombounds[i][0], roombounds[i][1]); - u.x = exclusive_flat(roombounds[i][2], roombounds[i][3]); - if (mapmonster[u.y][u.x] != -1) + if ((x2 < 0) || (x2 >= DUN_WIDTH)) { continue; } - break; + if (!(mapflags[y2][x2] & MAPFLAG_EXPLORED)) + { + mapflags[y2][x2] |= MAPFLAG_EXPLORED; + } + newsym(y2, x2); } - break; } - reloc_player(u.y, u.x); } /* map.c */ diff --git a/misc.c b/misc.c index 312f859..9a5d9e3 100644 --- a/misc.c +++ b/misc.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dunbash.h" +#include "cavechop.h" const char *damtype_names[DT_COUNT] = { [DT_PHYS] = "physical damage", diff --git a/mon2.c b/mon2.c index 7217a3b..4214ad4 100644 --- a/mon2.c +++ b/mon2.c @@ -26,7 +26,7 @@ /* TODO: Convert missile AI to a new-style AI function. */ #define MON2_C -#include "dunbash.h" +#include "cavechop.h" #include "bmagic.h" #include "monsters.h" #include "combat.h" @@ -259,90 +259,43 @@ static void get_seeking_prefs(int y, int x, int dy, int dx, int *pref_y, int *pr int j; int highest_score = -10000; int tryct; - int uroom; - int mroom; - int troom; *pref_y = y; *pref_x = x; ady = dy > 0 ? dy : -dy; adx = dx > 0 ? dx : -dx; build_ai_cells(ai_cells, y, x); - uroom = roomnums[u.y][u.x]; - mroom = roomnums[y][x]; for (i = 0; i < 8; i++) { - troom = roomnums[ai_cells[i].y][ai_cells[i].x]; ai_cells[i].dy = u.y - ai_cells[i].y; ai_cells[i].dx = u.x - ai_cells[i].x; /* Scoring factors: - * If player in a room: - * Square in player's room: +10 * Square closer to player: +1 * Square further from player: -1 - * Square in room with linkage 1 to player's room: +5 - * If player in corridor: - * Square closer to player: +1 - * Square matches one of player's coords: +1 - * Square further from player: -1 - * Note that now that wraiths are smart and can walk through - * walls, the player can only finally evade a wraith by - * killing it or leaving the level; fortunately, wraiths - * are slow. (Danenth will feature ethereal beings, in the - * form of chthonic spirits, which are *not* slow.) */ if (!mon_can_pass(mapmonster[y][x], ai_cells[i].y, ai_cells[i].x)) { /* Square impassable to this monster. Set score WAY - * out of bounds and continue. */ - ai_cells[i].score = -10000; - continue; - } - if (uroom != -1) - { - /* Player in a room */ - if (troom == uroom) - { - ai_cells[i].score += 10; - } - else if ((troom != -1) && (roomlinkage[troom][uroom] == 1)) - { - ai_cells[i].score += 5; - } - j = ai_cell_compare(ai_cells + i, dy, dx); - if (j > 0) - { - ai_cells[i].score -= 1; - } - else if (j < 0) - { - ai_cells[i].score += 1; - } - if (ai_cells[i].score > highest_score) - { - highest_score = ai_cells[i].score; - } - } - else - { - /* Player in a corridor */ - if ((ai_cells[i].y == u.y) || (ai_cells[i].x == u.x)) - { - ai_cells[i].score += 1; - } - j = ai_cell_compare(ai_cells + i, dy, dx); - if (j > 0) - { - ai_cells[i].score -= 1; - } - else if (j < 0) - { - ai_cells[i].score += 1; - } - if (ai_cells[i].score > highest_score) - { - highest_score = ai_cells[i].score; - } - } + * out of bounds and continue. */ + ai_cells[i].score = -10000; + continue; + } + if ((ai_cells[i].y == u.y) || (ai_cells[i].x == u.x)) + { + ai_cells[i].score += 1; + } + j = ai_cell_compare(ai_cells + i, dy, dx); + if (j > 0) + { + ai_cells[i].score -= 1; + } + else if (j < 0) + { + ai_cells[i].score += 1; + } + if (ai_cells[i].score > highest_score) + { + highest_score = ai_cells[i].score; + } } if (highest_score == -10000) { @@ -801,17 +754,15 @@ void mon_acts(int mon) } return; } + if (mon_visible(mon)) + { + mptr->awake = 1; + } if (meleerange) { /* Adjacent! Attack you. Demons have a 1 in 10 chance of * attempting to summon another demon instead of attacking * you. */ - if (!mptr->awake) - { - print_mon_name(mon, 2); - print_msg(" notices you.\n"); - mptr->awake = 1; - } if ((mptr->mon_id == PM_DEMON) && !zero_die(10)) { summon_demon_near(y, x); @@ -826,15 +777,9 @@ void mon_acts(int mon) mhitu(mon, DT_PHYS); } } - else if (inyourroom(y, x)) + else if (mon_visible(mon)) { - /* In same room. */ - if (!mptr->awake) - { - print_mon_name(mon, 2); - print_msg(" notices you.\n"); - mptr->awake = 1; - } + /* In sight. */ if (pmon_is_magician(mptr->mon_id)) { /* Two-thirds of the time, try to use black magic. */ @@ -916,7 +861,7 @@ void mon_acts(int mon) } /* Let's get the data again. */ compute_directions(u.y, u.x, y, x, &dy, &dx, &sy, &sx, &meleerange, &oncardinal); - if (meleerange || ((roomnums[u.y][u.x] != -1) && (roomnums[u.y][u.x] == roomnums[y][x]))) + if ((dy >= -10) && (dy <= 10) && (dx >= -10) && (dx >= 10)) { mptr->ai_lasty = u.y; mptr->ai_lastx = u.x; diff --git a/monsters.c b/monsters.c index c6ffc77..eb1fb77 100644 --- a/monsters.c +++ b/monsters.c @@ -25,7 +25,7 @@ */ #define MONSTERS_C -#include "dunbash.h" +#include "cavechop.h" #include "monsters.h" struct mon monsters[100]; @@ -84,7 +84,7 @@ int get_random_pmon(void) int pm; for (tryct = 0; tryct < 200; tryct++) { - pm = zero_die(PM_REAL_COUNT); + pm = zero_die(NUM_OF_PERMONS); if (reject_mon(pm)) { pm = -1; @@ -306,19 +306,19 @@ void damage_mon(int mon, int amount, int by_you) } else if (mon_visible(mon)) { - print_mon_name(mon, 2); - print_msg(" dies.\n"); - } - death_drop(mon); - mapmonster[mptr->y][mptr->x] = -1; - newsym(mptr->y, mptr->x); - mptr->used = 0; - map_updated = 1; - display_update(); + print_mon_name(mon, 2); + print_msg(" dies.\n"); + } + death_drop(mon); + mapmonster[mptr->y][mptr->x] = -1; + newsym(mptr->y, mptr->x); + mptr->used = 0; + map_updated = 1; + display_update(); } else { - mptr->hpcur -= amount; + mptr->hpcur -= amount; } } @@ -326,7 +326,7 @@ int reject_mon(int pm) { if ((permons[pm].power > depth) || (zero_die(100) < permons[pm].rarity)) { - return 1; + return 1; } return 0; } @@ -337,37 +337,17 @@ int teleport_mon_to_you(int mon) int dy, dx; int y, x; int success = 0; - int roomnum; - if (roomnums[u.y][u.x] == -1) - { - /* Player in corridor. Try to teleport next to him. */ - for (tryct = 0; tryct < 40; tryct++) - { - dy = zero_die(3) - 1; - dx = zero_die(3) - 1; - y = u.y + dy; - x = u.x + dx; - if (mon_can_pass(mon, y, x)) - { - success = 1; - break; - } - } - } - else - { - /* Player is in a room. Try to teleport into same room. */ - roomnum = roomnums[u.y][u.x]; - for (tryct = 0; tryct < 200; tryct++) - { - y = exclusive_flat(roombounds[roomnum][0], roombounds[roomnum][1]); - x = exclusive_flat(roombounds[roomnum][2], roombounds[roomnum][3]); - if (mon_can_pass(mon, y, x)) - { - success = 1; - break; - } - } + for (tryct = 0; tryct < 40; tryct++) + { + dy = zero_die(3) - 1; + dx = zero_die(3) - 1; + y = u.y + dy; + x = u.x + dx; + if (mon_can_pass(mon, y, x)) + { + success = 1; + break; + } } if (success) { @@ -382,24 +362,18 @@ int teleport_mon_to_you(int mon) int teleport_mon(int mon) { int rval = -1; - int room_try; int cell_try; - int room; int y, x; - for (room_try = 0; room_try < MAX_ROOMS * 4; room_try++) + for (cell_try = 0; cell_try < 200; cell_try++) { - room = zero_die(MAX_ROOMS); - for (cell_try = 0; cell_try < 200; cell_try++) - { - y = exclusive_flat(roombounds[room][0], roombounds[room][1]); - x = exclusive_flat(roombounds[room][2], roombounds[room][3]); - if ((mapmonster[y][x] == -1) && (terrain[y][x] == FLOOR) && ((y != u.y) || (x != u.x))) - { - move_mon(mon, y, x); - rval = 0; - break; - } - } + y = exclusive_flat(0, DUN_HEIGHT - 1); + x = exclusive_flat(0, DUN_WIDTH - 1); + if ((mapmonster[y][x] == -1) && (terrain[y][x] == FLOOR) && ((y != u.y) || (x != u.x))) + { + move_mon(mon, y, x); + rval = 0; + break; + } } return rval; } @@ -409,8 +383,8 @@ void move_mon(int mon, int y, int x) struct mon *mptr; if (!mon_can_pass(mon, y, x)) { - print_msg("Warning: monster attempted an invalid move.\n"); - return; + print_msg("Warning: monster attempted an invalid move.\n"); + return; } mptr = monsters + mon; if (mapmonster[mptr->y][mptr->x] != mon) @@ -458,8 +432,8 @@ int mon_visible(int mon) } dy = u.y - monsters[mon].y; dx = u.x - monsters[mon].x; - if (((dy > -2) && (dy < 2) && (dx > -2) && (dx < 2)) || - ((roomnums[u.y][u.x] != -1) && (roomnums[u.y][u.x] == roomnums[monsters[mon].y][monsters[mon].x]))) + /* Cave Chop FoV: The screen. */ + if (((dy > -11) && (dy < 11) && (dx > -11) && (dx < 11))) { return 1; } diff --git a/objects.c b/objects.c index 0addcc0..4f3077a 100644 --- a/objects.c +++ b/objects.c @@ -25,12 +25,11 @@ */ #define OBJECTS_C -#include "dunbash.h" +#include "cavechop.h" #include "monsters.h" struct obj objects[100]; int get_random_pobj(void); -static int consume_obj(int obj); const char ring_colours[20][16] = { "gold", "ruby", "sapphire", "ivory", "coral", @@ -59,123 +58,96 @@ int read_scroll(int obj) int i; switch (optr->obj_id) { - case PO_SCR_IDENTIFY: - print_msg("This is an identify scroll!\n"); - for (i = 0; i < 19; i++) - { - if (u.inventory[i] != -1) - { - permobjs[objects[u.inventory[i]].obj_id].known = 1; - } - } - break; case PO_SCR_TELEPORT: - teleport_u(); - break; + teleport_u(); + break; case PO_SCR_FIRE: - print_msg("The scroll explodes in flames!\n"); - if (u.ring != -1) - { - if (objects[u.ring].obj_id == PO_RING_FIRE) - { - print_msg("Your ring glows, and the flames seem cool.\n"); - permobjs[objects[u.ring].obj_id].known = 1; - break; - } - } - i = damage_u(dice(4, 10), DEATH_KILLED, "searing flames"); - if (!i) - { - print_msg("That hurt!\n"); - } - break; - case PO_SCR_MONSTERS: - i = summoning(u.y, u.x, one_die(3) + 1); - if (i > 0) - { - print_msg("Monsters appear!\n"); - } - else - { - print_msg("You hear a snarl of frustration.\n"); - } - break; - case PO_SCR_AGGRAVATE: - print_msg("You hear a high-pitched humming noise.\n"); - for (i = 0; i < 100; i++) - { - if (monsters[i].used) - { - monsters[i].awake = 1; - } - } - break; + print_msg("The scroll explodes in flames!\n"); + if (u.ring != -1) + { + if (objects[u.ring].obj_id == PO_RING_FIRE) + { + print_msg("Your ring glows, and the flames seem cool.\n"); + break; + } + } + 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)) + { + } + } + break; case PO_SCR_PROTECTION: - print_msg("You feel like something is helping you.\n"); - if (!u.protection) - { - /* Do not prolong existing protection, only grant - * protection to the unprotected. */ - u.protection = 100; - } - if (u.withering) - { - print_msg("Your limbs straighten.\n"); - u.withering = 0; - } - if (u.armourmelt) - { - print_msg("Your armour regains its strength.\n"); - u.armourmelt = 0; - } - if (u.leadfoot) - { - print_msg("You shed your feet of lead.\n"); - u.leadfoot = 0; - } - break; + print_msg("You feel like something is helping you.\n"); + if (!u.protection) + { + /* Do not prolong existing protection, only grant + * protection to the unprotected. */ + u.protection = 100; + } + if (u.withering) + { + print_msg("Your limbs straighten.\n"); + u.withering = 0; + } + if (u.armourmelt) + { + print_msg("Your armour regains its strength.\n"); + u.armourmelt = 0; + } + if (u.leadfoot) + { + print_msg("You shed your feet of lead.\n"); + u.leadfoot = 0; + } + break; default: - print_msg("Impossible: reading non-scroll\n"); - return 0; + print_msg("Impossible: reading non-scroll\n"); + return 0; } - permobjs[optr->obj_id].known = 1; return consume_obj(obj); } -static int consume_obj(int obj) +int consume_obj(int obj) { int i; objects[obj].quan--; if (objects[obj].quan == 0) { - objects[obj].used = 0; - if (objects[obj].with_you) - { - if (obj == u.armour) - { - u.armour = -1; - recalc_defence(); - } - else if (obj == u.weapon) - { - u.weapon = -1; - recalc_defence(); - } - else if (obj == u.ring) - { - u.ring = -1; - recalc_defence(); - } - for (i = 0; i < 19; i++) - { - if (u.inventory[i] == obj) - { - u.inventory[i] = -1; - break; - } - } - } - return 1; + objects[obj].used = 0; + if (objects[obj].with_you) + { + if (obj == u.armour) + { + u.armour = -1; + recalc_defence(); + } + else if (obj == u.weapon) + { + u.weapon = -1; + recalc_defence(); + } + else if (obj == u.ring) + { + u.ring = -1; + recalc_defence(); + } + for (i = 0; i < 19; i++) + { + if (u.inventory[i] == obj) + { + u.inventory[i] = -1; + break; + } + } + } + return 1; } return 0; } @@ -185,16 +157,16 @@ int eat_food(int obj) struct obj *optr = objects + obj; if (permobjs[optr->obj_id].poclass != POCLASS_FOOD) { - print_msg("Error: attempt to eat non-food (%d)!\n", optr->obj_id); - return -1; + print_msg("Error: attempt to eat non-food (%d)!\n", optr->obj_id); + return -1; } if (u.food < 0) { - print_msg("You ravenously devour your food!\n"); + print_msg("You ravenously devour your food!\n"); } else { - print_msg("You eat some food.\n"); + print_msg("You eat some food.\n"); } u.food += 1500; status_updated = 1; @@ -208,61 +180,50 @@ int quaff_potion(int obj) switch (optr->obj_id) { case PO_POT_BODY: - gain_body(1, 1); - break; + gain_body(1, 1); + break; case PO_POT_AGILITY: - gain_agility(1, 1); - break; - case PO_POT_WEAKNESS: - print_msg("You feel that was a bad idea!\n"); - drain_body(one_die(4), "a potion of weakness", 1); - drain_agility(one_die(4), "a potion of weakness", 1); - break; - case PO_POT_POISON: - print_msg("This is poison!\n"); - damage_u(dice(3, 12), DEATH_KILLED, "drinking poison"); - display_update(); - break; + 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); - break; + /* Heal player; if hit points brought to max, gain one + * hit point. */ + heal_u(dice(3, 12), 1, 1); + break; case PO_POT_RESTORATION: - print_msg("This potion makes you feel warm all over.\n"); - status_updated = 1; - if (!zero_die(2)) - { - if (u.adam) - { - u.adam = 0; - print_msg("You feel less clumsy.\n"); - } - else if (u.bdam) - { - u.bdam = 0; - print_msg("You feel less feeble.\n"); - } - } - else - { - if (u.bdam) - { - u.bdam = 0; - print_msg("You feel less feeble.\n"); - } - else if (u.adam) - { - u.adam = 0; - print_msg("You feel less clumsy.\n"); - } - } - break; + print_msg("This potion makes you feel warm all over.\n"); + status_updated = 1; + if (!zero_die(2)) + { + if (u.adam) + { + u.adam = 0; + print_msg("You feel less clumsy.\n"); + } + else if (u.bdam) + { + u.bdam = 0; + print_msg("You feel less feeble.\n"); + } + } + else + { + if (u.bdam) + { + u.bdam = 0; + print_msg("You feel less feeble.\n"); + } + else if (u.adam) + { + u.adam = 0; + print_msg("You feel less clumsy.\n"); + } + } + break; default: - print_msg("Impossible: quaffing non-potion\n"); - return 0; + print_msg("Impossible: quaffing non-potion\n"); + return 0; } - permobjs[optr->obj_id].known = 1; return consume_obj(obj); } @@ -277,73 +238,66 @@ void flavours_init(void) /* Rings */ for (i = 0; i < 10;) { - colour_choices[i] = zero_die(20); - done = 1; - for (j = 0; j < i; j++) - { - if (colour_choices[i] == colour_choices[j]) - { - done = 0; - } - } - if (done) - { - i++; - } + colour_choices[i] = zero_die(20); + done = 1; + for (j = 0; j < i; j++) + { + if (colour_choices[i] == colour_choices[j]) + { + done = 0; + } + } + if (done) + { + i++; + } } permobjs[PO_RING_REGEN].power = colour_choices[0]; permobjs[PO_RING_FIRE].power = colour_choices[1]; - permobjs[PO_RING_WEDDING].power = colour_choices[2]; - permobjs[PO_RING_VAMPIRE].power = colour_choices[3]; - permobjs[PO_RING_FROST].power = colour_choices[4]; - permobjs[PO_RING_DOOM].power = colour_choices[5]; - permobjs[PO_RING_TELEPORT].power = colour_choices[6]; + permobjs[PO_RING_VAMPIRE].power = colour_choices[2]; + permobjs[PO_RING_FROST].power = colour_choices[3]; + permobjs[PO_RING_TELEPORT].power = colour_choices[4]; /* Scrolls */ for (i = 0; i < 10;) { - colour_choices[i] = zero_die(20); - done = 1; - for (j = 0; j < i; j++) - { - if (colour_choices[i] == colour_choices[j]) - { - done = 0; - } - } - if (done) - { - i++; - } + colour_choices[i] = zero_die(20); + done = 1; + for (j = 0; j < i; j++) + { + if (colour_choices[i] == colour_choices[j]) + { + done = 0; + } + } + if (done) + { + i++; + } } permobjs[PO_SCR_FIRE].power = colour_choices[0]; permobjs[PO_SCR_TELEPORT].power = colour_choices[1]; - permobjs[PO_SCR_MONSTERS].power = colour_choices[2]; - permobjs[PO_SCR_IDENTIFY].power = colour_choices[3]; - permobjs[PO_SCR_PROTECTION].power = colour_choices[4]; - permobjs[PO_SCR_AGGRAVATE].power = colour_choices[5]; + permobjs[PO_SCR_PROTECTION].power = colour_choices[2]; /* Potions */ for (i = 0; i < 10;) { - colour_choices[i] = zero_die(20); - done = 1; - for (j = 0; j < i; j++) - { - if (colour_choices[i] == colour_choices[j]) - { - done = 0; - } - } - if (done) - { - i++; - } + colour_choices[i] = zero_die(20); + done = 1; + for (j = 0; j < i; j++) + { + if (colour_choices[i] == colour_choices[j]) + { + done = 0; + } + } + if (done) + { + i++; + } } permobjs[PO_POT_HEAL].power = colour_choices[0]; permobjs[PO_POT_BODY].power = colour_choices[1]; - permobjs[PO_POT_POISON].power = colour_choices[2]; - permobjs[PO_POT_AGILITY].power = colour_choices[3]; - permobjs[PO_POT_WEAKNESS].power = colour_choices[4]; - permobjs[PO_POT_RESTORATION].power = colour_choices[5]; + permobjs[PO_POT_AGILITY].power = colour_choices[2]; + permobjs[PO_POT_RESTORATION].power = colour_choices[3]; } int create_obj_class(enum poclass_num po_class, int quantity, int with_you, int y, int x) @@ -353,38 +307,38 @@ int create_obj_class(enum poclass_num po_class, int quantity, int with_you, int int tryct; for (obj = 0; obj < 100; obj++) { - if (!objects[obj].used) - { - break; - } + if (!objects[obj].used) + { + break; + } } if (obj == 100) { - print_msg("ERROR: Ran out of objects[].\n"); - return -1; + print_msg("ERROR: Ran out of objects[].\n"); + return -1; } for (tryct = 0; tryct < 200; tryct++) { - switch (po_class) - { - case POCLASS_POTION: - po_idx = inclusive_flat(PO_FIRST_POTION, PO_LAST_POTION); - break; - case POCLASS_SCROLL: - po_idx = inclusive_flat(PO_FIRST_SCROLL, PO_LAST_SCROLL); - break; - case POCLASS_RING: - po_idx = inclusive_flat(PO_FIRST_RING, PO_LAST_RING); - break; - default: - /* No getting armour/weapons by class... yet. */ - return -1; - } - if (zero_die(100) < permobjs[po_idx].rarity) - { - continue; - } - break; + switch (po_class) + { + case POCLASS_POTION: + po_idx = inclusive_flat(PO_FIRST_POTION, PO_LAST_POTION); + break; + case POCLASS_SCROLL: + po_idx = inclusive_flat(PO_FIRST_SCROLL, PO_LAST_SCROLL); + break; + case POCLASS_RING: + po_idx = inclusive_flat(PO_FIRST_RING, PO_LAST_RING); + break; + default: + /* No getting armour/weapons by class... yet. */ + return -1; + } + if (zero_die(100) < permobjs[po_idx].rarity) + { + continue; + } + break; } objects[obj].obj_id = po_idx; objects[obj].quan = quantity; @@ -397,21 +351,21 @@ int get_random_pobj(void) int po_idx; for (tryct = 0; tryct < 200; tryct++) { - po_idx = zero_die(PO_REAL_COUNT); - if (zero_die(100) < permobjs[po_idx].rarity) - { - po_idx = -1; - continue; - } - /* v1.3: Do not permit generation of particularly powerful - * items (runeswords, mage armour, etc.) at shallow depths. - * (game balance fix) */ - if (depth < permobjs[po_idx].depth) - { - po_idx = -1; - continue; - } - break; + po_idx = zero_die(NUM_OF_PERMOBJS); + if (zero_die(100) < permobjs[po_idx].rarity) + { + po_idx = -1; + continue; + } + /* v1.3: Do not permit generation of particularly powerful + * items (runeswords, mage armour, etc.) at shallow depths. + * (game balance fix) */ + if (depth < permobjs[po_idx].depth) + { + po_idx = -1; + continue; + } + break; } return po_idx; } @@ -421,52 +375,45 @@ int create_obj(int po_idx, int quantity, int with_you, int y, int x) int i; for (i = 0; i < 100; i++) { - if (!objects[i].used) - { - break; - } + if (!objects[i].used) + { + break; + } } if (i == 100) { - print_msg("ERROR: Ran out of objects[].\n"); - return -1; + print_msg("ERROR: Ran out of objects[].\n"); + return -1; } if (po_idx == -1) { - po_idx = get_random_pobj(); - if (po_idx == -1) - { - return -1; - } + po_idx = get_random_pobj(); + if (po_idx == -1) + { + return -1; + } } objects[i].obj_id = po_idx; objects[i].with_you = with_you; objects[i].used = 1; objects[i].y = y; objects[i].x = x; - if (po_idx == PO_GOLD) - { - objects[i].quan = dice(depth + 1, 20); - } - else - { - objects[i].quan = quantity; - } + objects[i].quan = quantity; switch (permobjs[po_idx].poclass) { case POCLASS_WEAPON: case POCLASS_ARMOUR: - /* Set durability of weapons and armour to a suitable value. - * 100 has been chosen for the moment, but this may need - * tuning. */ - objects[i].durability = OBJ_MAX_DUR; - break; + /* Set durability of weapons and armour to a suitable value. + * 100 has been chosen for the moment, but this may need + * tuning. */ + objects[i].durability = OBJ_MAX_DUR; + break; default: - break; + break; } if (!objects[i].with_you) { - mapobject[y][x] = i; + mapobject[y][x] = i; } return i; } @@ -477,75 +424,22 @@ void fprint_obj_name(FILE *fp, int obj) struct permobj *poptr; optr = objects + obj; poptr = permobjs + optr->obj_id; - if (poptr->known) - { - if (optr->quan > 1) - { - fprintf(fp, "%d %s", optr->quan, poptr->plural); - } - else if (po_is_stackable(optr->obj_id)) - { - fprintf(fp, "1 %s", poptr->name); - } - else if ((poptr->poclass == POCLASS_WEAPON) || - (poptr->poclass == POCLASS_ARMOUR)) - { - fprintf(fp, "a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR); - } - else - { - fprintf(fp, "a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name); - } + if (optr->quan > 1) + { + fprintf(fp, "%d %s", optr->quan, poptr->plural); + } + else if (po_is_stackable(optr->obj_id)) + { + fprintf(fp, "1 %s", poptr->name); + } + else if ((poptr->poclass == POCLASS_WEAPON) || + (poptr->poclass == POCLASS_ARMOUR)) + { + fprintf(fp, "a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR); } else { - switch (poptr->poclass) - { - case POCLASS_NONE: - fprintf(fp, "a non-thing (%d)", optr->obj_id); - break; - case POCLASS_FOOD: - fprintf(fp, "a mysterious food (%d)", optr->obj_id); - break; - case POCLASS_WEAPON: - fprintf(fp, "a mysterious weapon (%d)", optr->obj_id); - break; - case POCLASS_ARMOUR: - if ((optr->obj_id == PO_ROBE) || - (optr->obj_id == PO_ROBE_SHADOWS) || - (optr->obj_id == PO_ROBE_SWIFTNESS)) - { - fprintf(fp, "a robe"); - } - else - { - fprintf(fp, "some mysterious armour (%d)", optr->obj_id); - } - break; - case POCLASS_SCROLL: - if (optr->quan > 1) - { - fprintf(fp, "%d scrolls '%s'", optr->quan, scroll_titles[poptr->power]); - } - else - { - fprintf(fp, "1 scroll '%s'", scroll_titles[poptr->power]); - } - break; - case POCLASS_POTION: - if (optr->quan > 1) - { - fprintf(fp, "%d %s potions", optr->quan, potion_colours[poptr->power]); - } - else - { - fprintf(fp, "1 %s potion", potion_colours[poptr->power]); - } - break; - case POCLASS_RING: - fprintf(fp, "a%s %s ring", is_vowel(ring_colours[poptr->power][0]) ? "n" : "", ring_colours[poptr->power]); - break; - } + fprintf(fp, "a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name); } } @@ -555,75 +449,22 @@ void print_obj_name(int obj) struct permobj *poptr; optr = objects + obj; poptr = permobjs + optr->obj_id; - if (poptr->known) - { - if (optr->quan > 1) - { - print_msg("%d %s", optr->quan, poptr->plural); - } - else if (po_is_stackable(optr->obj_id)) - { - print_msg("1 %s", poptr->name); - } - else if ((poptr->poclass == POCLASS_WEAPON) || - (poptr->poclass == POCLASS_ARMOUR)) - { - print_msg("a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR); - } - else - { - print_msg("a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name); - } + if (optr->quan > 1) + { + print_msg("%d %s", optr->quan, poptr->plural); + } + else if (po_is_stackable(optr->obj_id)) + { + print_msg("1 %s", poptr->name); + } + else if ((poptr->poclass == POCLASS_WEAPON) || + (poptr->poclass == POCLASS_ARMOUR)) + { + print_msg("a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR); } else { - switch (poptr->poclass) - { - case POCLASS_NONE: - print_msg("a non-thing (%d)", optr->obj_id); - break; - case POCLASS_FOOD: - print_msg("a mysterious food (%d)", optr->obj_id); - break; - case POCLASS_WEAPON: - print_msg("a mysterious weapon (%d)", optr->obj_id); - break; - case POCLASS_ARMOUR: - if ((optr->obj_id == PO_ROBE) || - (optr->obj_id == PO_ROBE_SHADOWS) || - (optr->obj_id == PO_ROBE_SWIFTNESS)) - { - print_msg("a robe"); - } - else - { - print_msg("some mysterious armour (%d)", optr->obj_id); - } - break; - case POCLASS_SCROLL: - if (optr->quan > 1) - { - print_msg("%d scrolls '%s'", optr->quan, scroll_titles[poptr->power]); - } - else - { - print_msg("1 scroll '%s'", scroll_titles[poptr->power]); - } - break; - case POCLASS_POTION: - if (optr->quan > 1) - { - print_msg("%d %s potions", optr->quan, potion_colours[poptr->power]); - } - else - { - print_msg("1 %s potion", potion_colours[poptr->power]); - } - break; - case POCLASS_RING: - print_msg("a%s %s ring", is_vowel(ring_colours[poptr->power][0]) ? "n" : "", ring_colours[poptr->power]); - break; - } + print_msg("a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name); } } @@ -633,23 +474,23 @@ int drop_obj(int inv_idx) optr = objects + u.inventory[inv_idx]; if (mapobject[u.y][u.x] == -1) { - optr->y = u.y; - optr->x = u.x; - mapobject[u.y][u.x] = u.inventory[inv_idx]; - if (u.weapon == u.inventory[inv_idx]) - { - u.weapon = -1; - } - u.inventory[inv_idx] = -1; - optr->with_you = 0; - print_msg("You drop "); - print_obj_name(mapobject[u.y][u.x]); - print_msg(".\n"); - return 0; + optr->y = u.y; + optr->x = u.x; + mapobject[u.y][u.x] = u.inventory[inv_idx]; + if (u.weapon == u.inventory[inv_idx]) + { + u.weapon = -1; + } + u.inventory[inv_idx] = -1; + optr->with_you = 0; + print_msg("You drop "); + print_obj_name(mapobject[u.y][u.x]); + print_msg(".\n"); + return 0; } else { - print_msg("There is already an item here.\n"); + print_msg("There is already an item here.\n"); } return -1; } @@ -659,11 +500,11 @@ int po_is_stackable(int po) switch (permobjs[po].poclass) { default: - return 0; + return 0; case POCLASS_POTION: case POCLASS_SCROLL: case POCLASS_FOOD: - return 1; + return 1; } } @@ -671,45 +512,37 @@ void attempt_pickup(void) { int i; int stackable; - if (objects[mapobject[u.y][u.x]].obj_id == PO_GOLD) - { - print_msg("You get %d gold.\n", objects[mapobject[u.y][u.x]].quan); - u.gold += objects[mapobject[u.y][u.x]].quan; - objects[mapobject[u.y][u.x]].used = 0; - mapobject[u.y][u.x] = -1; - return; - } stackable = po_is_stackable(objects[mapobject[u.y][u.x]].obj_id); if (stackable) { - for (i = 0; i < 19; i++) - { - if ((objects[u.inventory[i]].obj_id == objects[mapobject[u.y][u.x]].obj_id)) - { - print_msg("You get "); - print_obj_name(mapobject[u.y][u.x]); - print_msg(".\nYou now have\n"); - objects[u.inventory[i]].quan += objects[mapobject[u.y][u.x]].quan; - objects[mapobject[u.y][u.x]].used = 0; - mapobject[u.y][u.x] = -1; - print_msg("%c) ", 'a' + i); - print_obj_name(u.inventory[i]); - print_msg("\n"); - return; - } - } + for (i = 0; i < 19; i++) + { + if ((objects[u.inventory[i]].obj_id == objects[mapobject[u.y][u.x]].obj_id)) + { + print_msg("You get "); + print_obj_name(mapobject[u.y][u.x]); + print_msg(".\nYou now have\n"); + objects[u.inventory[i]].quan += objects[mapobject[u.y][u.x]].quan; + objects[mapobject[u.y][u.x]].used = 0; + mapobject[u.y][u.x] = -1; + print_msg("%c) ", 'a' + i); + print_obj_name(u.inventory[i]); + print_msg("\n"); + return; + } + } } for (i = 0; i < 19; i++) { - if (u.inventory[i] == -1) - { - break; - } + if (u.inventory[i] == -1) + { + break; + } } if (i == 19) { - print_msg("Your pack is full.\n"); - return; + print_msg("Your pack is full.\n"); + return; } u.inventory[i] = mapobject[u.y][u.x]; mapobject[u.y][u.x] = -1; @@ -727,21 +560,21 @@ void damage_obj(int obj) /* Only weapons and armour have non-zero durability. */ if (objects[obj].durability == 0) { - /* Break the object. Weapons and armour don't stack. */ - if (obj == u.weapon) - { - print_msg("Your weapon breaks!\n"); - } - else if (obj == u.armour) - { - print_msg("Your armour is ruined!\n"); - } - consume_obj(obj); - recalc_defence(); + /* Break the object. Weapons and armour don't stack. */ + if (obj == u.weapon) + { + print_msg("Your weapon breaks!\n"); + } + else if (obj == u.armour) + { + print_msg("Your armour is ruined!\n"); + } + consume_obj(obj); + recalc_defence(); } else { - objects[obj].durability--; + objects[obj].durability--; } } @@ -752,41 +585,7 @@ void describe_object(int obj) print_obj_name(obj); optr = objects + obj; poptr = permobjs + optr->obj_id; - if (poptr->known) - { - print_msg("\n%s\n", poptr->description); - } - else - { - switch (poptr->poclass) - { - case POCLASS_NONE: - default: - print_msg("This unidentified permobj (%d) is indescribable.\n", optr->obj_id); - break; - case POCLASS_ARMOUR: - if ((optr->obj_id == PO_ROBE) || - (optr->obj_id == PO_ROBE_SHADOWS) || - (optr->obj_id == PO_ROBE_SWIFTNESS)) - { - print_msg("\nA simple woolen robe.\n"); - } - else - { - print_msg("\nAn unidentified and indescribable piece of armour (%d)\n", optr->obj_id); - } - break; - case POCLASS_SCROLL: - print_msg("\nA mysterious scroll.\nReading it will unleash its enchantment.\n"); - break; - case POCLASS_POTION: - print_msg("\nA rather dubious-looking liquid.\nQuaffing it may be baleful or beneficial.\n"); - break; - case POCLASS_RING: - print_msg("\nSome rings are baneful, some are beneficial, and\nsome are junk.\n"); - break; - } - } + print_msg("\n%s\n", poptr->description); } int evasion_penalty(int obj) @@ -794,32 +593,32 @@ int evasion_penalty(int obj) switch (objects[obj].obj_id) { case PO_ROBE: - return 5; + return 5; case PO_LEATHER_ARMOUR: case PO_DRAGON_ARMOUR: - return 10; + return 10; case PO_CHAINMAIL: case PO_SACRED_MAIL: - return 25; + return 25; case PO_PLATE_ARMOUR: case PO_MAGE_ARMOUR: case PO_METEOR_ARMOUR: - return 40; + return 40; case PO_ROBE_SWIFTNESS: - return 0; + return 0; case PO_ROBE_SHADOWS: - return -15; /* This is a bonus. */ + return -15; /* This is a bonus. */ default: - /* If you've somehow managed to wear a non-armour, you're abusing - * a bug; get a 100% penalty to evasion. */ - print_msg("Trying to find evasion penalty of non-armour!\n"); - return 100; + /* If you've somehow managed to wear a non-armour, you're abusing + * a bug; get a 100% penalty to evasion. */ + print_msg("Trying to find evasion penalty of non-armour!\n"); + return 100; } } diff --git a/permobj.c b/permobj.c index 495fce0..7d51c8c 100644 --- a/permobj.c +++ b/permobj.c @@ -25,165 +25,153 @@ */ #define PERMOBJ_C -#include "dunbash.h" +#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, 1 + "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, 1, 4 + "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, 1, 2 + "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, 1, 12 + "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, 1 + "bow", "bows", "A recurve composite bow.", POCLASS_WEAPON, 45, '(', 8, 1, 1 }, [PO_CROSSBOW] = { - "crossbow", "crossbows", "A crossbow.", POCLASS_WEAPON, 70, '(', 16, 1, 1, 6 + "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, 0, 1 - }, - [PO_POT_POISON] = - { - "poison potion", "poison potions", "This liquid is poisonous.", POCLASS_POTION, 10, '!', 0, 1, 0, 1 + "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, 0, 5 + "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, 0, 5 - }, - [PO_POT_WEAKNESS] = - { - "weakness potion", "weakness potions", "This magic elixir causes physical degeneration in\nwhoever drinks it.", POCLASS_POTION, 40, '!', 0, 1, 0, 1 + "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, 0, 1 + "restoration potion", "restoration potions", "This magic elixir cures temporary damage to one's\nabilities.", POCLASS_POTION, 70, '!', 0, 1, 1 }, - [PO_SCR_TELEPORT] = + [PO_FLASK_POISON] = { - "teleport scroll", "teleport scrolls", "Reading this scroll will teleport you to a random\nlocation.", POCLASS_SCROLL, 40, '?', 0, 1, 0, 1 + "poison flask", "poison flask", "This fragile bottle is full of contact poison.", POCLASS_FLASK, 10, '~', 0, 1, 1 }, - [PO_SCR_FIRE] = + [PO_FLASK_FIRE] = { - "fire scroll", "fire scrolls", "Reading this scroll will engulf you in flames.", POCLASS_SCROLL, 30, '?', 0, 1, 0, 1 + "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_SCR_MONSTERS] = + [PO_FLASK_WEAKNESS] = { - "summoning scroll", "summoning scrolls", "Reading this scroll will summon hostile monsters to\nyour side.", POCLASS_SCROLL, 30, '?', 0, 1, 0, 1 + "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_IDENTIFY] = + [PO_SCR_TELEPORT] = { - "identify scroll", "identify scrolls", "Reading this scroll will reveal the nature of your\npossessions.", POCLASS_SCROLL, 70, '?', 0, 1, 0, 3 + "teleport scroll", "teleport scrolls", "Reading this scroll will teleport you to a random\nlocation.", POCLASS_SCROLL, 40, '?', 0, 1, 1 }, - [PO_SCR_AGGRAVATE] = + [PO_SCR_FIRE] = { - "aggravating scroll", "aggravating scrolls", "Reading this scroll will awaken every monster on the\nlevel.", POCLASS_SCROLL, 50, '?', 0, 1, 0, 3 + "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, 0, 8 + "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, 1 + "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, 1, 3 + "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, 1, 6 + "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, 1, 12 + "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, 0, 1 + "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, 0, 8 + "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, 0, 18 + "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, 1, 21 + "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, 1, 27 + "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, 1, 24 + "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, 0, 1 + "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, 0, 1 - }, - [PO_RING_WEDDING] = - { - "wedding ring", "wedding rings", "This ring is but a simple love-token.", POCLASS_RING, 20, '=', 0, 1, 0, 1 + "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, 0, 12 + "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, 0, 1 - }, - [PO_RING_DOOM] = - { - "doom ring", "doom rings", "This accursed ring inflicts great misery on its wearer.\nIt is said that even its removal is painful.", POCLASS_RING, 80, '=', 0, 1, 0, 1 + "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 causes the wearer to teleport at\nrandom.", POCLASS_RING, 70, '=', 0, 1, 0, 1 + "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, 1 + "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, 1 + "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, 1 - }, - [PO_GOLD] = - { - "gold piece", "gold pieces", "The wealth of ages. Not that it will do you much good.", POCLASS_NONE, 1, '$', 0, 1, 1, 1 - }, + "round of elven waybread", "rounds of elven waybread", "A tasty, filling, nutritious piece of elven waybread.", POCLASS_FOOD, 85, '%', 0, 1, 1 + } }; /* permobj.c */ diff --git a/permons.c b/permons.c index 717c730..967ad90 100644 --- a/permons.c +++ b/permons.c @@ -25,7 +25,7 @@ */ #define PERMONS_C -#include "dunbash.h" +#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", @@ -38,125 +38,125 @@ * Supernatural Beasts */ struct permon permons[NUM_OF_PERMONS] = { - [PM_NEWT] = - { - "newt", "newts", 'n', DBCLR_RED, 20, 1, 3, 0, -1, 2, -1, DT_PHYS, "", 1, 1, 0, PMF_STUPID - }, - [PM_RAT] = - { - "rat", "rats", 'r', DBCLR_BROWN, 15, 1, 4, 0, -1, 2, -1, DT_PHYS, "", 4, 2, 2, PMF_STUPID - }, - [PM_WOLF] = - { - "wolf", "wolves", 'c', DBCLR_BROWN, 30, 6, 20, 8, -1, 10, -1, DT_PHYS, "", 6, 15, 2, 0 - }, - [PM_SNAKE] = - { - /* Saps one Body on a really good hit */ - "snake", "snakes", 's', DBCLR_RED, 20, 6, 15, 10, -1, 3, -1, DT_PHYS, "", 9, 40, 2, PMF_STUPID - }, - [PM_THUG] = - { - /* may drop a mace or leather armour */ - "thug", "thugs", 't', DBCLR_BROWN, 30, 1, 8, 5, -1, 5, -1, DT_PHYS, "", 4, 5, 1, 0 - }, - [PM_GOON] = - { - "goon", "goons", 't', DBCLR_YELLOW, 20, 3, 20, 6, -1, 10, -1, DT_PHYS, "", 8, 10, 1, 0 - }, - [PM_HUNTER] = - { - /* Has a ranged attack - arrows */ - "hunter", "hunters", 'h', DBCLR_GREEN, 30, 9, 40, 6, 20, 6, 10, DT_PHYS, "shoots an arrow", 10, 50, 1, PMF_ARCHER - }, - [PM_DUELLIST] = - { - "duellist", "duellists", 'f', DBCLR_RED, 40, 12, 60, 30, -1, 15, -1, DT_PHYS, "", 15, 130, 1, PMF_SMART - }, - [PM_WARLORD] = - { - "warlord", "warlords", 'f', DBCLR_L_RED, 30, 15, 80, 25, -1, 20, -1, DT_PHYS, "", 20, 400, 2, PMF_SMART - }, - [PM_GOBLIN] = - { - /* may drop a dagger */ - "goblin", "goblins", 'g', DBCLR_BROWN, 20, 1, 6, 1, -1, 3, -1, DT_PHYS, "", 3, 3, 1, 0 - }, - [PM_BAD_ELF] = - { - "bad elf", "bad elves", 'e', DBCLR_L_GREY, 40, 3, 15, 10, -1, 6, -1, DT_PHYS, "", 8, 15, 2, PMF_SMART - }, - [PM_TROLL] = - { - "troll", "trolls", 'T', DBCLR_GREEN, 20, 12, 80, 15, -1, 15, -1, DT_PHYS, "", 13, 150, 1, PMF_STUPID - }, - [PM_GIANT] = - { - "giant", "giants", 'H', DBCLR_BROWN, 20, 21, 80, 15, -1, 25, -1, DT_PHYS, "", 20, 500, 1, PMF_STUPID - }, - [PM_GIANT_JARL] = - { - "giant jarl", "giant jarls", 'H', DBCLR_L_GREY, 80, 25, 160, 20, -1, 30, -1, DT_PHYS, "", 22, 1000, 1, 0 - }, - [PM_WIZARD] = - { - /* Uses black magic against you; see bmagic.c for details. */ - "wizard", "wizards", 'w', DBCLR_BLUE, 80, 12, 40, 10, 20, 10, 10, DT_ELEC, "casts", 15, 200, 1, PMF_SMART | PMF_MAGICIAN - }, - [PM_ARCHMAGE] = - { - /* Uses black magic against you; see bmagic.c for details. */ - "archmage", "archmagi", 'w', DBCLR_L_BLUE, 80, 24, 80, 15, 30, 15, 15, DT_ELEC, "casts", 15, 1500, 1, PMF_SMART | PMF_MAGICIAN - }, - [PM_ZOMBIE] = - { - "zombie", "zombies", 'z', DBCLR_L_GREY, 25, 3, 30, 2, -1, 20, -1, DT_PHYS, "", 1, 7, 0, PMF_STUPID | PMF_UNDEAD | PMF_RESIST_COLD - }, - [PM_WRAITH] = - { - "wraith", "wraiths", 'W', DBCLR_WHITE, 25, 12, 40, 25, -1, 5, -1, DT_PHYS, "", 5, 100, 0, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD - }, - [PM_LICH] = - { - /* Uses black magic against you; see bmagic.c for details. */ - "lich", "liches", 'L', DBCLR_L_GREY, 70, 15, 70, 15, 25, 15, 15, DT_NECRO, "casts", 15, 250, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_MAGICIAN - }, - [PM_VAMPIRE] = - { - /* Vampires heal by hitting you. */ - "vampire", "vampires", 'V', DBCLR_RED, 55, 18, 70, 25, -1, 15, -1, DT_PHYS, "", 22, 750, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD - }, - [PM_MASTER_LICH] = - { - /* Master liches use black magic against you, more powerfully - * than lesser practitioners. */ - "master lich", "master liches", 'L', DBCLR_PURPLE, 60, 30, 150, 30, 30, 20, 30, DT_NECRO, "", 30, 3000, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_MAGICIAN - }, - [PM_DEMON] = - { - /* Demons summon more demons if you don't kill them - * quickly. */ - "demon", "demons", '&', DBCLR_RED, 60, 18, 40, 25, -1, 20, -1, DT_PHYS, "", 15, 500, 1, PMF_SMART | PMF_DEMONIC | PMF_RESIST_FIRE - }, - [PM_DEFILER] = - { - /* Defilers use black magic against you. */ - "defiler", "defilers", '&', DBCLR_L_GREEN, 65, 27, 120, 30, 30, 20, 30, DT_FIRE, "", 25, 2000, 1, PMF_SMART | PMF_DEMONIC | PMF_RESIST_FIRE | PMF_MAGICIAN - }, - [PM_CENTAUR] = - { - "centaur", "centaurs", 'C', DBCLR_BROWN, 30, 9, 40, 15, -1, 10, -1, DT_PHYS, "", 10, 50, 2, 0 - }, - [PM_ICE_MONSTER] = - { - /* Fires ice blasts. */ - "ice monster", "ice monsters", 'I', DBCLR_WHITE, 50, 6, 40, 10, 20, 15, 15, DT_COLD, "launches a blast of", 10, 35, 0, PMF_RESIST_COLD | PMF_ARCHER - }, - [PM_DRAGON] = - { - /* Breathes fire. */ - "dragon", "dragons", 'D', DBCLR_RED, 50, 15, 80, 20, 20, 20, 20, DT_FIRE, "breathes", 18, 300, 1, PMF_RESIST_FIRE | PMF_ARCHER - }, + [PM_NEWT] = + { + "newt", "newts", 'n', DBCLR_RED, 20, 1, 3, 0, -1, 2, -1, DT_PHYS, "", 1, 1, 0, PMF_STUPID + }, + [PM_RAT] = + { + "rat", "rats", 'r', DBCLR_BROWN, 15, 1, 4, 0, -1, 2, -1, DT_PHYS, "", 4, 2, 2, PMF_STUPID + }, + [PM_WOLF] = + { + "wolf", "wolves", 'c', DBCLR_BROWN, 30, 6, 20, 8, -1, 10, -1, DT_PHYS, "", 6, 15, 2, 0 + }, + [PM_SNAKE] = + { + /* Saps one Body on a really good hit */ + "snake", "snakes", 's', DBCLR_RED, 20, 6, 15, 10, -1, 3, -1, DT_PHYS, "", 9, 40, 2, PMF_STUPID + }, + [PM_THUG] = + { + /* may drop a mace or leather armour */ + "thug", "thugs", 't', DBCLR_BROWN, 30, 1, 8, 5, -1, 5, -1, DT_PHYS, "", 4, 5, 1, 0 + }, + [PM_GOON] = + { + "goon", "goons", 't', DBCLR_YELLOW, 20, 3, 20, 6, -1, 10, -1, DT_PHYS, "", 8, 10, 1, 0 + }, + [PM_HUNTER] = + { + /* Has a ranged attack - arrows */ + "hunter", "hunters", 'h', DBCLR_GREEN, 30, 9, 40, 6, 20, 6, 10, DT_PHYS, "shoots an arrow", 10, 50, 1, PMF_ARCHER + }, + [PM_DUELLIST] = + { + "duellist", "duellists", 'f', DBCLR_RED, 40, 12, 60, 30, -1, 15, -1, DT_PHYS, "", 15, 130, 1, PMF_SMART + }, + [PM_WARLORD] = + { + "warlord", "warlords", 'f', DBCLR_L_RED, 30, 15, 80, 25, -1, 20, -1, DT_PHYS, "", 20, 400, 2, PMF_SMART + }, + [PM_GOBLIN] = + { + /* may drop a dagger */ + "goblin", "goblins", 'g', DBCLR_BROWN, 20, 1, 6, 1, -1, 3, -1, DT_PHYS, "", 3, 3, 1, 0 + }, + [PM_BAD_ELF] = + { + "bad elf", "bad elves", 'e', DBCLR_L_GREY, 40, 3, 15, 10, -1, 6, -1, DT_PHYS, "", 8, 15, 2, PMF_SMART + }, + [PM_TROLL] = + { + "troll", "trolls", 'T', DBCLR_GREEN, 20, 12, 80, 15, -1, 15, -1, DT_PHYS, "", 13, 150, 1, PMF_STUPID + }, + [PM_GIANT] = + { + "giant", "giants", 'H', DBCLR_BROWN, 20, 21, 80, 15, -1, 25, -1, DT_PHYS, "", 20, 500, 1, PMF_STUPID + }, + [PM_GIANT_JARL] = + { + "giant jarl", "giant jarls", 'H', DBCLR_L_GREY, 80, 25, 160, 20, -1, 30, -1, DT_PHYS, "", 22, 1000, 1, 0 + }, + [PM_WIZARD] = + { + /* Uses black magic against you; see bmagic.c for details. */ + "wizard", "wizards", 'w', DBCLR_BLUE, 80, 12, 40, 10, 20, 10, 10, DT_ELEC, "casts", 15, 200, 1, PMF_SMART | PMF_MAGICIAN + }, + [PM_ARCHMAGE] = + { + /* Uses black magic against you; see bmagic.c for details. */ + "archmage", "archmagi", 'w', DBCLR_L_BLUE, 80, 24, 80, 15, 30, 15, 15, DT_ELEC, "casts", 15, 1500, 1, PMF_SMART | PMF_MAGICIAN | PMF_RESIST_ELEC + }, + [PM_ZOMBIE] = + { + "zombie", "zombies", 'z', DBCLR_L_GREY, 25, 3, 30, 2, -1, 20, -1, DT_PHYS, "", 1, 7, 0, PMF_STUPID | PMF_UNDEAD | PMF_RESIST_COLD | PMF_RESIST_POIS | PMF_RESIST_NECR + }, + [PM_WRAITH] = + { + "wraith", "wraiths", 'W', DBCLR_WHITE, 25, 12, 40, 25, -1, 5, -1, DT_PHYS, "", 5, 100, 0, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_RESIST_POIS | PMF_RESIST_NECR + }, + [PM_LICH] = + { + /* Uses black magic against you; see bmagic.c for details. */ + "lich", "liches", 'L', DBCLR_L_GREY, 70, 15, 70, 15, 25, 15, 15, DT_NECRO, "casts", 15, 250, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_MAGICIAN | PMF_RESIST_POIS | PMF_RESIST_NECR + }, + [PM_VAMPIRE] = + { + /* Vampires heal by hitting you. */ + "vampire", "vampires", 'V', DBCLR_RED, 55, 18, 70, 25, -1, 15, -1, DT_PHYS, "", 22, 750, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_RESIST_POIS | PMF_RESIST_NECR + }, + [PM_MASTER_LICH] = + { + /* Master liches use black magic against you, more powerfully + * than lesser practitioners. */ + "master lich", "master liches", 'L', DBCLR_PURPLE, 60, 30, 150, 30, 30, 20, 30, DT_NECRO, "", 30, 3000, 1, PMF_SMART | PMF_UNDEAD | PMF_RESIST_COLD | PMF_MAGICIAN | PMF_RESIST_POIS | PMF_RESIST_NECR + }, + [PM_DEMON] = + { + /* Demons summon more demons if you don't kill them + * quickly. */ + "demon", "demons", '&', DBCLR_RED, 60, 18, 40, 25, -1, 20, -1, DT_PHYS, "", 15, 500, 1, PMF_SMART | PMF_DEMONIC | PMF_RESIST_FIRE + }, + [PM_DEFILER] = + { + /* Defilers use black magic against you. */ + "defiler", "defilers", '&', DBCLR_L_GREEN, 65, 27, 120, 30, 30, 20, 30, DT_FIRE, "", 25, 2000, 1, PMF_SMART | PMF_DEMONIC | PMF_RESIST_FIRE | PMF_MAGICIAN | PMF_RESIST_POIS + }, + [PM_CENTAUR] = + { + "centaur", "centaurs", 'C', DBCLR_BROWN, 30, 9, 40, 15, -1, 10, -1, DT_PHYS, "", 10, 50, 2, 0 + }, + [PM_ICE_MONSTER] = + { + /* Fires ice blasts. */ + "ice monster", "ice monsters", 'I', DBCLR_WHITE, 50, 6, 40, 10, 20, 15, 15, DT_COLD, "launches a blast of", 10, 35, 0, PMF_RESIST_COLD | PMF_ARCHER + }, + [PM_DRAGON] = + { + /* Breathes fire. */ + "dragon", "dragons", 'D', DBCLR_RED, 50, 15, 80, 20, 20, 20, 20, DT_FIRE, "breathes", 18, 300, 1, PMF_RESIST_FIRE | PMF_ARCHER + }, }; /* permons.c */ diff --git a/pmon2.c b/pmon2.c index f265f82..da7fdc0 100644 --- a/pmon2.c +++ b/pmon2.c @@ -25,40 +25,55 @@ */ #define PMON2_C -#include "dunbash.h" +#include "cavechop.h" #include "monsters.h" -int pmon_resists_fire(int pm) +bool pmon_resists_fire(int pm) { return !!(permons[pm].flags & PMF_RESIST_FIRE); } -int pmon_resists_cold(int pm) +bool pmon_resists_cold(int pm) { return !!(permons[pm].flags & PMF_RESIST_COLD); } -int pmon_is_undead(int pm) +bool pmon_resists_poison(int pm) +{ + return !!(permons[pm].flags & PMF_RESIST_POIS); +} + +bool pmon_resists_necro(int pm) +{ + return !!(permons[pm].flags & PMF_RESIST_NECR); +} + +bool pmon_resists_elec(int pm) +{ + return !!(permons[pm].flags & PMF_RESIST_ELEC); +} + +bool pmon_is_undead(int pm) { return !!(permons[pm].flags & PMF_UNDEAD); } -int pmon_is_stupid(int pm) +bool pmon_is_stupid(int pm) { return !!(permons[pm].flags & PMF_STUPID); } -int pmon_is_smart(int pm) +bool pmon_is_smart(int pm) { return !!(permons[pm].flags & PMF_SMART); } -int pmon_is_magician(int pm) +bool pmon_is_magician(int pm) { return !!(permons[pm].flags & PMF_MAGICIAN); } -int pmon_is_archer(int pm) +bool pmon_is_archer(int pm) { return !!(permons[pm].flags & PMF_ARCHER); } diff --git a/rng.c b/rng.c index 303615f..401b8f1 100644 --- a/rng.c +++ b/rng.c @@ -25,50 +25,49 @@ */ -#include "dunbash.h" +#include "cavechop.h" #include #include +#include -/* FIX mpr v1.1 2005.02.06: Changed type of RNG stuff to "unsigned int" to - * prevent malformed behaviour on x86-64 (where long int is 64 bits). */ -unsigned int rng_state[5]; -unsigned int saved_state[5]; +uint32_t rng_state[5]; +uint32_t saved_state[5]; -unsigned int rng(void) +uint32_t rng(void) { - unsigned int tmp; - tmp = rng_state[0] ^ (rng_state[0] >> 7); - rng_state[0] = rng_state[1]; - rng_state[1] = rng_state[2]; - rng_state[2] = rng_state[3]; - rng_state[3] = rng_state[4]; - rng_state[4] = (rng_state[4] ^ (rng_state[4] << 6)) ^ (tmp ^ (tmp << 13)); - return (rng_state[2] + rng_state[2] + 1) * rng_state[4]; + uint32_t tmp; + tmp = rng_state[0] ^ (rng_state[0] >> 7); + rng_state[0] = rng_state[1]; + rng_state[1] = rng_state[2]; + rng_state[2] = rng_state[3]; + rng_state[3] = rng_state[4]; + rng_state[4] = (rng_state[4] ^ (rng_state[4] << 6)) ^ (tmp ^ (tmp << 13)); + return (rng_state[2] + rng_state[2] + 1) * rng_state[4]; } void rng_init(void) { - int i; - /* To make manipulating the RNG by monitoring the system time - * harder, we use PID and UID to perturb the return value of time() - * used to initialise the libc RNG. - * - * Yes, I am aware that the libc RNG on many platforms is a steaming - * pile of shite. However, I need *something* with which to populate - * my RNG's state array. - */ - srand(time(NULL) ^ getpid() ^ (getuid() << 16)); - rng_state[0] = rand(); - rng_state[1] = rand(); - rng_state[2] = rand(); - rng_state[3] = rand(); - rng_state[4] = rand(); - /* Flush through the first 100 numbers just in case some bastard - * tries to run us with a 16-bit rand(). */ - for (i = 0; i < 100; i++) - { - rng(); - } + int i; + /* To make manipulating the RNG by monitoring the system time + * harder, we use PID and UID to perturb the return value of time() + * used to initialise the libc RNG. + * + * Yes, I am aware that the libc RNG on many platforms is a steaming + * pile of shite. However, I need *something* with which to populate + * my RNG's state array. + */ + srand(time(NULL) ^ getpid() ^ (getuid() << 16)); + rng_state[0] = rand(); + rng_state[1] = rand(); + rng_state[2] = rand(); + rng_state[3] = rand(); + rng_state[4] = rand(); + /* Flush through the first 100 numbers just in case some bastard + * tries to run us with a 16-bit rand(). */ + for (i = 0; i < 100; i++) + { + rng(); + } } /* rng.c */ diff --git a/u.c b/u.c index c6d31ae..f94a084 100644 --- a/u.c +++ b/u.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dunbash.h" +#include "cavechop.h" #include "combat.h" #include #include @@ -111,65 +111,48 @@ int move_player(int dy, int dx) case STAIRS: reloc_player(u.y + dy, u.x + dx); return 1; + case LAVA: + if (u.resistances[DT_FIRE]) + { + reloc_player(u.y + dy, u.x + dx); + return 1; + } + else + { + print_msg("The fierce heat of the molten rock repels you.\n"); + return 0; + } + case WATER: + if (u.ring != -1) + { + if (objects[u.weapon].obj_id == PO_RING_FROST) + { + 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"); + } + } } return 0; } int reloc_player(int y, int x) { - int y2, x2; int oy, ox; oy = u.y; ox = u.x; u.y = y; u.x = x; - newsym(oy, ox); - newsym(u.y, u.x); - if ((roomnums[oy][ox] != roomnums[y][x]) && - (roomnums[oy][ox] != -1)) - { - for (y2 = roombounds[roomnums[oy][ox]][0]; y2 <= roombounds[roomnums[oy][ox]][1]; y2++) - { - for (x2 = roombounds[roomnums[oy][ox]][2]; x2 <= roombounds[roomnums[oy][ox]][3]; x2++) - { - newsym(y2, x2); - } - } - } - if (roomnums[y][x] != -1) - { - for (y2 = roombounds[roomnums[y][x]][0]; y2 <= roombounds[roomnums[y][x]][1]; y2++) - { - for (x2 = roombounds[roomnums[y][x]][2]; x2 <= roombounds[roomnums[y][x]][3]; x2++) - { - if (!(mapflags[y2][x2] & MAPFLAG_EXPLORED)) - { - mapflags[y2][x2] |= MAPFLAG_EXPLORED; - } - newsym(y2, x2); - } - } - } - for (y2 = y - 1; y2 <= y + 1; y2++) - { - if ((y2 < 0) || (y2 >= DUN_HEIGHT)) - { - continue; - } - for (x2 = x - 1; x2 <= x + 1; x2++) - { - if ((x2 < 0) || (x2 >= DUN_WIDTH)) - { - continue; - } - if (!(mapflags[y2][x2] & MAPFLAG_EXPLORED)) - { - mapflags[y2][x2] |= MAPFLAG_EXPLORED; - } - newsym(y2, x2); - } - } + + touch_one_screen(oy, ox); + explore_around(u.y, u.x); map_updated = 1; status_updated = 1; if (mapobject[y][x] != -1) @@ -352,7 +335,7 @@ int do_death(enum death d, const char *what) } if (!wizard_mode) { - fp = fopen("dunbash.log", "a"); + fp = fopen("cavechop.log", "a"); } fprintf(fp, "%s, ", u.name); print_msg("THOU ART SLAIN!\n"); @@ -390,13 +373,12 @@ int do_death(enum death d, const char *what) } if (!wizard_mode) { - fprintf(fp, "You died after %d ticks, with %d XP and %d gold, on dungeon level %d.\n\n", game_tick, u.experience, u.gold, depth); + fprintf(fp, "You died after %d ticks, with %d XP, on dungeon level %d.\n\n", game_tick, u.experience, depth); fflush(fp); fclose(fp); } print_msg("Your game lasted %d ticks.\n", game_tick); print_msg("You killed monsters worth %d experience.\n", u.experience); - print_msg("You found %d pieces of gold.\n", u.gold); return 1; } @@ -413,8 +395,7 @@ void write_char_dump(void) print_msg("Couldn't create dump file. Dump failed.\n"); return; } - fprintf(fp, "%s, level %d adventurer (%d XP)\n", u.name, u.level, u.experience); - fprintf(fp, "%d gold pieces collected.\n", u.gold); + fprintf(fp, "%s, level %d princess (%d XP)\n", u.name, u.level, u.experience); fprintf(fp, "%d of %d hit points.\n", u.hpcur, u.hpmax); fprintf(fp, "Body %d (%d damage).\n", u.body, u.bdam); fprintf(fp, "Agility %d (%d damage).\n", u.agility, u.adam); @@ -435,31 +416,42 @@ void write_char_dump(void) void u_init(void) { char * hasslash = NULL; + int i; u.name[16] = '\0'; do { - print_msg("What is your name, stranger?\n"); - read_input(u.name, 16); - hasslash = strchr(u.name, '/'); - /* Now that we create a named dump file, we must not - * permit the player's name to contain a slash, colon, - * or backslash. */ - if (hasslash) - { - print_msg("No slashes permitted.\n"); - continue; - } - hasslash = strchr(u.name, '\\'); - if (hasslash) - { - print_msg("No backslashes permitted.\n"); - continue; - } - hasslash = strchr(u.name, ':'); - if (hasslash) - { - print_msg("No colons permitted.\n"); - continue; - } + print_msg("What is your name, stranger?\n"); + i = read_input(u.name, 16); + if (i == 0) + { + /* Default name: Matilda - for either the Holy Roman Empress and + * pretender to the English throne, or the Margravine regnant of + * Tuscany. */ + strcpy(u.name, "Matilda"); + } + else + { + hasslash = strchr(u.name, '/'); + /* Now that we create a named dump file, we must not + * permit the player's name to contain a slash, colon, + * or backslash. */ + if (hasslash) + { + print_msg("No slashes permitted.\n"); + continue; + } + hasslash = strchr(u.name, '\\'); + if (hasslash) + { + print_msg("No backslashes permitted.\n"); + continue; + } + hasslash = strchr(u.name, ':'); + if (hasslash) + { + print_msg("No colons permitted.\n"); + continue; + } + } } while (hasslash != NULL); u.body = 10; u.bdam = 0; @@ -477,9 +469,10 @@ void u_init(void) print_msg("Couldn't create dagger!\n"); } u.inventory[1] = create_obj(PO_IRON_RATION, 1, 1, -1, -1); + u.inventory[2] = create_obj(PO_BATTLE_BALLGOWN, 1, 1, -1, -1); u.weapon = u.inventory[0]; u.ring = -1; - u.armour = -1; + u.armour = u.inventory[2]; recalc_defence(); } @@ -546,24 +539,18 @@ void gain_experience(int amount) int teleport_u(void) { - int room_try; int cell_try; - int room; int y, x; - for (room_try = 0; room_try < MAX_ROOMS * 4; room_try++) + for (cell_try = 0; cell_try < 200; cell_try++) { - room = zero_die(MAX_ROOMS); - for (cell_try = 0; cell_try < 200; cell_try++) - { - y = exclusive_flat(roombounds[room][0], roombounds[room][1]); - x = exclusive_flat(roombounds[room][2], roombounds[room][3]); - if ((mapmonster[y][x] == -1) && (terrain[y][x] == FLOOR) && ((y != u.y) || (x != u.x))) - { - print_msg("You are whisked away!\n"); - reloc_player(y, x); - return 0; - } - } + y = exclusive_flat(0, DUN_HEIGHT - 1); + x = exclusive_flat(0, DUN_WIDTH - 1); + if ((mapmonster[y][x] == -1) && (terrain[y][x] == FLOOR) && ((y != u.y) || (x != u.x))) + { + print_msg("You are whisked away!\n"); + reloc_player(y, x); + return 0; + } } print_msg("You feel briefly dislocated.\n"); return -1; @@ -573,9 +560,9 @@ void update_player(void) { if (!(game_tick % 5) && (u.food >= 0) && (u.hpcur < u.hpmax)) { - /* Heal player for one hit point; do not allow HP gain, - * and don't say anything. */ - heal_u(1, 0, 0); + /* Heal player for one hit point; do not allow HP gain, + * and don't say anything. */ + heal_u(1, 0, 0); } else if (!(game_tick % 60) && (u.hpcur < u.hpmax * 3 / 4)) { @@ -595,7 +582,6 @@ void update_player(void) * and don't say anything apart from the regen ring message. */ print_msg("Your ring pulses soothingly.\n"); heal_u(one_die(3), 0, 0); - permobjs[PO_RING_REGEN].known = 1; } if (u.food >= -1950) { -- 2.11.0