Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
00669593bd
commit
ce4b930551
48 changed files with 17601 additions and 0 deletions
475
srogue/pack.c
Normal file
475
srogue/pack.c
Normal file
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Routines to deal with the pack
|
||||
*
|
||||
* @(#)pack.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* add_pack:
|
||||
* Pick up an object and add it to the pack. If the argument
|
||||
* is non-null use it as the linked_list pointer instead of
|
||||
* getting it off the ground.
|
||||
*/
|
||||
add_pack(item, silent)
|
||||
struct linked_list *item;
|
||||
bool silent;
|
||||
{
|
||||
reg struct linked_list *ip, *lp;
|
||||
reg struct object *obj, *op;
|
||||
bool from_floor;
|
||||
char delchar;
|
||||
|
||||
if (player.t_room == NULL)
|
||||
delchar = PASSAGE;
|
||||
else
|
||||
delchar = FLOOR;
|
||||
if (item == NULL) {
|
||||
from_floor = TRUE;
|
||||
if ((item = find_obj(hero.y, hero.x)) == NULL) {
|
||||
mpos = 0;
|
||||
msg("That object must have been an illusion.");
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Check for scare monster scrolls
|
||||
*/
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type == SCROLL && obj->o_which == S_SCARE) {
|
||||
if (o_on(obj,ISFOUND)) {
|
||||
msg("The scroll turns to dust as you pick it up.");
|
||||
detach(lvl_obj, item);
|
||||
discard(item);
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
from_floor = FALSE;
|
||||
obj = OBJPTR(item);
|
||||
/*
|
||||
* See if this guy can carry any more weight
|
||||
*/
|
||||
if (itemweight(obj) + him->s_pack > him->s_carry) {
|
||||
msg("You can't carry that %s.", obj->o_typname);
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Check if there is room
|
||||
*/
|
||||
if (packvol + obj->o_vol > V_PACK) {
|
||||
msg("That %s won't fit in your pack.", obj->o_typname);
|
||||
return FALSE;
|
||||
}
|
||||
if (from_floor) {
|
||||
detach(lvl_obj, item);
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
}
|
||||
item->l_prev = NULL;
|
||||
item->l_next = NULL;
|
||||
setoflg(obj, ISFOUND);
|
||||
/*
|
||||
* start looking thru pack to find the start of items
|
||||
* with the same type.
|
||||
*/
|
||||
lp = pack;
|
||||
for (ip = pack; ip != NULL; ip = next(ip)) {
|
||||
op = OBJPTR(ip);
|
||||
/*
|
||||
* If we find a matching type then quit.
|
||||
*/
|
||||
if (op->o_type == obj->o_type)
|
||||
break;
|
||||
if (next(ip) != NULL)
|
||||
lp = next(lp); /* update "previous" entry */
|
||||
}
|
||||
/*
|
||||
* If the pack was empty, just stick the item in it.
|
||||
*/
|
||||
if (pack == NULL) {
|
||||
pack = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
/*
|
||||
* If we looked thru the pack, but could not find an
|
||||
* item of the same type, then stick it at the end,
|
||||
* unless it was food, then put it in front.
|
||||
*/
|
||||
else if (ip == NULL) {
|
||||
if (obj->o_type == FOOD) { /* insert food at front */
|
||||
item->l_next = pack;
|
||||
pack->l_prev = item;
|
||||
pack = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
else { /* insert other stuff at back */
|
||||
lp->l_next = item;
|
||||
item->l_prev = lp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Here, we found at least one item of the same type.
|
||||
* Look thru these items to see if there is one of the
|
||||
* same group. If so, increment the count and throw the
|
||||
* new item away. If not, stick it at the end of the
|
||||
* items with the same type. Also keep all similar
|
||||
* objects near each other, like all identify scrolls, etc.
|
||||
*/
|
||||
else {
|
||||
struct linked_list **save;
|
||||
|
||||
while (ip != NULL && op->o_type == obj->o_type) {
|
||||
if (op->o_group == obj->o_group) {
|
||||
if (op->o_flags == obj->o_flags) {
|
||||
op->o_count++;
|
||||
discard(item);
|
||||
item = ip;
|
||||
goto picked_up;
|
||||
}
|
||||
else {
|
||||
goto around;
|
||||
}
|
||||
}
|
||||
if (op->o_which == obj->o_which) {
|
||||
if (obj->o_type == FOOD)
|
||||
ip = next(ip);
|
||||
break;
|
||||
}
|
||||
around:
|
||||
ip = next(ip);
|
||||
if (ip != NULL) {
|
||||
op = OBJPTR(ip);
|
||||
lp = next(lp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If inserting into last of group at end of pack,
|
||||
* just tack on the end.
|
||||
*/
|
||||
if (ip == NULL) {
|
||||
lp->l_next = item;
|
||||
item->l_prev = lp;
|
||||
}
|
||||
/*
|
||||
* Insert into the last of a group of objects
|
||||
* not at the end of the pack.
|
||||
*/
|
||||
else {
|
||||
save = &((ip->l_prev)->l_next);
|
||||
item->l_next = ip;
|
||||
item->l_prev = ip->l_prev;
|
||||
ip->l_prev = item;
|
||||
*save = item;
|
||||
}
|
||||
}
|
||||
picked_up:
|
||||
obj = OBJPTR(item);
|
||||
if (!silent)
|
||||
msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj));
|
||||
if (obj->o_type == AMULET)
|
||||
amulet = TRUE;
|
||||
updpack(); /* new pack weight & volume */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* inventory:
|
||||
* Show what items are in a specific list
|
||||
*/
|
||||
inventory(list, type)
|
||||
struct linked_list *list;
|
||||
int type;
|
||||
{
|
||||
reg struct linked_list *pc;
|
||||
reg struct object *obj;
|
||||
reg char ch;
|
||||
reg int cnt;
|
||||
|
||||
if (list == NULL) { /* empty list */
|
||||
msg(type == 0 ? "Empty handed." : "Nothing appropriate.");
|
||||
return FALSE;
|
||||
}
|
||||
else if (next(list) == NULL) { /* only 1 item in list */
|
||||
obj = OBJPTR(list);
|
||||
msg("a) %s", inv_name(obj, FALSE));
|
||||
return TRUE;
|
||||
}
|
||||
cnt = 0;
|
||||
wclear(hw);
|
||||
for (ch = 'a', pc = list; pc != NULL; pc = next(pc), ch = npch(ch)) {
|
||||
obj = OBJPTR(pc);
|
||||
wprintw(hw,"%c) %s\n\r",ch,inv_name(obj, FALSE));
|
||||
if (++cnt > LINES - 2 && next(pc) != NULL) {
|
||||
dbotline(hw, morestr);
|
||||
cnt = 0;
|
||||
wclear(hw);
|
||||
}
|
||||
}
|
||||
dbotline(hw,spacemsg);
|
||||
restscr(cw);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pick_up:
|
||||
* Add something to characters pack.
|
||||
*/
|
||||
pick_up(ch)
|
||||
char ch;
|
||||
{
|
||||
nochange = FALSE;
|
||||
switch(ch) {
|
||||
case GOLD:
|
||||
money();
|
||||
when ARMOR:
|
||||
case POTION:
|
||||
case FOOD:
|
||||
case WEAPON:
|
||||
case SCROLL:
|
||||
case AMULET:
|
||||
case RING:
|
||||
case STICK:
|
||||
add_pack(NULL, FALSE);
|
||||
otherwise:
|
||||
msg("That item is ethereal !!!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* picky_inven:
|
||||
* Allow player to inventory a single item
|
||||
*/
|
||||
picky_inven()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg char ch, mch;
|
||||
|
||||
if (pack == NULL)
|
||||
msg("You aren't carrying anything.");
|
||||
else if (next(pack) == NULL)
|
||||
msg("a) %s", inv_name(OBJPTR(pack), FALSE));
|
||||
else {
|
||||
msg("Item: ");
|
||||
mpos = 0;
|
||||
if ((mch = readchar()) == ESCAPE) {
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
for (ch='a',item=pack; item != NULL; item=next(item),ch=npch(ch))
|
||||
if (ch == mch) {
|
||||
msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
|
||||
return;
|
||||
}
|
||||
if (ch == 'A')
|
||||
ch = 'z';
|
||||
else
|
||||
ch -= 1;
|
||||
msg("Range is 'a' to '%c'", ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_item:
|
||||
* pick something out of a pack for a purpose
|
||||
*/
|
||||
struct linked_list *
|
||||
get_item(purpose, type)
|
||||
char *purpose;
|
||||
int type;
|
||||
{
|
||||
reg struct linked_list *obj, *pit, *savepit;
|
||||
struct object *pob;
|
||||
int ch, och, anr, cnt;
|
||||
|
||||
if (pack == NULL) {
|
||||
msg("You aren't carrying anything.");
|
||||
return NULL;
|
||||
}
|
||||
if (type != WEAPON && (type != 0 || next(pack) == NULL)) {
|
||||
/*
|
||||
* see if we have any of the type requested
|
||||
*/
|
||||
pit = pack;
|
||||
anr = 0;
|
||||
for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) {
|
||||
pob = OBJPTR(pit);
|
||||
if (type == pob->o_type || type == 0) {
|
||||
++anr;
|
||||
savepit = pit; /* save in case of only 1 */
|
||||
}
|
||||
}
|
||||
if (anr == 0) {
|
||||
msg("Nothing to %s",purpose);
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
else if (anr == 1) { /* only found one of 'em */
|
||||
do {
|
||||
struct object *opb;
|
||||
|
||||
opb = OBJPTR(savepit);
|
||||
msg("%s what (* for the item)?",purpose);
|
||||
och = readchar();
|
||||
if (och == '*') {
|
||||
mpos = 0;
|
||||
msg("%c) %s",pack_char(opb),inv_name(opb,FALSE));
|
||||
continue;
|
||||
}
|
||||
if (och == ESCAPE) {
|
||||
msg("");
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
if (isalpha(och) && och != pack_char(opb)) {
|
||||
mpos = 0;
|
||||
msg("You can't %s that !!", purpose);
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
} while(!isalpha(och));
|
||||
mpos = 0;
|
||||
return savepit; /* return this item */
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
msg("%s what? (* for list): ",purpose);
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
if (ch == ESCAPE) { /* abort if escape hit */
|
||||
after = FALSE;
|
||||
msg(""); /* clear display */
|
||||
return NULL;
|
||||
}
|
||||
if (ch == '*') {
|
||||
wclear(hw);
|
||||
pit = pack; /* point to pack */
|
||||
cnt = 0;
|
||||
for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) {
|
||||
pob = OBJPTR(pit);
|
||||
if (type == 0 || type == pob->o_type) {
|
||||
wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE));
|
||||
if (++cnt > LINES - 2 && next(pit) != NULL) {
|
||||
cnt = 0;
|
||||
dbotline(hw, morestr);
|
||||
wclear(hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
wmove(hw, LINES - 1,0);
|
||||
wprintw(hw,"%s what? ",purpose);
|
||||
draw(hw); /* write screen */
|
||||
anr = FALSE;
|
||||
do {
|
||||
ch = readchar();
|
||||
if (isalpha(ch) || ch == ESCAPE)
|
||||
anr = TRUE;
|
||||
} while(!anr); /* do till we got it right */
|
||||
restscr(cw); /* redraw orig screen */
|
||||
if (ch == ESCAPE) {
|
||||
after = FALSE;
|
||||
msg(""); /* clear top line */
|
||||
return NULL; /* all done if abort */
|
||||
}
|
||||
/* ch has item to get from pack */
|
||||
}
|
||||
for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och))
|
||||
if (ch == och)
|
||||
break;
|
||||
if (obj == NULL) {
|
||||
if (och == 'A')
|
||||
och = 'z';
|
||||
else
|
||||
och -= 1;
|
||||
msg("Please specify a letter between 'a' and '%c'",och);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_char:
|
||||
* Get the character of a particular item in the pack
|
||||
*/
|
||||
char
|
||||
pack_char(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg char c;
|
||||
|
||||
c = 'a';
|
||||
for (item = pack; item != NULL; item = next(item))
|
||||
if (OBJPTR(item) == obj)
|
||||
return c;
|
||||
else
|
||||
c = npch(c);
|
||||
return '%';
|
||||
}
|
||||
|
||||
/*
|
||||
* idenpack:
|
||||
* Identify all the items in the pack
|
||||
*/
|
||||
idenpack()
|
||||
{
|
||||
reg struct linked_list *pc;
|
||||
|
||||
for (pc = pack ; pc != NULL ; pc = next(pc))
|
||||
whatis(pc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* del_pack:
|
||||
* Take something out of the hero's pack
|
||||
*/
|
||||
del_pack(what)
|
||||
struct linked_list *what;
|
||||
{
|
||||
reg struct object *op;
|
||||
|
||||
op = OBJPTR(what);
|
||||
cur_null(op); /* check for current stuff */
|
||||
if (op->o_count > 1) {
|
||||
op->o_count--;
|
||||
}
|
||||
else {
|
||||
detach(pack,what);
|
||||
discard(what);
|
||||
}
|
||||
updpack();
|
||||
}
|
||||
|
||||
/*
|
||||
* cur_null:
|
||||
* This updates cur_weapon etc for dropping things
|
||||
*/
|
||||
cur_null(op)
|
||||
struct object *op;
|
||||
{
|
||||
if (op == cur_weapon)
|
||||
cur_weapon = NULL;
|
||||
else if (op == cur_armor)
|
||||
cur_armor = NULL;
|
||||
else if (op == cur_ring[LEFT])
|
||||
cur_ring[LEFT] = NULL;
|
||||
else if (op == cur_ring[RIGHT])
|
||||
cur_ring[RIGHT] = NULL;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue