Sinks may be teleported or polymorphed by rings

Original patches by Leon Arnott and me.
This commit is contained in:
Pasi Kallinen
2015-04-14 19:21:32 +03:00
parent f1a5de16d9
commit 9b2c298fec
2 changed files with 81 additions and 7 deletions

View File

@@ -901,6 +901,7 @@ lichen corpse is an acid indicator
camera may contain a picture-painting demon camera may contain a picture-painting demon
some monsters can eat through iron bars some monsters can eat through iron bars
inaccessible niches occasionally have iron bars in front inaccessible niches occasionally have iron bars in front
sinks may teleport or polymorph
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -9,6 +9,8 @@
#include "lev.h" #include "lev.h"
STATIC_DCL void FDECL(trycall, (struct obj *)); STATIC_DCL void FDECL(trycall, (struct obj *));
STATIC_DCL void NDECL(polymorph_sink);
STATIC_DCL boolean NDECL(teleport_sink);
STATIC_DCL void FDECL(dosinkring, (struct obj *)); STATIC_DCL void FDECL(dosinkring, (struct obj *));
STATIC_PTR int FDECL(drop, (struct obj *)); STATIC_PTR int FDECL(drop, (struct obj *));
@@ -260,6 +262,72 @@ register struct obj *obj;
docall(obj); docall(obj);
} }
/** Transforms the sink at the player's position into
* a fountain, throne, altar or grave. */
STATIC_DCL
void
polymorph_sink()
{
if (levl[u.ux][u.uy].typ != SINK) return;
level.flags.nsinks--;
levl[u.ux][u.uy].doormask = 0;
switch(rn2(4)) {
default:
case 0:
levl[u.ux][u.uy].typ = FOUNTAIN;
level.flags.nfountains++;
break;
case 1:
levl[u.ux][u.uy].typ = THRONE;
break;
case 2:
levl[u.ux][u.uy].typ = ALTAR;
levl[u.ux][u.uy].altarmask = Align2amask(rn2((int)A_LAWFUL+2) - 1);
break;
case 3:
levl[u.ux][u.uy].typ = ROOM;
make_grave(u.ux, u.uy, (char *) 0);
break;
}
pline_The("sink transforms into %s!",
(levl[u.ux][u.uy].typ == THRONE) ?
"a throne" : an(surface(u.ux, u.uy)));
newsym(u.ux,u.uy);
}
/** Teleports the sink at the player's position.
* @return TRUE if sink teleported */
STATIC_DCL
boolean
teleport_sink()
{
int cx, cy;
int cnt = 0;
struct trap *trp;
struct engr *eng;
do {
cx = rnd(COLNO-1);
cy = rn2(ROWNO);
trp = t_at(cx,cy);
eng = engr_at(cx,cy);
} while (((levl[cx][cy].typ != ROOM) || (trp) || (eng) ||
cansee(cx,cy)) && (cnt++ < 200));
if ((levl[cx][cy].typ == ROOM) && !trp && !eng) {
/* create sink at new position */
levl[cx][cy].typ = SINK;
levl[cx][cy].looted = levl[u.ux][u.uy].looted;
newsym(cx,cy);
/* remove old sink */
levl[u.ux][u.uy].typ = ROOM;
levl[u.ux][u.uy].looted = 0;
newsym(u.ux,u.uy);
return TRUE;
}
return FALSE;
}
STATIC_OVL STATIC_OVL
void void
dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */ dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */
@@ -267,6 +335,7 @@ register struct obj *obj;
{ {
register struct obj *otmp,*otmp2; register struct obj *otmp,*otmp2;
register boolean ideed = TRUE; register boolean ideed = TRUE;
boolean nosink = FALSE;
You("drop %s down the drain.", doname(obj)); You("drop %s down the drain.", doname(obj));
obj->in_use = TRUE; /* block free identification via interrupt */ obj->in_use = TRUE; /* block free identification via interrupt */
@@ -289,8 +358,9 @@ giveback:
You("smell rotten %s.", makeplural(fruitname(FALSE))); You("smell rotten %s.", makeplural(fruitname(FALSE)));
break; break;
case RIN_AGGRAVATE_MONSTER: case RIN_AGGRAVATE_MONSTER:
pline("Several flies buzz angrily around the sink."); pline("Several %s buzz angrily around the sink.",
break; Hallucination ? makeplural(rndmonnam(NULL)) : "flies");
break;
case RIN_SHOCK_RESISTANCE: case RIN_SHOCK_RESISTANCE:
pline("Static electricity surrounds the sink."); pline("Static electricity surrounds the sink.");
break; break;
@@ -355,7 +425,8 @@ giveback:
You_see("the ring slide right down the drain!"); You_see("the ring slide right down the drain!");
break; break;
case RIN_SEE_INVISIBLE: case RIN_SEE_INVISIBLE:
You_see("some air in the sink."); You_see("some %s in the sink.",
Hallucination ? "oxygen molecules" : "air");
break; break;
case RIN_STEALTH: case RIN_STEALTH:
pline_The("sink seems to blend into the floor for a moment."); pline_The("sink seems to blend into the floor for a moment.");
@@ -377,13 +448,15 @@ giveback:
pline_The("sink glows %s for a moment.", hcolor(NH_WHITE)); pline_The("sink glows %s for a moment.", hcolor(NH_WHITE));
break; break;
case RIN_TELEPORTATION: case RIN_TELEPORTATION:
pline_The("sink momentarily vanishes."); nosink = teleport_sink();
pline_The("sink %svanishes.", nosink ? "" : "momentarily ");
break; break;
case RIN_TELEPORT_CONTROL: case RIN_TELEPORT_CONTROL:
pline_The("sink looks like it is being beamed aboard somewhere."); pline_The("sink looks like it is being beamed aboard somewhere.");
break; break;
case RIN_POLYMORPH: case RIN_POLYMORPH:
pline_The("sink momentarily looks like a fountain."); polymorph_sink();
nosink = TRUE;
break; break;
case RIN_POLYMORPH_CONTROL: case RIN_POLYMORPH_CONTROL:
pline_The("sink momentarily looks like a regularly erupting geyser."); pline_The("sink momentarily looks like a regularly erupting geyser.");
@@ -392,9 +465,9 @@ giveback:
} }
if(ideed) if(ideed)
trycall(obj); trycall(obj);
else else if (!nosink)
You_hear("the ring bouncing down the drainpipe."); You_hear("the ring bouncing down the drainpipe.");
if (!rn2(20)) { if (!rn2(20) && !nosink) {
pline_The("sink backs up, leaving %s.", doname(obj)); pline_The("sink backs up, leaving %s.", doname(obj));
obj->in_use = FALSE; obj->in_use = FALSE;
dropx(obj); dropx(obj);