Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
bcc2abe517
commit
9f62c197cc
44 changed files with 16770 additions and 0 deletions
421
rogue4/pack.c
Normal file
421
rogue4/pack.c
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* Routines to deal with the pack
|
||||
*
|
||||
* @(#)pack.c 4.15 (Berkeley) 4/6/82
|
||||
*
|
||||
* Rogue: Exploring the Dungeons of Doom
|
||||
* Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <curses.h>
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* update_mdest:
|
||||
* Called after picking up an object, before discarding it.
|
||||
* If this was the object of something's desire, that monster will
|
||||
* get mad and run at the hero
|
||||
*/
|
||||
update_mdest(obj)
|
||||
register THING *obj;
|
||||
{
|
||||
register THING *mp;
|
||||
|
||||
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||
if (mp->t_dest == &obj->o_pos)
|
||||
mp->t_dest = &hero;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 gettting
|
||||
* it off the ground.
|
||||
*/
|
||||
add_pack(obj, silent)
|
||||
register THING *obj;
|
||||
bool silent;
|
||||
{
|
||||
register THING *op, *lp = NULL;
|
||||
register bool exact, from_floor;
|
||||
register char floor;
|
||||
int discarded = 0;
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
from_floor = TRUE;
|
||||
if ((obj = find_obj(hero.y, hero.x)) == NULL)
|
||||
return;
|
||||
}
|
||||
else
|
||||
from_floor = FALSE;
|
||||
/*
|
||||
* Link it into the pack. Search the pack for a object of similar type
|
||||
* if there isn't one, stuff it at the beginning, if there is, look for one
|
||||
* that is exactly the same and just increment the count if there is.
|
||||
* it that. Food is always put at the beginning for ease of access, but
|
||||
* is not ordered so that you can't tell good food from bad. First check
|
||||
* to see if there is something in thr same group and if there is then
|
||||
* increment the count.
|
||||
*/
|
||||
/* floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR; */
|
||||
if (proom) floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||
else floor = FLOOR;
|
||||
if (obj->o_group)
|
||||
{
|
||||
for (op = pack; op != NULL; op = next(op))
|
||||
{
|
||||
if (op->o_group == obj->o_group)
|
||||
{
|
||||
/*
|
||||
* Put it in the pack and notify the user
|
||||
*/
|
||||
op->o_count++;
|
||||
if (from_floor)
|
||||
{
|
||||
detach(lvl_obj, obj);
|
||||
mvaddch(hero.y, hero.x, floor);
|
||||
chat(hero.y, hero.x) = floor;
|
||||
}
|
||||
update_mdest(obj);
|
||||
discard(obj);
|
||||
obj = op;
|
||||
discarded = 1;
|
||||
goto picked_up;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check if there is room
|
||||
*/
|
||||
if (inpack == MAXPACK-1)
|
||||
{
|
||||
msg("you can't carry anything else");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Check for and deal with scare monster scrolls
|
||||
*/
|
||||
if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
|
||||
if (obj->o_flags & ISFOUND)
|
||||
{
|
||||
detach(lvl_obj, obj);
|
||||
mvaddch(hero.y, hero.x, floor);
|
||||
chat(hero.y, hero.x) = floor;
|
||||
msg("the scroll turns to dust as you pick it up");
|
||||
return;
|
||||
}
|
||||
else
|
||||
obj->o_flags |= ISFOUND;
|
||||
|
||||
inpack++;
|
||||
if (from_floor)
|
||||
{
|
||||
detach(lvl_obj, obj);
|
||||
mvaddch(hero.y, hero.x, floor);
|
||||
chat(hero.y, hero.x) = floor;
|
||||
}
|
||||
/*
|
||||
* Search for an object of the same type
|
||||
*/
|
||||
exact = FALSE;
|
||||
for (op = pack; op != NULL; op = next(op))
|
||||
if (obj->o_type == op->o_type)
|
||||
break;
|
||||
if (op == NULL)
|
||||
{
|
||||
/*
|
||||
* Put it at the end of the pack since it is a new type
|
||||
*/
|
||||
for (op = pack; op != NULL; op = next(op))
|
||||
{
|
||||
if (op->o_type != FOOD)
|
||||
break;
|
||||
lp = op;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Search for an object which is exactly the same
|
||||
*/
|
||||
while (op->o_type == obj->o_type)
|
||||
{
|
||||
if (op->o_which == obj->o_which)
|
||||
{
|
||||
exact = TRUE;
|
||||
break;
|
||||
}
|
||||
lp = op;
|
||||
if ((op = next(op)) == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (op == NULL)
|
||||
{
|
||||
/*
|
||||
* Didn't find an exact match, just stick it here
|
||||
*/
|
||||
if (pack == NULL)
|
||||
pack = obj;
|
||||
else
|
||||
{
|
||||
lp->l_next = obj;
|
||||
obj->l_prev = lp;
|
||||
obj->l_next = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If we found an exact match. If it is a potion, food, or a
|
||||
* scroll, increase the count, otherwise put it with its clones.
|
||||
*/
|
||||
if (exact && ISMULT(obj->o_type))
|
||||
{
|
||||
op->o_count++;
|
||||
update_mdest(obj);
|
||||
discard(obj);
|
||||
obj = op;
|
||||
discarded = 1;
|
||||
goto picked_up;
|
||||
}
|
||||
if ((obj->l_prev = prev(op)) != NULL)
|
||||
obj->l_prev->l_next = obj;
|
||||
else
|
||||
pack = obj;
|
||||
obj->l_next = op;
|
||||
op->l_prev = obj;
|
||||
}
|
||||
picked_up:
|
||||
/*
|
||||
* If this was the object of something's desire, that monster will
|
||||
* get mad and run at the hero
|
||||
*/
|
||||
if (!discarded)
|
||||
update_mdest(obj);
|
||||
|
||||
if (obj->o_type == AMULET)
|
||||
amulet = TRUE;
|
||||
/*
|
||||
* Notify the user
|
||||
*/
|
||||
if (!silent)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("you now have ");
|
||||
msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* inventory:
|
||||
* List what is in the pack
|
||||
*/
|
||||
inventory(list, type)
|
||||
THING *list;
|
||||
int type;
|
||||
{
|
||||
register char ch;
|
||||
register int n_objs;
|
||||
char inv_temp[MAXSTR];
|
||||
|
||||
n_objs = 0;
|
||||
for (ch = 'a'; list != NULL; ch++, list = next(list))
|
||||
{
|
||||
if (type && type != list->o_type && !(type == CALLABLE &&
|
||||
(list->o_type == SCROLL || list->o_type == POTION ||
|
||||
list->o_type == RING || list->o_type == STICK)))
|
||||
continue;
|
||||
n_objs++;
|
||||
sprintf(inv_temp, "%c) %%s", ch);
|
||||
add_line(inv_temp, inv_name(list, FALSE));
|
||||
}
|
||||
if (n_objs == 0)
|
||||
{
|
||||
if (terse)
|
||||
msg(type == 0 ? "empty handed" :
|
||||
"nothing appropriate");
|
||||
else
|
||||
msg(type == 0 ? "you are empty handed" :
|
||||
"you don't have anything appropriate");
|
||||
return FALSE;
|
||||
}
|
||||
end_line();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pick_up:
|
||||
* Add something to characters pack.
|
||||
*/
|
||||
pick_up(ch)
|
||||
char ch;
|
||||
{
|
||||
register THING *obj, *mp;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case GOLD:
|
||||
if ((obj = find_obj(hero.y, hero.x)) == NULL)
|
||||
return;
|
||||
money(obj->o_goldval);
|
||||
detach(lvl_obj, obj);
|
||||
update_mdest(obj);
|
||||
discard(obj);
|
||||
proom->r_goldval = 0;
|
||||
break;
|
||||
default:
|
||||
#ifdef WIZARD
|
||||
debug("Where did you pick a '%s' up???", unctrol(ch));
|
||||
#endif
|
||||
case ARMOR:
|
||||
case POTION:
|
||||
case FOOD:
|
||||
case WEAPON:
|
||||
case SCROLL:
|
||||
case AMULET:
|
||||
case RING:
|
||||
case STICK:
|
||||
add_pack(NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* picky_inven:
|
||||
* Allow player to inventory a single item
|
||||
*/
|
||||
picky_inven()
|
||||
{
|
||||
register THING *obj;
|
||||
register char ch, mch;
|
||||
|
||||
if (pack == NULL)
|
||||
msg("you aren't carrying anything");
|
||||
else if (next(pack) == NULL)
|
||||
msg("a) %s", inv_name(pack, FALSE));
|
||||
else
|
||||
{
|
||||
msg(terse ? "item: " : "which item do you wish to inventory: ");
|
||||
mpos = 0;
|
||||
if ((mch = readchar()) == ESCAPE)
|
||||
{
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
for (ch = 'a', obj = pack; obj != NULL; obj = next(obj), ch++)
|
||||
if (ch == mch)
|
||||
{
|
||||
msg("%c) %s",ch,inv_name(obj, FALSE));
|
||||
return;
|
||||
}
|
||||
if (!terse)
|
||||
msg("'%s' not in pack", unctrol(mch));
|
||||
msg("range is 'a' to '%c'", --ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_item:
|
||||
* Pick something out of a pack for a purpose
|
||||
*/
|
||||
THING *
|
||||
get_item(purpose, type)
|
||||
char *purpose;
|
||||
int type;
|
||||
{
|
||||
register THING *obj;
|
||||
register char ch, och;
|
||||
|
||||
if (pack == NULL)
|
||||
msg("you aren't carrying anything");
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("which object do you want to ");
|
||||
addmsg(purpose);
|
||||
if (terse)
|
||||
addmsg(" what");
|
||||
msg("? (* for list): ");
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
/*
|
||||
* Give the poor player a chance to abort the command
|
||||
*/
|
||||
if (ch == ESCAPE || ch == CTRL('G'))
|
||||
{
|
||||
after = FALSE;
|
||||
msg("");
|
||||
return NULL;
|
||||
}
|
||||
if (ch == '*')
|
||||
{
|
||||
mpos = 0;
|
||||
if (inventory(pack, type) == 0)
|
||||
{
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
|
||||
if (ch == och)
|
||||
break;
|
||||
if (obj == NULL)
|
||||
{
|
||||
msg("please specify a letter between 'a' and '%c'", och-1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_char:
|
||||
* Return which character would address a pack object
|
||||
*/
|
||||
pack_char(obj)
|
||||
register THING *obj;
|
||||
{
|
||||
register THING *item;
|
||||
register char c;
|
||||
|
||||
c = 'a';
|
||||
for (item = pack; item != NULL; item = next(item))
|
||||
if (item == obj)
|
||||
return c;
|
||||
else
|
||||
c++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
/*
|
||||
* money:
|
||||
* Add or subtract gold from the pack
|
||||
*/
|
||||
money(value)
|
||||
register int value;
|
||||
{
|
||||
register char floor;
|
||||
|
||||
floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||
purse += value;
|
||||
mvaddch(hero.y, hero.x, floor);
|
||||
chat(hero.y, hero.x) = floor;
|
||||
if (value > 0)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("you found ");
|
||||
msg("%d gold pieces", value);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue