Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
8d570c89a5
commit
3741c4867d
61 changed files with 32413 additions and 0 deletions
526
rogue5/pack.c
Normal file
526
rogue5/pack.c
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
* Routines to deal with the pack
|
||||
*
|
||||
* @(#)pack.c 4.40 (Berkeley) 02/05/99
|
||||
*
|
||||
* Rogue: Exploring the Dungeons of Doom
|
||||
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#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.
|
||||
*/
|
||||
|
||||
void
|
||||
add_pack(THING *obj, int silent)
|
||||
{
|
||||
THING *op, *lp;
|
||||
int from_floor;
|
||||
int discarded = 0;
|
||||
|
||||
from_floor = FALSE;
|
||||
if (obj == NULL)
|
||||
{
|
||||
if ((obj = find_obj(hero.y, hero.x)) == NULL)
|
||||
return;
|
||||
from_floor = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_ch());
|
||||
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||
update_mdest(obj);
|
||||
discarded = 1;
|
||||
discard(obj);
|
||||
msg("the scroll turns to dust as you pick it up");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pack == NULL)
|
||||
{
|
||||
pack = obj;
|
||||
obj->o_packch = pack_char();
|
||||
inpack++;
|
||||
}
|
||||
else
|
||||
{
|
||||
lp = NULL;
|
||||
for (op = pack; op != NULL; op = next(op))
|
||||
{
|
||||
if (op->o_type != obj->o_type)
|
||||
lp = op;
|
||||
else
|
||||
{
|
||||
while (op->o_type == obj->o_type && op->o_which != obj->o_which)
|
||||
{
|
||||
lp = op;
|
||||
if (next(op) == NULL)
|
||||
break;
|
||||
else
|
||||
op = next(op);
|
||||
}
|
||||
if (op->o_type == obj->o_type && op->o_which == obj->o_which)
|
||||
{
|
||||
if (ISMULT(op->o_type))
|
||||
{
|
||||
if (!pack_room(from_floor, obj))
|
||||
return;
|
||||
op->o_count++;
|
||||
dump_it:
|
||||
update_mdest(obj);
|
||||
discard(obj);
|
||||
obj = op;
|
||||
discarded = 1;
|
||||
lp = NULL;
|
||||
goto out;
|
||||
}
|
||||
else if (obj->o_group)
|
||||
{
|
||||
lp = op;
|
||||
while (op->o_type == obj->o_type
|
||||
&& op->o_which == obj->o_which
|
||||
&& op->o_group != obj->o_group)
|
||||
{
|
||||
lp = op;
|
||||
if (next(op) == NULL)
|
||||
break;
|
||||
else
|
||||
op = next(op);
|
||||
}
|
||||
if (op->o_type == obj->o_type
|
||||
&& op->o_which == obj->o_which
|
||||
&& op->o_group == obj->o_group)
|
||||
{
|
||||
op->o_count += obj->o_count;
|
||||
inpack--;
|
||||
if (!pack_room(from_floor, obj))
|
||||
return;
|
||||
goto dump_it;
|
||||
}
|
||||
}
|
||||
else
|
||||
lp = op;
|
||||
}
|
||||
out:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lp != NULL)
|
||||
{
|
||||
if (!pack_room(from_floor, obj))
|
||||
return;
|
||||
else
|
||||
{
|
||||
obj->o_packch = pack_char();
|
||||
next(obj) = next(lp);
|
||||
prev(obj) = lp;
|
||||
if (next(lp) != NULL)
|
||||
prev(next(lp)) = obj;
|
||||
next(lp) = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj->o_flags |= ISFOUND;
|
||||
|
||||
/*
|
||||
* 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), obj->o_packch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_room:
|
||||
* See if there's room in the pack. If not, print out an
|
||||
* appropriate message
|
||||
*/
|
||||
int
|
||||
pack_room(int from_floor, THING *obj)
|
||||
{
|
||||
if (++inpack > MAXPACK)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("there's ");
|
||||
addmsg("no room");
|
||||
if (!terse)
|
||||
addmsg(" in your pack");
|
||||
endmsg();
|
||||
if (from_floor)
|
||||
move_msg(obj);
|
||||
inpack = MAXPACK;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (from_floor)
|
||||
{
|
||||
detach(lvl_obj, obj);
|
||||
mvaddch(hero.y, hero.x, floor_ch());
|
||||
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* leave_pack:
|
||||
* take an item out of the pack
|
||||
*/
|
||||
THING *
|
||||
leave_pack(THING *obj, int newobj, int all)
|
||||
{
|
||||
THING *nobj;
|
||||
|
||||
inpack--;
|
||||
nobj = obj;
|
||||
if (obj->o_count > 1 && !all)
|
||||
{
|
||||
last_pick = obj;
|
||||
obj->o_count--;
|
||||
if (obj->o_group)
|
||||
inpack++;
|
||||
if (newobj)
|
||||
{
|
||||
nobj = new_item();
|
||||
*nobj = *obj;
|
||||
next(nobj) = NULL;
|
||||
prev(nobj) = NULL;
|
||||
nobj->o_count = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_pick = NULL;
|
||||
pack_used[obj->o_packch - 'a'] = FALSE;
|
||||
detach(pack, obj);
|
||||
}
|
||||
return nobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_char:
|
||||
* Return the next unused pack character.
|
||||
*/
|
||||
int
|
||||
pack_char(void)
|
||||
{
|
||||
int *bp;
|
||||
|
||||
for (bp = pack_used; *bp; bp++)
|
||||
continue;
|
||||
*bp = TRUE;
|
||||
return ((int)(bp - pack_used) + 'a');
|
||||
}
|
||||
|
||||
/*
|
||||
* inventory:
|
||||
* List what is in the pack. Return TRUE if there is something of
|
||||
* the given type.
|
||||
*/
|
||||
int
|
||||
inventory(const THING *list, int type)
|
||||
{
|
||||
static char inv_temp[MAXSTR];
|
||||
|
||||
n_objs = 0;
|
||||
for (; list != NULL; list = next(list))
|
||||
{
|
||||
if (type && type != list->o_type && !(type == CALLABLE &&
|
||||
list->o_type != FOOD && list->o_type != AMULET) &&
|
||||
!(type == R_OR_S && (list->o_type == RING || list->o_type == STICK)))
|
||||
continue;
|
||||
n_objs++;
|
||||
#ifdef MASTER
|
||||
if (!list->o_packch)
|
||||
strcpy(inv_temp, "%s");
|
||||
else
|
||||
#endif
|
||||
sprintf(inv_temp, "%c) %%s", list->o_packch);
|
||||
msg_esc = TRUE;
|
||||
if (add_line(inv_temp, inv_name(list, FALSE)) == ESCAPE)
|
||||
{
|
||||
msg_esc = FALSE;
|
||||
msg("");
|
||||
return TRUE;
|
||||
}
|
||||
msg_esc = 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.
|
||||
*/
|
||||
|
||||
void
|
||||
pick_up(int ch)
|
||||
{
|
||||
THING *obj;
|
||||
|
||||
if (on(player, ISLEVIT))
|
||||
return;
|
||||
|
||||
obj = find_obj(hero.y, hero.x);
|
||||
if (move_on)
|
||||
move_msg(obj);
|
||||
else
|
||||
switch (ch)
|
||||
{
|
||||
case GOLD:
|
||||
if (obj == NULL)
|
||||
return;
|
||||
money(obj->o_goldval);
|
||||
detach(lvl_obj, obj);
|
||||
update_mdest(obj);
|
||||
discard(obj);
|
||||
proom->r_goldval = 0;
|
||||
break;
|
||||
default:
|
||||
#ifdef MASTER
|
||||
debug("Where did you pick a '%s' up???", unctrl(ch));
|
||||
#endif
|
||||
case ARMOR:
|
||||
case POTION:
|
||||
case FOOD:
|
||||
case WEAPON:
|
||||
case SCROLL:
|
||||
case AMULET:
|
||||
case RING:
|
||||
case STICK:
|
||||
add_pack(NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* move_msg:
|
||||
* Print out the message if you are just moving onto an object
|
||||
*/
|
||||
|
||||
void
|
||||
move_msg(const THING *obj)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("you ");
|
||||
msg("moved onto %s", inv_name(obj, TRUE));
|
||||
}
|
||||
|
||||
/*
|
||||
* picky_inven:
|
||||
* Allow player to inventory a single item
|
||||
*/
|
||||
|
||||
void
|
||||
picky_inven(void)
|
||||
{
|
||||
THING *obj;
|
||||
int 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 (obj = pack; obj != NULL; obj = next(obj))
|
||||
if (mch == obj->o_packch)
|
||||
{
|
||||
msg("%c) %s", mch, inv_name(obj, FALSE));
|
||||
return;
|
||||
}
|
||||
msg("'%s' not in pack", unctrl(mch));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_item:
|
||||
* Pick something out of a pack for a purpose
|
||||
*/
|
||||
THING *
|
||||
get_item(const char *purpose, int type)
|
||||
{
|
||||
THING *obj;
|
||||
int ch;
|
||||
|
||||
if (pack == NULL)
|
||||
msg("you aren't carrying anything");
|
||||
else if (again)
|
||||
if (last_pick)
|
||||
return last_pick;
|
||||
else
|
||||
msg("you ran out");
|
||||
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)
|
||||
{
|
||||
reset_last();
|
||||
after = FALSE;
|
||||
msg("");
|
||||
return NULL;
|
||||
}
|
||||
n_objs = 1; /* normal case: person types one char */
|
||||
if (ch == '*')
|
||||
{
|
||||
mpos = 0;
|
||||
if (inventory(pack, type) == 0)
|
||||
{
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (obj = pack; obj != NULL; obj = next(obj))
|
||||
if (obj->o_packch == ch)
|
||||
break;
|
||||
if (obj == NULL)
|
||||
{
|
||||
msg("'%s' is not a valid item",unctrl(ch));
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
msg("");
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* money:
|
||||
* Add or subtract gold from the pack
|
||||
*/
|
||||
|
||||
void
|
||||
money(int value)
|
||||
{
|
||||
purse += value;
|
||||
mvaddch(hero.y, hero.x, floor_ch());
|
||||
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||
if (value > 0)
|
||||
{
|
||||
if (!terse)
|
||||
addmsg("you found ");
|
||||
msg("%d gold pieces", value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* floor_ch:
|
||||
* Return the appropriate floor character for her room
|
||||
*/
|
||||
int
|
||||
floor_ch(void)
|
||||
{
|
||||
if (proom->r_flags & ISGONE)
|
||||
return PASSAGE;
|
||||
return (show_floor() ? FLOOR : ' ');
|
||||
}
|
||||
|
||||
/*
|
||||
* floor_at:
|
||||
* Return the character at hero's position, taking see_floor
|
||||
* into account
|
||||
*/
|
||||
int
|
||||
floor_at(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = chat(hero.y, hero.x);
|
||||
if (ch == FLOOR)
|
||||
ch = floor_ch();
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* reset_last:
|
||||
* Reset the last command when the current one is aborted
|
||||
*/
|
||||
|
||||
void
|
||||
reset_last(void)
|
||||
{
|
||||
last_comm = l_last_comm;
|
||||
last_dir = l_last_dir;
|
||||
last_pick = l_last_pick;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue