tims@zeus.UUCP (Tim Stoehr) (11/26/86)
#!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # shar: Shell Archiver # Run the following text with /bin/sh to create: # object.c # object.h # pack.c # play.c # use.c echo shar: extracting object.c cat - << \SHAR_EOF > object.c /* * object.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "monster.h" #include "room.h" object level_objects; unsigned short dungeon[DROWS][DCOLS]; short foods = 0; short party_counter; object *free_list = (object *) 0; char *fruit = "slime-mold "; fighter rogue = { 0, 0, /* armor, weapon */ 0, 0, /* rings */ INIT_HP, /* Hp current */ INIT_HP, /* Hp max */ 16, 16, /* Str */ {0}, /* pack */ 0, /* gold */ 1, 0, /* exp, exp_points */ 0, 0, /* row, col */ '@', /* char */ 1250 /* moves */ }; struct identify id_potions[POTIONS] = { {100, "blue \0 ", "of increase strength ", 0}, {250, "red \0 ", "of restore strength ", 0}, {100, "green \0 ", "of healing ", 0}, {200, "grey \0 ", "of extra healing ", 0}, {10, "brown \0 ", "of poison ", 0}, {300, "clear \0 ", "of raise level ", 0}, {10, "pink \0 ", "of blindness ", 0}, {25, "white \0 ", "of hallucination ", 0}, {100, "purple \0 ", "of detect monster ", 0}, {100, "black \0 ", "of detect things ", 0}, {10, "yellow \0 ", "of confusion ", 0}, {80, "plaid \0 ", "of levitation ", 0}, {150, "burgundy \0 ", "of haste self ", 0}, {145, "beige \0 ", "of see invisible ", 0} }; struct identify id_scrolls[SCROLLS] = { {505, " ", "of protect armor ", 0}, {200, " ", "of hold monster ", 0}, {235, " ", "of enchant weapon ", 0}, {235, " ", "of enchant armor ", 0}, {175, " ", "of identify ", 0}, {190, " ", "of teleportation ", 0}, {25, " ", "of sleep ", 0}, {610, " ", "of scare monster ", 0}, {210, " ", "of remove curse ", 0}, {100, " ", "of create monster ",0}, {25, " ", "of aggravate monster ",0}, {180, " ", "of magic mapping ",0} }; struct identify id_weapons[WEAPONS] = { {150, "short bow ", "", 0}, {8, "darts ", "", 0}, {15, "arrows ", "", 0}, {27, "daggers ", "", 0}, {35, "shurikens ", "", 0}, {360, "mace ", "", 0}, {470, "long sword ", "", 0}, {580, "two-handed sword ", "", 0} }; struct identify id_armors[ARMORS] = { {300, "leather armor ", "", (UNIDENTIFIED)}, {300, "ring mail ", "", (UNIDENTIFIED)}, {400, "scale mail ", "", (UNIDENTIFIED)}, {500, "chain mail ", "", (UNIDENTIFIED)}, {600, "banded mail ", "", (UNIDENTIFIED)}, {600, "splint mail ", "", (UNIDENTIFIED)}, {700, "plate mail ", "", (UNIDENTIFIED)} }; struct identify id_wands[WANDS] = { {25, " ", "of teleport away ",0}, {50, " ", "of slow monster ", 0}, {45, " ", "of confuse monster ",0}, {8, " ", "of invisibility ",0}, {55, " ", "of polymorph ",0}, {2, " ", "of haste monster ",0}, {25, " ", "of sleep ",0}, {20, " ", "of magic missile ",0}, {20, " ", "of cancellation ",0}, {0, " ", "of do nothing ",0} }; struct identify id_rings[RINGS] = { {250, " ", "of stealth ",0}, {100, " ", "of teleportation ", 0}, {255, " ", "of regeneration ",0}, {295, " ", "of slow digestion ",0}, {200, " ", "of add strength ",0}, {250, " ", "of sustain strength ",0}, {250, " ", "of dexterity ",0}, {25, " ", "of adornment ",0}, {300, " ", "of see invisible ",0}, {290, " ", "of maintain armor ",0}, {270, " ", "of searching ",0}, }; extern short current_level, max_level; extern short party_room; extern char *error_file; extern boolean is_wood[]; put_objects() { short i, n; object *obj, *get_rand_object(); if (current_level < max_level) { return; } n = coin_toss() ? get_rand(2, 4) : get_rand(3, 5); while (rand_percent(33)) { n++; } if (current_level == party_counter) { make_party(); party_counter = next_party(); } for (i = 0; i < n; i++) { obj = get_rand_object(); put_object_rand_location(obj); } put_gold(); } put_gold() { short i, j; short row,col; unsigned short is_maze, is_room; for (i = 0; i < MAXROOMS; i++) { is_maze = (rooms[i].is_room & R_MAZE); is_room = (rooms[i].is_room & R_ROOM); if (!(is_room || is_maze)) { continue; } if (is_maze || rand_percent(GOLD_PERCENT)) { for (j = 0; j < 50; j++) { row = get_rand(rooms[i].top_row+1, rooms[i].bottom_row-1); col = get_rand(rooms[i].left_col+1, rooms[i].right_col-1); if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) { put_gold_at(row, col, is_maze); break; } } } } } put_gold_at(row, col, is_maze) short row, col; boolean is_maze; { object *obj; object *alloc_object(), *add_to_pack(); obj = alloc_object(); obj->row = row; obj->col = col; obj->what_is = GOLD; obj->quantity = get_rand((2 * current_level), (16 * current_level)); if (is_maze) { obj->quantity += obj->quantity / 2; } dungeon[row][col] |= OBJECT; add_to_pack(obj, &level_objects, 0); } put_object_at(obj, row, col) object *obj; { object *add_to_pack(); obj->row = row; obj->col = col; dungeon[row][col] |= OBJECT; add_to_pack(obj, &level_objects, 0); } object * object_at(pack, row, col) register object *pack; short row, col; { object *obj; obj = pack->next_object; while (obj && ((obj->row != row) || (obj->col != col))) { obj = obj->next_object; } return(obj); } object * get_letter_object(ch) { object *obj; obj = rogue.pack.next_object; while (obj && (obj->ichar != ch)) { obj = obj->next_object; } return(obj); } free_stuff(objlist) object *objlist; { object *obj; while (objlist->next_object) { obj = objlist->next_object; objlist->next_object = objlist->next_object->next_object; free_object(obj); } } free_free_list() { object *obj; while (free_list) { obj = free_list; free_list = free_list->next_object; free_object(obj); } } char * name_of(obj) object *obj; { char *retstring; switch(obj->what_is) { case SCROLL: retstring = obj->quantity > 1 ? "scrolls " : "scroll "; break; case POTION: retstring = obj->quantity > 1 ? "potions " : "potion "; break; case FOOD: if (obj->which_kind == RATION) { retstring = "food "; } else { retstring = fruit; } break; case WAND: retstring = is_wood[obj->which_kind] ? "staff " : "wand "; break; case WEAPON: switch(obj->which_kind) { case DART: retstring=obj->quantity > 1 ? "darts " : "dart "; break; case ARROW: retstring=obj->quantity > 1 ? "arrows " : "arrow "; break; case DAGGER: retstring=obj->quantity > 1 ? "daggers " : "dagger "; break; case SHURIKEN: retstring=obj->quantity > 1?"shurikens ":"shuriken "; break; default: retstring = id_weapons[obj->which_kind].title; } break; case ARMOR: retstring = "armor "; break; case RING: retstring = "ring "; break; case AMULET: retstring = "amulet "; break; default: retstring = "unknown "; break; } return(retstring); } object * get_rand_object() { object *obj, *alloc_object(); unsigned short get_rand_what_is(); obj = alloc_object(); if (foods < (current_level / 3)) { obj->what_is = FOOD; foods++; } else { obj->what_is = get_rand_what_is(); } switch(obj->what_is) { case SCROLL: get_rand_scroll(obj); break; case POTION: get_rand_potion(obj); break; case WEAPON: get_rand_weapon(obj, 1); break; case ARMOR: get_rand_armor(obj); break; case WAND: get_rand_wand(obj); break; case FOOD: get_food(obj, 0); break; case RING: get_rand_ring(obj, 1); break; } return(obj); } unsigned short get_rand_what_is() { short percent; unsigned short what_is; percent = get_rand(1, 91); if (percent <= 30) { what_is = SCROLL; } else if (percent <= 60) { what_is = POTION; } else if (percent <= 64) { what_is = WAND; } else if (percent <= 74) { what_is = WEAPON; } else if (percent <= 83) { what_is = ARMOR; } else if (percent <= 88) { what_is = FOOD; } else { what_is = RING; } return(what_is); } get_rand_scroll(obj) object *obj; { short percent; percent = get_rand(0, 85); obj->what_is = SCROLL; if (percent <= 5) { obj->which_kind = PROTECT_ARMOR; } else if (percent <= 11) { obj->which_kind = HOLD_MONSTER; } else if (percent <= 20) { obj->which_kind = CREATE_MONSTER; } else if (percent <= 35) { obj->which_kind = IDENTIFY; } else if (percent <= 43) { obj->which_kind = TELEPORT; } else if (percent <= 50) { obj->which_kind = SLEEP; } else if (percent <= 55) { obj->which_kind = SCARE_MONSTER; } else if (percent <= 64) { obj->which_kind = REMOVE_CURSE; } else if (percent <= 69) { obj->which_kind = ENCHANT_ARMOR; } else if (percent <= 74) { obj->which_kind = ENCHANT_WEAPON; } else if (percent <= 80) { obj->which_kind = AGGRAVATE_MONSTER; } else { obj->which_kind = MAGIC_MAPPING; } } get_rand_potion(obj) object *obj; { short percent; percent = get_rand(1, 118); obj->what_is = POTION; if (percent <= 5) { obj->which_kind = RAISE_LEVEL; } else if (percent <= 15) { obj->which_kind = DETECT_OBJECTS; } else if (percent <= 25) { obj->which_kind = DETECT_MONSTER; } else if (percent <= 35) { obj->which_kind = INCREASE_STRENGTH; } else if (percent <= 45) { obj->which_kind = RESTORE_STRENGTH; } else if (percent <= 55) { obj->which_kind = HEALING; } else if (percent <= 65) { obj->which_kind = EXTRA_HEALING; } else if (percent <= 75) { obj->which_kind = BLINDNESS; } else if (percent <= 85) { obj->which_kind = HALLUCINATION; } else if (percent <= 95) { obj->which_kind = CONFUSION; } else if (percent <= 105) { obj->which_kind = POISON; } else if (percent <= 110) { obj->which_kind = LEVITATION; } else if (percent <= 114) { obj->which_kind = HASTE_SELF; } else { obj->which_kind = SEE_INVISIBLE; } } get_rand_weapon(obj, assign_wk) object *obj; int assign_wk; { short percent; short i; short blessing, increment; obj->what_is = WEAPON; if (assign_wk) { obj->which_kind = get_rand(0, (WEAPONS - 1)); } if ((obj->which_kind == ARROW) || (obj->which_kind == DAGGER) || (obj->which_kind == SHURIKEN) | (obj->which_kind == DART)) { obj->quantity = get_rand(3, 15); obj->quiver = get_rand(0, 126); } else { obj->quantity = 1; } obj->to_hit_enchantment = obj->damage_enchantment = 0; percent = get_rand(1, 96); blessing = get_rand(1, 3); if (percent <= 16) { increment = 1; } else if (percent <= 32) { increment = -1; obj->is_cursed = 1; } if (percent <= 32) { for (i = 0; i < blessing; i++) { if (coin_toss()) { obj->to_hit_enchantment += increment; } else { obj->damage_enchantment += increment; } } } switch(obj->which_kind) { case BOW: case DART: obj->damage = "1d1"; break; case ARROW: obj->damage = "1d2"; break; case DAGGER: obj->damage = "1d3"; break; case SHURIKEN: obj->damage = "1d4"; break; case MACE: obj->damage = "2d3"; break; case LONG_SWORD: obj->damage = "3d4"; break; case TWO_HANDED_SWORD: obj->damage = "4d5"; break; } } get_rand_armor(obj) object *obj; { short percent; short blessing; obj->what_is = ARMOR; obj->which_kind = get_rand(0, (ARMORS - 1)); obj->class = obj->which_kind + 2; if ((obj->which_kind == PLATE) || (obj->which_kind == SPLINT)) { obj->class--; } obj->is_protected = 0; obj->damage_enchantment = 0; percent = get_rand(1, 100); blessing = get_rand(1, 3); if (percent <= 16) { obj->is_cursed = 1; obj->damage_enchantment -= blessing; } else if (percent <= 33) { obj->damage_enchantment += blessing; } } get_rand_wand(obj) object *obj; { obj->what_is = WAND; obj->which_kind = get_rand(0, (WANDS - 1)); if (obj->which_kind == MAGIC_MISSILE) { obj->class = get_rand(6, 12); } else if (obj->which_kind == CANCELLATION) { obj->class = get_rand(5, 9); } else { obj->class = get_rand(3, 6); } } get_food(obj, force_ration) object *obj; boolean force_ration; { obj->what_is = FOOD; if (force_ration || rand_percent(80)) { obj->which_kind = RATION; } else { obj->which_kind = FRUIT; } } put_stairs() { short row, col; get_rand_row_col(&row, &col, (FLOOR | TUNNEL)); dungeon[row][col] |= STAIRS; } get_armor_class(obj) object *obj; { if (obj) { return(obj->class + obj->damage_enchantment); } return(0); } object * alloc_object() { object *obj; char *malloc(); if (free_list) { obj = free_list; free_list = free_list->next_object; } else if (!(obj = (object *) malloc(sizeof(object)))) { free_free_list(); message("cannot allocate object, saving game", 0); save_into_file(error_file); } obj->quantity = 1; obj->ichar = 'L'; obj->picked_up = obj->is_cursed = 0; obj->in_use_flags = NOT_USED; obj->identified = UNIDENTIFIED; obj->damage = "1d1"; return(obj); } free_object(obj) object *obj; { obj->next_object = free_list; free_list = obj; } make_party() { short n; party_room = get_rand_room(); n = rand_percent(99) ? fill_party_room_with_objects(party_room) : 11; if (rand_percent(99)) { fill_party_room_with_monsters(party_room, n); } } show_objects() { object *obj; short mc, rc, row, col; object *monster, *object_at(); obj = level_objects.next_object; while (obj) { row = obj->row; col = obj->col; rc = get_mask_char(obj->what_is); if (dungeon[row][col] & MONSTER) { if (monster = object_at(&level_monsters, row, col)) { monster->trail_char = rc; } } mc = mvinch(row, col); if (((mc < 'A') || (mc > 'Z')) && ((row != rogue.row) || (col != rogue.col))) { mvaddch(row, col, rc); } obj = obj->next_object; } monster = level_monsters.next_object; while (monster) { if (monster->m_flags & IMITATES) { mvaddch(monster->row, monster->col, monster->disguise); } monster = monster->next_monster; } } put_amulet() { object *obj, *alloc_object(); obj = alloc_object(); obj->what_is = AMULET; put_object_rand_location(obj); } put_object_rand_location(obj) object *obj; { short row, col; get_rand_row_col(&row, &col, (FLOOR | TUNNEL)); put_object_at(obj, row, col); } create_object_for_wizard() { short ch, max, wk; object *obj, *alloc_object(), *add_to_pack(); char buf[80]; if (get_pack_count(0) >= MAX_PACK_COUNT) { message("pack full", 0); return; } message("type of object?", 0); while (!index("!?:)]=/,\033", (ch = rgetchar()))) { sound_bell(); } check_message(); if (ch == '\033') { return; } obj = alloc_object(); switch(ch) { case '!': obj->what_is = POTION; max = POTIONS - 1; break; case '?': obj->what_is = SCROLL; max = SCROLLS - 1; break; case ',': obj->what_is = AMULET; break; case ':': get_food(obj, 0); break; case ')': get_rand_weapon(obj, 0); max = WEAPONS - 1; break; case ']': get_rand_armor(obj); max = ARMORS - 1; break; case '/': get_rand_wand(obj); max = WANDS - 1; break; case '=': max = RINGS - 1; obj->what_is = RING; break; } if ((ch != ',') && (ch != ':')) { GIL: if (get_input_line("which kind?", "", buf, "", 0, 1)) { wk = get_number(buf); if ((wk >= 0) && (wk <= max)) { obj->which_kind = (unsigned char) wk; if (obj->what_is == RING) { get_rand_ring(obj, 0); } } else { sound_bell(); goto GIL; } } else { free_object(obj); return; } } get_description(obj, buf); message(buf, 0); add_to_pack(obj, &rogue.pack, 1); } next_party() { int n; n = current_level; while (n % PARTY_TIME) { n++; } return(get_rand((n + 1), (n + PARTY_TIME))); } SHAR_EOF echo shar: extracting object.h cat - << \SHAR_EOF > object.h /* * object.h * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #define boolean char #define NOTHING ((unsigned short) 0) #define OBJECT ((unsigned short) 01) #define MONSTER ((unsigned short) 02) #define STAIRS ((unsigned short) 04) #define HORWALL ((unsigned short) 010) #define VERTWALL ((unsigned short) 020) #define DOOR ((unsigned short) 040) #define FLOOR ((unsigned short) 0100) #define TUNNEL ((unsigned short) 0200) #define TRAP ((unsigned short) 0400) #define HIDDEN ((unsigned short) 01000) #define ARMOR ((unsigned short) 01) #define WEAPON ((unsigned short) 02) #define SCROLL ((unsigned short) 04) #define POTION ((unsigned short) 010) #define GOLD ((unsigned short) 020) #define FOOD ((unsigned short) 040) #define WAND ((unsigned short) 0100) #define RING ((unsigned short) 0200) #define AMULET ((unsigned short) 0400) #define ALL_OBJECTS ((unsigned short) 0777) #define LEATHER 0 #define RINGMAIL 1 #define SCALE 2 #define CHAIN 3 #define BANDED 4 #define SPLINT 5 #define PLATE 6 #define ARMORS 7 #define BOW 0 #define DART 1 #define ARROW 2 #define DAGGER 3 #define SHURIKEN 4 #define MACE 5 #define LONG_SWORD 6 #define TWO_HANDED_SWORD 7 #define WEAPONS 8 #define MAX_PACK_COUNT 24 #define PROTECT_ARMOR 0 #define HOLD_MONSTER 1 #define ENCHANT_WEAPON 2 #define ENCHANT_ARMOR 3 #define IDENTIFY 4 #define TELEPORT 5 #define SLEEP 6 #define SCARE_MONSTER 7 #define REMOVE_CURSE 8 #define CREATE_MONSTER 9 #define AGGRAVATE_MONSTER 10 #define MAGIC_MAPPING 11 #define SCROLLS 12 #define INCREASE_STRENGTH 0 #define RESTORE_STRENGTH 1 #define HEALING 2 #define EXTRA_HEALING 3 #define POISON 4 #define RAISE_LEVEL 5 #define BLINDNESS 6 #define HALLUCINATION 7 #define DETECT_MONSTER 8 #define DETECT_OBJECTS 9 #define CONFUSION 10 #define LEVITATION 11 #define HASTE_SELF 12 #define SEE_INVISIBLE 13 #define POTIONS 14 #define TELEPORT_AWAY 0 #define SLOW_MONSTER 1 #define CONFUSE_MONSTER 2 #define INVISIBILITY 3 #define POLYMORPH 4 #define HASTE_MONSTER 5 #define PUT_TO_SLEEP 6 #define MAGIC_MISSILE 7 #define CANCELLATION 8 #define DO_NOTHING 9 #define WANDS 10 #define STEALTH 0 #define R_TELEPORT 1 #define REGENERATION 2 #define SLOW_DIGEST 3 #define ADD_STRENGTH 4 #define SUSTAIN_STRENGTH 5 #define DEXTERITY 6 #define ADORNMENT 7 #define R_SEE_INVISIBLE 8 #define MAINTAIN_ARMOR 9 #define SEARCHING 10 #define RINGS 11 #define RATION 0 #define FRUIT 1 #define NOT_USED ((unsigned short) 0) #define BEING_WIELDED ((unsigned short) 01) #define BEING_WORN ((unsigned short) 02) #define ON_LEFT_HAND ((unsigned short) 04) #define ON_RIGHT_HAND ((unsigned short) 010) #define ON_EITHER_HAND ((unsigned short) 014) #define BEING_USED ((unsigned short) 017) #define NO_TRAP -1 #define TRAP_DOOR 0 #define BEAR_TRAP 1 #define TELEPORT_TRAP 2 #define POISON_DART_TRAP 3 #define SLEEPING_GAS_TRAP 4 #define RUST_TRAP 5 #define TRAPS 6 #define STEALTH_FACTOR 3 #define R_TELEPORT_PERCENT 8 #define UNIDENTIFIED ((unsigned char) 00) /* MUST BE ZERO! */ #define IDENTIFIED ((unsigned char) 01) #define CALLED ((unsigned char) 02) #define DROWS 24 #define DCOLS 80 #define MAX_TITLE_LENGTH 30 #define MORE "-more-" #define MAXSYLLABLES 40 #define MAX_METAL 14 #define WAND_MATERIALS 30 #define GEMS 14 #define GOLD_PERCENT 46 struct identify { short value; char *title; char *real; unsigned char id_status; }; /* The following #defines provide more meaningful names for some of the struct object fields that are used for monsters. This, since each monster and object (scrolls, potions, etc) are represented by a struct object. */ #define m_damage damage #define hp_to_kill quantity #define m_char ichar #define first_level is_protected #define last_level is_cursed #define m_hit_chance class #define stationary_damage identified #define drop_percent which_kind #define trail_char damage_enchantment #define slowed_toggle quiver #define moves_confused to_hit_enchantment #define nap_length picked_up #define disguise what_is #define next_monster next_object struct object { /* comment is monster meaning */ unsigned long m_flags; /* monster flags */ char *damage; /* damage it does */ short quantity; /* hit points to kill */ char ichar; /* 'A' is for aquatar */ short kill_exp; /* exp for killing it */ boolean is_protected; /* level starts */ boolean is_cursed; /* level ends */ char class; /* chance of hitting you */ short identified; /* 'F' damage, 1,2,3... */ unsigned char which_kind; /* item carry/drop % */ char o_row, o_col, o; /* o is how many times stuck at o_row, o_col */ char row, col; /* current row, col */ char damage_enchantment;/* room char when detect_monster */ char quiver; /* monster slowed toggle */ char trow, tcol; /* target row, col */ char to_hit_enchantment;/* how many moves is confused */ unsigned short what_is; /* imitator's charactor (?!%: */ boolean picked_up; /* sleep from wand of sleep */ unsigned short in_use_flags; struct object *next_object; /* next monster */ }; typedef struct object object; #define INIT_HP 12 struct fighter { object *armor; object *weapon; object *left_ring, *right_ring; short hp_current; short hp_max; char strength_current; char strength_max; object pack; int gold; char exp; long exp_points; short row, col; char fchar; short moves_left; }; typedef struct fighter fighter; struct door { char other_room; char other_row, other_col; char door_row, door_col; }; typedef struct door door; struct room { char bottom_row, right_col, left_col, top_row; door doors[4]; unsigned short is_room; }; typedef struct room room; struct trap { short trap_type; short trap_row, trap_col; }; typedef struct trap trap; extern fighter rogue; extern room rooms[]; extern trap traps[]; extern unsigned short dungeon[DROWS][DCOLS]; extern object level_objects; extern struct identify id_scrolls[]; extern struct identify id_potions[]; extern struct identify id_wands[]; extern struct identify id_rings[]; extern struct identify id_weapons[]; extern struct identify id_armors[]; extern object monster_tab[]; extern object level_monsters; SHAR_EOF echo shar: extracting pack.c cat - << \SHAR_EOF > pack.c /* * pack.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include "curses.h" #include "move.h" #include "object.h" #include "room.h" char *curse_message = "you can't, it appears to be cursed"; object * add_to_pack(obj, pack, condense) object *obj, *pack; { object *op, *check_duplicate(); if (condense) { if (op = check_duplicate(obj, pack)) { free_object(obj); return(op); } else { obj->ichar = next_avail_ichar(); } } if (pack->next_object == 0) { pack->next_object = obj; } else { op = pack->next_object; while (op->next_object) { op = op->next_object; } op->next_object = obj; } obj->next_object = 0; return(obj); } remove_from_pack(obj, pack) object *obj, *pack; { while (pack->next_object != obj) { pack = pack->next_object; } pack->next_object = pack->next_object->next_object; } object * pick_up(row, col, status) short *status; { object *obj, *object_at(), *add_to_pack(); obj = object_at(&level_objects, row, col); *status = 1; if ((obj->what_is == SCROLL) && (obj->which_kind == SCARE_MONSTER) && obj->picked_up) { message("the scroll turns to dust as you pick it up", 0); dungeon[row][col] &= (~OBJECT); vanish(obj, 0, &level_objects); *status = 0; if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) { id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED; } return(0); } if (obj->what_is == GOLD) { rogue.gold += obj->quantity; dungeon[row][col] &= ~(OBJECT); remove_from_pack(obj, &level_objects); print_stats(STAT_GOLD); return(obj); /* obj will be free_object()ed in single_move() */ } if (get_pack_count(obj) >= MAX_PACK_COUNT) { message("pack too full", 1); return(0); } dungeon[row][col] &= ~(OBJECT); remove_from_pack(obj, &level_objects); obj = add_to_pack(obj, &rogue.pack, 1); obj->picked_up = 1; return(obj); } drop() { object *obj, *get_letter_object(), *new; short ch; object *alloc_object(); char description[DCOLS]; if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) { message("there's already something there", 0); return; } if (!rogue.pack.next_object) { message("you have nothing to drop", 0); return; } if ((ch = get_pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->in_use_flags & BEING_WIELDED) { if (obj->is_cursed) { message(curse_message, 0); return; } unwield(rogue.weapon); } else if (obj->in_use_flags & BEING_WORN) { if (obj->is_cursed) { message(curse_message, 0); return; } mv_aquatars(); unwear(rogue.armor); print_stats(STAT_ARMOR); } else if (obj->in_use_flags & ON_EITHER_HAND) { if (obj->is_cursed) { message(curse_message, 0); return; } un_put_on(obj); } obj->row = rogue.row; obj->col = rogue.col; if ((obj->quantity > 1) && (obj->what_is != WEAPON)) { obj->quantity--; new = alloc_object(); *new = *obj; new->quantity = 1; obj = new; } else { obj->ichar = 'L'; remove_from_pack(obj, &rogue.pack); } put_object_at(obj, rogue.row, rogue.col); strcpy(description, "dropped "); get_description(obj, description+8); message(description, 0); register_move(); } object * check_duplicate(obj, pack) object *obj, *pack; { object *op; if (!(obj->what_is & (WEAPON | FOOD | SCROLL | POTION))) { return(0); } if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) { return(0); } op = pack->next_object; while (op) { if ((op->what_is == obj->what_is) && (op->which_kind == obj->which_kind)) { if ((obj->what_is != WEAPON) || ((obj->what_is == WEAPON) && ((obj->which_kind == ARROW) || (obj->which_kind == DAGGER) || (obj->which_kind == DART) || (obj->which_kind == SHURIKEN)) && (obj->quiver == op->quiver))) { op->quantity += obj->quantity; return(op); } } op = op->next_object; } return(0); } next_avail_ichar() { register object *obj; register i; boolean ichars[26]; for (i = 0; i < 26; i++) { ichars[i] = 0; } obj = rogue.pack.next_object; while (obj) { ichars[(obj->ichar - 'a')] = 1; obj = obj->next_object; } for (i = 0; i < 26; i++) { if (!ichars[i]) { return(i + 'a'); } } return('?'); } wait_for_ack(prompt) { if (prompt) { printf("%s ", MORE); fflush(stdout); } while (rgetchar() != ' ') ; } get_pack_letter(prompt, mask) char *prompt; unsigned short mask; { short ch; unsigned short tmask = mask; if (!mask_in_pack(&rogue.pack, mask)) { message("nothing appropriate", 0); return(CANCEL); } for (;;) { message(prompt, 0); for (;;) { ch = rgetchar(); if (!is_pack_letter(&ch, &mask)) { sound_bell(); } else { break; } } if (ch == LIST) { check_message(); inventory(&rogue.pack, mask); } else { break; } mask = tmask; } check_message(); return(ch); } take_off() { char description[DCOLS]; object *obj; if (rogue.armor) { if (rogue.armor->is_cursed) { message(curse_message, 0); } else { mv_aquatars(); obj = rogue.armor; unwear(rogue.armor); strcpy(description, "was wearing "); get_description(obj, description+12); message(description, 0); print_stats(STAT_ARMOR); register_move(); } } else { message("not wearing any", 0); } } wear() { short ch; register object *obj; char description[DCOLS]; if (rogue.armor) { message("your already wearing some", 0); return; } ch = get_pack_letter("wear what?", ARMOR); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != ARMOR) { message("you can't wear that", 0); return; } obj->identified = 1; strcpy(description, "wearing "); get_description(obj, description + 8); message(description, 0); do_wear(obj); print_stats(STAT_ARMOR); register_move(); } unwear(obj) object *obj; { if (obj) { obj->in_use_flags &= (~BEING_WORN); } rogue.armor = (object *) 0; } do_wear(obj) object *obj; { rogue.armor = obj; obj->in_use_flags |= BEING_WORN; obj->identified = 1; } wield() { short ch; register object *obj; char description[DCOLS]; if (rogue.weapon && rogue.weapon->is_cursed) { message(curse_message, 0); return; } ch = get_pack_letter("wield what?", WEAPON); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("No such item.", 0); return; } if (obj->what_is & (ARMOR | RING)) { sprintf(description, "you can't wield %s", ((obj->what_is == ARMOR) ? "armor" : "rings")); message(description, 0); return; } if (obj->in_use_flags & BEING_WIELDED) { message("in use", 0); } else { unwield(rogue.weapon); strcpy(description, "wielding "); get_description(obj, description + 9); message(description, 0); do_wield(obj); register_move(); } } do_wield(obj) object *obj; { rogue.weapon = obj; obj->in_use_flags |= BEING_WIELDED; } unwield(obj) object *obj; { if (obj) { obj->in_use_flags &= (~BEING_WIELDED); } rogue.weapon = (object *) 0; } call_it() { short ch; register object *obj; struct identify *id_table, *get_id_table(); char buf[MAX_TITLE_LENGTH+2]; ch = get_pack_letter("call what?", (SCROLL | POTION | WAND | RING)); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (!(obj->what_is & (SCROLL | POTION | WAND | RING))) { message("surely you already know what that's called", 0); return; } id_table = get_id_table(obj); if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) { id_table[obj->which_kind].id_status = CALLED; strcpy(id_table[obj->which_kind].title, buf); } } get_pack_count(new_obj) object *new_obj; { object *obj; short count = 0; obj = rogue.pack.next_object; while (obj) { if (obj->what_is != WEAPON) { count += obj->quantity; } else if (!new_obj) { count++; } else if ((new_obj->what_is != WEAPON) || ((obj->which_kind != ARROW) && (obj->which_kind != DAGGER) && (obj->which_kind != DART) && (obj->which_kind != SHURIKEN)) || (new_obj->which_kind != obj->which_kind) || (obj->quiver != new_obj->quiver)) { count++; } obj = obj->next_object; } return(count); } mask_in_pack(pack, mask) object *pack; unsigned short mask; { while (pack->next_object) { pack = pack->next_object; if (pack->what_is & mask) { return(1); } } return(0); } is_pack_letter(c, mask) short *c; unsigned short *mask; { if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') || (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) { switch(*c) { case '?': *mask = SCROLL; break; case '!': *mask = POTION; break; case ':': *mask = FOOD; break; case ')': *mask = WEAPON; break; case ']': *mask = ARMOR; break; case '/': *mask = WAND; break; case '=': *mask = RING; break; case ',': *mask = AMULET; break; } *c = LIST; return(1); } return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST)); } has_amulet() { return(mask_in_pack(&rogue.pack, AMULET)); } SHAR_EOF echo shar: extracting play.c cat - << \SHAR_EOF > play.c /* * play.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "move.h" boolean interrupted = 0; char *unknown_command = "unknown command"; extern short party_room, bear_trap; extern char hit_message[]; extern boolean wizard, trap_door; play_level() { short ch; int count; for (;;) { interrupted = 0; if (hit_message[0]) { message(hit_message, 1); hit_message[0] = 0; } if (trap_door) { trap_door = 0; return; } move(rogue.row, rogue.col); refresh(); ch = rgetchar(); check_message(); count = 0; CH: switch(ch) { case '.': rest((count > 0) ? count : 1); break; case 's': search(((count > 0) ? count : 1), 0); break; case 'i': inventory(&rogue.pack, ALL_OBJECTS); break; case 'f': fight(0); break; case 'F': fight(1); break; case 'h': case 'j': case 'k': case 'l': case 'y': case 'u': case 'n': case 'b': single_move_rogue(ch, 1); break; case 'H': case 'J': case 'K': case 'L': case 'B': case 'Y': case 'U': case 'N': case '\010': case '\012': case '\013': case '\014': case '\031': case '\025': case '\016': case '\002': multiple_move_rogue(ch); break; case 'e': eat(); break; case 'q': quaff(); break; case 'r': read_scroll(); break; case 'm': move_onto(); break; case 'd': drop(); break; case 'P': put_on_ring(); break; case 'R': remove_ring(); break; case '\020': remessage(); break; case '\027': wizardize(); break; case '>': if (check_down()) { return; } break; case '<': if (check_up()) { return; } break; case ')': case ']': inventory_armor_weapon(ch == ')'); break; case '=': inventory_rings(); break; case '^': identify_trap(); break; case 'I': single_inventory(0); break; case 'T': take_off(); break; case 'W': wear(); break; case 'w': wield(); break; case 'c': call_it(); break; case 'z': zapp(); break; case 't': throw(); break; case '!': shell(); break; case 'v': message("rogue-clone: Version II. (Tim Stoehr was here), tektronix!zeus!tims", 0); break; case 'Q': quit(0); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': move(rogue.row, rogue.col); refresh(); do { if (count < 100) { count = (10 * count) + (ch - '0'); } ch = rgetchar(); } while ((ch >= '0') && (ch <= '9')); if (ch != CANCEL) { goto CH; } break; case ' ': break; case '\011': if (wizard) { inventory(&level_objects, ALL_OBJECTS); } else { message(unknown_command, 0); } break; case '\023': if (wizard) { draw_magic_map(); } else { message(unknown_command, 0); } break; case '\024': if (wizard) { show_traps(); } else { message(unknown_command, 0); } break; case '\017': if (wizard) { show_objects(); } else { message(unknown_command, 0); } break; case '\001': show_average_hp(); break; case '\003': if (wizard) { create_object_for_wizard(); } else { message(unknown_command, 0); } break; case '\015': if (wizard) { show_monsters(); } else { message(unknown_command, 0); } break; case 'S': save_game(); break; default: message(unknown_command, 0); break; } } } SHAR_EOF echo shar: extracting use.c cat - << \SHAR_EOF > use.c /* * use.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "move.h" #include "monster.h" #include "room.h" short halluc = 0; short blind = 0; short confused = 0; short levitate = 0; short haste_self = 0; boolean see_invisible = 0; short extra_hp = 0; boolean detect_monster = 0; char *strange_feeling = "you have a strange feeling for a moment, then it passes"; extern short bear_trap; extern char hunger_str[]; extern short current_room; extern long level_points[]; extern boolean being_held; extern char *fruit, *you_can_move_again; extern boolean sustain_strength; quaff() { short ch; char buf[80]; object *obj, *get_letter_object(); ch = get_pack_letter("quaff what?", POTION); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != POTION) { message("you can't drink that", 0); return; } switch(obj->which_kind) { case INCREASE_STRENGTH: message("you feel stronger now, what bulging muscles!", 0); rogue.strength_current++; if (rogue.strength_current > rogue.strength_max) { rogue.strength_max = rogue.strength_current; } break; case RESTORE_STRENGTH: rogue.strength_current = rogue.strength_max; message("this tastes great, you feel warm all over", 0); break; case HEALING: message("you begin to feel better", 0); potion_heal(0); break; case EXTRA_HEALING: message("you begin to feel much better", 0); potion_heal(1); break; case POISON: if (!sustain_strength) { rogue.strength_current -= get_rand(1, 3); if (rogue.strength_current < 1) { rogue.strength_current = 1; } } message("you feel very sick now", 0); if (halluc) { unhallucinate(); } break; case RAISE_LEVEL: rogue.exp_points = level_points[rogue.exp - 1]; add_exp(1, 1); break; case BLINDNESS: go_blind(); break; case HALLUCINATION: message("oh wow, everything seems so cosmic", 0); halluc += get_rand(500, 800); break; case DETECT_MONSTER: show_monsters(); if (!(level_monsters.next_monster)) { message(strange_feeling, 0); } break; case DETECT_OBJECTS: if (level_objects.next_object) { if (!blind) { show_objects(); } } else { message(strange_feeling, 0); } break; case CONFUSION: message((halluc ? "what a trippy feeling" : "you feel confused"), 0); confuse(); break; case LEVITATION: message("you start to float in the air", 0); levitate += get_rand(15, 30); being_held = bear_trap = 0; break; case HASTE_SELF: message("you feel yourself moving much faster", 0); haste_self += get_rand(11, 21); if (!(haste_self % 2)) { haste_self++; } break; case SEE_INVISIBLE: sprintf(buf, "hmm, this potion tastes like %sjuice", fruit); message(buf, 0); if (blind) { unblind(); } see_invisible = 1; relight(); break; } print_stats((STAT_STRENGTH | STAT_HP)); if (id_potions[obj->which_kind].id_status != CALLED) { id_potions[obj->which_kind].id_status = IDENTIFIED; } vanish(obj, 1, &rogue.pack); } read_scroll() { short ch; object *obj, *get_letter_object(); char msg[DCOLS]; char *get_ench_color(), *name_of(); ch = get_pack_letter("read what?", SCROLL); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != SCROLL) { message("you can't read that", 0); return; } switch(obj->which_kind) { case SCARE_MONSTER: message("you hear a maniacal laughter in the distance", 0); break; case HOLD_MONSTER: hold_monster(); break; case ENCHANT_WEAPON: if (rogue.weapon) { if (rogue.weapon->what_is == WEAPON) { sprintf(msg, "your %sglow%s %sfor a moment", name_of(rogue.weapon), ((rogue.weapon->quantity <= 1) ? "s" : ""), get_ench_color()); message(msg, 0); if (coin_toss()) { rogue.weapon->to_hit_enchantment++; } else { rogue.weapon->damage_enchantment++; } } rogue.weapon->is_cursed = 0; } else { message("your hands tingle", 0); } break; case ENCHANT_ARMOR: if (rogue.armor) { sprintf(msg, "your armor glows %sfor a moment", get_ench_color()); message(msg, 0); rogue.armor->damage_enchantment++; rogue.armor->is_cursed = 0; print_stats(STAT_ARMOR); } else { message("your skin crawls", 0); } break; case IDENTIFY: message("this is a scroll of identify", 0); obj->identified = 1; id_scrolls[obj->which_kind].id_status = IDENTIFIED; identify(); break; case TELEPORT: teleport(); break; case SLEEP: message("you fall asleep", 0); take_a_nap(); break; case PROTECT_ARMOR: if (rogue.armor) { message( "your armor is covered by a shimmering gold shield",0); rogue.armor->is_protected = 1; rogue.armor->is_cursed = 0; } else { message("your acne seems to have disappeared", 0); } break; case REMOVE_CURSE: message((!halluc) ? "you feel as though someone is watching over you" : "you feel in touch with the universal oneness", 0); uncurse_all(); break; case CREATE_MONSTER: create_monster(); break; case AGGRAVATE_MONSTER: aggravate(); break; case MAGIC_MAPPING: message("this scroll seems to have a map on it", 0); draw_magic_map(); break; } if (id_scrolls[obj->which_kind].id_status != CALLED) { id_scrolls[obj->which_kind].id_status = IDENTIFIED; } vanish(obj, (obj->which_kind != SLEEP), &rogue.pack); } /* vanish() does NOT handle a quiver of weapons with more than one arrow (or whatever) in the quiver. It will only decrement the count. */ vanish(obj, rm, pack) object *obj; short rm; object *pack; { if (obj->quantity > 1) { obj->quantity--; } else { if (obj->in_use_flags & BEING_WIELDED) { unwield(obj); } else if (obj->in_use_flags & BEING_WORN) { unwear(obj); } else if (obj->in_use_flags & ON_EITHER_HAND) { un_put_on(obj); } remove_from_pack(obj, pack); free_object(obj); } if (rm) { register_move(); } } potion_heal(extra) { float ratio; short add; rogue.hp_current += rogue.exp; ratio = ((float)rogue.hp_current) / rogue.hp_max; if (ratio >= 1.00) { rogue.hp_max += (extra ? 2 : 1); extra_hp += (extra ? 2 : 1); rogue.hp_current = rogue.hp_max; } else if (ratio >= 0.90) { rogue.hp_max += (extra ? 1 : 0); extra_hp += (extra ? 1 : 0); rogue.hp_current = rogue.hp_max; } else { if (ratio < 0.33) { ratio = 0.33; } if (extra) { ratio += ratio; } add = (short)(ratio * ((float)rogue.hp_max - rogue.hp_current)); rogue.hp_current += add; if (rogue.hp_current > rogue.hp_max) { rogue.hp_current = rogue.hp_max; } } if (blind) { unblind(); } if (confused && extra) { unconfuse(); } else if (confused) { confused = (confused / 2) + 1; } if (halluc && extra) { unhallucinate(); } else if (halluc) { halluc = (halluc / 2) + 1; } } identify() { short ch; object *obj, *get_letter_object(); struct identify *id_table, *get_id_table(); char description[DCOLS]; AGAIN: ch = get_pack_letter("what would you like to identify?", ALL_OBJECTS); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item, try again", 0); message("", 0); check_message(); goto AGAIN; } obj->identified = 1; if (obj->what_is & (SCROLL | POTION | WEAPON | ARMOR | WAND | RING)) { id_table = get_id_table(obj); id_table[obj->which_kind].id_status = IDENTIFIED; } get_description(obj, description); message(description, 0); } eat() { short ch; short moves; object *obj, *get_letter_object(); char buf[70]; ch = get_pack_letter("eat what?", FOOD); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != FOOD) { message("you can't eat that", 0); return; } if ((obj->which_kind == FRUIT) || rand_percent(60)) { moves = get_rand(900, 1100); if (obj->which_kind == RATION) { message("yum, that tasted good", 0); } else { sprintf(buf, "my, that was a yummy %s", fruit); message(buf, 0); } } else { moves = get_rand(700, 900); message("yuk, that food tasted awful", 0); add_exp(2, 1); } rogue.moves_left /= 3; rogue.moves_left += moves; hunger_str[0] = 0; print_stats(STAT_HUNGER); vanish(obj, 1, &rogue.pack); } hold_monster() { short i, j; short mcount = 0; object *monster, *object_at(); short row, col; for (i = -2; i <= 2; i++) { for (j = -2; j <= 2; j++) { row = rogue.row + i; col = rogue.col + j; if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col > (DCOLS-1))) { continue; } if (dungeon[row][col] & MONSTER) { monster = object_at(&level_monsters, row, col); monster->m_flags |= ASLEEP; monster->m_flags &= (~WAKENS); mcount++; } } } if (mcount == 0) { message("you feel a strange sense of loss", 0); } else if (mcount == 1) { message("the monster freezes", 0); } else { message("the monsters around you freeze", 0); } } teleport() { mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col)); if (current_room >= 0) { darken_room(current_room); } put_player(get_room_number(rogue.row, rogue.col)); being_held = bear_trap = 0; } hallucinate() { object *obj, *monster; short ch; if (blind) return; obj = level_objects.next_object; while (obj) { ch = mvinch(obj->row, obj->col); if (((ch < 'A') || (ch > 'Z')) && ((obj->row != rogue.row) || (obj->col != rogue.col))) if ((ch != ' ')&&(ch != '.')&&(ch != '#')&&(ch != '+')) { addch(get_rand_obj_char()); } obj = obj->next_object; } monster = level_monsters.next_monster; while (monster) { ch = mvinch(monster->row, monster->col); if ((ch >= 'A') && (ch <= 'Z')) { addch(get_rand('A', 'Z')); } monster = monster->next_monster; } } unhallucinate() { halluc = 0; relight(); message("everything looks SO boring now", 1); } unblind() { blind = 0; message("the veil of darkness lifts", 1); relight(); if (halluc) { hallucinate(); } if (detect_monster) { show_monsters(); } } relight() { if (current_room == PASSAGE) { light_passage(rogue.row, rogue.col); } else { light_up_room(); } mvaddch(rogue.row, rogue.col, rogue.fchar); } take_a_nap() { short i; i = get_rand(2, 5); sleep(1); while (i--) { move_monsters(); } sleep(1); message(you_can_move_again, 0); } go_blind() { short i, j; if (!blind) { message("a cloak of darkness falls around you", 0); } blind += get_rand(500, 800); if (detect_monster) { object *monster; monster = level_monsters.next_monster; while (monster) { mvaddch(monster->row, monster->col, monster->trail_char); monster = monster->next_monster; } } if (current_room >= 0) { for (i = rooms[current_room].top_row + 1; i < rooms[current_room].bottom_row; i++) { for (j = rooms[current_room].left_col + 1; j < rooms[current_room].right_col; j++) { mvaddch(i, j, ' '); } } } mvaddch(rogue.row, rogue.col, rogue.fchar); } char *get_ench_color() { if (halluc) { return(id_potions[get_rand(0, POTIONS-1)].title); } return("blue "); } confuse() { confused += get_rand(12, 22); } unconfuse() { char msg[80]; confused = 0; sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused")); message(msg, 1); } uncurse_all() { object *obj; obj = rogue.pack.next_object; while (obj) { obj->is_cursed = 0; obj = obj->next_object; } } SHAR_EOF