There should only be two changes in behavior: arogue7/fight.c, arogue7/fight.c: a to-hit bonus is now correctly applied to characters who are not monks instead of monks who are not empty-handed. urogue/fight.c: fixed an interaction with the "debug" macro that could cause the wrong message to be displayed.
373 lines
7.2 KiB
C
373 lines
7.2 KiB
C
/*
|
|
* Mostly wizard commands. Sometimes used by players.
|
|
*
|
|
* @(#)wizard.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 <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include "rogue.h"
|
|
#include "rogue.ext"
|
|
|
|
/*
|
|
* whatis:
|
|
* What a certain object is
|
|
*/
|
|
void
|
|
whatis(struct linked_list *what)
|
|
{
|
|
reg struct object *obj;
|
|
reg struct linked_list *item;
|
|
reg int wh;
|
|
|
|
if (what == NULL) { /* we need to ask */
|
|
if ((item = get_item("identify", 0)) == NULL)
|
|
return;
|
|
}
|
|
else /* no need to ask */
|
|
item = what;
|
|
obj = OBJPTR(item);
|
|
setoflg(obj, ISKNOW);
|
|
wh = obj->o_which;
|
|
switch (obj->o_type) {
|
|
case SCROLL:
|
|
s_know[wh] = TRUE;
|
|
if (s_guess[wh]) {
|
|
free(s_guess[wh]);
|
|
s_guess[wh] = NULL;
|
|
}
|
|
when POTION:
|
|
p_know[wh] = TRUE;
|
|
if (p_guess[wh]) {
|
|
free(p_guess[wh]);
|
|
p_guess[wh] = NULL;
|
|
}
|
|
when STICK:
|
|
ws_know[wh] = TRUE;
|
|
if (ws_guess[wh]) {
|
|
free(ws_guess[wh]);
|
|
ws_guess[wh] = NULL;
|
|
}
|
|
when RING:
|
|
r_know[wh] = TRUE;
|
|
if (r_guess[wh]) {
|
|
free(r_guess[wh]);
|
|
r_guess[wh] = NULL;
|
|
}
|
|
}
|
|
if (what == NULL)
|
|
msg(inv_name(obj, FALSE));
|
|
}
|
|
|
|
|
|
/*
|
|
* create_obj:
|
|
* Create any object for wizard or scroll (almost)
|
|
*/
|
|
void
|
|
create_obj(bool fscr)
|
|
{
|
|
reg struct linked_list *item;
|
|
reg struct object *obj;
|
|
reg int wh, ch, otype;
|
|
char newitem, newtype, msz, *oname;
|
|
struct magic_info *mf;
|
|
bool nogood = TRUE, inhw = FALSE;
|
|
|
|
if (fscr)
|
|
msg(" ");
|
|
else if (wizard) {
|
|
msg("Create what?%s: ", starlist);
|
|
ch = readchar();
|
|
mpos = 0;
|
|
if (ch == ESCAPE)
|
|
return;
|
|
else if (ch != '*')
|
|
nogood = FALSE;
|
|
}
|
|
if (nogood) {
|
|
inhw = TRUE;
|
|
wclear(hw);
|
|
wprintw(hw,"Item\tKey\n\n");
|
|
for (otype = 0; otype < NUMTHINGS; otype++) {
|
|
if (otype != TYP_AMULET || wizard) {
|
|
mf = &thnginfo[otype];
|
|
wprintw(hw,"%s\t %c\n",things[otype].mi_name,mf->mf_show);
|
|
}
|
|
}
|
|
if (wizard)
|
|
waddstr(hw,"monster\t (A-z)");
|
|
wprintw(hw,"\n\nWhat do you want to create? ");
|
|
draw(hw);
|
|
do {
|
|
ch = readchar();
|
|
if (ch == ESCAPE) {
|
|
after = FALSE;
|
|
restscr(cw);
|
|
return;
|
|
}
|
|
switch (ch) {
|
|
case RING: case STICK: case POTION:
|
|
case SCROLL: case ARMOR: case WEAPON:
|
|
case FOOD: case AMULET:
|
|
nogood = FALSE;
|
|
break;
|
|
default:
|
|
if (isalpha(ch))
|
|
nogood = FALSE;
|
|
}
|
|
} while (nogood);
|
|
}
|
|
if (isalpha(ch)) {
|
|
if (inhw)
|
|
restscr(cw);
|
|
makemons(ch); /* make monster & be done with it */
|
|
return;
|
|
}
|
|
otype = getindex(ch);
|
|
if (otype == -1 || (otype == AMULET && !wizard)) {
|
|
if (inhw)
|
|
restscr(cw);
|
|
mpos = 0;
|
|
msg("You can't create that !!");
|
|
return;
|
|
}
|
|
newitem = ch;
|
|
mf = &thnginfo[otype];
|
|
oname = things[otype].mi_name;
|
|
msz = mf->mf_max;
|
|
nogood = TRUE;
|
|
if (msz == 1) { /* if only one type of item */
|
|
ch = 'a';
|
|
nogood = FALSE;
|
|
}
|
|
else if (!fscr && wizard) {
|
|
if (!inhw) {
|
|
msg("Which %s?%s: ", oname, starlist);
|
|
ch = readchar();
|
|
if (ch == ESCAPE)
|
|
return;
|
|
if (ch != '*')
|
|
nogood = FALSE;
|
|
}
|
|
}
|
|
if (nogood) {
|
|
struct magic_item *wmi;
|
|
int ii;
|
|
|
|
mpos = 0;
|
|
inhw = TRUE;
|
|
switch(newitem) {
|
|
case POTION: wmi = &p_magic[0];
|
|
when SCROLL: wmi = &s_magic[0];
|
|
when RING: wmi = &r_magic[0];
|
|
when STICK: wmi = &ws_magic[0];
|
|
when WEAPON: wmi = &w_magic[0];
|
|
otherwise: wmi = &a_magic[0];
|
|
}
|
|
wclear(hw);
|
|
for (ii = 0 ; ii < msz ; ii++) {
|
|
mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
|
|
waddstr(hw,") ");
|
|
waddstr(hw,wmi->mi_name);
|
|
wmi++;
|
|
}
|
|
sprintf(prbuf,"Which %s? ", oname);
|
|
mvwaddstr(hw,LINES - 1, 0, prbuf);
|
|
draw(hw);
|
|
do {
|
|
ch = readchar();
|
|
if (ch == ESCAPE) {
|
|
restscr(cw);
|
|
msg("");
|
|
return;
|
|
}
|
|
} while (!isalpha(ch));
|
|
}
|
|
if (inhw) /* restore screen if need be */
|
|
restscr(cw);
|
|
|
|
newtype = tolower(ch) - 'a';
|
|
if (newtype < 0 || newtype >= msz) { /* if an illegal value */
|
|
mpos = 0;
|
|
after = FALSE;
|
|
if (inhw)
|
|
restscr(cw);
|
|
msg("There is no such %s", oname);
|
|
return;
|
|
}
|
|
mpos = 0;
|
|
item = new_thing(FALSE, newitem, newtype);
|
|
obj = OBJPTR(item);
|
|
wh = obj->o_type;
|
|
if (wh == WEAPON || wh == ARMOR || wh == RING) {
|
|
if (fscr) /* users get +3 to -3 */
|
|
ch = rnd(7) - 3;
|
|
else { /* wizard gets to choose */
|
|
if (wh == RING)
|
|
init_ring(obj, TRUE);
|
|
else
|
|
ch = getbless();
|
|
}
|
|
if (wh == WEAPON)
|
|
obj->o_hplus = obj->o_dplus = ch;
|
|
else if (wh == ARMOR)
|
|
obj->o_ac = armors[obj->o_which].a_class - ch;
|
|
if (ch < 0)
|
|
setoflg(obj, ISCURSED);
|
|
else
|
|
resoflg(obj, ISCURSED);
|
|
}
|
|
/* Don't let scrolls of aquirement give multiple scrolls of
|
|
* aquirement, or you will be able to scum for ANYTHING. */
|
|
if (!wizard && wh == SCROLL && obj->o_which == S_MAKEIT)
|
|
obj->o_count = 1;
|
|
mpos = 0;
|
|
if (fscr)
|
|
whatis(item); /* identify for aquirement scroll */
|
|
wh = add_pack(item, FALSE);
|
|
if (wh == FALSE) /* won't fit in pack */
|
|
discard(item);
|
|
}
|
|
|
|
|
|
/*
|
|
* getbless:
|
|
* Get a blessing for a wizards object
|
|
*/
|
|
int
|
|
getbless(void)
|
|
{
|
|
int bless;
|
|
|
|
msg("Blessing: ");
|
|
prbuf[0] = '\0';
|
|
bless = get_str(prbuf, cw);
|
|
if (bless == NORM)
|
|
bless = atoi(prbuf);
|
|
else
|
|
bless = 0;
|
|
return bless;
|
|
}
|
|
|
|
/*
|
|
* makemons:
|
|
* Make a monster
|
|
*/
|
|
bool
|
|
makemons(int what)
|
|
{
|
|
reg int x, y, oktomake = FALSE, appear = 1;
|
|
struct coord mp;
|
|
|
|
oktomake = FALSE;
|
|
for (x = hero.x - 1 ; x <= hero.x + 1 ; x++) {
|
|
for (y = hero.y - 1 ; y <= hero.y + 1 ; y++) {
|
|
if (x != hero.x || y != hero.y) {
|
|
if (step_ok(winat(y, x)) && rnd(++appear) == 0) {
|
|
mp.x = x;
|
|
mp.y = y;
|
|
oktomake = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (oktomake) {
|
|
new_monster(midx(what), &mp, FALSE);
|
|
look(FALSE);
|
|
}
|
|
return oktomake;
|
|
}
|
|
|
|
/*
|
|
* telport:
|
|
* Bamf the thing someplace else
|
|
*/
|
|
int
|
|
teleport(struct coord spot, struct thing *th)
|
|
{
|
|
reg int rm, y, x;
|
|
struct coord oldspot;
|
|
struct room *rp;
|
|
bool ishero;
|
|
|
|
ishero = (th == &player);
|
|
oldspot = th->t_pos;
|
|
y = th->t_pos.y;
|
|
x = th->t_pos.x;
|
|
mvwaddch(cw, y, x, th->t_oldch);
|
|
if (!ishero)
|
|
mvwaddch(mw, y, x, ' ');
|
|
rp = roomin(&spot);
|
|
if (spot.y < 0 || !step_ok(winat(spot.y, spot.x))) {
|
|
rp = &rooms[rnd_room()];
|
|
th->t_pos = *rnd_pos(rp);
|
|
}
|
|
else
|
|
th->t_pos = spot;
|
|
rm = rp - &rooms[0];
|
|
th->t_room = rp;
|
|
th->t_oldch = mvwinch(cw, th->t_pos.y, th->t_pos.x) & A_CHARTEXT;
|
|
if (ishero)
|
|
light(&oldspot);
|
|
th->t_nomove = 0;
|
|
if (ishero) {
|
|
light(&hero);
|
|
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
|
/*
|
|
* turn off ISHELD in case teleportation was done
|
|
* while fighting a Fungi or Bone Devil.
|
|
*/
|
|
if (pl_on(ISHELD))
|
|
unhold('F');
|
|
count = 0;
|
|
running = FALSE;
|
|
flushinp(); /* flush typeahead */
|
|
nochange = FALSE;
|
|
}
|
|
else
|
|
mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
|
|
return rm;
|
|
}
|
|
|
|
/*
|
|
* passwd:
|
|
* See if user knows password
|
|
*/
|
|
bool
|
|
passwd(void)
|
|
{
|
|
reg char *sp, c;
|
|
bool passok;
|
|
char buf[LINLEN], *xcrypt();
|
|
|
|
msg(wizstr);
|
|
mpos = 0;
|
|
sp = buf;
|
|
while ((c = getchar()) != '\n' && c != '\r' && c != ESCAPE)
|
|
if (c == md_killchar())
|
|
sp = buf;
|
|
else if (c == md_erasechar() && sp > buf)
|
|
sp--;
|
|
else
|
|
*sp++ = c;
|
|
if (sp == buf)
|
|
passok = FALSE;
|
|
else {
|
|
*sp = '\0';
|
|
passok = (strcmp(PASSWD, xcrypt(buf, "mT")) == 0);
|
|
}
|
|
return passok;
|
|
}
|