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
461
rogue4/sticks.c
Normal file
461
rogue4/sticks.c
Normal file
|
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
* Functions to implement the various sticks one might find
|
||||
* while wandering around the dungeon.
|
||||
*
|
||||
* @(#)sticks.c 4.22 (Berkeley) 5/19/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 <string.h>
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* fix_stick:
|
||||
* Set up a new stick
|
||||
*/
|
||||
fix_stick(cur)
|
||||
register THING *cur;
|
||||
{
|
||||
if (strcmp(ws_type[cur->o_which], "staff") == 0)
|
||||
strcpy(cur->o_damage,"2d3");
|
||||
else
|
||||
strcpy(cur->o_damage,"1d1");
|
||||
strcpy(cur->o_hurldmg,"1d1");
|
||||
|
||||
cur->o_charges = 3 + rnd(5);
|
||||
switch (cur->o_which)
|
||||
{
|
||||
case WS_HIT:
|
||||
cur->o_hplus = 100;
|
||||
cur->o_dplus = 3;
|
||||
strcpy(cur->o_damage,"1d8");
|
||||
when WS_LIGHT:
|
||||
cur->o_charges = 10 + rnd(10);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* do_zap:
|
||||
* Perform a zap with a wand
|
||||
*/
|
||||
do_zap()
|
||||
{
|
||||
register THING *obj, *tp;
|
||||
register int y, x;
|
||||
register char *name;
|
||||
|
||||
if ((obj = get_item("zap with", STICK)) == NULL)
|
||||
return;
|
||||
if (obj->o_type != STICK)
|
||||
{
|
||||
after = FALSE;
|
||||
msg("you can't zap with that!");
|
||||
return;
|
||||
}
|
||||
if (obj->o_charges == 0)
|
||||
{
|
||||
msg("nothing happens");
|
||||
return;
|
||||
}
|
||||
switch (obj->o_which)
|
||||
{
|
||||
case WS_LIGHT:
|
||||
/*
|
||||
* Reddy Kilowat wand. Light up the room
|
||||
*/
|
||||
ws_know[WS_LIGHT] = TRUE;
|
||||
if (proom->r_flags & ISGONE)
|
||||
msg("the corridor glows and then fades");
|
||||
else
|
||||
{
|
||||
proom->r_flags &= ~ISDARK;
|
||||
/*
|
||||
* Light the room and put the player back up
|
||||
*/
|
||||
enter_room(&hero);
|
||||
addmsg("the room is lit");
|
||||
if (!terse)
|
||||
addmsg(" by a shimmering blue light");
|
||||
endmsg();
|
||||
}
|
||||
when WS_DRAIN:
|
||||
/*
|
||||
* Take away 1/2 of hero's hit points, then take it away
|
||||
* evenly from the monsters in the room (or next to hero
|
||||
* if he is in a passage)
|
||||
*/
|
||||
if (pstats.s_hpt < 2)
|
||||
{
|
||||
msg("you are too weak to use it");
|
||||
return;
|
||||
}
|
||||
else
|
||||
drain();
|
||||
when WS_POLYMORPH:
|
||||
case WS_TELAWAY:
|
||||
case WS_TELTO:
|
||||
case WS_CANCEL:
|
||||
{
|
||||
register char monster, oldch;
|
||||
register int rm;
|
||||
|
||||
y = hero.y;
|
||||
x = hero.x;
|
||||
while (step_ok(winat(y, x)))
|
||||
{
|
||||
y += delta.y;
|
||||
x += delta.x;
|
||||
}
|
||||
if ((tp = moat(y, x)) != NULL)
|
||||
{
|
||||
register char omonst;
|
||||
|
||||
omonst = monster = tp->t_type;
|
||||
if (monster == 'F')
|
||||
player.t_flags &= ~ISHELD;
|
||||
if (obj->o_which == WS_POLYMORPH)
|
||||
{
|
||||
register THING *pp;
|
||||
|
||||
pp = tp->t_pack;
|
||||
detach(mlist, tp);
|
||||
if (see_monst(tp))
|
||||
mvaddch(y, x, chat(y, x));
|
||||
oldch = tp->t_oldch;
|
||||
delta.y = y;
|
||||
delta.x = x;
|
||||
new_monster(tp, monster = rnd(26) + 'A', &delta);
|
||||
if (see_monst(tp))
|
||||
mvaddch(y, x, monster);
|
||||
tp->t_oldch = oldch;
|
||||
tp->t_pack = pp;
|
||||
ws_know[WS_POLYMORPH] |= (monster != omonst);
|
||||
}
|
||||
else if (obj->o_which == WS_CANCEL)
|
||||
{
|
||||
tp->t_flags |= ISCANC;
|
||||
tp->t_flags &= ~(ISINVIS|CANHUH);
|
||||
tp->t_disguise = tp->t_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isupper(toascii(mvinch(y,x))))
|
||||
mvaddch(y, x, tp->t_oldch);
|
||||
if (obj->o_which == WS_TELAWAY)
|
||||
{
|
||||
do
|
||||
{
|
||||
rm = rnd_room();
|
||||
rnd_pos(&rooms[rm], &tp->t_pos);
|
||||
} until (winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
|
||||
tp->t_room = roomin(&tp->t_pos);
|
||||
tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
|
||||
if (see_monst(tp))
|
||||
mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
|
||||
else if (on(player, SEEMONST))
|
||||
{
|
||||
standout();
|
||||
mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
|
||||
standend();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tp->t_pos.y = hero.y + delta.y;
|
||||
tp->t_pos.x = hero.x + delta.x;
|
||||
|
||||
if (tp->t_pos.y != y || tp->t_pos.x != x)
|
||||
tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
|
||||
}
|
||||
moat(y, x) = NULL;
|
||||
moat(tp->t_pos.y, tp->t_pos.x) = tp;
|
||||
if (tp->t_type == 'F')
|
||||
player.t_flags &= ~ISHELD;
|
||||
}
|
||||
tp->t_dest = &hero;
|
||||
tp->t_flags |= ISRUN;
|
||||
}
|
||||
}
|
||||
when WS_MISSILE:
|
||||
{
|
||||
THING bolt;
|
||||
|
||||
ws_know[WS_MISSILE] = TRUE;
|
||||
bolt.o_type = '*';
|
||||
strcpy(bolt.o_hurldmg,"1d4");
|
||||
bolt.o_hplus = 100;
|
||||
bolt.o_dplus = 1;
|
||||
bolt.o_flags = ISMISL;
|
||||
if (cur_weapon != NULL)
|
||||
bolt.o_launch = cur_weapon->o_which;
|
||||
do_motion(&bolt, delta.y, delta.x);
|
||||
if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL && !save_throw(VS_MAGIC, tp))
|
||||
hit_monster(unc(bolt.o_pos), &bolt);
|
||||
else if (terse)
|
||||
msg("missle vanishes");
|
||||
else
|
||||
msg("the missle vanishes with a puff of smoke");
|
||||
}
|
||||
when WS_HIT:
|
||||
delta.y += hero.y;
|
||||
delta.x += hero.x;
|
||||
if ((tp = moat(delta.y, delta.x)) != NULL)
|
||||
{
|
||||
if (rnd(20) == 0)
|
||||
{
|
||||
strcpy(obj->o_damage,"3d8");
|
||||
obj->o_dplus = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(obj->o_damage,"1d8");
|
||||
obj->o_dplus = 3;
|
||||
}
|
||||
fight(&delta, tp->t_type, obj, FALSE);
|
||||
}
|
||||
when WS_HASTE_M:
|
||||
case WS_SLOW_M:
|
||||
y = hero.y;
|
||||
x = hero.x;
|
||||
while (step_ok(winat(y, x)))
|
||||
{
|
||||
y += delta.y;
|
||||
x += delta.x;
|
||||
}
|
||||
if ((tp = moat(y, x)) != NULL)
|
||||
{
|
||||
if (obj->o_which == WS_HASTE_M)
|
||||
{
|
||||
if (on(*tp, ISSLOW))
|
||||
tp->t_flags &= ~ISSLOW;
|
||||
else
|
||||
tp->t_flags |= ISHASTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (on(*tp, ISHASTE))
|
||||
tp->t_flags &= ~ISHASTE;
|
||||
else
|
||||
tp->t_flags |= ISSLOW;
|
||||
tp->t_turn = TRUE;
|
||||
}
|
||||
delta.y = y;
|
||||
delta.x = x;
|
||||
runto(&delta, &hero);
|
||||
}
|
||||
when WS_ELECT:
|
||||
case WS_FIRE:
|
||||
case WS_COLD:
|
||||
if (obj->o_which == WS_ELECT)
|
||||
name = "bolt";
|
||||
else if (obj->o_which == WS_FIRE)
|
||||
name = "flame";
|
||||
else
|
||||
name = "ice";
|
||||
fire_bolt(&hero, &delta, name);
|
||||
ws_know[obj->o_which] = TRUE;
|
||||
when WS_NOP:
|
||||
otherwise:
|
||||
msg("what a bizarre schtick!");
|
||||
}
|
||||
obj->o_charges--;
|
||||
}
|
||||
|
||||
/*
|
||||
* drain:
|
||||
* Do drain hit points from player shtick
|
||||
*/
|
||||
drain()
|
||||
{
|
||||
register THING *mp;
|
||||
register int cnt;
|
||||
register struct room *corp;
|
||||
register THING **dp;
|
||||
register bool inpass;
|
||||
static THING *drainee[40];
|
||||
|
||||
/*
|
||||
* First cnt how many things we need to spread the hit points among
|
||||
*/
|
||||
cnt = 0;
|
||||
if (chat(hero.y, hero.x) == DOOR)
|
||||
corp = &passages[flat(hero.y, hero.x) & F_PNUM];
|
||||
else
|
||||
corp = NULL;
|
||||
inpass = (proom->r_flags & ISGONE);
|
||||
dp = drainee;
|
||||
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||
if (mp->t_room == proom || mp->t_room == corp ||
|
||||
(inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR &&
|
||||
&passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom))
|
||||
*dp++ = mp;
|
||||
if ((cnt = dp - drainee) == 0)
|
||||
{
|
||||
msg("you have a tingling feeling");
|
||||
return;
|
||||
}
|
||||
*dp = NULL;
|
||||
pstats.s_hpt /= 2;
|
||||
cnt = pstats.s_hpt / cnt;
|
||||
/*
|
||||
* Now zot all of the monsters
|
||||
*/
|
||||
for (dp = drainee; *dp; dp++)
|
||||
{
|
||||
mp = *dp;
|
||||
if ((mp->t_stats.s_hpt -= cnt) <= 0)
|
||||
killed(mp, see_monst(mp));
|
||||
else
|
||||
runto(&mp->t_pos, &hero);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fire_bolt:
|
||||
* Fire a bolt in a given direction from a specific starting place
|
||||
*/
|
||||
fire_bolt(start, dir, name)
|
||||
coord *start, *dir;
|
||||
char *name;
|
||||
{
|
||||
register char dirch, ch;
|
||||
register THING *tp;
|
||||
register bool hit_hero, used, changed;
|
||||
register int i, j;
|
||||
coord pos;
|
||||
coord spotpos[BOLT_LENGTH];
|
||||
THING bolt;
|
||||
|
||||
bolt.o_type = WEAPON;
|
||||
bolt.o_which = FLAME;
|
||||
strcpy(bolt.o_hurldmg,"6d6");
|
||||
bolt.o_hplus = 100;
|
||||
bolt.o_dplus = 0;
|
||||
bolt.o_flags = 0;
|
||||
w_names[FLAME] = name;
|
||||
switch (dir->y + dir->x)
|
||||
{
|
||||
case 0: dirch = '/';
|
||||
when 1: case -1: dirch = (dir->y == 0 ? '-' : '|');
|
||||
when 2: case -2: dirch = '\\';
|
||||
}
|
||||
pos = *start;
|
||||
hit_hero = (start != &hero);
|
||||
used = FALSE;
|
||||
changed = FALSE;
|
||||
for (i = 0; i < BOLT_LENGTH && !used; i++)
|
||||
{
|
||||
pos.y += dir->y;
|
||||
pos.x += dir->x;
|
||||
ch = winat(pos.y, pos.x);
|
||||
spotpos[i] = pos;
|
||||
switch (ch)
|
||||
{
|
||||
case DOOR:
|
||||
/*
|
||||
* this code is necessary if the hero is on a door
|
||||
* and he fires at the wall the door is in, it would
|
||||
* otherwise loop infinitely
|
||||
* It is also needed if a dragon flames at the hero.
|
||||
* If the hero is at a door, the dragon flame would bounce
|
||||
* and could kill other monsters inadvertly.
|
||||
*/
|
||||
if (ce(hero, pos))
|
||||
goto def;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '|':
|
||||
case '-':
|
||||
case ' ':
|
||||
if (!changed)
|
||||
hit_hero = !hit_hero;
|
||||
changed = FALSE;
|
||||
dir->y = -dir->y;
|
||||
dir->x = -dir->x;
|
||||
i--;
|
||||
msg("the %s bounces", name);
|
||||
break;
|
||||
default:
|
||||
def:
|
||||
if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL)
|
||||
{
|
||||
hit_hero = TRUE;
|
||||
changed = !changed;
|
||||
tp->t_oldch = chat(pos.y, pos.x);
|
||||
if (!save_throw(VS_MAGIC, tp))
|
||||
{
|
||||
bolt.o_pos = pos;
|
||||
used = TRUE;
|
||||
if (tp->t_type == 'D' && strcmp(name, "flame") == 0)
|
||||
{
|
||||
addmsg("the flame bounces");
|
||||
if (!terse)
|
||||
msg("off the dragon");
|
||||
endmsg();
|
||||
}
|
||||
else
|
||||
hit_monster(unc(pos), &bolt);
|
||||
}
|
||||
else if (ch != 'M' || tp->t_disguise == 'M')
|
||||
{
|
||||
if (start == &hero)
|
||||
runto(&pos, &hero);
|
||||
if (terse)
|
||||
msg("%s misses", name);
|
||||
else
|
||||
msg("the %s whizzes past the %s", name, monsters[ch-'A'].m_name);
|
||||
}
|
||||
}
|
||||
else if (hit_hero && ce(pos, hero))
|
||||
{
|
||||
hit_hero = FALSE;
|
||||
changed = !changed;
|
||||
if (!save(VS_MAGIC))
|
||||
{
|
||||
if ((pstats.s_hpt -= roll(6, 6)) <= 0)
|
||||
if (start == &hero)
|
||||
death('b');
|
||||
else
|
||||
death(moat(start->y, start->x)->t_type);
|
||||
used = TRUE;
|
||||
if (terse)
|
||||
msg("the %s hits", name);
|
||||
else
|
||||
msg("you are hit by the %s", name);
|
||||
}
|
||||
else
|
||||
msg("the %s whizzes by you", name);
|
||||
}
|
||||
mvaddch(pos.y, pos.x, dirch);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
for (j = 0; j < i; j++)
|
||||
mvaddch(spotpos[j].y, spotpos[j].x, chat(spotpos[j].y, spotpos[j].x));
|
||||
}
|
||||
|
||||
/*
|
||||
* charge_str:
|
||||
* Return an appropriate string for a wand charge
|
||||
*/
|
||||
char *
|
||||
charge_str(obj)
|
||||
register THING *obj;
|
||||
{
|
||||
static char buf[20];
|
||||
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
buf[0] = '\0';
|
||||
else if (terse)
|
||||
sprintf(buf, " [%d]", obj->o_charges);
|
||||
else
|
||||
sprintf(buf, " [%d charges]", obj->o_charges);
|
||||
return buf;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue