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

Elf Madman gameplay changes

Madman init alignment changed to 0

Madmen are better casters:
-Reduced base spellcasting penalty (8->3)
-Reduced armor penalty (20->10)

Psionic caster flavor change: psi casters are described as "concentrating" instead of "casting a spell"

The elven PC is revealed as Lawful and changes to that alignment when opening their box.
-Their alignment does not change if they are crowned or have already changed alignments.

Elf madman sword is also wrathful.

Armor revisions
-Add Protection from Shape changers, deflection, and grappling upgrades.
--Deflection adds spe to AC again (rin protection)
--Grappling replaces the unarmed attack with a grapple (as grappler's grasp)
--Prot from shape changers gives the extrinsic
--Kicking+Jumping == knockback like hammerfeet
--Blind res improves AC and DR by 1 point
-Re order flags to ascending order rather than grouping by armor piece.
-Move flight upgrade from boots to armor.
-Bolt improvements
--If zapped while two-weaponing, the gauntlets holy bolts cost 2x energy (20 vs 10) and deal 2x damage.
--Holy and unholy missile phase worn armor.
--1/2 spe (rounded up) is added to the number of dice. This is still less than the typical number of dice from an attack wand.


"Many wormy fingers entity" (Psurlon template)
-May be applied to:
--Dark worms, baby long and purple worms, long and purple worms.
--Giant eels, electrick eels, kraken, centipedes, garter snakes, water moccasins, pit vipers, pythongs, cobras, and daughters of naunet.
--Adult Dragons (Wyrms)
-Generation rules are slightly different for each class.
--Generate based on both insight and madness. Elf madmen are especially targeted, and skip one insight check. The first insight check is also skipped in the future.
--Even pre-placed worms and dragons can recieve the template.
--Pre placed wormy things can recieve the template for Elf madmen.
--Dragons require a second insight check.
--Dragons and worms roll a flat madness check.
--Wormy things roll an quadratic madness check.
--Madness checks are defeated by Clear Thoughts.
-Adds weapon, offhand, and psionic spellcasting power
--Worms get quarterstaffs and robes
-+6 special AC and DR (all slots)
-Flag changes
--Not an animal or mindless
--Hostile, collects some items, turns tratorous, eats whatever.
--Causes san loss and grants insight
--Nasty
--No longer limbless/handless
--Snakeleg body plan
--telepathic and normal vision
--Alien and G.O.O. (part of the "many wormy fingers" entity)
-Favor (50%) the Mind Crush/Crush bolt spell

Mind Crush/Crush bolt spell
-Vs. PC:
--If the PC does not have Fixed Abilities, reduces one mental stat (int, wis, cha) by one point then checks brainlessness
---The highest stat is chosen, with ties going wis>cha>int.
---The PC is therefore unlikely to actually die to brainlessness, but it could happen!
--Inflicts San damage
--Inflicts further damage based on stat chosen (even if not reduced)
---Wis: drains energy
---Cha: increments the babble counter
---Int: damages spell knowledge

Worms don't have eyes (worms don't)

Introduce amulets of wound closure and vs. evil eyes.
-Two traditional amulet uses.
-Useable by monsters

The madman quest spawns cats instead of rats above ground, and worms instead of bats below ground.

Mistweaver Priestess and Deminymph chats

Random mad monsters in madman quest don't spawn with the dreams madness (they die of the dreams and rise as yellow monsters if they have it)

Add witch to the list of surgery monsters
This commit is contained in:
chris 2023-03-28 15:12:23 -04:00
parent dced723652
commit f662207905
23 changed files with 461 additions and 161 deletions

View file

@ -428,11 +428,48 @@
(ptr)->mtyp == PM_PHASE_SPIDER ||\
(ptr)->mtyp == PM_MIRKWOOD_ELDER \
))
#define is_rat(ptr) ((ptr)->mtyp == PM_SEWER_RAT || \
#define is_rat(ptr) ((ptr)->mlet == S_RODENT && ( \
(ptr)->mtyp == PM_SEWER_RAT || \
(ptr)->mtyp == PM_GIANT_RAT || \
(ptr)->mtyp == PM_RABID_RAT || \
(ptr)->mtyp == PM_ENORMOUS_RAT || \
(ptr)->mtyp == PM_RODENT_OF_UNUSUAL_SIZE)
(ptr)->mtyp == PM_RODENT_OF_UNUSUAL_SIZE))
#define is_basic_worm(ptr) ((ptr)->mlet == S_WORM && (\
(ptr)->mtyp == PM_DARK_WORM ||\
(ptr)->mtyp == PM_BABY_LONG_WORM ||\
(ptr)->mtyp == PM_BABY_PURPLE_WORM ||\
(ptr)->mtyp == PM_LONG_WORM ||\
(ptr)->mtyp == PM_PURPLE_WORM \
))
#define is_wormy_thing(ptr) (((ptr)->mlet == S_EEL && (\
(ptr)->mtyp == PM_GIANT_EEL ||\
(ptr)->mtyp == PM_ELECTRIC_EEL ||\
(ptr)->mtyp == PM_KRAKEN \
)) || ((ptr)->mlet == S_SPIDER && (\
(ptr)->mtyp == PM_CENTIPEDE \
)) || ((ptr)->mlet == S_SNAKE && (\
(ptr)->mtyp == PM_GARTER_SNAKE ||\
(ptr)->mtyp == PM_SNAKE ||\
(ptr)->mtyp == PM_WATER_MOCCASIN ||\
(ptr)->mtyp == PM_PIT_VIPER ||\
(ptr)->mtyp == PM_PYTHON ||\
(ptr)->mtyp == PM_COBRA ||\
(ptr)->mtyp == PM_DAUGHTER_OF_NAUNET \
))\
)
#define is_wormy_dragon(ptr) ((ptr)->mlet == S_DRAGON && (\
(ptr)->mtyp == PM_GRAY_DRAGON ||\
(ptr)->mtyp == PM_SILVER_DRAGON ||\
(ptr)->mtyp == PM_SHIMMERING_DRAGON ||\
(ptr)->mtyp == PM_WHITE_DRAGON ||\
(ptr)->mtyp == PM_ORANGE_DRAGON ||\
(ptr)->mtyp == PM_BLACK_DRAGON ||\
(ptr)->mtyp == PM_BLUE_DRAGON ||\
(ptr)->mtyp == PM_GREEN_DRAGON ||\
(ptr)->mtyp == PM_RED_DRAGON ||\
(ptr)->mtyp == PM_DEEP_DRAGON ||\
(ptr)->mtyp == PM_YELLOW_DRAGON\
))
#define is_dragon(ptr) (((ptr)->mflagsa & MA_DRAGON) != 0L)
#define is_true_dragon(ptr) ((monsndx(ptr) >= PM_BABY_GRAY_DRAGON && monsndx(ptr) <= PM_YELLOW_DRAGON) || \
(ptr)->mtyp == PM_PLATINUM_DRAGON || (ptr)->mtyp == PM_CHROMATIC_DRAGON)

View file

@ -452,8 +452,9 @@
#define MON_RED_WORD GOD_RAY+1
//100
#define HYPNOTIC_COLORS MON_RED_WORD+1
#define CRUSH_BOLT HYPNOTIC_COLORS+1
#define MON_LASTSPELL HYPNOTIC_COLORS
#define MON_LASTSPELL CRUSH_BOLT
//Not yet implemented
// #define MON_FIRE STRANGLE+1
// #define MON_BLIZZARD MON_FIRAGA+1

View file

@ -276,7 +276,7 @@ struct monst {
#define M_BLACK_WEB 13 /* Zombie with a shadow blade attack */
#define M_GREAT_WEB 14 /* Has a stronger shadow blade attack */
#define SLIME_REMNANT 15 /* slimey, like an ancient of corruption */
#define YELLOW_TEMPLATE 16 /* causes sleep and damages sanity (unimplemented) */
#define YELLOW_TEMPLATE 16 /* causes sleep and damages sanity */
#define DREAM_LEECH 17 /* sucks mental atributes */
#define MAD_TEMPLATE 18 /* mad angel template */
#define FALLEN_TEMPLATE 19 /* fallen angel template */
@ -287,7 +287,8 @@ struct monst {
#define PLAGUE_TEMPLATE 24 /* suffering from a life-drain plague, cure to recruit */
#define SPORE_ZOMBIE 25 /* fungus zombie */
#define CORDYCEPS 26 /* spore shedder */
#define MAXTEMPLATE CORDYCEPS
#define PSURLON 27 /* psychic worm */
#define MAXTEMPLATE PSURLON
//define HALF_DEMON FACTION_PADDING+1 /* half-demon ??? */
//define HALF_DEVIL FACTION_PADDING+2 /* half-devil ??? */

View file

@ -329,6 +329,7 @@ struct obj {
#define ovar1_acidSplashDamage ovar1
#define ovar1_corpseRumorCooldown ovar1
#define ovar1_secretsSecret ovar1
#define ovar1_iea_upgrades ovar1
#define ovar1_gober ovar1
#define ovar1_seals ovar1
@ -370,70 +371,44 @@ struct obj {
#define GIBBOUS_MOON 3
#define FULL_MOON 4
#define check_imp_mod(obj, prop) ((obj)->ovar1&(prop))
#define add_imp_mod(obj, prop) ((obj)->ovar1 |= (prop))
//Body
///Ring
#define IEA_FIXED_ABIL 0x0000000000000001L
///Ring
#define IEA_FAST_HEAL 0x0000000000000002L
///Shield or amulet
#define IEA_REFLECTING 0x0000000000000004L
///Amulet
#define IEA_SICK_RES 0x0000000000000008L
///Cloak
#define IEA_HALF_PHDAM 0x0000000000000010L
///Cloak?
#define IEA_HALF_SPDAM 0x0000000000000020L
///Cloak
#define IEA_DISPLACED 0x0000000000000040L
///Cloak or ring
#define IEA_INVIS 0x0000000000000080L
#define check_imp_mod(obj, prop) ((obj)->ovar1_iea_upgrades&(prop))
#define add_imp_mod(obj, prop) ((obj)->ovar1_iea_upgrades |= (prop))
#define IEA_BODY_MASK (IEA_FIXED_ABIL|IEA_FAST_HEAL|IEA_REFLECTING|IEA_SICK_RES|IEA_HALF_PHDAM|IEA_HALF_SPDAM|IEA_DISPLACED|IEA_INVIS)
//Gauntlet
///Water walking boots
#define IEA_SWIMMING 0x0000000000000100L
///gauntlets of power
#define IEA_GOPOWER 0x0000000000000200L
///gauntlets of dexterity
#define IEA_GODEXTERITY 0x0000000000000400L
///Ring
#define IEA_INC_DAM 0x0000000000000800L
///Wand MM
#define IEA_BOLTS 0x0000000000001000L
#define IEA_FIXED_ABIL 0x00000001L
#define IEA_FAST_HEAL 0x00000002L
#define IEA_REFLECTING 0x00000004L
#define IEA_SICK_RES 0x00000008L
#define IEA_HALF_PHDAM 0x00000010L
#define IEA_HALF_SPDAM 0x00000020L
#define IEA_DISPLACED 0x00000040L
#define IEA_INVIS 0x00000080L
#define IEA_SWIMMING 0x00000100L
#define IEA_GOPOWER 0x00000200L
#define IEA_GODEXTERITY 0x00000400L
#define IEA_INC_DAM 0x00000800L
#define IEA_BOLTS 0x00001000L
#define IEA_FLYING 0x00002000L
#define IEA_JUMPING 0x00004000L
#define IEA_FAST 0x00008000L
#define IEA_TELEPORT 0x00010000L
#define IEA_NOBREATH 0x00020000L
#define IEA_LIFESENSE 0x00040000L
#define IEA_SEE_INVIS 0x00080000L
#define IEA_TELEPAT 0x00100000L
#define IEA_BLIND_RES 0x00200000L
#define IEA_INC_ACC 0x00400000L
#define IEA_TELE_CNTRL 0x00800000L
#define IEA_KICKING 0x01000000L
#define IEA_PROT_SHAPE 0x02000000L
#define IEA_DEFLECTION 0x04000000L
#define IEA_STRANGLE 0x08000000L
#define IEA_GLOVE_MASK (IEA_SWIMMING|IEA_GOPOWER|IEA_GODEXTERITY|IEA_INC_DAM|IEA_BOLTS)
#define IEA_HELM_MASK (IEA_NOBREATH|IEA_LIFESENSE|IEA_SEE_INVIS|IEA_TELEPAT|IEA_BLIND_RES|IEA_INC_ACC|IEA_TELE_CNTRL|IEA_PROT_SHAPE)
#define IEA_BODY_MASK (IEA_FLYING|IEA_FIXED_ABIL|IEA_FAST_HEAL|IEA_REFLECTING|IEA_SICK_RES|IEA_HALF_PHDAM|IEA_HALF_SPDAM|IEA_DISPLACED|IEA_INVIS|IEA_DEFLECTION)
#define IEA_GLOVE_MASK (IEA_SWIMMING|IEA_GOPOWER|IEA_GODEXTERITY|IEA_INC_DAM|IEA_BOLTS|IEA_STRANGLE)
#define IEA_BOOT_MASK (IEA_JUMPING|IEA_FAST|IEA_TELEPORT|IEA_KICKING)
//Boots
#define IEA_FLYING 0x0000000000002000L
#define IEA_JUMPING 0x0000000000004000L
///Boots or Wand or ring
#define IEA_FAST 0x0000000000008000L
///Wand or ring
#define IEA_TELEPORT 0x0000000000010000L
//Boots
#define IEA_KICKING 0x0000000001000000L
#define IEA_BOOT_MASK (IEA_FLYING|IEA_JUMPING|IEA_FAST|IEA_TELEPORT|IEA_KICKING)
//Helm
///Amulet
#define IEA_NOBREATH 0x0000000000020000L
///Wand of draining
#define IEA_LIFESENSE 0x0000000000040000L
///Ring
#define IEA_SEE_INVIS 0x0000000000080000L
///Helm
#define IEA_TELEPAT 0x0000000000100000L
///Crystal
#define IEA_BLIND_RES 0x0000000000200000L
///Ring
#define IEA_INC_ACC 0x0000000000400000L
///Ring
#define IEA_TELE_CNTRL 0x0000000000800000L
#define IEA_HELM_MASK (IEA_NOBREATH|IEA_LIFESENSE|IEA_SEE_INVIS|IEA_TELEPAT|IEA_BLIND_RES|IEA_INC_ACC|IEA_TELE_CNTRL)
/* Songs that the Singing Sword has heard */
/* Spirits bound into the Pen of the Void */
@ -970,15 +945,19 @@ struct obj {
|| (obj)->otyp == CRYSTAL_HELM \
|| (obj)->otyp == RIN_INCREASE_ACCURACY \
|| (obj)->otyp == RIN_TELEPORT_CONTROL \
|| (obj)->otyp == RIN_PROTECTION_FROM_SHAPE_CHAN \
) && objects[(obj)->otyp].oc_name_known)
#define gauntlets_upgrade_obj(obj) (((obj)->otyp == WATER_WALKING_BOOTS\
|| (obj)->otyp == GAUNTLETS_OF_POWER \
|| (obj)->otyp == GAUNTLETS_OF_DEXTERITY \
|| (obj)->otyp == RIN_INCREASE_DAMAGE \
|| (obj)->otyp == WAN_MAGIC_MISSILE \
|| (obj)->otyp == AMULET_OF_STRANGULATION \
) && objects[(obj)->otyp].oc_name_known)
#define armor_upgrade_obj(obj) (((obj)->otyp == RIN_SUSTAIN_ABILITY \
#define armor_upgrade_obj(obj) (((obj)->otyp == FLYING_BOOTS \
|| (obj)->otyp == RIN_SUSTAIN_ABILITY \
|| (obj)->otyp == RIN_REGENERATION \
|| (obj)->otyp == AMULET_OF_WOUND_CLOSURE \
|| (obj)->otyp == AMULET_OF_REFLECTION \
|| (obj)->otyp == SHIELD_OF_REFLECTION \
|| (obj)->otyp == JUMPING_BOOTS \
@ -991,9 +970,9 @@ struct obj {
|| (obj)->otyp == CLOAK_OF_INVISIBILITY \
|| (obj)->otyp == RIN_INVISIBILITY \
|| (obj)->otyp == WAN_MAKE_INVISIBLE \
|| (obj)->otyp == RIN_PROTECTION \
) && objects[(obj)->otyp].oc_name_known)
#define boots_upgrade_obj(obj) (((obj)->otyp == FLYING_BOOTS \
|| (obj)->otyp == JUMPING_BOOTS \
#define boots_upgrade_obj(obj) (((obj)->otyp == JUMPING_BOOTS \
|| (obj)->otyp == SPEED_BOOTS \
|| (obj)->otyp == KICKING_BOOTS \
|| (obj)->otyp == WAN_SPEED_MONSTER \
@ -1299,6 +1278,8 @@ struct obj {
||otyp == AMULET_VERSUS_CURSES \
||otyp == AMULET_OF_ESP \
||otyp == AMULET_VERSUS_POISON \
||otyp == AMULET_OF_WOUND_CLOSURE \
||otyp == AMULET_VERSUS_EVIL_EYES \
)
/* helpers, simple enough to be macros */

View file

@ -7893,10 +7893,10 @@ upgradeImpArmor()
STANDARD_UPGRADE(IEA_NOBREATH, "life-support subsystem")
break;
case WAN_DRAINING:
STANDARD_UPGRADE(IEA_LIFESENSE, "life-sign detector")
STANDARD_UPGRADE(IEA_LIFESENSE, "life-sign sensor")
break;
case RIN_SEE_INVISIBLE:
STANDARD_UPGRADE(IEA_SEE_INVIS, "crystal eye sensor")
STANDARD_UPGRADE(IEA_SEE_INVIS, "crystal eye")
break;
case HELM_OF_TELEPATHY:
case AMULET_OF_ESP:
@ -7911,6 +7911,9 @@ upgradeImpArmor()
case RIN_TELEPORT_CONTROL:
STANDARD_UPGRADE(IEA_TELE_CNTRL, "teleportation control subsystem")
break;
case RIN_PROTECTION_FROM_SHAPE_CHAN:
STANDARD_UPGRADE(IEA_PROT_SHAPE, "self-bored lens")
break;
default:
impossible("Unknown repair component, sorry :(.");
return MOVE_CANCELLED;
@ -7932,17 +7935,20 @@ upgradeImpArmor()
STANDARD_UPGRADE(IEA_SWIMMING, "swimming webs")
break;
case GAUNTLETS_OF_POWER:
STANDARD_UPGRADE(IEA_GOPOWER, "power subsystem")
STANDARD_UPGRADE(IEA_GOPOWER, "power servos")
break;
case GAUNTLETS_OF_DEXTERITY:
STANDARD_UPGRADE(IEA_GODEXTERITY, "dexterity subsystem")
STANDARD_UPGRADE(IEA_GODEXTERITY, "dexterity servos")
break;
case RIN_INCREASE_DAMAGE:
STANDARD_UPGRADE(IEA_INC_DAM, "microtargetting subsystem")
STANDARD_UPGRADE(IEA_INC_DAM, "microtargetting servos")
break;
case WAN_MAGIC_MISSILE:
STANDARD_UPGRADE(IEA_BOLTS, "missile projectors")
break;
case AMULET_OF_STRANGULATION:
STANDARD_UPGRADE(IEA_STRANGLE, "grappling servos")
break;
default:
impossible("Unknown repair component, sorry :(.");
return MOVE_CANCELLED;
@ -7960,10 +7966,14 @@ upgradeImpArmor()
return MOVE_CANCELLED;
}
switch(upitm->otyp){
case FLYING_BOOTS:
STANDARD_UPGRADE(IEA_FLYING, "moth wings")
break;
case RIN_SUSTAIN_ABILITY:
STANDARD_UPGRADE(IEA_FIXED_ABIL, "stasis subsystem")
break;
case RIN_REGENERATION:
case AMULET_OF_WOUND_CLOSURE:
STANDARD_UPGRADE(IEA_FAST_HEAL, "medical subsystem")
break;
case AMULET_OF_REFLECTION:
@ -7990,6 +8000,9 @@ upgradeImpArmor()
case WAN_MAKE_INVISIBLE:
STANDARD_UPGRADE(IEA_INVIS, "active camouflage system")
break;
case RIN_PROTECTION:
STANDARD_UPGRADE(IEA_DEFLECTION, "deflectors")
break;
default:
impossible("Unknown repair component, sorry :(.");
return MOVE_CANCELLED;
@ -8007,9 +8020,6 @@ upgradeImpArmor()
return MOVE_CANCELLED;
}
switch(upitm->otyp){
case FLYING_BOOTS:
STANDARD_UPGRADE(IEA_FLYING, "flight subsystem")
break;
case JUMPING_BOOTS:
STANDARD_UPGRADE(IEA_JUMPING, "jump jets")
break;

View file

@ -4754,7 +4754,10 @@ boolean printmessages; /* print generic elemental damage messages */
/* EXTERNAL damage sources -- explosions and the like, primarily */
/* knockback effect */
if (((arti_attack_prop(otmp, ARTA_KNOCKBACK) && !rn2(4)) || arti_attack_prop(otmp, ARTA_KNOCKBACKX)) && !(
if (((arti_attack_prop(otmp, ARTA_KNOCKBACK) && !rn2(4))
|| arti_attack_prop(otmp, ARTA_KNOCKBACKX)
|| (otmp->otyp == IMPERIAL_ELVEN_BOOTS && check_imp_mod(otmp, IEA_KICKING) && check_imp_mod(otmp, IEA_JUMPING))
) && !(
/* exclusions below */
(oartifact == ART_TOBIUME) /* Tobiume only does the knockback if mdef is nearly dead */
))
@ -4956,7 +4959,7 @@ boolean printmessages; /* print generic elemental damage messages */
}
/* The Grappler's Grasp has a chance to begin grapples. */
if (oartifact == ART_GRAPPLER_S_GRASP) {
if (oartifact == ART_GRAPPLER_S_GRASP || (otmp->otyp == IMPERIAL_ELVEN_GAUNTLETS && check_imp_mod(otmp, IEA_STRANGLE))) {
/* check if we can begin a grapple -- Damage is done by adding an AT_HUGS to your attack chain, NOT here. */
if ((youagr || youdef) && !u.ustuck && !sticks(mdef))
{

View file

@ -943,6 +943,7 @@ boolean full;
else if (full && template == PLAGUE_TEMPLATE) Sprintf(buf2, "%s, plague victim", buf);
else if (full && template == SPORE_ZOMBIE) Sprintf(buf2, "%s, spore infectee", buf);
else if (full && template == CORDYCEPS) Sprintf(buf2, "%s's sporulating corpse", buf);
else if (full && template == PSURLON) Sprintf(buf2, "%s the finger", buf);
else Strcpy(buf2, buf);
}
else {
@ -972,6 +973,7 @@ boolean full;
else if (full && template == PLAGUE_TEMPLATE) Sprintf(buf2, "%s plague-victim", buf);
else if (full && template == SPORE_ZOMBIE) Sprintf(buf2, "%s infectee", buf);
else if (full && template == CORDYCEPS) Sprintf(buf2, "%s cordyceps", buf);
else if (full && template == PSURLON) Sprintf(buf2, "%s finger", buf);
else Strcpy(buf2, buf);
}

View file

@ -2145,6 +2145,10 @@ struct obj * otmp;
// visored helm's bonus IS affected by mat and erosion
if (otmp->otyp == find_vhelm()) def += 1;
// Ditto the bonus for repairing the visor of an IEHelm
if (otmp->otyp == IMPERIAL_ELVEN_HELM && check_imp_mod(otmp, IEA_BLIND_RES))
def += 1;
// add material bonus
def += material_def_bonus(otmp, def, TRUE);
@ -2175,6 +2179,10 @@ struct obj * otmp;
spemult *= 2;
def += (otmp->spe * spemult + 0) / 2;
//Full spe bonus to AC on top of normal 1/2 bonus.
if(otmp->otyp == IMPERIAL_ELVEN_ARMOR && check_imp_mod(otmp, IEA_DEFLECTION))
def += otmp->spe;
}
// artifact bonus def
@ -2229,6 +2237,10 @@ struct obj * otmp;
// visored helm's bonus IS affected by mat and erosion
if (otmp->otyp == find_vhelm()) def += 1;
// Ditto the bonus for repairing the visor of an IEHelm
if (otmp->otyp == IMPERIAL_ELVEN_HELM && check_imp_mod(otmp, IEA_BLIND_RES))
def += 1;
// add material bonus
def += material_def_bonus(otmp, def, FALSE);

View file

@ -4150,6 +4150,43 @@ boolean goodequip;
}
}
STATIC_OVL void
worm_initweap(mtmp, mkobjflags, faction, goodequip)
register struct monst *mtmp;
int mkobjflags;
int faction;
boolean goodequip;
{
int mm = mtmp->mtyp;
int chance;
struct permonst *ptr = mtmp->data;
struct obj *otmp;
if(has_template(mtmp, PSURLON)){
mongets(mtmp, QUARTERSTAFF, NO_MKOBJ_FLAGS);
}
}
STATIC_OVL void
worm_initinv(mtmp, mkobjflags, faction, goodequip)
register struct monst *mtmp;
int mkobjflags;
int faction;
boolean goodequip;
{
int mm = mtmp->mtyp;
int chance;
struct permonst *ptr = mtmp->data;
struct obj *otmp;
if(has_template(mtmp, PSURLON)){
otmp = mongets(mtmp, ROBE, NO_MKOBJ_FLAGS);
if(otmp){
otmp->obj_color = !rn2(3) ? CLR_BLUE : rn2(2) ? CLR_RED : CLR_MAGENTA;
}
}
}
STATIC_OVL void
m_initweap(mtmp, mkobjflags, faction, goodequip, mmflags)
register struct monst *mtmp;
@ -4194,6 +4231,9 @@ int mmflags;
case S_ELEMENTAL:
elemental_initweap(mtmp, mkobjflags, faction, goodequip);
break;
case S_WORM:
worm_initweap(mtmp, mkobjflags, faction, goodequip);
break;
case S_HUMAN:
human_initweap(mtmp, mkobjflags, faction, goodequip);
break;
@ -10074,6 +10114,9 @@ boolean goodequip;
case S_UMBER:
umber_initinv(mtmp, mkobjflags, faction, goodequip);
break;
case S_WORM:
worm_initinv(mtmp, mkobjflags, faction, goodequip);
break;
case S_ANT:
if(In_law(&u.uz)){
//Civilized ants
@ -12215,6 +12258,16 @@ boolean randmonst;
else if(Is_earthlevel(&u.uz) && ptr->mtyp == PM_MAHADEVA) {
mkmon_template = WORLD_SHAPER;
}
/* the worm-entity has it out for mad elves for some reason */
else if(((Role_if(PM_MADMAN) && Race_if(PM_ELF)) || Infuture || check_insight()) && is_basic_worm(ptr) && roll_generic_flat_madness(TRUE)){
mkmon_template = PSURLON;
}
else if(((Role_if(PM_MADMAN) && Race_if(PM_ELF)) || Infuture || (randmonst && check_insight())) && is_wormy_thing(ptr) && roll_generic_madness(TRUE)){
mkmon_template = PSURLON;
}
else if(((Role_if(PM_MADMAN) && Race_if(PM_ELF)) || Infuture || check_insight()) && is_wormy_dragon(ptr) && roll_generic_flat_madness(TRUE) && check_insight() && randmonst){
mkmon_template = PSURLON;
}
/* insight check: making pseudonatural creatures out of anything reasonable */
else if(randmonst && can_undead(ptr) && check_insight()){
mkmon_template = PSEUDONATURAL;

View file

@ -370,6 +370,10 @@ unsigned int type;
}
}
boolean quake = FALSE;
if(has_template(mtmp, PSURLON)){
if(rn2(2))
return CRUSH_BOLT;
}
//50% favored spells
if (rn2(2)) {
switch(monsndx(mtmp->data)) {
@ -1966,6 +1970,7 @@ const char * spellname[] =
"MON_RED_WORD",
//100
"HYPNOTIC_COLORS",
"CRUSH_BOLT",
};
@ -2091,11 +2096,18 @@ int tary;
!is_aoe_attack_spell(spellnum)) {
/* message */
if ((youagr || canspotmon(magr)) && magr->mtyp != PM_HOUND_OF_TINDALOS) {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
levl[tarx][tary].typ == WATER
? "empty water" : "thin air");
if(attk->adtyp == AD_PSON){
pline("%s concentrate%s.",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s");
}
else {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
levl[tarx][tary].typ == WATER
? "empty water" : "thin air");
}
}
/* monsters figure out you aren't there */
if (!youagr && youdef) {
@ -2204,23 +2216,30 @@ int tary;
&& spellnum != MON_RED_WORD
&& spellnum != HYPNOTIC_COLORS
) {
if (is_undirected_spell(spellnum) || notarget || (!foundem && distmin(x(mdef), y(mdef), tarx, tary) > 2))
buf[0] = '\0';
else
{
Sprintf(buf, " at %s",
youdef
? ( (Displaced && (!foundem)) ?
"your displaced image" :
(!foundem) ?
"a spot near you" :
"you")
: (canspotmon(mdef) ? mon_nam(mdef) : "something"));
if(attk->adtyp == AD_PSON){
pline("%s concentrate%s.",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s");
}
else {
if (is_undirected_spell(spellnum) || notarget || (!foundem && distmin(x(mdef), y(mdef), tarx, tary) > 2))
buf[0] = '\0';
else
{
Sprintf(buf, " at %s",
youdef
? ( (Displaced && (!foundem)) ?
"your displaced image" :
(!foundem) ?
"a spot near you" :
"you")
: (canspotmon(mdef) ? mon_nam(mdef) : "something"));
}
pline("%s cast%s a spell%s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
buf);
}
pline("%s cast%s a spell%s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
buf);
}
}
@ -2330,22 +2349,36 @@ int tary;
if (!foundem) {
if ((youagr || youdef || canspotmon(magr))
&& magr->mtyp != PM_HOUND_OF_TINDALOS
) {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canseemon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
levl[tarx][tary].typ == WATER
? "empty water" : "thin air");
) {
if(attk->adtyp == AD_PSON){
pline("%s concentrate%s.",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s");
}
else {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canseemon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
levl[tarx][tary].typ == WATER
? "empty water" : "thin air");
}
}
return MM_MISS;
}
/* otherwise, print a spellcasting message */
else {
if ((youagr || youdef || canspotmon(magr)) && magr->mtyp != PM_HOUND_OF_TINDALOS) {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
youdef ? "you" : (canspotmon(mdef) ? mon_nam(mdef) : "something"));
if(attk->adtyp == AD_PSON){
pline("%s concentrate%s.",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s");
}
else {
pline("%s cast%s a spell at %s!",
youagr ? "You" : canspotmon(magr) ? Monnam(magr) : "Something",
youagr ? "" : "s",
youdef ? "you" : (canspotmon(mdef) ? mon_nam(mdef) : "something"));
}
}
}
@ -2779,6 +2812,7 @@ int tary;
case DOUBT_BOLT:
case BARF_BOLT:
case BABBLE_BOLT:
case CRUSH_BOLT:
/* needs direct target */
if (!foundem) {
impossible("No mdef for mind-bolt");
@ -2902,6 +2936,36 @@ int tary;
mdef->mconf = TRUE;
}
}
else if(spell == CRUSH_BOLT){
if (youdef) {
int stat = ACURR(A_INT) <= ACURR(A_CHA) ? A_CHA : A_INT;
stat = ACURR(stat) <= ACURR(A_WIS) ? A_WIS : stat;
pline("Your mind is being crushed!");
if(!Fixed_abil){
adjattrib(stat, -1, FALSE);
exercise(A_INT, FALSE);
exercise(A_WIS, FALSE);
exercise(A_CHA, FALSE);
check_brainlessness();
}
if(save_vs_sanloss())
change_usanity(-1*(25-ACURR(stat))/2, FALSE);
else
change_usanity(-1*(25-ACURR(stat)), TRUE);
if(stat == A_INT)
damage_spells(dmg/10);
else if(stat == A_WIS)
drain_en(dmg);
else if(stat == A_CHA)
HBabble += dmg;
}
else {
if (canseemon(mdef))
pline("%s falters!", Monnam(mdef));
mdef->mspec_used += dmg;
mdef->mconf = TRUE;
}
}
/* deal damage */
return xdamagey(magr, mdef, attk, dmg);
@ -6173,6 +6237,7 @@ int spellnum;
case DOUBT_BOLT:
case BARF_BOLT:
case BABBLE_BOLT:
case CRUSH_BOLT:
case OPEN_WOUNDS:
case MAGIC_MISSILE:
case CONE_OF_COLD:

View file

@ -509,6 +509,27 @@ int template;
ptr->hdr = 0; //Exposed brain
ptr->mflagst &= ~(MT_ANIMAL|MT_MINDLESS);
ptr->mflagsg |= (MG_INSIGHT|MG_SANLOSS);
ptr->mflagsv |= MV_TELEPATHIC;
if(!(ptr->mflagsw&MW_EYE_OF_YGG)){
ptr->mflagsw |= MW_ELDER_SIGN;
}
break;
case PSURLON:
ptr->pac += 6;
ptr->spe_hdr += 6;
ptr->spe_bdr += 6;
ptr->spe_gdr += 6;
ptr->spe_ldr += 6;
ptr->spe_fdr += 6;
ptr->mflagst &= ~(MT_ANIMAL|MT_MINDLESS);
ptr->mflagst |= (MT_HOSTILE|MT_GREEDY|MT_JEWELS|MT_COLLECT|MT_TRAITOR|MT_OMNIVORE);
ptr->mflagsg |= (MG_NASTY|MG_INSIGHT|MG_SANLOSS);
ptr->mflagsb &= ~(MB_NOLIMBS|MB_NOHANDS|MB_ANIMAL);
ptr->mflagsb |= MB_HUMANOID|MB_SLITHY;
ptr->mflagsv |= MV_TELEPATHIC|MV_NORMAL;
ptr->mflagsa |= MA_ET|MA_G_O_O;
if(!(ptr->mflagsm&MM_TUNNEL) && !(ptr->mflagsm&MM_WALLWALK))
ptr->mflagsm |= (MM_TUNNEL|MM_NEEDPICK);
if(!(ptr->mflagsw&MW_EYE_OF_YGG)){
ptr->mflagsw |= MW_ELDER_SIGN;
}
@ -761,6 +782,8 @@ int template;
/* adjust attacks in the permonst */
extern struct attack noattack;
boolean special = FALSE;
boolean special_2 = FALSE;
boolean special_3 = FALSE;
struct attack * attk;
boolean insert;
int i, j;
@ -918,12 +941,12 @@ int template;
attk->damd = max(attk->damd, max(ptr->msize * 2, 4));
}
/* some templates want to adjust existing attacks, or add additional attacks */
#define insert_okay (!special && (is_null_attk(attk) || \
((attk->aatyp > AT_HUGS && !weapon_aatyp(attk->aatyp) \
&& !(attk->aatyp == AT_BREA && ptr->mlet == S_DRAGON)) || attk->aatyp == AT_NONE)) \
#define insert_okay(specvar) (!(specvar) && (is_null_attk(attk) || \
((attk->aatyp > AT_HUGS && !weapon_aatyp(attk->aatyp) \
&& !(attk->aatyp == AT_BREA && ptr->mlet == S_DRAGON)) || attk->aatyp == AT_NONE)) \
&& (insert = TRUE))
#define end_insert_okay (!special && (is_null_attk(attk) || attk->aatyp == AT_NONE) && (insert = TRUE))
#define maybe_insert() if(insert) {for(j=NATTK-i-1;j>0;j--)attk[j]=attk[j-1];*attk=noattack;i++;}
#define end_insert_okay(specvar) (!(specvar) && (is_null_attk(attk) || attk->aatyp == AT_NONE) && (insert = TRUE))
#define maybe_insert() if(insert) {for(j=NATTK-i-1;j>0;j--)attk[j]=attk[j-1];*attk=noattack;insert=FALSE;}
/* zombies/skeletons get a melee attack if they don't have any (likely due to disallowed aatyp) */
if ((template == ZOMBIFIED || template == SKELIFIED || template == MINDLESS) && (
i == 0 && (!nolimbs(ptr) || has_head(ptr)) && (
@ -932,8 +955,8 @@ int template;
) && (insert = TRUE)
)
){
maybe_insert()
attk->aatyp = !nolimbs(ptr) ? AT_CLAW : AT_BITE;
maybe_insert();
attk->aatyp = !nolimbs(ptr) ? AT_CLAW : AT_BITE;
attk->adtyp = AD_PHYS;
attk->damn = ptr->mlevel / 10 + (template == ZOMBIFIED ? 1 : 2);
attk->damd = max(ptr->msize * 2, 4);
@ -941,7 +964,7 @@ int template;
/* skeletons get a paralyzing touch */
if (template == SKELIFIED && (
insert_okay
insert_okay(special)
))
{
maybe_insert();
@ -954,7 +977,7 @@ int template;
/* vitreans get a cold touch */
if (template == CRYSTALFIED && (
insert_okay
insert_okay(special)
))
{
maybe_insert();
@ -965,7 +988,7 @@ int template;
special = TRUE;
}
if (template == MISTWEAVER && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -982,7 +1005,7 @@ int template;
attk->adtyp == AD_SQUE ||
attk->adtyp == AD_SAMU
))
|| insert_okay
|| insert_okay(special)
))
{
maybe_insert();
@ -1005,7 +1028,7 @@ int template;
/* vampires' bites are vampiric: pt 2: primary bites*/
if (template == VAMPIRIC && (
attk->aatyp == AT_BITE
|| (insert_okay && !nomouth(ptr->mtyp))
|| (insert_okay(special) && !nomouth(ptr->mtyp))
)
){
maybe_insert();
@ -1028,7 +1051,7 @@ int template;
/* infectees' bites are sickening: pt 2: primary bites*/
if (template == SPORE_ZOMBIE && (
attk->aatyp == AT_BITE
|| (insert_okay && !nomouth(ptr->mtyp))
|| (insert_okay(special) && !nomouth(ptr->mtyp))
)
){
maybe_insert();
@ -1041,7 +1064,7 @@ int template;
/* pseudonatural's bites become int-draining tentacles */
if (template == PSEUDONATURAL && (
(attk->aatyp == AT_BITE)
|| insert_okay
|| insert_okay(special)
))
{
maybe_insert();
@ -1084,7 +1107,7 @@ int template;
}
/* tomb herd also gets an abduction attack */
if (template == TOMB_HERD && (
insert_okay
insert_okay(special)
))
{
maybe_insert();
@ -1096,7 +1119,7 @@ int template;
}
/* yith gain spellcasting */
if (template == YITH && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1108,7 +1131,41 @@ int template;
}
/* cranium rats gain psionic spellcasting */
if (template == CRANIUM_RAT && (
end_insert_okay
attk->aatyp == AT_MAGC || end_insert_okay(special)
))
{
maybe_insert();
attk->aatyp = AT_MAGC;
attk->adtyp = AD_PSON;
attk->damn = 0;
attk->damd = 15;
special = TRUE;
}
/* psurlons have hands and psionic spellcasting */
if (template == PSURLON && (
attk->aatyp == AT_WEAP || insert_okay(special_2)
)
){
maybe_insert();
attk->aatyp = AT_WEAP;
attk->adtyp = AD_PHYS;
attk->damn = 1;
attk->damd = ptr->msize+1;
special_2 = TRUE;
}
if (template == PSURLON && (
attk->aatyp == AT_XWEP || insert_okay(special_3)
))
{
maybe_insert();
attk->aatyp = AT_XWEP;
attk->adtyp = AD_PHYS;
attk->damn = 1;
attk->damd = ptr->msize+1;
special_3 = TRUE;
}
if (template == PSURLON && (
attk->aatyp == AT_MAGC || end_insert_okay(special)
))
{
maybe_insert();
@ -1120,7 +1177,7 @@ int template;
}
/* monsters that have mastered the black web gain shadow blades */
if (template == M_BLACK_WEB && (
insert_okay
insert_okay(special)
))
{
maybe_insert();
@ -1131,7 +1188,7 @@ int template;
special = TRUE;
}
if (template == M_GREAT_WEB && (
insert_okay
insert_okay(special)
))
{
maybe_insert();
@ -1164,7 +1221,7 @@ int template;
attk->damd = max(ptr->msize * 2, 4);
}
if (template == SLIME_REMNANT && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1179,7 +1236,7 @@ int template;
attk->damd += 2;
}
if (template == YELLOW_TEMPLATE && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1190,7 +1247,7 @@ int template;
special = TRUE;
}
if (template == DREAM_LEECH && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1206,7 +1263,7 @@ int template;
attk->damd += 4;
}
if (template == FALLEN_TEMPLATE && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1217,7 +1274,7 @@ int template;
special = TRUE;
}
if (template == MOLY_TEMPLATE && (
end_insert_okay
end_insert_okay(special)
))
{
maybe_insert();
@ -1295,6 +1352,9 @@ int mtyp;
case CRANIUM_RAT:
/* is a rodent */
return is_rat(ptr);
case PSURLON:
/* is a basic worm */
return is_basic_worm(ptr);
case MISTWEAVER:
/* could be a worshipper of the Goat */
return !(nonliving(ptr) || is_whirly(ptr) || noncorporeal(ptr));

View file

@ -2056,7 +2056,7 @@ NEARDATA struct permonst mons[] = {
A(ATTK(AT_BITE, AD_DISE, 1, 2)),
SIZ(10, 10, MS_SILENT, MZ_SMALL), 0, 0,
0 /*MM*/, MT_HOSTILE|MT_CONCEAL|MT_ANIMAL|MT_CARNIVORE|MT_NOTAKE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, MG_NASTY /*MG*/,
MB_NOEYES|MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, MG_NASTY /*MG*/,
0 /*MA*/, MV_EARTHSENSE /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_BLACK),
MON("baby long worm", S_WORM,//5
LVL(4, 6, 0, 0), G_GENO,
@ -2064,7 +2064,7 @@ NEARDATA struct permonst mons[] = {
A(ATTK(AT_BITE, AD_PHYS, 2, 2)),
SIZ(600, 250, MS_SILENT, MZ_SMALL), 0, 0,
0 /*MM*/, MT_ANIMAL|MT_HOSTILE|MT_CARNIVORE|MT_NOTAKE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, 0 /*MG*/,
MB_NOEYES|MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, 0 /*MG*/,
0 /*MA*/, MV_EARTHSENSE /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_BROWN),
MON("baby purple worm", S_WORM,//9
LVL(8, 3, 0, 0), G_GENO,
@ -2072,7 +2072,7 @@ NEARDATA struct permonst mons[] = {
A(ATTK(AT_BITE, AD_PHYS, 1, 6)),
SIZ(600, 250, MS_SILENT, MZ_SMALL), 0, 0,
0 /*MM*/, MT_HOSTILE|MT_ANIMAL|MT_CARNIVORE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, 0 /*MG*/,
MB_NOEYES|MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/, 0 /*MG*/,
0 /*MA*/, MV_NORMAL /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_MAGENTA),
MON("long worm", S_WORM,//9
LVL(8, 12, 10, 0), (G_GENO|2),
@ -2080,7 +2080,7 @@ NEARDATA struct permonst mons[] = {
A(ATTK(AT_BITE, AD_PHYS, 8, 2)), //8 long worm teeth, +2d4 if last segment in line
SIZ(WT_GIGANTIC, CN_GIGANTIC, MS_SILENT, MZ_GIGANTIC), 0, 0,
MM_DOORBUST /*MM*/, MT_HOSTILE|MT_ANIMAL|MT_CARNIVORE|MT_NOTAKE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS|MB_OVIPAROUS|MB_STRONG /*MB*/, MG_NASTY /*MG*/,
MB_NOEYES|MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS|MB_OVIPAROUS|MB_STRONG /*MB*/, MG_NASTY /*MG*/,
0 /*MA*/, MV_EARTHSENSE /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_BROWN),
MON("purple worm", S_WORM,//17
LVL(15, 9, 20, 0), (G_GENO|2),
@ -2088,7 +2088,7 @@ NEARDATA struct permonst mons[] = {
A(ATTK(AT_BITE, AD_PHYS, 2, 8), ATTK(AT_ENGL, AD_DGST, 1,10)),
SIZ(WT_GIGANTIC, CN_GIGANTIC, MS_SILENT, MZ_GIGANTIC), 0, 0,
MM_WEBRIP /*MM*/, MT_ANIMAL|MT_HOSTILE|MT_CARNIVORE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_STRONG|MB_SLITHY|MB_NOLIMBS|MB_OVIPAROUS /*MB*/, MG_NASTY /*MG*/,
MB_NOEYES|MB_LONGHEAD|MB_STRONG|MB_SLITHY|MB_NOLIMBS|MB_OVIPAROUS /*MB*/, MG_NASTY /*MG*/,
MM_DOORBUST /*MA*/, MV_NORMAL /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_MAGENTA),
MON("hunting horror", S_WORM,//28
LVL(25, 16, 30, 0), (G_NOHELL|G_LGROUP|G_GENO|1),
@ -9225,7 +9225,7 @@ is a red right hand
SIZ(10, 10, MS_GLYPHS, MZ_TINY), 0, 0,
MM_STATIONARY /*MM*/,
MT_PEACEFUL|MT_ANIMAL|MT_CARNIVORE|MT_NOTAKE /*MT*/, 0 /*MF*/,
MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/,
MB_NOEYES|MB_LONGHEAD|MB_SLITHY|MB_NOLIMBS /*MB*/,
MG_NOTAME|MG_NOPOLY|MG_SANLOSS|MG_INSIGHT /*MG*/,
MA_PRIMORDIAL /*MA*/, MV_NORMAL|MV_SCENT /*MV*/, MW_ELDER_SIGN /*MW*/, CLR_RED),
MON("radiant pyramid", S_PIERCER,//20 /*Needs encyc entry*/

View file

@ -1003,7 +1003,9 @@ const int good_amulets[] = {
AMULET_OF_UNCHANGING,
AMULET_OF_NULLIFY_MAGIC,
AMULET_OF_REFLECTION,
AMULET_OF_MAGICAL_BREATHING
AMULET_OF_MAGICAL_BREATHING,
AMULET_OF_WOUND_CLOSURE,
AMULET_VERSUS_EVIL_EYES
};
int

View file

@ -1095,18 +1095,20 @@ RING(("protection from shape changers", "black signet"), {PROT_FROM_SHAPE_CHANGE
AMULET_CLASS, prob, 0, 20, 150, {0}, {0}, 0, 0, 0, 20, HI_METAL, __VA_ARGS__ )
AMULET(("amulet of drain resistance", "warped"), {DRAIN_RES}, 60),
AMULET(("amulet of ESP", "circular"), {TELEPAT}, 130),
AMULET(("amulet of ESP", "circular"), {TELEPAT}, 100),
AMULET(("amulet of life saving", "spherical"), {LIFESAVED}, 70),
AMULET(("amulet of strangulation", "oval"), {STRANGLED}, 100),
AMULET(("amulet of restful sleep", "triangular"), {SLEEPING}, 100),
AMULET(("amulet versus poison", "pyramidal"), {POISON_RES}, 130),
AMULET(("amulet of strangulation", "oval"), {STRANGLED}, 90),
AMULET(("amulet of restful sleep", "triangular"), {SLEEPING}, 90),
AMULET(("amulet versus poison", "pyramidal"), {POISON_RES}, 100),
AMULET(("amulet versus sickness", "teardrop"), {SICK_RES}, 25),
AMULET(("amulet of change", "square"), {0}, 110),
AMULET(("amulet of change", "square"), {0}, 100),
AMULET(("amulet versus curses", "convex"), {0}, 55),/*Needs tile*/
AMULET(("amulet of unchanging", "concave"), {UNCHANGING}, 45),
AMULET(("amulet of nullify magic", "pentagonal"), {NULLMAGIC}, 45),/*Needs tile*/
AMULET(("amulet of reflection", "hexagonal"), {REFLECTING}, 70),
AMULET(("amulet of magical breathing", "octagonal"), {MAGICAL_BREATHING}, 60),
AMULET(("amulet of wound closure", "cardioid"), {REGENERATION}, 30),/*Needs tile*/
AMULET(("amulet versus evil eyes", "oblong"), {GAZE_RES}, 60),/*Needs tile*/
AMULET(("cheap plastic imitation of the Amulet of Yendor", "Amulet of Yendor"), {0}, 0,
O_USKWN(1), O_MAGIC(0), O_MAT(PLASTIC), O_COST(20), O_NUT(1)),

View file

@ -1541,6 +1541,8 @@ char * str;
template = YITH;
else if (strstri(s_temp, "crani") == s_temp)
template = CRANIUM_RAT;
else if (strstri(s_temp, "psurlon") == s_temp)
template = PSURLON;
else if (strstri(s_temp, "mistweaver") == s_temp)
template = MISTWEAVER;
else if (strstri(s_temp, "deloused") == s_temp)

View file

@ -2961,6 +2961,25 @@ boolean past;
knows_object(ELVEN_SHIELD);
knows_object(ELVEN_BOOTS);
knows_object(ELVEN_CLOAK);
//The PC was actually lawful, and changes back if they are uncrowned and still their starting alignment
if(u.ugodbase[UGOD_CURRENT] == u.ugodbase[UGOD_ORIGINAL] && !u.uevent.uhand_of_elbereth){
/* The player wears a helm of opposite alignment? */
if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT)
u.ugodbase[UGOD_ORIGINAL] = u.ugodbase[UGOD_CURRENT] = GOD_ZO_KALAR;
else {
u.ualign.god = u.ugodbase[UGOD_ORIGINAL] = u.ugodbase[UGOD_CURRENT] = GOD_ZO_KALAR;
u.ualign.type = A_LAWFUL;
}
You("have a sudden sense of returning to an old direction.");
flags.initalign = 0;
flags.botl = TRUE;
change_luck(-3);
u.ublesscnt += 300;
u.lastprayed = moves;
u.reconciled = REC_NONE;
u.lastprayresult = PRAY_CONV;
adjalign(-1*u.ualign.record);
}
break;
case PM_DROW:
if(flags.initgend){

View file

@ -550,6 +550,18 @@ qt_montype()
if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GONE && !In_quest(&u.uz)))
return (&mons[qpm]);
return (mkclass(S_DEMON, G_HELL));
} else if(Role_if(PM_MADMAN) && (u.uz.dlevel >= qlocate_level.dlevel)){
int qpm;
if(rn2(5)){
qpm = PM_LARGE_CAT;
if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GONE && !In_quest(&u.uz)))
return (&mons[qpm]);
return (mkclass(S_WORM, G_NOHELL));
}
qpm = PM_CONTAMINATED_PATIENT;
if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GONE && !In_quest(&u.uz)))
return (&mons[qpm]);
return (mkclass(S_BAT, G_NOHELL|G_HELL));
} else if(Role_if(PM_MONK)){
int qpm;
int monks_of_kaen[] = {PM_XORN_MONK, PM_DAO_LAO_GUI_MONK, PM_ZHI_REN_MONK, PM_XUENU_MONK};

View file

@ -3685,6 +3685,9 @@ char *in_buff;
else if (!strncmpi(bufp, "cranium ", l = 8)) {
undeadtype = CRANIUM_RAT;
}
else if (!strncmpi(bufp, "psurlon ", l = 8)) {
undeadtype = PSURLON;
}
else if (!strncmpi(bufp, "mistweaver ", l = 11)) {
undeadtype = MISTWEAVER;
}
@ -3749,6 +3752,8 @@ char *in_buff;
undeadtype = YITH;
else if (!strncmpi(p, "cranium", 7))
undeadtype = CRANIUM_RAT;
else if (!strncmpi(p, "psurlon", 7))
undeadtype = PSURLON;
else if (!strncmpi(p, "mistweaver", 10))
undeadtype = MISTWEAVER;
else if (!strncmpi(p, "worldshaper", 11))
@ -3759,6 +3764,8 @@ char *in_buff;
undeadtype = SPORE_ZOMBIE;
else if (!strncmpi(p, "cordyceps", 9))
undeadtype = CORDYCEPS;
else if (!strncmpi(p, "finger", 6))
undeadtype = PSURLON;
else if (!strncmpi(p, "plague-victim", 13))
undeadtype = PLAGUE_TEMPLATE;
else

View file

@ -274,7 +274,8 @@ struct Role roles[] = {
"Mad", "Archer Asylum", "the ground floor",
PM_MADMAN, PM_MADWOMAN, NON_PM,
PM_CASSILDA_THE_IRON_MAIDEN, PM_PATIENT, PM_DOCTOR_ARCHER,
PM_ENORMOUS_RAT, PM_CONTAMINATED_PATIENT, S_RODENT, S_BAT,
PM_ENORMOUS_RAT, PM_CONTAMINATED_PATIENT, S_RODENT, S_WORM,
//Switches to PM_LARGE_CAT, PM_CONTAMINATED_PATIENT, S_WORM, S_BAT from locate level onwards
ART_STAR_OF_HYPERNOTUS,
MA_HUMAN|MA_DWARF|MA_GNOME|MA_ORC|MA_ELF|MA_VAMPIRE|MA_DRAGON|MA_FEY, ROLE_MALE|ROLE_FEMALE |
ROLE_LAWFUL|ROLE_NEUTRAL|ROLE_CHAOTIC,
@ -284,7 +285,7 @@ struct Role roles[] = {
/* Init Lower Higher */
{ 12, 0, 0, 8, 0, 1 }, /* Hit points */
{ 4, 3, 0, 1, 2, 4 },14, /* Energy */
10, 8,-2, 2, 20, A_CHA, SPE_CONFUSE_MONSTER, -24
0, 3,-2, 2, 10, A_CHA, SPE_CONFUSE_MONSTER, -24
},
// "The Silver Fire", "_The Fury", "The Shadow", /* Sorta-eberron */
// "_The Inheritor", "_The Dawnflower", "_The Everbloom", /* Sorta-glorion */

View file

@ -2080,7 +2080,22 @@ humanoid_sound:
else{
const char *talkabt = "talks about %s.";
const char *discuss = "discusses %s.";
switch (monsndx(ptr)) {
if((ptr->mtyp == PM_PRIESTESS || ptr->mtyp == PM_DEMINYMPH)
&& has_template(mtmp, MISTWEAVER)
){
switch(rn2(3)){
case 0:
verbl_msg = "Ia! Shub-Niggurath! The Goat with a Thousand Young!";
break;
case 1:
verbl_msg = "Abundance to the Black Goat of the Woods!";
break;
case 2:
verbl_msg = "From the wells of night to the gulfs of space, and from the gulfs of space to the wells of night, ever Their praises!";
break;
}
}
else switch (monsndx(ptr)) {
case PM_VALAVI:
Sprintf(msgbuff, talkabt, rn2(2) ? "herding" : rn2(2) ? "carpentry" : rn2(10) ? "pottery" : "delicious sawdust recipes");
pline_msg = msgbuff;

View file

@ -1196,21 +1196,18 @@ struct mkroom *croom;
mon->mtalons = 1;
break;
case 11:
mon->mdreams = 1;
break;
case 12:
mon->msciaphilia = 1;
break;
case 13:
case 12:
mon->mforgetful = 1;
break;
case 14:
case 13:
mon->mapostasy = 1;
break;
case 15:
case 14:
mon->mtoobig = 1;
break;
case 16:
case 15:
mon->mformication = 1;
break;
}
@ -1232,6 +1229,7 @@ struct mkroom *croom;
PM_VAMPIRE_LORD, PM_VAMPIRE_LADY, PM_HALF_DRAGON, PM_HALF_DRAGON,
PM_YUKI_ONNA, PM_DEMINYMPH,
PM_PRIESTESS,
PM_WITCH,
PM_COILING_BRAWN, PM_FUNGAL_BRAIN
};
struct monst *mon;
@ -1256,6 +1254,13 @@ struct mkroom *croom;
makemon(&mons[PM_NURSE], otmp->ox, otmp->oy, MM_ADJACENTOK);
makemon(&mons[PM_NURSE], otmp->ox, otmp->oy, MM_ADJACENTOK);
break;
case PM_WITCH:
(void)mongets(mon, SHACKLES, NO_MKOBJ_FLAGS);
mon->entangled = SHACKLES;
mk_mplayer(&mons[PM_HEALER], otmp->ox, otmp->oy, MM_ADJACENTOK);
makemon(&mons[PM_NURSE], otmp->ox, otmp->oy, MM_ADJACENTOK);
makemon(&mons[PM_NURSE], otmp->ox, otmp->oy, MM_ADJACENTOK);
break;
case PM_COILING_BRAWN:
mon->msleeping = 1;
break;
@ -1884,6 +1889,7 @@ default_case:
stuff->spe = 2;
set_material_gm(stuff, GOLD);
add_oprop(stuff, OPROP_ELFLW);
add_oprop(stuff, OPROP_WRTHW);
add_to_container(otmp, stuff);
stuff = mksobj(IMPERIAL_ELVEN_BOOTS, MKOBJ_NOINIT);

View file

@ -220,6 +220,10 @@ int otyp;
if(check_imp_mod(obj, IEA_TELEPORT))
got_prop = TRUE;
break;
case PROT_FROM_SHAPE_CHANGERS:
if(check_imp_mod(obj, IEA_PROT_SHAPE))
got_prop = TRUE;
break;
}
}
// if we've got the property, add it to the array

View file

@ -2396,9 +2396,10 @@ register struct obj *wand;
return 1;
}
else if(wand->otyp == IMPERIAL_ELVEN_GAUNTLETS && check_imp_mod(wand, IEA_BOLTS)){
if(!wand->owornmask || u.uen < 10)
int encost = u.twoweap ? 20 : 10;
if(!wand->owornmask || u.uen < encost)
return 0;
u.uen -= 10;
u.uen -= encost;
flags.botl = TRUE;
return 1;
}
@ -2670,13 +2671,13 @@ boolean ordinary;
break;
case IMPERIAL_ELVEN_GAUNTLETS:
if(u.ualign.record > 3){
damage = d(1,8);
damage = d(max(1, 1+(obj->spe+1)/2),8);
if(hates_holy(youracedata))
damage *= 2;
pline("Idiot! You've shot yourself!");
}
else if(u.ualign.record < -3){
damage = d(1,8);
damage = d(max(1, 1+(obj->spe+1)/2),8);
if(hates_unholy(youracedata))
damage *= 2;
pline("Idiot! You've shot yourself!");
@ -2686,7 +2687,7 @@ boolean ordinary;
shieldeff(u.ux, u.uy);
pline_The("missiles bounce!");
} else {
damage = d(1,4);
damage = d(max(1, 1+(obj->spe+1)/2),4);
pline("Idiot! You've shot yourself!");
}
}
@ -3312,15 +3313,19 @@ register struct obj *obj;
zap_dig(-1,-1,-1);//-1-1-1 = "use defaults"
else if(otyp == IMPERIAL_ELVEN_GAUNTLETS && check_imp_mod(obj, IEA_BOLTS)){
basiczap(&zapdat, 0, ZAP_WAND, 1);
zapdat.damn = max(1, P_SKILL(P_WAND_POWER));
zapdat.damn = max(1, P_SKILL(P_WAND_POWER)+(obj->spe+1)/2);
if(u.twoweap)
zapdat.damn *= 2;
zapdat.affects_floor = FALSE;
if(u.ualign.record > 3){
zapdat.damd = 8;
zapdat.adtyp = AD_HOLY;
zapdat.phase_armor = TRUE;
}
else if(u.ualign.record < -3){
zapdat.damd = 8;
zapdat.adtyp = AD_UNHY;
zapdat.phase_armor = TRUE;
}
else {
zapdat.damd = 4;