two new monsters from slash'em
Adds two monsters originally from slash'em. I used the slash'em tiles this time, also its code as a starting point but made various revisions. Both the tiles could benefit from some touch-ups. displacer beast: blue 'f'. Attempting a melee hit (ie, trying to move to its spot) has a 50:50 chance for it to swap places with you. Fairly tough monster to begin with, then half your ordinary attacks effectively miss and if you try to face a mob by retreating to a corridor or backing into a corner you can end up being drawn back into the open. I added bargethrough capability, and also it won't be fooled about hero's location by Displacement. [It only swaps places during combat when contact is initiated by the hero, not when attacked by another monster or when attacking.] genetic engineer: green 'Q'. Its attack causes the target to be polymorphed unless that target resists. Hero will almost always have magic resistance by the time this monster is encountered, but it can make conflict become risky by hitting and polymorphing other monsters. Slash'em flagged it hell-only but I took that flag off; I also took away its ability to teleport. Slash'em polymorphs the hero if a genetic engineer corpse is eaten; that's included and I introduced that for monsters too. I added both of these to the list of candidates for monster spell 'summon nasties' and for post-Wizard harassment. I also gave all the 'f's infravision. Probably only matters if the hero polymorphs into a feline. Displacer beast is originally from AD&D which depicts it as a six- legged cougar with a pair of tentacles; it has Displacement rather be able to affect an attacker's location. I think genetic engineer is original to slash'em where it expands Q class but seems mainly to be the base monster for Dr.Frankenstein (a unique monster with a one-level side-branch lair in slash'em's incarnation of Gehennom).
This commit is contained in:
@@ -322,6 +322,8 @@ boiling a pool or fountain now creates a temporary cloud of steam
|
||||
random themed rooms in the dungeons of doom
|
||||
extended achievement and conduct fields for xlogfile
|
||||
record amount of gold in hero's possession in xlogfile
|
||||
new objects: amulets of flying and guarding
|
||||
new monsters: displacer beast ('f') and genetic engineer ('Q')
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -137,11 +137,11 @@ enum explosion_types {
|
||||
* is_safepet(mon)
|
||||
*
|
||||
* A special case check used in attack() and domove(). Placing the
|
||||
* definition here is convenient.
|
||||
* definition here is convenient. No longer limited to pets.
|
||||
*/
|
||||
#define is_safepet(mon) \
|
||||
(mon && (mon->mtame || mon->mpeaceful) && canspotmon(mon) && flags.safe_dog && !Confusion \
|
||||
&& !Hallucination && !Stunned)
|
||||
#define is_safepet(mon) \
|
||||
(flags.safe_dog && (mon) && (mon)->mpeaceful && canspotmon(mon) \
|
||||
&& !Confusion && !Hallucination && !Stunned)
|
||||
|
||||
/*
|
||||
* canseeself()
|
||||
|
||||
@@ -1264,9 +1264,10 @@ E int FDECL(buzzmu, (struct monst *, struct attack *));
|
||||
/* ### mhitm.c ### */
|
||||
|
||||
E int FDECL(fightm, (struct monst *));
|
||||
E int FDECL(mdisplacem, (struct monst *, struct monst *, BOOLEAN_P));
|
||||
E int FDECL(mattackm, (struct monst *, struct monst *));
|
||||
E boolean FDECL(engulf_target, (struct monst *, struct monst *));
|
||||
E int FDECL(mdisplacem, (struct monst *, struct monst *, BOOLEAN_P));
|
||||
E int FDECL(mon_poly, (struct monst *, struct monst *, int));
|
||||
E void FDECL(paralyze_monst, (struct monst *, int));
|
||||
E int FDECL(sleep_monst, (struct monst *, int, int));
|
||||
E void FDECL(slept_monst, (struct monst *));
|
||||
|
||||
@@ -289,7 +289,8 @@ typedef struct sortloot_item Loot;
|
||||
#include "extern.h"
|
||||
#endif /* USE_TRAMPOLI */
|
||||
|
||||
/* flags to control makemon(); goodpos() uses some plus has some of its own */
|
||||
/* flags to control makemon(); goodpos() uses some plus has some of its own;
|
||||
these flags have exceeded 16-bits worth so ought to be changed to 'long' */
|
||||
#define NO_MM_FLAGS 0x00000 /* use this rather than plain 0 */
|
||||
#define NO_MINVENT 0x00001 /* suppress minvent when creating mon */
|
||||
#define MM_NOWAIT 0x00002 /* don't set STRAT_WAITMASK flags */
|
||||
@@ -308,6 +309,7 @@ typedef struct sortloot_item Loot;
|
||||
/* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */
|
||||
#define GP_ALLOW_XY 0x08000 /* [actually used by enexto() to decide whether
|
||||
* to make an extra call to goodpos()] */
|
||||
#define GP_ALLOW_U 0x10000 /* don't reject hero's location */
|
||||
|
||||
/* flags for make_corpse() and mkcorpstat() */
|
||||
#define CORPSTAT_NONE 0x00
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
#define AD_SLIM 40 /* turns you into green slime */
|
||||
#define AD_ENCH 41 /* remove enchantment (disenchanter) */
|
||||
#define AD_CORR 42 /* corrode armor (black pudding) */
|
||||
#define AD_POLY 43 /* polymorph the target (genetic engineer) */
|
||||
|
||||
#define AD_CLRC 240 /* random clerical spell */
|
||||
#define AD_SPEL 241 /* random magic spell */
|
||||
|
||||
@@ -244,7 +244,9 @@ struct obj {
|
||||
#define stale_egg(egg) \
|
||||
((g.monstermoves - (egg)->age) > (2 * MAX_EGG_HATCH_TIME))
|
||||
#define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN)
|
||||
#define polyfodder(obj) (ofood(obj) && pm_to_cham((obj)->corpsenm) != NON_PM)
|
||||
#define polyfodder(obj) \
|
||||
(ofood(obj) && (pm_to_cham((obj)->corpsenm) != NON_PM \
|
||||
|| dmgtype(&mons[(obj)->corpsenm], AD_POLY)))
|
||||
#define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH)
|
||||
#define mhealup(obj) (ofood(obj) && (obj)->corpsenm == PM_NURSE)
|
||||
#define Is_pudding(o) \
|
||||
|
||||
@@ -1065,10 +1065,13 @@ int pm;
|
||||
case PM_CHAMELEON:
|
||||
case PM_DOPPELGANGER:
|
||||
case PM_SANDESTIN: /* moot--they don't leave corpses */
|
||||
case PM_GENETIC_ENGINEER:
|
||||
if (Unchanging) {
|
||||
You_feel("momentarily different."); /* same as poly trap */
|
||||
} else {
|
||||
You_feel("a change coming over you.");
|
||||
You("%s.", (pm == PM_GENETIC_ENGINEER)
|
||||
? "undergo a freakish metamorphosis"
|
||||
: "feel a change coming over you");
|
||||
polyself(0);
|
||||
}
|
||||
break;
|
||||
|
||||
47
src/hack.c
47
src/hack.c
@@ -1393,6 +1393,7 @@ domove_core()
|
||||
ballx = 0, bally = 0; /* ball&chain new positions */
|
||||
int bc_control = 0; /* control for ball&chain */
|
||||
boolean cause_delay = FALSE, /* dragging ball will skip a move */
|
||||
displaceu = FALSE, /* involuntary swap */
|
||||
u_with_boulder = (sobj_at(BOULDER, u.ux, u.uy) != 0);
|
||||
|
||||
if (g.context.travel) {
|
||||
@@ -1642,9 +1643,24 @@ domove_core()
|
||||
if (g.context.forcefight || !mtmp->mundetected || sensemon(mtmp)
|
||||
|| ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)
|
||||
&& !is_safepet(mtmp))) {
|
||||
/* try to attack; note that it might evade */
|
||||
/* also, we don't attack tame when _safepet_ */
|
||||
if (attack(mtmp))
|
||||
|
||||
/* target monster might decide to switch places with you... */
|
||||
if (mtmp->data == &mons[PM_DISPLACER_BEAST] && !rn2(2)
|
||||
&& mtmp->mux == u.ux0 && mtmp->muy == u.uy0
|
||||
&& mtmp->mcanmove && !mtmp->msleeping && !mtmp->meating
|
||||
&& !mtmp->mtrapped && !u.utrap && !u.ustuck && !u.usteed
|
||||
&& !(u.dx && u.dy
|
||||
&& (NODIAG(u.umonnum)
|
||||
|| (bad_rock(mtmp->data, x, u.uy0)
|
||||
&& bad_rock(mtmp->data, u.ux0, y))
|
||||
|| (bad_rock(g.youmonst.data, u.ux0, y)
|
||||
&& bad_rock(g.youmonst.data, x, u.uy0))))
|
||||
&& goodpos(u.ux0, u.uy0, mtmp, GP_ALLOW_U))
|
||||
displaceu = TRUE;
|
||||
|
||||
/* try to attack; note that it might evade;
|
||||
also, we don't attack tame when _safepet_ */
|
||||
else if (attack(mtmp))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1788,6 +1804,22 @@ domove_core()
|
||||
exercise_steed(); /* train riding skill */
|
||||
}
|
||||
|
||||
if (displaceu && mtmp) {
|
||||
remove_monster(u.ux, u.uy);
|
||||
place_monster(mtmp, u.ux0, u.uy0);
|
||||
newsym(u.ux, u.uy);
|
||||
newsym(u.ux0, u.uy0);
|
||||
/* monst still knows where hero is */
|
||||
mtmp->mux = u.ux, mtmp->muy = u.uy;
|
||||
|
||||
pline("%s swaps places with you...", Monnam(mtmp));
|
||||
/* monster chose to swap places; hero doesn't get any credit
|
||||
or blame if something bad happens to it */
|
||||
g.context.mon_moving = 1;
|
||||
if (!minliquid(mtmp))
|
||||
(void) mintrap(mtmp);
|
||||
g.context.mon_moving = 0;
|
||||
|
||||
/*
|
||||
* If safepet at destination then move the pet to the hero's
|
||||
* previous location using the same conditions as in attack().
|
||||
@@ -1798,7 +1830,8 @@ domove_core()
|
||||
* Ceiling-hiding pets are skipped by this section of code, to
|
||||
* be caught by the normal falling-monster code.
|
||||
*/
|
||||
if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
|
||||
} else if (is_safepet(mtmp)
|
||||
&& !(is_hider(mtmp->data) && mtmp->mundetected)) {
|
||||
/* if it turns out we can't actually move */
|
||||
boolean didnt_move = FALSE;
|
||||
|
||||
@@ -1821,8 +1854,8 @@ domove_core()
|
||||
You("stop. %s can't move diagonally.", upstart(y_monnam(mtmp)));
|
||||
didnt_move = TRUE;
|
||||
} else if (u_with_boulder
|
||||
&& !(verysmall(mtmp->data)
|
||||
&& (!mtmp->minvent || curr_mon_load(mtmp) <= 600))) {
|
||||
&& !(verysmall(mtmp->data)
|
||||
&& (!mtmp->minvent || curr_mon_load(mtmp) <= 600))) {
|
||||
/* can't swap places when pet won't fit there with the boulder */
|
||||
You("stop. %s won't fit into the same spot that you're at.",
|
||||
upstart(y_monnam(mtmp)));
|
||||
@@ -1840,7 +1873,7 @@ domove_core()
|
||||
You("stop. %s can't move out of that trap.",
|
||||
upstart(y_monnam(mtmp)));
|
||||
didnt_move = TRUE;
|
||||
} else if (mtmp->mpeaceful
|
||||
} else if (mtmp->mpeaceful && !mtmp->mtame
|
||||
&& (!goodpos(u.ux0, u.uy0, mtmp, 0)
|
||||
|| t_at(u.ux0, u.uy0) != NULL
|
||||
|| mundisplaceable(mtmp))) {
|
||||
|
||||
75
src/mhitm.c
75
src/mhitm.c
@@ -833,7 +833,7 @@ struct attack *mattk;
|
||||
/*
|
||||
* See comment at top of mattackm(), for return values.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
mdamagem(magr, mdef, mattk, mwep, dieroll)
|
||||
struct monst *magr, *mdef;
|
||||
struct attack *mattk;
|
||||
@@ -1438,6 +1438,10 @@ int dieroll;
|
||||
/* there's no msomearmor() function, so just do damage */
|
||||
/* if (cancelled) break; */
|
||||
break;
|
||||
case AD_POLY:
|
||||
if (!magr->mcan && tmp < mdef->mhp)
|
||||
tmp = mon_poly(magr, mdef, tmp);
|
||||
break;
|
||||
default:
|
||||
tmp = 0;
|
||||
break;
|
||||
@@ -1480,6 +1484,75 @@ int dieroll;
|
||||
return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT;
|
||||
}
|
||||
|
||||
int
|
||||
mon_poly(magr, mdef, dmg)
|
||||
struct monst *magr, *mdef;
|
||||
int dmg;
|
||||
{
|
||||
if (mdef == &g.youmonst) {
|
||||
if (Antimagic) {
|
||||
shieldeff(mdef->mx, mdef->my);
|
||||
} else if (Unchanging) {
|
||||
; /* just take a little damage */
|
||||
} else {
|
||||
/* system shock might take place in polyself() */
|
||||
if (u.ulycn == NON_PM) {
|
||||
You("are subjected to a freakish metamorphosis.");
|
||||
polyself(0);
|
||||
} else if (u.umonnum != u.ulycn) {
|
||||
You_feel("an unnatural urge coming on.");
|
||||
you_were();
|
||||
} else {
|
||||
You_feel("a natural urge coming on.");
|
||||
you_unwere(FALSE);
|
||||
}
|
||||
dmg = 0;
|
||||
}
|
||||
} else {
|
||||
char Before[BUFSZ];
|
||||
|
||||
Strcpy(Before, Monnam(mdef));
|
||||
if (resists_magm(mdef)) {
|
||||
/* Magic resistance */
|
||||
if (g.vis)
|
||||
shieldeff(mdef->mx, mdef->my);
|
||||
} else if (resist(mdef, WAND_CLASS, 0, TELL)) {
|
||||
/* general resistance to magic... */
|
||||
;
|
||||
} else if (!rn2(25) && mdef->cham == NON_PM
|
||||
&& (mdef->mcan
|
||||
|| pm_to_cham(monsndx(mdef->data)) != NON_PM)) {
|
||||
/* system shock; this variation takes away half of mon's HP
|
||||
rather than kill outright */
|
||||
if (g.vis)
|
||||
pline("%s shudders!", Before);
|
||||
|
||||
dmg += (mdef->mhpmax + 1) / 2;
|
||||
mdef->mhp -= dmg;
|
||||
dmg = 0;
|
||||
if (DEADMONSTER(mdef)) {
|
||||
if (magr == &g.youmonst)
|
||||
xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
|
||||
else
|
||||
monkilled(mdef, "", AD_RBRE);
|
||||
}
|
||||
} else if (newcham(mdef, (struct permonst *) 0, FALSE, FALSE)) {
|
||||
if (g.vis && canspotmon(mdef))
|
||||
pline("%s%s turns into %s.", Before,
|
||||
!flags.verbose ? ""
|
||||
: " undergoes a freakish metamorphosis and",
|
||||
x_monnam(mdef, ARTICLE_A, (char *) 0,
|
||||
(SUPPRESS_NAME | SUPPRESS_IT
|
||||
| SUPPRESS_INVISIBLE), FALSE));
|
||||
dmg = 0;
|
||||
} else {
|
||||
if (g.vis && flags.verbose)
|
||||
pline1(nothing_happens);
|
||||
}
|
||||
}
|
||||
return dmg;
|
||||
}
|
||||
|
||||
void
|
||||
paralyze_monst(mon, amt)
|
||||
struct monst *mon;
|
||||
|
||||
@@ -1727,6 +1727,10 @@ register struct attack *mattk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AD_POLY:
|
||||
if (uncancelled && Maybe_Half_Phys(dmg) < (Upolyd ? u.mh : u.uhp))
|
||||
dmg = mon_poly(mtmp, &g.youmonst, dmg);
|
||||
break;
|
||||
default:
|
||||
dmg = 0;
|
||||
break;
|
||||
|
||||
10
src/mon.c
10
src/mon.c
@@ -1720,10 +1720,12 @@ struct monst *magr, /* monster that is currently deciding where to move */
|
||||
struct permonst *pa = magr->data, *pd = mdef->data;
|
||||
|
||||
/* if attacker can't barge through, there's nothing to do;
|
||||
or if defender can barge through too, don't let attacker
|
||||
do so, otherwise they might just end up swapping places
|
||||
again when defender gets its chance to move */
|
||||
if ((pa->mflags3 & M3_DISPLACES) != 0 && (pd->mflags3 & M3_DISPLACES) == 0
|
||||
or if defender can barge through too and has a level at least
|
||||
as high as the attacker, don't let attacker do so, otherwise
|
||||
they might just end up swapping places again when defender
|
||||
gets its chance to move */
|
||||
if ((pa->mflags3 & M3_DISPLACES) != 0
|
||||
&& ((pd->mflags3 & M3_DISPLACES) == 0 || magr->m_lev > mdef->m_lev)
|
||||
/* no displacing grid bugs diagonally */
|
||||
&& !(magr->mx != mdef->mx && magr->my != mdef->my
|
||||
&& NODIAG(monsndx(pd)))
|
||||
|
||||
@@ -1625,8 +1625,8 @@ void
|
||||
set_apparxy(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
boolean notseen, gotu;
|
||||
register int disp, mx = mtmp->mux, my = mtmp->muy;
|
||||
boolean notseen, notthere, gotu;
|
||||
int disp, mx = mtmp->mux, my = mtmp->muy;
|
||||
long umoney = money_cnt(g.invent);
|
||||
|
||||
/*
|
||||
@@ -1643,24 +1643,25 @@ register struct monst *mtmp;
|
||||
goto found_you;
|
||||
|
||||
notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data)));
|
||||
notthere = (Displaced && mtmp->data != &mons[PM_DISPLACER_BEAST]);
|
||||
/* add cases as required. eg. Displacement ... */
|
||||
if (notseen || Underwater) {
|
||||
if (Underwater) {
|
||||
disp = 1;
|
||||
} else if (notseen) {
|
||||
/* Xorns can smell quantities of valuable metal
|
||||
like that in solid gold coins, treat as seen */
|
||||
if ((mtmp->data == &mons[PM_XORN]) && umoney && !Underwater)
|
||||
disp = 0;
|
||||
else
|
||||
disp = 1;
|
||||
} else if (Displaced) {
|
||||
like that in solid gold coins, treat as seen */
|
||||
disp = (mtmp->data == &mons[PM_XORN] && umoney) ? 0 : 1;
|
||||
} else if (notthere) {
|
||||
disp = couldsee(mx, my) ? 2 : 1;
|
||||
} else
|
||||
} else {
|
||||
disp = 0;
|
||||
}
|
||||
if (!disp)
|
||||
goto found_you;
|
||||
|
||||
/* without something like the following, invisibility and displacement
|
||||
are too powerful */
|
||||
gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE;
|
||||
gotu = notseen ? !rn2(3) : notthere ? !rn2(4) : FALSE;
|
||||
|
||||
if (!gotu) {
|
||||
register int try_cnt = 0;
|
||||
|
||||
52
src/monst.c
52
src/monst.c
@@ -347,47 +347,53 @@ NEARDATA struct permonst mons_init[] = {
|
||||
* felines
|
||||
*/
|
||||
MON("kitten", S_FELINE, LVL(2, 18, 6, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 1, 6),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(150, 150, MS_MEW, MZ_SMALL), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_WANDER | M2_DOMESTIC,
|
||||
M3_INFRAVISIBLE, 3, HI_DOMESTIC),
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 3, HI_DOMESTIC),
|
||||
MON("housecat", S_FELINE, LVL(4, 16, 5, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 1, 6),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(200, 200, MS_MEW, MZ_SMALL), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_DOMESTIC, M3_INFRAVISIBLE,
|
||||
5, HI_DOMESTIC),
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_DOMESTIC,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 5, HI_DOMESTIC),
|
||||
MON("jaguar", S_FELINE, LVL(4, 15, 6, 0, 0), (G_GENO | 2),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 1, 4), ATTK(AT_CLAW, AD_PHYS, 1, 4),
|
||||
ATTK(AT_BITE, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(600, 300, MS_GROWL, MZ_LARGE), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
|
||||
6, CLR_BROWN),
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 6, CLR_BROWN),
|
||||
MON("lynx", S_FELINE, LVL(5, 15, 6, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 1, 4), ATTK(AT_CLAW, AD_PHYS, 1, 4),
|
||||
ATTK(AT_BITE, AD_PHYS, 1, 10), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(600, 300, MS_GROWL, MZ_SMALL), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
|
||||
7, CLR_CYAN),
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_CYAN),
|
||||
MON("panther", S_FELINE, LVL(5, 15, 6, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_CLAW, AD_PHYS, 1, 6),
|
||||
ATTK(AT_BITE, AD_PHYS, 1, 10), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(600, 300, MS_GROWL, MZ_LARGE), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
|
||||
7, CLR_BLACK),
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_BLACK),
|
||||
MON("large cat", S_FELINE, LVL(6, 15, 4, 0, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 2, 4),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(250, 250, MS_MEW, MZ_SMALL), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_STRONG | M2_DOMESTIC,
|
||||
M3_INFRAVISIBLE, 7, HI_DOMESTIC),
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 7, HI_DOMESTIC),
|
||||
MON("tiger", S_FELINE, LVL(6, 12, 6, 0, 0), (G_GENO | 2),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 2, 4), ATTK(AT_CLAW, AD_PHYS, 2, 4),
|
||||
ATTK(AT_BITE, AD_PHYS, 1, 10), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(600, 300, MS_GROWL, MZ_LARGE), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
|
||||
8, CLR_YELLOW),
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_YELLOW),
|
||||
MON("displacer beast", S_FELINE, LVL(12, 12, -10, 0, -3), (G_GENO | 1),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 4, 4), ATTK(AT_CLAW, AD_PHYS, 4, 4),
|
||||
ATTK(AT_BITE, AD_PHYS, 2, 10), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(750, 400, MS_GROWL, MZ_LARGE), 0, 0,
|
||||
M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE | M2_NASTY,
|
||||
M3_INFRAVISIBLE | M3_INFRAVISION | M3_DISPLACES, 14, CLR_BLUE),
|
||||
/*
|
||||
* gremlins and gargoyles
|
||||
*/
|
||||
@@ -1731,11 +1737,17 @@ struct permonst _mons2[] = {
|
||||
* Quantum mechanics
|
||||
*/
|
||||
MON("quantum mechanic", S_QUANTMECH, LVL(7, 12, 3, 10, 0), (G_GENO | 3),
|
||||
A(ATTK(AT_CLAW, AD_TLPT, 1, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
A(ATTK(AT_CLAW, AD_TLPT, 1, 4),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 20, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE | M1_POIS | M1_TPORT, M2_HOSTILE,
|
||||
M3_INFRAVISIBLE, 9, CLR_CYAN),
|
||||
MON("genetic engineer", S_QUANTMECH, LVL(12, 12, 3, 10, 0), (G_GENO | 1),
|
||||
A(ATTK(AT_CLAW, AD_POLY, 1, 4),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 20, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE | M1_POIS, M2_HOSTILE | M2_NASTY,
|
||||
M3_INFRAVISIBLE, 14, CLR_GREEN),
|
||||
/*
|
||||
* Rust monster or disenchanter
|
||||
*/
|
||||
|
||||
@@ -45,7 +45,8 @@ struct monst *mtmp;
|
||||
unsigned gpflags;
|
||||
{
|
||||
struct permonst *mdat = (struct permonst *) 0;
|
||||
boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0);
|
||||
boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0),
|
||||
allow_u = ((gpflags & GP_ALLOW_U) != 0);
|
||||
|
||||
if (!isok(x, y))
|
||||
return FALSE;
|
||||
@@ -56,10 +57,12 @@ unsigned gpflags;
|
||||
* which could be co-located and thus get restricted a bit too much.
|
||||
* oh well.
|
||||
*/
|
||||
if (x == u.ux && y == u.uy
|
||||
&& mtmp != &g.youmonst && (mtmp != u.ustuck || !u.uswallow)
|
||||
&& (!u.usteed || mtmp != u.usteed))
|
||||
return FALSE;
|
||||
if (!allow_u) {
|
||||
if (x == u.ux && y == u.uy && mtmp != &g.youmonst
|
||||
&& (mtmp != u.ustuck || !u.uswallow)
|
||||
&& (!u.usteed || mtmp != u.usteed))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mtmp) {
|
||||
struct monst *mtmp2 = m_at(x, y);
|
||||
|
||||
@@ -2011,6 +2011,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */
|
||||
mdef->mconf = 1;
|
||||
}
|
||||
break;
|
||||
case AD_POLY:
|
||||
if (!negated && tmp < mdef->mhp)
|
||||
tmp = mon_poly(&g.youmonst, mdef, tmp);
|
||||
break;
|
||||
default:
|
||||
tmp = 0;
|
||||
break;
|
||||
|
||||
@@ -33,6 +33,7 @@ static NEARDATA const int nasties[] = {
|
||||
PM_XORN, PM_ZRUTY, PM_LEOCROTTA, PM_BALUCHITHERIUM,
|
||||
PM_CARNIVOROUS_APE, PM_FIRE_ELEMENTAL, PM_JABBERWOCK,
|
||||
PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME,
|
||||
PM_DISPLACER_BEAST, PM_GENETIC_ENGINEER,
|
||||
/* chaotic */
|
||||
PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LORD,
|
||||
PM_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE,
|
||||
@@ -597,8 +598,9 @@ struct monst *summoner;
|
||||
bypos.x = u.ux;
|
||||
bypos.y = u.uy;
|
||||
for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i) {
|
||||
/* Of the 42 nasties[], 10 are lawful, 14 are chaotic,
|
||||
* and 18 are neutral.
|
||||
/* Of the 44 nasties[], 10 are lawful, 14 are chaotic,
|
||||
* and 20 are neutral. [These numbers are up date for
|
||||
* 3.7.0; the ones in the next paragraph are not....]
|
||||
*
|
||||
* Neutral caster, used for late-game harrassment,
|
||||
* has 18/42 chance to stop the inner loop on each
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user