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:
parent
f32785e58e
commit
8e3e2a729c
35 changed files with 368 additions and 92 deletions
dat
include
src
|
@ -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",' '
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)) || \
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
166
src/allmain.c
166
src/allmain.c
|
@ -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*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
43
src/monst.c
43
src/monst.c
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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( \
|
||||
|
|
15
src/objnam.c
15
src/objnam.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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))
|
||||
|
|
16
src/weapon.c
16
src/weapon.c
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
42
src/xhity.c
42
src/xhity.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue