Confused #loot (trunk only)
Attempting to loot while suffering from confusion and not on top
of a container will drop gold if hero is carrying some, but it behaved
differently for GOLDOBJ config (gold dropped over a hole or down stairs
always stayed on current level) than for !GOLDOBJ (gold had a chance to
fall to lower level) when done at some location other than a throne.
This makes GOLDOBJ use dropx() instead of dropy(), same as !GOLDOBJ.
And with access to a throne it can be used to repeatedly summon
monsters until they're extinct. This makes it check for confusion before
finding containers, but the chest/exchequer code doesn't always kick in
so can't be attempted as many times before confusion expires, throttling
summoning a little. Also, when placing hero's gold into a chest, it now
clears the contents-known flag and relocks the chest.
This commit is contained in:
@@ -30,6 +30,7 @@ class genocide recognizes species name as an example of the class to
|
|||||||
internals: use Is_box rather than explicitly checking what it checks
|
internals: use Is_box rather than explicitly checking what it checks
|
||||||
fix some unreachable messages (either make then reachable or remove them)
|
fix some unreachable messages (either make then reachable or remove them)
|
||||||
can quiver coins when GOLDOBJ is defined
|
can quiver coins when GOLDOBJ is defined
|
||||||
|
make #loot behave same for GOLDOBJ as for !GOLDOBJ
|
||||||
grammar, spelling and other typos
|
grammar, spelling and other typos
|
||||||
keep various delayed killers separate to avoid mixed up messages
|
keep various delayed killers separate to avoid mixed up messages
|
||||||
don't place randomly-placed aquatic monsters in lava on special levels
|
don't place randomly-placed aquatic monsters in lava on special levels
|
||||||
|
|||||||
+89
-57
@@ -40,6 +40,7 @@ STATIC_DCL char FDECL(in_or_out_menu, (const char *,struct obj *,
|
|||||||
BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
|
BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
|
||||||
STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P));
|
STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(able_to_loot, (int,int,BOOLEAN_P));
|
STATIC_DCL boolean FDECL(able_to_loot, (int,int,BOOLEAN_P));
|
||||||
|
STATIC_DCL boolean NDECL(reverse_loot);
|
||||||
STATIC_DCL boolean FDECL(mon_beside, (int, int));
|
STATIC_DCL boolean FDECL(mon_beside, (int, int));
|
||||||
STATIC_DCL void FDECL(tipcontainer, (struct obj *));
|
STATIC_DCL void FDECL(tipcontainer, (struct obj *));
|
||||||
|
|
||||||
@@ -1537,6 +1538,13 @@ doloot() /* loot a container on the floor or loot saddle from mon. */
|
|||||||
You("have no hands!"); /* not `body_part(HAND)' */
|
You("have no hands!"); /* not `body_part(HAND)' */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (Confusion) {
|
||||||
|
if (rn2(6) && reverse_loot()) return 1;
|
||||||
|
if (rn2(2)) {
|
||||||
|
pline("Being confused, you find nothing to loot.");
|
||||||
|
return 1; /* costs a turn */
|
||||||
|
} /* else fallthrough to normal looting */
|
||||||
|
}
|
||||||
cc.x = u.ux; cc.y = u.uy;
|
cc.x = u.ux; cc.y = u.uy;
|
||||||
|
|
||||||
lootcont:
|
lootcont:
|
||||||
@@ -1583,63 +1591,6 @@ lootcont:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (any) c = 'y';
|
if (any) c = 'y';
|
||||||
} else if (Confusion) {
|
|
||||||
#ifndef GOLDOBJ
|
|
||||||
if (u.ugold){
|
|
||||||
long contribution = rnd((int)min(LARGEST_INT,u.ugold));
|
|
||||||
struct obj *goldob = mkgoldobj(contribution);
|
|
||||||
#else
|
|
||||||
struct obj *goldob;
|
|
||||||
/* Find a money object to mess with */
|
|
||||||
for (goldob = invent; goldob; goldob = goldob->nobj) {
|
|
||||||
if (goldob->oclass == COIN_CLASS) break;
|
|
||||||
}
|
|
||||||
if (goldob){
|
|
||||||
long contribution = rnd((int)min(LARGEST_INT, goldob->quan));
|
|
||||||
if (contribution < goldob->quan)
|
|
||||||
goldob = splitobj(goldob, contribution);
|
|
||||||
freeinv(goldob);
|
|
||||||
#endif
|
|
||||||
if (IS_THRONE(levl[u.ux][u.uy].typ)){
|
|
||||||
struct obj *coffers;
|
|
||||||
int pass;
|
|
||||||
/* find the original coffers chest, or any chest */
|
|
||||||
for (pass = 2; pass > -1; pass -= 2)
|
|
||||||
for (coffers = fobj; coffers; coffers = coffers->nobj)
|
|
||||||
if (coffers->otyp == CHEST && coffers->spe == pass)
|
|
||||||
goto gotit; /* two level break */
|
|
||||||
gotit:
|
|
||||||
if (coffers) {
|
|
||||||
verbalize("Thank you for your contribution to reduce the debt.");
|
|
||||||
(void) add_to_container(coffers, goldob);
|
|
||||||
coffers->owt = weight(coffers);
|
|
||||||
} else {
|
|
||||||
struct monst *mon = makemon(courtmon(),
|
|
||||||
u.ux, u.uy, NO_MM_FLAGS);
|
|
||||||
if (mon) {
|
|
||||||
#ifndef GOLDOBJ
|
|
||||||
mon->mgold += goldob->quan;
|
|
||||||
delobj(goldob);
|
|
||||||
pline("The exchequer accepts your contribution.");
|
|
||||||
} else {
|
|
||||||
dropx(goldob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dropx(goldob);
|
|
||||||
#else
|
|
||||||
add_to_minv(mon, goldob);
|
|
||||||
pline("The exchequer accepts your contribution.");
|
|
||||||
} else {
|
|
||||||
dropy(goldob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dropy(goldob);
|
|
||||||
#endif
|
|
||||||
pline("Ok, now there is loot here.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
|
} else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
|
||||||
You("need to dig up the grave to effectively loot it...");
|
You("need to dig up the grave to effectively loot it...");
|
||||||
}
|
}
|
||||||
@@ -1690,6 +1641,87 @@ gotit:
|
|||||||
return (timepassed);
|
return (timepassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called when attempting to #loot while confused */
|
||||||
|
STATIC_OVL boolean
|
||||||
|
reverse_loot()
|
||||||
|
{
|
||||||
|
struct obj *goldob = 0, *coffers, *otmp, boxdummy;
|
||||||
|
struct monst *mon;
|
||||||
|
long contribution;
|
||||||
|
int n, x = u.ux, y = u.uy;
|
||||||
|
|
||||||
|
if (!rn2(3)) {
|
||||||
|
/* n objects: 1/(n+1) chance per object plus 1/(n+1) to fall off end */
|
||||||
|
for (n = inv_cnt(), otmp = invent; otmp; --n, otmp = otmp->nobj)
|
||||||
|
if (!rn2(n + 1)) {
|
||||||
|
prinv("You find old loot:", otmp, 0L);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef GOLDOBJ
|
||||||
|
if (u.ugold) {
|
||||||
|
contribution = ((long)rnd(5) * u.ugold + 4L) / 5L;
|
||||||
|
goldob = mkgoldobj(contribution);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* find a money object to mess with */
|
||||||
|
for (goldob = invent; goldob; goldob = goldob->nobj)
|
||||||
|
if (goldob->oclass == COIN_CLASS) {
|
||||||
|
contribution = ((long)rnd(5) * goldob->quan + 4L) / 5L;
|
||||||
|
if (contribution < goldob->quan)
|
||||||
|
goldob = splitobj(goldob, contribution);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!goldob) return FALSE;
|
||||||
|
|
||||||
|
if (!IS_THRONE(levl[x][y].typ)) {
|
||||||
|
dropx(goldob);
|
||||||
|
/* the dropped gold might have fallen to lower level */
|
||||||
|
if (g_at(x, y)) pline("Ok, now there is loot here.");
|
||||||
|
} else {
|
||||||
|
/* find original coffers chest if present, otherwise use nearest one */
|
||||||
|
otmp = 0;
|
||||||
|
for (coffers = fobj; coffers; coffers = coffers->nobj)
|
||||||
|
if (coffers->otyp == CHEST) {
|
||||||
|
if (coffers->spe == 2) break; /* a throne room chest */
|
||||||
|
if (!otmp ||
|
||||||
|
distu(coffers->ox, coffers->oy) < distu(otmp->ox, otmp->oy))
|
||||||
|
otmp = coffers; /* remember closest ordinary chest */
|
||||||
|
}
|
||||||
|
if (!coffers) coffers = otmp;
|
||||||
|
|
||||||
|
if (coffers) {
|
||||||
|
verbalize("Thank you for your contribution to reduce the debt.");
|
||||||
|
#ifdef GOLDOBJ
|
||||||
|
freeinv(goldob);
|
||||||
|
#endif
|
||||||
|
(void)add_to_container(coffers, goldob);
|
||||||
|
coffers->owt = weight(coffers);
|
||||||
|
coffers->cknown = 0;
|
||||||
|
if (!coffers->olocked) {
|
||||||
|
boxdummy = zeroobj, boxdummy.otyp = SPE_WIZARD_LOCK;
|
||||||
|
(void)boxlock(coffers, &boxdummy);
|
||||||
|
}
|
||||||
|
} else if ((mon = makemon(courtmon(), x, y, NO_MM_FLAGS)) != 0) {
|
||||||
|
#ifndef GOLDOBJ
|
||||||
|
mon->mgold += goldob->quan;
|
||||||
|
delobj(goldob);
|
||||||
|
#else
|
||||||
|
freeinv(goldob);
|
||||||
|
add_to_minv(mon, goldob);
|
||||||
|
#endif
|
||||||
|
pline("The exchequer accepts your contribution.");
|
||||||
|
} else {
|
||||||
|
You("drop %s.", doname(goldob));
|
||||||
|
dropx(goldob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* loot_mon() returns amount of time passed.
|
/* loot_mon() returns amount of time passed.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user