* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "dunbash.h"
+#include "cavechop.h"
#include "combat.h"
#include "monsters.h"
struct obj *wep;
struct permobj *pwep;
struct obj *ring;
- struct permobj *pring;
int tohit;
int damage;
int healing;
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");
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");
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");
if (unaffected & RESIST_RING)
{
print_msg("Your ring flashes red.\n");
- permobjs[PO_RING_FIRE].known = 1;
}
break;
case DT_COLD:
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;
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)
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;
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 */
/* 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
#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);
*/
#define DISPLAY_C
-#include "dunbash.h"
+#include "cavechop.h"
#include "monsters.h"
#include <curses.h>
#include <stdio.h>
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);
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;
return EXAMINE_MONSTER;
case '#':
return SHOW_TERRAIN;
- case '\\':
- return SHOW_DISCOVERIES;
case '\x12':
return RNG_TEST;
case '4':
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;
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 */
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "dunbash.h"
+#include "cavechop.h"
#include "combat.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
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);
/* 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);
fflush(fp);
fclose(fp);
/* Compress! */
- system("gzip dunbash.sav");
+ system("gzip cavechop.sav");
game_finished = 1;
return;
}
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);
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;
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);
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)
{
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)
{
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)
}
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
{
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;
{
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;
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! */
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "dunbash.h"
+#include "cavechop.h"
#include "monsters.h"
#include <string.h>
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)
{
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 */
void make_new_level(void)
{
- room_reset();
build_level();
populate_level();
inject_player();
{
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)
{
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++)
{
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 */
* 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",
/* 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"
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)
{
}
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);
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. */
}
/* 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;
*/
#define MONSTERS_C
-#include "dunbash.h"
+#include "cavechop.h"
#include "monsters.h"
struct mon monsters[100];
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;
}
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;
}
}
{
if ((permons[pm].power > depth) || (zero_die(100) < permons[pm].rarity))
{
- return 1;
+ return 1;
}
return 0;
}
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)
{
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;
}
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)
}
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;
}
*/
#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",
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;
}
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;
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);
}
/* 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)
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;
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;
}
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;
}
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);
}
}
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);
}
}
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;
}
switch (permobjs[po].poclass)
{
default:
- return 0;
+ return 0;
case POCLASS_POTION:
case POCLASS_SCROLL:
case POCLASS_FOOD:
- return 1;
+ return 1;
}
}
{
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;
/* 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--;
}
}
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)
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;
}
}
*/
#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 */
*/
#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",
* 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 */
*/
#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);
}
*/
-#include "dunbash.h"
+#include "cavechop.h"
#include <time.h>
#include <unistd.h>
+#include <stdint.h>
-/* 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 */
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "dunbash.h"
+#include "cavechop.h"
#include "combat.h"
#include <limits.h>
#include <string.h>
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)
}
if (!wizard_mode)
{
- fp = fopen("dunbash.log", "a");
+ fp = fopen("cavechop.log", "a");
}
fprintf(fp, "%s, ", u.name);
print_msg("THOU ART SLAIN!\n");
}
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;
}
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);
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;
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();
}
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;
{
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))
{
* 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)
{