Generate random eroded, erodeproof, or greased items

Items in initial hero inventory, or generated via lua in
special levels or themed rooms are not subject to this.

Code via xnethack by copperwater <aosdict@gmail.com>,
with some modifications.
This commit is contained in:
Pasi Kallinen
2023-01-29 11:15:38 +02:00
parent 76bac9efe3
commit 7c2c692ee5
3 changed files with 59 additions and 0 deletions

View File

@@ -1101,6 +1101,7 @@ eating garlic makes nearby monsters flee
giants occasionally get a battle axe or a two-handed sword
give gremlin the property it stole, if possible
'F'orcefighting with a war hammer has a small chance of breaking iron bars
very rarely random items are generated eroded, erodeproof, or greased
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -5,6 +5,8 @@
#include "hack.h"
static boolean may_generate_eroded(struct obj *);
static void mkobj_erosions(struct obj *);
static void mkbox_cnts(struct obj *);
static unsigned nextoid(struct obj *, struct obj *);
static int item_on_ice(struct obj *);
@@ -168,6 +170,54 @@ free_omailcmd(struct obj *otmp)
}
}
/* can object be generated eroded? */
static boolean
may_generate_eroded(struct obj *otmp)
{
/* initial hero inventory */
if (gm.moves <= 1 && !gi.in_mklev)
return FALSE;
/* already erodeproof or cannot be eroded */
if (otmp->oerodeproof || !erosion_matters(otmp) || !is_damageable(otmp))
return FALSE;
/* part of a monster's body and produced when it dies */
if (otmp->otyp == WORM_TOOTH || otmp->otyp == UNICORN_HORN)
return FALSE;
/* artifacts cannot be generated eroded */
if (otmp->oartifact)
return FALSE;
return TRUE;
}
/* random chance of applying erosions/grease to object */
static void
mkobj_erosions(struct obj *otmp)
{
if (may_generate_eroded(otmp)) {
/* A small fraction of non-artifact items will generate eroded or
* possibly erodeproof. An item that generates eroded will never be
* erodeproof, and vice versa. */
if (!rn2(100)) {
otmp->oerodeproof = 1;
} else {
if (!rn2(80) && (is_flammable(otmp) || is_rustprone(otmp))) {
do {
otmp->oeroded++;
} while (otmp->oeroded < 3 && !rn2(9));
}
if (!rn2(80) && (is_rottable(otmp) || is_corrodeable(otmp))) {
do {
otmp->oeroded2++;
} while (otmp->oeroded2 < 3 && !rn2(9));
}
}
/* and an extremely small fraction of the time, erodable items
* will generate greased */
if (!rn2(1000))
otmp->greased = 1;
}
}
struct obj *
mkobj_at(char let, coordxy x, coordxy y, boolean artif)
{
@@ -1097,6 +1147,8 @@ mksobj(int otyp, boolean init, boolean artif)
}
}
mkobj_erosions(otmp);
/* some things must get done (corpsenm, timers) even if init = 0 */
switch ((otmp->oclass == POTION_CLASS && otmp->otyp != POT_OIL)
? POT_WATER

View File

@@ -2217,6 +2217,9 @@ create_object(object* o, struct mkroom* croom)
otmp->oeroded = (o->eroded % 4);
otmp->oeroded2 = ((o->eroded >> 2) % 4);
}
} else {
otmp->oeroded = otmp->oeroded2 = 0;
otmp->oerodeproof = 0;
}
if (o->recharged)
otmp->recharged = (o->recharged % 8);
@@ -2230,6 +2233,9 @@ create_object(object* o, struct mkroom* croom)
otmp->otrapped = o->trapped;
if (o->greased)
otmp->greased = 1;
else {
otmp->greased = 0;
}
if (o->quan > 0 && objects[otmp->otyp].oc_merge) {
otmp->quan = o->quan;