1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-07-27 07:52:25 +01:00

Rage-walker implementation

Levels where lots of elves and fey have been killed with iron weapons can spawn nymphs of murder and anger as insight encounters.

Rage-walker:
-20th level, 18 speed, 30 mr, -10 AC, 4-6 DR nymph
-25-33 insight to see
-Vampire claw attacks, seduce at low sanity, mandrake shriek when killed.
-Automatic electric chain lashes against adjacent enemies
-Up to three generated per level. High rage and insight and low sanity control chance.
-Created in the company of a large number of poltergiests, vorticies, and spheres.
-While unseen, can create further batches of poltergiests.

Poltergiest:
-20th level, 18 speed, 50 MR, -5 AC ghost
-1d6 weapon attack (expert weapon user).
-Created

"Heavy Iron Balls" renamed to "Balls", with special handling to add "heavy" before the material-word. Allows for things like "heavy gold ball" etc.

Attacks can have high-san or low-san requirements
This commit is contained in:
ChrisANG 2025-02-24 15:26:00 -05:00
parent f32785e58e
commit 8e3e2a729c
35 changed files with 368 additions and 92 deletions

View file

@ -70,8 +70,8 @@ OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "ball", random
OBJECT[50%]: '0', "ball", random
# Non diggable walls
NON_DIGGABLE:(00,00,75,19)
@ -186,7 +186,7 @@ OBJECT: '_', "chain", (2,15)
OBJECT: '_', "chain", (3,15)
OBJECT: '_', "chain", (3,15)
OBJECT: '_', "chain", (4,15)
OBJECT: '0', "heavy iron ball", (4,15)
OBJECT: '0', "ball", (4,15)
OBJECT: '_', "chain", (4,15)
OBJECT: '_', "chain", (5,15)
OBJECT: '_', "chain", (5,15)
@ -194,7 +194,7 @@ OBJECT: '_', "chain", (6,15)
OBJECT: '_', "chain", (6,15)
OBJECT: '_', "chain", (6,15)
OBJECT: '_', "chain", (7,15)
OBJECT: '0', "heavy iron ball", (7,15)
OBJECT: '0', "ball", (7,15)
OBJECT: '_', "chain", (8,15)
OBJECT: '_', "chain", (8,15)
OBJECT: '_', "chain", (9,15)
@ -205,9 +205,9 @@ OBJECT: '_', "chain", (10,15)
OBJECT: '_', "chain", (10,15)
OBJECT: '_', "chain", (11,15)
OBJECT: '_', "chain", (11,15)
OBJECT: '0', "heavy iron ball", (11,15)
OBJECT: '0', "ball", (11,15)
OBJECT: '_', "chain", (2,16)
OBJECT: '0', "heavy iron ball", (2,16)
OBJECT: '0', "ball", (2,16)
OBJECT: '_', "chain", (3,16)
OBJECT: '_', "chain", (3,16)
OBJECT: '_', "chain", (3,16)
@ -219,7 +219,7 @@ OBJECT: '_', "chain", (6,16)
OBJECT: '_', "chain", (6,16)
OBJECT: '_', "chain", (7,16)
OBJECT: '_', "chain", (7,16)
OBJECT: '0', "heavy iron ball", (7,16)
OBJECT: '0', "ball", (7,16)
OBJECT: '_', "chain", (7,16)
OBJECT: '_', "chain", (8,16)
OBJECT: '_', "chain", (8,16)
@ -234,10 +234,10 @@ OBJECT: '_', "chain", (3,17)
OBJECT: '_', "chain", (3,17)
OBJECT: '_', "chain", (3,17)
OBJECT: '_', "chain", (4,17)
OBJECT: '0', "heavy iron ball", (4,17)
OBJECT: '0', "ball", (4,17)
OBJECT: '_', "chain", (4,17)
OBJECT: '_', "chain", (4,17)
OBJECT: '0', "heavy iron ball", (4,17)
OBJECT: '0', "ball", (4,17)
OBJECT: '_', "chain", (5,17)
OBJECT: '_', "chain", (6,17)
OBJECT: '#', "rusty iron trephination kit", (6,17)
@ -245,15 +245,15 @@ OBJECT: '_', "chain", (7,17)
OBJECT: '_', "chain", (7,17)
OBJECT: '_', "chain", (7,17)
OBJECT: '_', "chain", (8,17)
OBJECT: '0', "heavy iron ball", (8,17)
OBJECT: '0', "ball", (8,17)
OBJECT: '_', "chain", (9,17)
OBJECT: '_', "chain", (9,17)
OBJECT: '0', "heavy iron ball", (9,17)
OBJECT: '0', "ball", (9,17)
OBJECT: '_', "chain", (9,17)
OBJECT: '_', "chain", (10,17)
OBJECT: '_', "chain", (10,17)
OBJECT: '_', "chain", (10,17)
OBJECT: '0', "heavy iron ball", (10,17)
OBJECT: '0', "ball", (10,17)
OBJECT: '_', "chain", (11,17)
# pre-placed inherited artifact
OBJECT: '_', "chain", place[0], uncursed, 0, "Inherited"
@ -321,8 +321,8 @@ MONSTER: '&',"lava demon",(26,14),hostile,awake
MONSTER: ''',"iron golem",(04,13),hostile
# Objects
OBJECT:'(',"spoon",(31,10),blessed,0,"The Iron Spoon of Liberation"
# OBJECT:'0',"heavy iron ball",(31,10),blessed,0,"The Iron Ball of Levitation"
# OBJECT:'0',"heavy iron ball",(31,10),blessed,0,"The Iron Ball of Liberation"
# OBJECT:'0',"ball",(31,10),blessed,0,"The Iron Ball of Levitation"
# OBJECT:'0',"ball",(31,10),blessed,0,"The Iron Ball of Liberation"
#Box full of crazy
CONTAINER:'(',"chest",(55,18),cursed,6
OBJECT:'#',"blessed iron +2 magic-resistant visored helmet named Mask of Waterdeep",contained
@ -458,8 +458,8 @@ OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "ball", random
OBJECT[50%]: '0', "ball", random
MAZE:"Con-filb",' '

View file

@ -124,8 +124,8 @@ OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "ball", random
OBJECT[50%]: '0', "ball", random
# Non diggable walls
NON_DIGGABLE:(25,00,43,18)
@ -234,8 +234,8 @@ OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "ball", random
OBJECT[50%]: '0', "ball", random
DOOR:locked,(28,02)
DOOR:locked,(31,02)
@ -636,8 +636,8 @@ OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[75%]: '_', "chain", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "heavy iron ball", random
OBJECT[50%]: '0', "ball", random
OBJECT[50%]: '0', "ball", random
DOOR:locked,(27,02)
DOOR:locked,(27,04)

View file

@ -213,13 +213,13 @@ MONSTER:'@',"pirate brother",(37,11)
MONSTER:'@',"pirate brother",(47,10)
#Used Cannon Balls
OBJECT:'0',"heavy iron ball",(13,15) [skipcheck]
OBJECT:'0',"heavy iron ball",(16,12) [skipcheck]
OBJECT:'0',"heavy iron ball",(21,09) [skipcheck]
OBJECT:'0',"heavy iron ball",(21,16) [skipcheck]
OBJECT:'0',"heavy iron ball",(45,08) [skipcheck]
OBJECT:'0',"heavy iron ball",(51,08) [skipcheck]
OBJECT:'0',"heavy iron ball",(52,08) [skipcheck]
OBJECT:'0',"ball",(13,15) [skipcheck]
OBJECT:'0',"ball",(16,12) [skipcheck]
OBJECT:'0',"ball",(21,09) [skipcheck]
OBJECT:'0',"ball",(21,16) [skipcheck]
OBJECT:'0',"ball",(45,08) [skipcheck]
OBJECT:'0',"ball",(51,08) [skipcheck]
OBJECT:'0',"ball",(52,08) [skipcheck]
# Non diggable walls
NON_DIGGABLE:(00,00,75,20)

View file

@ -287,7 +287,7 @@ ENDMAP
NON_DIGGABLE:(00,00,75,20)
PORTAL:(35,10,35,10),(00,00,00,00),"chaosm"
OBJECT:'0',"heavy iron ball",(35,10)
OBJECT:'0',"ball",(35,10)
BRANCH:(35,19,35,19),(0,0,0,0)
@ -640,7 +640,7 @@ STAIR:(16,19),down
LADDER:(16,01),down
ALTAR:(35,09),noalign,altar,"Chaos"
OBJECT:'0',"heavy iron ball",(35,10)
OBJECT:'0',"ball",(35,10)
MAZEWALK:(02,10),south
MAZEWALK:(02,10),north

View file

@ -7957,6 +7957,15 @@ quit*
quivering blob
A blind, brainless monster that lives in a state of constant,
undirected terror.
rage-walker
rage walker
This tall creature looks at once slender and deadly. Its
generally humanoid body has thin legs and arms, and its
features are concealed by tight-fitting metal armor.
The creature's movements are graceful and sure, yet
they are sharp and angry at the same time.
[ Monster Manual III,
by Skip Williams, Johnathan Tweet, and Monte Cook ]
raijin
raiden
The Japanese god of thunder (rai) and lightning (den). He prevented

View file

@ -2057,14 +2057,14 @@ A("The Sceptre of Might", MACE, (const char *)0,
CONFLICT, NOFLAG
),
// old-style artifact block
// A("The Iron Ball of Liberation", HEAVY_IRON_BALL, 0, 0,
// A("The Iron Ball of Liberation", BALL, 0, 0,
// (SPFX_NOGEN|SPFX_RESTR|SPFX_LUCK|SPFX_INTEL),
// (SPFX_SEARCH|SPFX_SEEK|SPFX_WARN), 0,
// NO_ATTK(), NO_DFNS, CARY(AD_MAGM),
// PHASING, A_CHAOTIC, PM_CONVICT, NON_PM, 5000L,
// SPFX2_STLTH,0,0), /*Note: it had caried stealth before*/
A("The Iron Ball of Levitation", HEAVY_IRON_BALL, (const char *)0,
A("The Iron Ball of Levitation", BALL, (const char *)0,
5000L, MT_DEFAULT, MZ_DEFAULT, WT_DEFAULT,
A_CHAOTIC, PM_CONVICT, NON_PM, TIER_A, (ARTG_NOGEN|ARTG_NOWISH|ARTG_MAJOR),
NO_MONS(),

View file

@ -14,11 +14,13 @@ typedef struct d_flags { /* dungeon/level type flags */
Bitfield(raise, 3); /* corpse resurection type (current max 8) */
Bitfield(mirror, 1); /* has at least one mirror on the ground */
Bitfield(day, 1); /* Is the map currently in day mode? */
Bitfield(walkers, 2); /* How many rage-walkers for this level? (0-3) */
} d_flags;
typedef struct d_level { /* basic dungeon level element */
int dnum; /* dungeon number */
int dlevel; /* level number */
int rage; /* rage-walker rage*/
d_flags flags; /* type flags */
} d_level;

View file

@ -39,6 +39,7 @@ E void FDECL(dochaos_mon, (struct monst *));
E void FDECL(dohost_mon, (struct monst *));
E void FDECL(dosnake, (struct monst *));
E void FDECL(dokraken_mon, (struct monst *));
E void FDECL(dochain_lashes, (struct monst *));
E void FDECL(dotailslap, (struct monst *));
E void FDECL(dovines, (struct monst *));
E void FDECL(dostarblades, (struct monst *));

View file

@ -177,6 +177,7 @@
(ptr)->mtyp == PM_SCRAP_TITAN || \
(ptr)->mtyp == PM_HELLFIRE_COLOSSUS || \
(ptr)->mtyp == PM_HELLFIRE_ORB || \
(ptr)->mtyp == PM_RAGE_WALKER || \
(ptr)->mtyp == PM_FERRUMACH_RILMANI)
#define is_iron_mon(mon) (is_iron((mon)->data))
#define is_silver(ptr) ((ptr)->mtyp == PM_ARGENACH_RILMANI || \
@ -641,6 +642,8 @@
|| (ptr)->mtyp == PM_GHAELE_ELADRIN || (ptr)->mtyp == PM_LUMINOUS_CLOUD\
|| (ptr)->mtyp == PM_PYROCLASTIC_VORTEX)
#define is_storm_mon(mon) ((is_level_storm_mtyp((mon)->data) && (mon)->m_lev >= 20) || is_storm_mtyp((mon)->data))
#define is_chain_lash_mtyp(ptr) ((ptr)->mtyp == PM_RAGE_WALKER)
#define is_chain_lash_mon(mon) (is_chain_lash_mtyp((mon)->data))
#define is_dancer(ptr) ((ptr)->mtyp == PM_PORO_AULON || (ptr)->mtyp == PM_SEYLL_AUZKOVYN || (ptr)->mtyp == PM_ANULO_DANCER || (ptr)->mtyp == PM_MYRKALFAR_MATRON)
#define goat_monster(ptr) (In_lost_cities(&u.uz) ? lost_cities_goat_monster(ptr) : always_goat_monster(ptr))

View file

@ -207,6 +207,7 @@ struct monst {
Bitfield(mequipping,7); /*146*/
Bitfield(mironmarked,1);/* recently hit by an iron weapon (elves/fey/rage-walker) */ /*147*/
unsigned long long int seenmadnesses; /* monster has seen these madnesses */
char mbdrown; /* drowning in blood */

View file

@ -1143,7 +1143,7 @@ struct obj {
is_weptool((otmp)) || \
(otmp)->otyp == BOULDER || \
(otmp)->otyp == MASS_OF_STUFF || \
(otmp)->otyp == HEAVY_IRON_BALL || \
(otmp)->otyp == BALL || \
(otmp)->otyp == CHAIN || \
(otmp)->oclass == GEM_CLASS)
#define throwing_weapon(otmp) (is_missile((otmp)) || is_spear((otmp)) || \

View file

@ -24,6 +24,7 @@ struct attack {
boolean offhand; /*This attack is blocked by a shield (offhand weapons and spiritual rapiers handled via at_ type).*/
boolean polywep; /*This attack is changed to a weapon attack if you're poly'd into this form and wielding a weapon.*/
uchar ins_req; /*The PC must have reached X insight for the attacker to get this attack.*/
char san_req; /*The PC must have fallen below or risen above X sanity for the attacker to get this attack.*/
};
#define is_null_attk(attk) ((attk) && ((attk)->aatyp == 0 && (attk)->adtyp == 0 && (attk)->damn == 0 && (attk)->damd == 0))

View file

@ -48,6 +48,7 @@ STATIC_DCL void FDECL(goat_sacrifice, (struct monst *));
STATIC_DCL void FDECL(palid_stranger, (struct monst *));
STATIC_DCL void FDECL(sib_follow, (struct monst *));
STATIC_DCL void FDECL(invisible_twin_act, (struct monst *));
void FDECL(make_rage_walker_polts, (int));
#ifdef OVL0
@ -2548,6 +2549,18 @@ karemade:
}
}
}
if(u.uz.flags.walkers < 3 && rnd(100)+3 < u.uz.rage && roll_generic_flat_madness(TRUE) && rnd(98)+2 < u.uinsight){
mtmp = makemon(&mons[PM_RAGE_WALKER], 0, 0, MM_ADJACENTOK);
if(mtmp){
make_rage_walker_polts(u.uz.rage+3);
u.uz.rage = 0;
}
int i;
int vort[] = {PM_ICE_VORTEX, PM_ENERGY_VORTEX, PM_FIRE_VORTEX};
for(i = d(3,3); i > 0; i--) makemon(&mons[ROLL_FROM(vort)], 0, 0, NO_MM_FLAGS);
int sphere[] = {PM_FREEZING_SPHERE, PM_FLAMING_SPHERE, PM_SHOCKING_SPHERE};
for(i = d(3,3); i > 0; i--) makemon(&mons[ROLL_FROM(sphere)], 0, 0, NO_MM_FLAGS);
}
}
if(Infuture && !(Is_qstart(&u.uz) && !Race_if(PM_ANDROID)) && !rn2(35)){
struct monst* mtmp = makemon(&mons[PM_SEMBLANCE], rn1(COLNO-3,2), rn1(ROWNO-3,2), MM_ADJACENTOK);
@ -4715,12 +4728,21 @@ printAttacks(buf, ptr)
if(attk->lev_req > 0){
Sprintf(eos(buf), "level %d+", attk->lev_req);
}
if(attk->lev_req > 0 && attk->ins_req > 0){
if(attk->lev_req > 0 && (attk->ins_req > 0 || attk->san_req != 0)){
Sprintf(eos(buf), " and ");
}
if(attk->ins_req > 0){
Sprintf(eos(buf), "%d+ [[insight]]", attk->ins_req);
}
if((attk->lev_req > 0 || attk->ins_req > 0) && attk->san_req != 0){
Sprintf(eos(buf), " and ");
}
if(attk->san_req < 0){
Sprintf(eos(buf), "<%d [[sanity]]", -1*attk->san_req);
}
if(attk->san_req > 0){
Sprintf(eos(buf), ">%d [[sanity]]", attk->san_req);
}
Sprintf(eos(buf), ")");
}
}
@ -4870,6 +4892,8 @@ struct monst *mon;
alkilith_spawn(mon);
else if(mon->mux == u.uz.dnum && mon->muy == u.uz.dlevel && mon->mtyp == PM_MOUTH_OF_THE_GOAT)
goat_sacrifice(mon);
else if(mon->mux == u.uz.dnum && mon->muy == u.uz.dlevel && mon->mtyp == PM_RAGE_WALKER && (check_insight() || (!rn2(u.uevent.udemigod ? 25 : 50) && roll_generic_madness(TRUE))))
make_rage_walker_polts(u.uz.rage+3);
else if(mon->mtyp == PM_STRANGER)
palid_stranger(mon);
else if(mon->mtyp == PM_PUPPET_EMPEROR_XELETH || mon->mtyp == PM_PUPPET_EMPRESS_XEDALLI)
@ -6984,6 +7008,146 @@ struct monst *magr;
}
void
dochain_lashes(magr)
struct monst *magr;
{
struct monst *mdef;
extern const int clockwisex[8];
extern const int clockwisey[8];
struct attack attkbuff = {AT_WEAP, AD_ELEC, 3, 6};
int i = rnd(8),j;
int ax, ay, n;
int chain_count = 0;
struct obj *ofirst;
struct obj *chain;
boolean youagr = (magr == &youmonst);
boolean youdef;
struct permonst *pa;
pa = youagr ? youracedata : magr->data;
ofirst = youagr ? invent : magr->minvent;
// Find chains etc:
for(chain = ofirst; chain; chain = chain->nobj){
if(chain->otyp == CHAIN)
chain_count+=4;
else if(chain->otyp == BALL)
chain_count++;
}
if(!chain_count)
return;
chain_count = rnd(chain_count);
for(chain = ofirst; chain; chain = chain->nobj){
if(chain->otyp == CHAIN)
chain_count-=4;
else if(chain->otyp == BALL)
chain_count--;
if(chain_count <= 0)
break;
}
if(!chain)
return;
for(j=8;j>=1;j--){
ax = x(magr)+clockwisex[(i+j)%8];
ay = y(magr)+clockwisey[(i+j)%8];
if(youagr && u.ustuck && u.uswallow)
mdef = u.ustuck;
else if(!isok(ax, ay))
continue;
else if(onscary(ax, ay, magr))
continue;
else mdef = m_at(ax, ay);
if(u.ux == ax && u.uy == ay)
mdef = &youmonst;
if(!mdef)
continue;
if(!rn2(3))
continue;
youdef = (mdef == &youmonst);
if(youagr && (mdef->mpeaceful))
continue;
if(youdef && (magr->mpeaceful))
continue;
if(youdef && Invulnerable)
continue;
if(!youagr && !youdef && ((mdef->mpeaceful == magr->mpeaceful) || (!!mdef->mtame == !!magr->mtame)))
continue;
if(youdef && u.uswallow)
continue;
if(!youdef && nonthreat(mdef))
continue;
if(mdef->mtyp == PM_PALE_NIGHT)
continue;
xmeleehity(magr, mdef, &attkbuff, &chain, +3, 0, FALSE);
}
}
void
make_rage_walker_polts(int rage)
{
struct obj *otmp, *nobj;
struct monst *polt;
int ox, oy;
boolean created = FALSE;
int otyp = ELVEN_BROADSWORD;
int otyp_index = 0;
int elven_weapon_types[] = {ELVEN_BROADSWORD, ELVEN_SHORT_SWORD, ELVEN_SPEAR, ELVEN_SICKLE, ELVEN_SCIMITAR, HIGH_ELVEN_WARSWORD, ELVEN_LANCE, ELVEN_MACE};
while(rage > 0){
if(!otyp){
polt = makemon(&mons[PM_POLTERGEIST], 0, 0, MM_ADJACENTOK|NO_MINVENT);
otmp = mksobj(ROLL_FROM(elven_weapon_types), NO_MKOBJ_FLAGS);
set_material_gm(otmp, IRON);
rage--;
if(otmp->spe < 3)
otmp->spe = 3;
curse(otmp);
mpickobj(polt, otmp);
m_dowear(polt, TRUE);
continue;
}
created = FALSE;
for(ox = 0; ox < COLNO && rage > 0; ox++){
for(oy = 0; oy < ROWNO && rage > 0; oy++){
otmp = level.objects[ox][oy];
if(!otmp)
continue;
for(; otmp; otmp = otmp->nexthere){
if(otmp->otyp == otyp){
polt = makemon(&mons[PM_POLTERGEIST], otmp->ox, otmp->oy, MM_ADJACENTOK|NO_MINVENT);
obj_extract_self(otmp);
set_material_gm(otmp, IRON);
rage--;
if(otmp->spe < 3)
otmp->spe = 3;
curse(otmp);
mpickobj(polt, otmp);
m_dowear(polt, TRUE);
created = TRUE;
break; //Break nexthere loop, continue location loop
}
}
}}
if(!created){
otyp_index++;
if(otyp_index < SIZE(elven_weapon_types)){
otyp = elven_weapon_types[otyp_index];
}
else otyp = 0;
}
}
doredraw(); //Just moved a bunch of items
}
#endif /* OVLB */
/*allmain.c*/

View file

@ -9905,7 +9905,7 @@ arti_invoke(obj)
for(i = 12; i > 0; i--){
int xadj=0;
int yadj=0;
otmp = mksobj(HEAVY_IRON_BALL, NO_MKOBJ_FLAGS);
otmp = mksobj(BALL, NO_MKOBJ_FLAGS);
otmp->blessed = 0;
otmp->cursed = 0;
if(u.dy == 0) yadj = d(1,3)-2;
@ -14651,6 +14651,8 @@ do_passive_attacks()
dohost_mon(mtmp);
if(is_storm_mon(mtmp))
dostorm(mtmp);
if(is_chain_lash_mon(mtmp))
dochain_lashes(mtmp);
if(mtmp->mtyp == PM_KRAKEN__THE_FIEND_OF_WATER)
dokraken_mon(mtmp);
if(mtmp->mtyp == PM_CHAOS && !PURIFIED_WATER)

View file

@ -851,7 +851,7 @@ bc_sanity_check()
uball ? "iron ball" : "");
}
/* ball is free when swallowed, changing levels, other times? */
if (uball && (uball->otyp != HEAVY_IRON_BALL
if (uball && (uball->otyp != BALL
|| (uball->where != OBJ_FLOOR
&& uball->where != OBJ_INVENT
&& uball->where != OBJ_FREE)

View file

@ -1378,7 +1378,7 @@ dipforge(struct obj *obj)
/* If punished and wielding a hammer, there's a good chance
* you can use a forge to free yourself */
if (Punished && obj->otyp == HEAVY_IRON_BALL) {
if (Punished && obj->otyp == BALL) {
if ((uwep && !is_hammer(uwep)) || !uwep) { /* sometimes drop a hint */
if (!rn2(4))
pline("You'll need a hammer to be able to break the chain.");

View file

@ -2795,7 +2795,7 @@ winid *datawin;
}
/* Object classes currently with no special messages here: amulets. */
if (olet == WEAPON_CLASS || (olet == TOOL_CLASS && oc.oc_skill) || otyp == HEAVY_IRON_BALL || olet == GEM_CLASS || has_artidmg) {
if (olet == WEAPON_CLASS || (olet == TOOL_CLASS && oc.oc_skill) || otyp == BALL || olet == GEM_CLASS || has_artidmg) {
int mask = attack_mask(obj, otyp, oartifact, &youmonst);
boolean otyp_is_blaster = (otyp == CARCOSAN_STING || otyp == HAND_BLASTER || otyp == ARM_BLASTER || otyp == MASS_SHADOW_PISTOL || otyp == CUTTING_LASER || otyp == RAYGUN);
boolean otyp_is_launcher = (((oc.oc_skill >= P_BOW && oc.oc_skill <= P_CROSSBOW) || otyp == ATLATL) && !otyp_is_blaster);

View file

@ -3232,7 +3232,7 @@ boolean greatequip;
(void) mpickobj(mtmp, otmp);
// ifdef CONVICT
} else if (mm == PM_INMATE){
(void)mongets(mtmp, rn2(2) ? HEAVY_IRON_BALL : SPOON, mkobjflags);
(void)mongets(mtmp, rn2(2) ? BALL : SPOON, mkobjflags);
(void)mongets(mtmp, STRIPED_SHIRT, mkobjflags);
// endif
} else if (mm == PM_ATTENDANT){
@ -3586,7 +3586,7 @@ boolean greatequip;
otmp->spe = 5;
(void) mpickobj(mtmp, otmp);
} else if (mm == PM_ROBERT_THE_LIFER){
otmp = mksobj(HEAVY_IRON_BALL, mkobjflags|MKOBJ_NOINIT);
otmp = mksobj(BALL, mkobjflags|MKOBJ_NOINIT);
curse(otmp);
otmp->spe = -5;
(void) mpickobj(mtmp, otmp);
@ -3952,8 +3952,8 @@ boolean greatequip;
otmp->cursed = TRUE;
// otmp->spe = -6;
(void) mpickobj(mtmp,otmp);
(void)mongets(mtmp, HEAVY_IRON_BALL, mkobjflags);
(void)mongets(mtmp, HEAVY_IRON_BALL, mkobjflags);
(void)mongets(mtmp, BALL, mkobjflags);
(void)mongets(mtmp, BALL, mkobjflags);
} else if (mm == PM_MINER) {
(void)mongets(mtmp, PICK_AXE, mkobjflags);
otmp = mksobj(LANTERN, mkobjflags);
@ -9449,7 +9449,7 @@ int mmflags;
}
break;
}
} else {//not shopkeepers, deminymphs, or intoners
} else {//not shopkeepers, deminymphs, rage-walkers, or intoners
int threshold = rnd(10)+rn2(11);
if(mtmp->female && (faction == GOATMOM_FACTION) && u.uinsight > threshold){
set_template(mtmp, MISTWEAVER);
@ -11366,6 +11366,26 @@ boolean greatequip;
(void) mongets(mtmp, VICTORIAN_UNDERWEAR, mkobjflags);
(void) mongets(mtmp, LONG_GLOVES, mkobjflags);
(void) mongets(mtmp, STILETTOS, mkobjflags);
} else if(ptr->mtyp == PM_RAGE_WALKER){
#define RAGE_WALKER_ITEM(otyp) \
otmp = mksobj(otyp, NO_MKOBJ_FLAGS); \
otmp->spe = 3; \
add_oprop(otmp, OPROP_SPIKED); \
set_material_gm(otmp, IRON); \
curse(otmp); \
(void) mpickobj(mtmp, otmp);
RAGE_WALKER_ITEM(ELVEN_BOOTS)
RAGE_WALKER_ITEM(HIGH_ELVEN_PLATE)
RAGE_WALKER_ITEM(HIGH_ELVEN_GAUNTLETS)
RAGE_WALKER_ITEM(FACELESS_HELM)
/*Note: none of this is equipped */
RAGE_WALKER_ITEM(CHAIN)
RAGE_WALKER_ITEM(CHAIN)
RAGE_WALKER_ITEM(CHAIN)
RAGE_WALKER_ITEM(CHAIN)
RAGE_WALKER_ITEM(SHACKLES)
RAGE_WALKER_ITEM(BALL)
RAGE_WALKER_ITEM(BALL)
} else if(Infuture && ptr->mtyp != PM_INTONER && ptr->mtyp != PM_DEMINYMPH && ptr->mtyp != PM_NEVERWAS && ptr->mtyp != PM_CARCOSAN_COURTIER){
if(rn2(3)){
(void) mongets(mtmp, ELVEN_CLOAK, mkobjflags);

View file

@ -4947,7 +4947,7 @@ int tary;
Is_rogue_level(&u.uz) ||
#endif
(In_endgame(&u.uz) && !Is_earthlevel(&u.uz)));
otmp = mksobj(iron ? HEAVY_IRON_BALL : BOULDER, MKOBJ_NOINIT);
otmp = mksobj(iron ? BALL : BOULDER, MKOBJ_NOINIT);
otmp->quan = 1;
otmp->owt = weight(otmp);
if (iron) otmp->owt += 160 * rn2(2);

View file

@ -2704,7 +2704,7 @@ int mat;
case GOLD_BLADED_VIBROZANBATO:
if(mat != GOLD) obj->otyp = WHITE_VIBROZANBATO;
break;
// case HEAVY_IRON_BALL:
// case BALL:
// obj->otyp = ;
// break;
// case CHAIN:
@ -2915,7 +2915,7 @@ register struct obj *obj;
return eaten_stat((int)obj->quan * wt, obj);
} else if (obj->oclass == COIN_CLASS)
return (int)((obj->quan + 50L) / 100L);
else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0)
else if (obj->otyp == BALL && obj->owt != 0)
return((int)(obj->owt)); /* kludge for "very" heavy iron ball */
return((wt || obj->oartifact) ? wt*(int)obj->quan : ((int)obj->quan + 1)>>1);
}

View file

@ -609,7 +609,7 @@ register struct monst *mtmp;
}
num = d(2,4);
while(num--)
obj = mksobj_at(HEAVY_IRON_BALL, x, y, NO_MKOBJ_FLAGS);
obj = mksobj_at(BALL, x, y, NO_MKOBJ_FLAGS);
rem_mx(mtmp, MX_ENAM);
otmp = mksobj(MACE, NO_MKOBJ_FLAGS);
otmp = oname(otmp, artiname(ART_FIELD_MARSHAL_S_BATON));
@ -1804,6 +1804,7 @@ struct monst *mtmp;
mtmp->mflamemarked = FALSE;
mtmp->mibitemarked = FALSE;
mtmp->myoumarked = FALSE;
mtmp->mironmarked = FALSE;
/* gradually time out temporary problems */
if (mtmp->mblinded && !--mtmp->mblinded)
@ -6567,6 +6568,12 @@ xkilled(mtmp, dest)
if (corpse_chance(mtmp, (struct monst *)0, FALSE)){
corpse = make_corpse(mtmp);
}
if(mtmp->mironmarked && (
is_elf(mtmp->data)
|| is_fey(mtmp->data)
)){
u.uz.rage++;
}
if(mtmp->mibitemarked){
mtmp->mflamemarked = FALSE;
mtmp->mgoatmarked = FALSE;

View file

@ -543,8 +543,10 @@ boolean digest_meal;
mon->mhp -= rnd(6);
if(hates_silver(mon->data) && entangle_material(mon, SILVER))
mon->mhp -= rnd(20);
if(hates_iron(mon->data) && (entangle_material(mon, IRON) || entangle_material(mon, GREEN_STEEL)))
if(hates_iron(mon->data) && (entangle_material(mon, IRON) || entangle_material(mon, GREEN_STEEL))){
mon->mhp -= rnd(mon->m_lev);
mon->mironmarked = TRUE;
}
if(hates_unholy_mon(mon) && entangle_material(mon, GREEN_STEEL))
mon->mhp -= d(2,9);
beat = entangle_beatitude(mon, -1);

View file

@ -52,16 +52,17 @@ void NDECL(monst_init);
#define LVL(lvl,mov,mr,aln) lvl,mov,mr,aln
#define SIZ(wt,nut,snd,siz) wt,nut,snd,siz
/* ATTK() and A() are to avoid braces and commas within args to MON() */
#define ATTK(at,ad,n,d) {at,ad,n,d,0,0,0,0}
#define ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,0,0,0}
#define ATTK_INS(at,ad,n,d, ins) {at,ad,n,d,0,0,0,ins}
#define ATTK_INS_LEV(at,ad,n,d, ins, lev) {at,ad,n,d,lev,0,0,ins}
#define OFFHND_ATTK(at,ad,n,d) {at,ad,n,d,0,1,0,0}
#define OFFHND_ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,1,0,0}
#define OFFHND_ATTK_INS(at,ad,n,d, ins) {at,ad,n,d,0,1,0,ins}
#define POLYWEP_ATTK(at,ad,n,d) {at,ad,n,d,0,0,1,0}
#define POLYWEP_ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,0,1,0}
#define NO_ATTK {0,0,0,0,0,0,0,0}
#define ATTK(at,ad,n,d) {at,ad,n,d,0,0,0,0,0}
#define ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,0,0,0,0}
#define ATTK_INS(at,ad,n,d, ins) {at,ad,n,d,0,0,0,ins,0}
#define ATTK_SAN(at,ad,n,d, san) {at,ad,n,d,0,0,0,0,san}
#define ATTK_INS_LEV(at,ad,n,d, ins, lev) {at,ad,n,d,lev,0,0,ins,0}
#define OFFHND_ATTK(at,ad,n,d) {at,ad,n,d,0,1,0,0,0}
#define OFFHND_ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,1,0,0,0}
#define OFFHND_ATTK_INS(at,ad,n,d, ins) {at,ad,n,d,0,1,0,ins,0}
#define POLYWEP_ATTK(at,ad,n,d) {at,ad,n,d,0,0,1,0,0}
#define POLYWEP_ATTK_LEV(at,ad,n,d, lev) {at,ad,n,d,lev,0,1,0,0}
#define NO_ATTK {0,0,0,0,0,0,0,0,0}
#define A(...) {FIRST_TEN(dummy, ##__VA_ARGS__, NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK,NO_ATTK)}
#define FIRST_TEN(dummy, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a1, a2, a3, a4, a5, a6, a7, a8, a9, a10
@ -600,7 +601,7 @@ NEARDATA struct permonst mons[] = {
SIZ(WT_DIMINUTIVE, CN_DIMINUTIVE, MS_SILENT, MZ_SMALL), MR_ELEC|MR_POISON|MR_SICK, MR_ELEC,
MM_FLY|MM_FLOAT|MM_BREATHLESS /*MM*/, MT_HOSTILE|MT_MINDLESS /*MT*/, 0 /*MF*/,
MB_NOLIMBS|MB_NOHEAD|MB_NEUTER /*MB*/, 0 /*MG*/,
MA_ELEMENTAL /*MA*/, MV_TELEPATHIC /*MV*/, MW_ELDER_EYE_ELEM /*MW*/, CLR_GRAY),
MA_ELEMENTAL /*MA*/, MV_TELEPATHIC /*MV*/, MW_ELDER_EYE_ELEM /*MW*/, 0 /*light radius*/, CLR_GRAY),
MON("pursuer", S_EYE, //3 /* needs encyc entry */
LVL(2, 13, 0, 0), (G_NOCORPSE|G_NOGEN),
@ -1426,6 +1427,17 @@ NEARDATA struct permonst mons[] = {
0 /*MM*/, MT_OMNIVORE|MT_HOSTILE|MT_COLLECT /*MT*/, MF_MARTIAL_S|MF_BAB_FULL /*MF*/,
MB_STRONG|MB_FEMALE|MB_HUMANOID /*MB*/, MG_INFRAVISIBLE /*MG*/,
MA_UNDEAD|MA_MINION|MA_PLANT /*MA*/, MV_NORMAL /*MV*/, MW_ELDER_SIGN /*MW*/, 0 /*light radius*/, CLR_BRIGHT_MAGENTA),
MON("rage-walker", S_NYMPH,//37 /*Needs tile, Needs encyc entry*/
LVL(20, 18, 30, -10), (G_NOGEN|G_S_INST(33)),
DEF(NAT_AC(12), SPE_AC(8), NAT_DR_ALL(4,6,4,6,4)),
A(ATTK(AT_CLAW, AD_VAMP, 3, 6), ATTK(AT_CLAW, AD_VAMP, 3, 6), OFFHND_ATTK(AT_CLAW, AD_VAMP, 3, 6),
ATTK_SAN(AT_CLAW, AD_SEDU, 0, 0, -50), ATTK_SAN(AT_CLAW, AD_SEDU, 0, 0, -10),
ATTK(AT_BOOM, AD_MAND, 0, 0)),
SIZ(WT_HUMAN, CN_HUMAN, MS_SHRIEK, MZ_HUMAN),
MR_COLD|MR_FIRE|MR_ELEC|MR_POISON|MR_SLEEP|MR_DRAIN, 0,
MM_BREATHLESS /*MM*/, MT_CARNIVORE|MT_HOSTILE|MT_NOTAKE /*MT*/, MF_MARTIAL_S|MF_BAB_FULL /*MF*/,
MB_STRONG|MB_FEMALE|MB_HUMANOID /*MB*/, MG_INFRAVISIBLE|MG_SANLOSS|MG_INSIGHT /*MG*/,
MA_UNDEAD|MA_ELF|MA_FEY /*MA*/, MV_NORMAL /*MV*/, MW_ELDER_SIGN /*MW*/, 0 /*light radius*/, CLR_CYAN),
MON("Echo", S_NYMPH,//24 /* Needs encyc entry */
LVL(20, 12, 50, -15), (G_NOGEN|G_UNIQ),
DEF(NAT_AC(8)),
@ -6564,6 +6576,15 @@ is a red right hand
MM_BREATHLESS /*MM*/, MT_HIDE|MT_STALK|MT_HOSTILE /*MT*/, MF_MARTIAL_E /*MF*/,
MB_HUMANOID /*MB*/, MG_RPIERCE|MG_NOPOLY|MG_LORD|MG_TRACKER /*MG*/,
MA_UNDEAD /*MA*/, MV_EXTRAMISSION|MV_SEE_INVIS /*MV*/, MW_ELDER_EYE_ENERGY /*MW*/, 0 /*light radius*/, CLR_MAGENTA),
MON("poltergeist", S_GHOST,//12
LVL(20, 18, 50, -5), (G_NOCORPSE|G_NOGEN),
DEF(SPE_AC(15)),
A(ATTK(AT_WEAP, AD_PHYS, 0, 6)),
SIZ(0, 0, MS_SILENT, MZ_HUMAN),
MR_COLD|MR_FIRE|MR_ELEC|MR_DISINT|MR_SLEEP|MR_POISON|MR_STONE|MR_SICK|MR_DRAIN, 0,
MM_FLY|MM_BREATHLESS /*MM*/, MT_STALK|MT_HOSTILE|MT_MINDLESS /*MT*/, MF_BAB_FULL|MF_MARTIAL_E /*MF*/,
MB_HUMANOID|MB_UNSOLID /*MB*/, MG_NOPOLY|MG_HATESHOLY|MG_SANLOSS /*MG*/,
MA_UNDEAD /*MA*/, MV_EXTRAMISSION /*MV*/, MW_ELDER_EYE_ENERGY /*MW*/, 0 /*light radius*/, CLR_CYAN),
/*
* shades
*/

View file

@ -674,7 +674,7 @@ int *weapon, *secweapon, *rweapon, *rwammo, *armor, *shirt, *cloak, *helm, *boot
#ifdef PM_CONVICT
case PM_CONVICT:
if (rn2(4)) *weapon = FLAIL;
else if(rn2(3)) *weapon = HEAVY_IRON_BALL;
else if(rn2(3)) *weapon = BALL;
else *weapon = SPOON;
if(special){
*helm = find_vhelm();

View file

@ -505,7 +505,7 @@ int whodidit; /* 1==hero, 0=other, -1==just check whether it'll pass thru */
if (whodidit ? hero_breaks(otmp, x, y, FALSE) : breaks(otmp, x, y))
*obj_p = otmp = 0; /* object is now gone */
/* breakage makes its own noises */
else if (obj_type == BOULDER || obj_type == STATUE || obj_type == HEAVY_IRON_BALL)
else if (obj_type == BOULDER || obj_type == STATUE || obj_type == BALL)
pline("Whang!");
else if (otmp->oclass == COIN_CLASS ||
otmp->obj_material == GOLD ||

View file

@ -2542,7 +2542,7 @@ museamnesia:
if (vismon){
pline("%s flicks a whip towards your %s!", Monnam(mtmp), hand);
}
if (obj->otyp == HEAVY_IRON_BALL) {
if (obj->otyp == BALL) {
pline("%s fails to wrap around %s.", The_whip, the_weapon);
return 1;
}

View file

@ -1976,11 +1976,11 @@ OBJECT(("Bergonic chair", "strange chair"), BITS(0,0,0,0,0,0,0,0,MZ_LARGE,1,0,0,
BED_CLASS, 0, 0, 60, 100, DMG(D(4)), DMG(D(4)), 0, 0, 0, 2000, HI_ZAP),
#ifdef CONVICT
OBJECT(("heavy iron ball"), BITS(1,0,0,0,0,0,0,0,MZ_LARGE,0,0,0,WHACK,P_FLAIL,IRON,0), {0},
OBJECT(("ball"), BITS(1,0,0,0,0,0,0,0,MZ_LARGE,0,0,0,WHACK,P_FLAIL,IRON,0), {0},
#else
OBJECT(("heavy iron ball"), BITS(1,0,0,0,0,0,0,0,MZ_LARGE,0,0,0,WHACK,P_NONE,IRON,0), {0},
OBJECT(("ball"), BITS(1,0,0,0,0,0,0,0,MZ_LARGE,0,0,0,WHACK,P_NONE,IRON,0), {0},
#endif /* CONVICT */
BALL_CLASS, 1000, 0, 480, 10, DMG(D(25)), DMG(D(25)), 0, 0, 0, 200, HI_METAL),
BALL_CLASS, 1000, 0, 480, 10, DMG(D(25)), DMG(D(25)), 0, 0, 0, 200, HI_METAL, O_MATSPEC(IDED|UNIDED)),
/* +d4 when "very heavy" */
#define CHAIN(names,sdam,ldam,nutr,wt,cost,hitbon,dtyp,mat,color,...) OBJECT( \

View file

@ -1697,6 +1697,12 @@ add_material_words(obj, buf)
struct obj *obj;
char *buf;
{
if (obj->otyp == BALL && (obj->owt > objects[BALL].oc_weight)) {
Strcat(buf, "very ");
}
if(obj->otyp == BALL){
Strcat(buf, "heavy ");
}
/*To avoid an if statement with a massive condition, detect cases where the material should NOT be printed, and return out*/
/*Materials don't matter for lit lightsabers, and they should be described in terms of color*/
if(is_lightsaber(obj) && litsaber(obj))
@ -2036,9 +2042,6 @@ boolean getting_obj_base_desc;
Strcat(buf, OBJ_NAME(objects[ptyp]));
Strcat(buf, " ");
}
if (obj->oclass == BALL_CLASS && (obj->owt > ocl->oc_weight)) {
Strcat(buf, "very ");
}
if (typ == STATUE) {
if (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
Strcat(buf, "historic ");
@ -3787,7 +3790,7 @@ struct alt_spellings {
{ "orichalcum gauntlets", ORIHALCYON_GAUNTLETS },
{ "chain", CHAIN },
{ "iron chain", CHAIN },
{ "iron ball", HEAVY_IRON_BALL },
{ "iron ball", BALL },
{ "mattock", DWARVISH_MATTOCK },
{ "amulet of poison resistance", AMULET_VERSUS_POISON },
{ "amulet of curse resistance", AMULET_VERSUS_CURSES },
@ -5675,7 +5678,7 @@ typfnd:
/* Fall through */
case SKELETON_KEY: case UNIVERSAL_KEY: case CHEST: case BOX:
case SARCOPHAGUS:
case HEAVY_IRON_BALL: case CHAIN: case STATUE:
case BALL: case CHAIN: case STATUE:
/* otmp->cobj already done in mksobj() */
break;
#ifdef MAIL
@ -6105,7 +6108,7 @@ typfnd:
}
}
otmp->owt = weight(otmp);
if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
if (very && otmp->otyp == BALL) otmp->owt += 160;
*wishreturn = WISH_SUCCESS;
return(otmp);

View file

@ -235,7 +235,7 @@ boolean impaired; /* TRUE if throwing/firing slipped OR magr is confused/stun
/* player exercises STR just be throwing heavy things */
if (youagr && !launcher && !(hmoncode & HMON_KICKED) && (
is_boulder(thrownobj) ||
thrownobj->otyp == HEAVY_IRON_BALL
thrownobj->otyp == BALL
))
{
exercise(A_STR, TRUE);
@ -480,7 +480,7 @@ boolean impaired; /* TRUE if throwing/firing slipped OR magr is confused/stun
}
/* limit range of iron balls so hero won't make an invalid move */
if (range > 0 && thrownobj && thrownobj->otyp == HEAVY_IRON_BALL) {
if (range > 0 && thrownobj && thrownobj->otyp == BALL) {
struct obj *bobj;
struct trap *t;
if ((bobj = boulder_at(bhitpos.x, bhitpos.y)) != 0) {
@ -2156,7 +2156,7 @@ int * hurtle_dist;
* than 1, so the effects from throwing attached balls are
* actually possible
*/
if (ammo->otyp == HEAVY_IRON_BALL)
if (ammo->otyp == BALL)
range = urange - (heaviness / 100);
else
range = urange - (heaviness / 40);
@ -3398,7 +3398,7 @@ int n; /* number to try to fire */
ammo_type = SILVER_ARROW;
break;
case AD_BALL:
ammo_type = HEAVY_IRON_BALL;
ammo_type = BALL;
qvr = mksobj(ammo_type, MKOBJ_NOINIT);
rngmod = 8;
break;
@ -3414,7 +3414,7 @@ int n; /* number to try to fire */
rngmod = 8;
break;
case AD_VBLD:
ammo_type = HEAVY_IRON_BALL;
ammo_type = BALL;
qvr = mksobj(ammo_type, MKOBJ_NOINIT);
rngmod = 8;
volley = TRUE;

View file

@ -450,7 +450,7 @@ chat_with_leader()
urole.lgod = GOD_ILSENSINE;
} else if(Role_if(PM_CONVICT)){
struct obj *obj;
obj = mksobj(HEAVY_IRON_BALL, NO_MKOBJ_FLAGS);
obj = mksobj(BALL, NO_MKOBJ_FLAGS);
obj = oname(obj, artiname(ART_IRON_BALL_OF_LEVITATION));
obj->oerodeproof = TRUE;
obj->blessed = TRUE;

View file

@ -3609,7 +3609,7 @@ register struct obj *sobj;
}
setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
#ifdef CONVICT
if (((otmp = carrying(HEAVY_IRON_BALL)) != 0) &&(otmp->oartifact ==
if (((otmp = carrying(BALL)) != 0) &&(otmp->oartifact ==
ART_IRON_BALL_OF_LEVITATION)) {
setworn(otmp, W_BALL);
Your("%s chains itself to you!", xname(otmp));

View file

@ -1605,6 +1605,9 @@ struct obj *otmp;
pline("The cold-iron sears %s!", //half cold-iron damage
mon_nam(mtmp));
}
if(hates_iron(mtmp->data) && tt == SPIKED_PIT){
mtmp->mironmarked = TRUE;
}
if (mtmp->mhp <= 0 ||
thitm(mtmp, rnd((tt == PIT) ? 6 : 10) + ((tt == SPIKED_PIT && hates_iron(mtmp->data)) ? rnd(mtmp->m_lev) : 0), FALSE))
trapkilled = TRUE;
@ -2445,6 +2448,9 @@ glovecheck: target = which_armor(mtmp, W_ARMG);
pline("The cold-iron sears %s!",
mon_nam(mtmp));
}
if(hates_iron(mtmp->data) && tt == SPIKED_PIT){
mtmp->mironmarked = TRUE;
}
mselftouch(mtmp, "Falling, ", FALSE);
if (mtmp->mhp <= 0 ||
thitm(mtmp, rnd((tt == PIT) ? 6 : 10) + ((tt == SPIKED_PIT && hates_iron(mtmp->data)) ? rnd(mtmp->m_lev) : 0), FALSE))

View file

@ -650,8 +650,8 @@ struct monst *magr;
ignore_rolls += u.usanity > 50 ? 0 : u.usanity > 25 ? 1 : u.usanity > 10 ? 2 : 3;
}
if (otyp == HEAVY_IRON_BALL) {
int wt = (int)objects[HEAVY_IRON_BALL].oc_weight;
if (otyp == BALL) {
int wt = (int)objects[BALL].oc_weight;
if ((int)obj->owt > wt) {
wt = ((int)obj->owt - wt) / 160;
@ -1615,7 +1615,7 @@ oselect(struct monst *mtmp, int x, int spot, boolean marilith)
|| (marilith && ok_mariwep(otmp, mtmp, mtmp->data, FALSE))
|| (otmp->otyp == CHAIN && mtmp->mtyp == PM_CATHEZAR)
|| (otmp->otyp == CHAIN && mtmp->mtyp == PM_FIERNA)
|| (otmp->otyp == HEAVY_IRON_BALL && mtmp->mtyp == PM_WARDEN_ARIANNA)
|| (otmp->otyp == BALL && (mtmp->mtyp == PM_WARDEN_ARIANNA || mtmp->mtyp == PM_ARIANNA || mtmp->mtyp == PM_RAGE_WALKER))
|| (mtmp->mtyp == PM_BASTARD_OF_THE_BOREAL_VALLEY)
|| (mtmp->mtyp == PM_LUNGORTHIN)
|| (mtmp->mtyp == PM_CORVIAN_KNIGHT)
@ -1952,7 +1952,7 @@ static const NEARDATA short hwep[] = {
MIRRORBLADE/*your weapon is probably pretty darn good*/,
TOOTH/*6d6/3d12+3*/,
GREATCLUB/*3d6/1d12*/,
HEAVY_IRON_BALL,/*1d25/1d25*/
BALL,/*1d25/1d25*/
VIBROBLADE,/*2d6+3/2d8+4*/
ROD_OF_FORCE/*2d8/2d12*/,
CRYSTAL_SWORD/*2d8/2d12*/,
@ -2084,7 +2084,7 @@ static const NEARDATA short hpwep[] = {
MIRRORBLADE/*your weapon is probably pretty darn good*/,
TOOTH/*6d6/3d12+3*/,
GREATCLUB/*3d6/1d12*/,
HEAVY_IRON_BALL,/*1d25/1d25*/
BALL,/*1d25/1d25*/
VIBROBLADE,/*2d6+3/2d8+4*/
ROD_OF_FORCE/*2d8/2d12*/,
CRYSTAL_SWORD/*2d8/2d12*/,
@ -2277,7 +2277,7 @@ register struct monst *mtmp;
for(otmp=mtmp->minvent; otmp; otmp = otmp->nobj) {
if (/* valid weapon */
(otmp->oclass == WEAPON_CLASS || is_weptool(otmp)
|| otmp->otyp == CHAIN || otmp->otyp == HEAVY_IRON_BALL
|| otmp->otyp == CHAIN || otmp->otyp == BALL
) &&
/* an artifact or other special weapon*/
(otmp->oartifact
@ -2354,7 +2354,7 @@ register struct monst *mtmp;
for(otmp=mtmp->minvent; otmp; otmp = otmp->nobj) {
if (/* valid weapon */
(otmp->oclass == WEAPON_CLASS || is_weptool(otmp)
|| otmp->otyp == CHAIN || otmp->otyp == HEAVY_IRON_BALL
|| otmp->otyp == CHAIN || otmp->otyp == BALL
) &&
/* not already weided in main hand */
(otmp != MON_WEP(mtmp)) &&
@ -3682,7 +3682,7 @@ struct obj *obj;
/* Not using a weapon */
return (P_BARE_HANDED_COMBAT);
#ifdef CONVICT
if ((obj->otyp == HEAVY_IRON_BALL) && (Role_if(PM_CONVICT) || u.sealsActive&SEAL_AHAZU))
if ((obj->otyp == BALL) && (Role_if(PM_CONVICT) || u.sealsActive&SEAL_AHAZU))
return objects[obj->otyp].oc_skill;
#endif /* CONVICT */
if ((obj->otyp == CHAIN) && (Role_if(PM_CONVICT) || u.sealsActive&SEAL_AHAZU))

View file

@ -57,7 +57,7 @@ STATIC_DCL int FDECL(ready_weapon, (struct obj *, boolean));
/* probably should be renamed */
#define erodeable_wep(optr) ((optr)->oclass == WEAPON_CLASS \
|| is_weptool(optr) \
|| (optr)->otyp == HEAVY_IRON_BALL \
|| (optr)->otyp == BALL \
|| (optr)->otyp == CHAIN)
/* used by welded(), and also while wielding */

View file

@ -1951,6 +1951,37 @@ int * tohitmod; /* some attacks are made with decreased accuracy */
if(attk->ins_req > u.uinsight){
GETNEXT
}
/*Some attacks have sanity requirements*/
if(attk->san_req > 0){
if(youdef || by_the_book){
if(NightmareAware_Sanity < attk->san_req){
GETNEXT
}
}
else if(mdef){
if(mdef->encouraged < attk->san_req/10){
GETNEXT
}
}
else {
GETNEXT
}
}
else if(attk->san_req < 0){
if(youdef || by_the_book){
if(NightmareAware_Sanity > -1*attk->san_req){
GETNEXT
}
}
else if(mdef){
if(mdef->encouraged > -1*attk->san_req/10){
GETNEXT
}
}
else {
GETNEXT
}
}
/* khaamnun tanninim switch to sucking memories after dragging target in close */
if (pa->mtyp == PM_KHAAMNUN_TANNIN
&& mdef && distmin(x(magr),y(magr), x(mdef),y(mdef)) <= 1
@ -3819,7 +3850,7 @@ int *shield_margin;
(u.sealsActive&SEAL_EVE) ||
(weapon->otyp == DAGGER && Role_if(PM_ROGUE)) ||
(weapon->otyp == DART && Role_if(PM_TOURIST)) ||
(weapon->otyp == HEAVY_IRON_BALL && Role_if(PM_CONVICT))
(weapon->otyp == BALL && Role_if(PM_CONVICT))
)) {
base_acc = mlev(magr);
}
@ -4112,7 +4143,7 @@ int *shield_margin;
}
/* some objects are more likely to hit than others */
switch (weapon->otyp) {
case HEAVY_IRON_BALL:
case BALL:
if (weapon != uball)
rang_acc += 2;
break;
@ -9640,9 +9671,10 @@ xmeleehurty_core(struct monst *magr, struct monst *mdef, struct attack *attk, st
(youagr ? "Your" : s_suffix(Monnam(magr))),
(youdef ? "you" : mon_nam(mdef))
);
result = xdamagey(magr, mdef, attk, d(rnd(5), (mlev(mdef) + 1) / 2));
if (result&(MM_DEF_DIED|MM_DEF_LSVD)) return result;
}
mdef->mironmarked = TRUE;
result = xdamagey(magr, mdef, attk, d(rnd(5), (mlev(mdef) + 1) / 2));
if (result&(MM_DEF_DIED|MM_DEF_LSVD)) return result;
}
}
/* 1/5 chance of radiant feathers */
@ -9658,6 +9690,7 @@ xmeleehurty_core(struct monst *magr, struct monst *mdef, struct attack *attk, st
pline("The cold iron rachises sear %s.",
(youdef ? "you" : mon_nam(mdef)));
}
mdef->mironmarked = TRUE;
result = xdamagey(magr, mdef, attk, d(5, mlev(mdef)));
if (result&(MM_DEF_DIED|MM_DEF_LSVD)) return result;
}
@ -14518,6 +14551,7 @@ hmoncore(struct monst *magr, struct monst *mdef, struct attack *attk, struct att
/* Simurgh's iron claws, for the player attacking with bared hands */
ironobj |= W_SKIN;
seardmg += rnd(mlev(mdef));
mdef->mironmarked = TRUE;
}
}