sunsword vs gremlin
The original report complained that gremlins seemed impervious to Sunsword's light yet a flash from a camera caused them to cry out in pain despite "The long sword named Sunsword begins to shine brilliantly!" This commit does two things: 1. A dmg bonus is applied against gremlins using a lit Sunsword. 2. Gremlins will generally avoid the light emitted by Sunsword. There's a few minor flavor bits thrown in also. It is understood that this effectively makes Sunsword provide "gremlin-proofing", but the gremlin myth and Sunsword's characteristic feature pretty much demand it. bug 42
This commit is contained in:
@@ -131,6 +131,8 @@ wishing for "orange" could yield orange or orange colored gem/potion/spellbook
|
||||
a sleeping or paralyzed mon would be frightened by its reflection when
|
||||
applying a mirror
|
||||
prevent leash showing unseen monster as "attached to it"
|
||||
gremlins seemed impervious to Sunsword's light yet a flash from a camera
|
||||
caused them to cry out in pain
|
||||
|
||||
|
||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1438,6 +1438,7 @@ FDECL(can_blnd, (struct monst *, struct monst *, UCHAR_P, struct obj *));
|
||||
E boolean FDECL(ranged_attk, (struct permonst *));
|
||||
E boolean FDECL(hates_silver, (struct permonst *));
|
||||
E boolean FDECL(mon_hates_silver, (struct monst *));
|
||||
E boolean FDECL(mon_hates_light, (struct monst *));
|
||||
E boolean FDECL(passes_bars, (struct permonst *));
|
||||
E boolean FDECL(can_blow, (struct monst *));
|
||||
E boolean FDECL(can_chant, (struct monst *));
|
||||
|
||||
@@ -175,6 +175,8 @@
|
||||
|
||||
#define is_vampire(ptr) ((ptr)->mlet == S_VAMPIRE)
|
||||
|
||||
#define hates_light(ptr) ((ptr) == &mons[PM_GREMLIN])
|
||||
|
||||
/* used to vary a few messages */
|
||||
#define weirdnonliving(ptr) (is_golem(ptr) || (ptr)->mlet == S_VORTEX)
|
||||
#define nonliving(ptr) \
|
||||
|
||||
@@ -312,6 +312,14 @@ register struct permonst *ptr;
|
||||
|| (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
|
||||
}
|
||||
|
||||
/* True if specific monster is especially affected by light-emitting weapons */
|
||||
boolean
|
||||
mon_hates_light(mon)
|
||||
struct monst *mon;
|
||||
{
|
||||
return (boolean) (hates_light(mon->data));
|
||||
}
|
||||
|
||||
/* True iff the type of monster pass through iron bars */
|
||||
boolean
|
||||
passes_bars(mptr)
|
||||
|
||||
@@ -255,6 +255,14 @@ struct monst *mon;
|
||||
}
|
||||
}
|
||||
|
||||
#define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN] && \
|
||||
(uwep && artifact_light(uwep) && uwep->lamplit))
|
||||
|
||||
/* we could include this in the above macro, but probably overkill/overhead */
|
||||
/* (!((which_armor((mon), W_ARMC) != 0) && ((which_armor((mon), W_ARMH) != 0))) && */
|
||||
|
||||
|
||||
|
||||
/* monster begins fleeing for the specified time, 0 means untimed flee
|
||||
* if first, only adds fleetime if monster isn't already fleeing
|
||||
* if fleemsg, prints a message about new flight, otherwise, caller should */
|
||||
@@ -289,9 +297,15 @@ boolean fleemsg;
|
||||
/* unfortunately we can't distinguish between temporary
|
||||
sleep and temporary paralysis, so both conditions
|
||||
receive the same alternate message */
|
||||
if (!mtmp->mcanmove || !mtmp->data->mmove)
|
||||
if (!mtmp->mcanmove || !mtmp->data->mmove) {
|
||||
pline("%s seems to flinch.", Adjmonnam(mtmp, "immobile"));
|
||||
else
|
||||
} else if (flees_light(mtmp)) {
|
||||
if (rn2(10) || Deaf)
|
||||
pline("%s flees from the painful light of %s.",
|
||||
Monnam(mtmp), bare_artifactname(uwep));
|
||||
else
|
||||
verbalize("Bright light!");
|
||||
} else
|
||||
pline("%s turns to flee.", Monnam(mtmp));
|
||||
}
|
||||
mtmp->mflee = 1;
|
||||
@@ -306,7 +320,7 @@ register struct monst *mtmp;
|
||||
int *inrange, *nearby, *scared;
|
||||
{
|
||||
int seescaryx, seescaryy;
|
||||
boolean sawscary = FALSE;
|
||||
boolean sawscary = FALSE, bravegremlin = (rn2(5) == 0);
|
||||
|
||||
*inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
|
||||
<= (BOLT_LIM * BOLT_LIM));
|
||||
@@ -329,6 +343,7 @@ int *inrange, *nearby, *scared;
|
||||
|
||||
sawscary = onscary(seescaryx, seescaryy, mtmp);
|
||||
if (*nearby && (sawscary
|
||||
|| (flees_light(mtmp) && !bravegremlin)
|
||||
|| (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
|
||||
*scared = 1;
|
||||
monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
|
||||
@@ -336,6 +351,8 @@ int *inrange, *nearby, *scared;
|
||||
*scared = 0;
|
||||
}
|
||||
|
||||
#undef flees_light
|
||||
|
||||
/* perform a special one-time action for a monster; returns -1 if nothing
|
||||
special happened, 0 if monster uses up its turn, 1 if monster is killed */
|
||||
STATIC_OVL int
|
||||
|
||||
31
src/uhitm.c
31
src/uhitm.c
@@ -658,6 +658,7 @@ int dieroll;
|
||||
boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
|
||||
unpoisonmsg = FALSE;
|
||||
boolean silvermsg = FALSE, silverobj = FALSE;
|
||||
boolean lightobj = FALSE;
|
||||
boolean valid_weapon_attack = FALSE;
|
||||
boolean unarmed = !uwep && !uarm && !uarms;
|
||||
boolean hand_to_hand = (thrown == HMON_MELEE
|
||||
@@ -699,7 +700,10 @@ int dieroll;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Strcpy(saved_oname, cxname(obj));
|
||||
if (!(artifact_light(obj) && obj->lamplit))
|
||||
Strcpy(saved_oname, cxname(obj));
|
||||
else
|
||||
Strcpy(saved_oname, bare_artifactname(obj));
|
||||
if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
|
||||
|| obj->oclass == GEM_CLASS) {
|
||||
/* is it not a melee weapon? */
|
||||
@@ -803,6 +807,8 @@ int dieroll;
|
||||
silvermsg = TRUE;
|
||||
silverobj = TRUE;
|
||||
}
|
||||
if (artifact_light(obj) && obj->lamplit && mon_hates_light(mon))
|
||||
lightobj = TRUE;
|
||||
if (u.usteed && !thrown && tmp > 0
|
||||
&& weapon_type(obj) == P_LANCE && mon != u.ustuck) {
|
||||
jousting = joust(mon, obj);
|
||||
@@ -1251,6 +1257,29 @@ int dieroll;
|
||||
whom = strcat(s_suffix(whom), " flesh");
|
||||
pline(fmt, whom);
|
||||
}
|
||||
if (lightobj) {
|
||||
const char *fmt;
|
||||
char *whom = mon_nam(mon);
|
||||
char emitlightobjbuf[BUFSZ];
|
||||
|
||||
if (canspotmon(mon)) {
|
||||
if (saved_oname[0]) {
|
||||
Sprintf(emitlightobjbuf,
|
||||
"%s radiance penetrates deep into",
|
||||
s_suffix(saved_oname));
|
||||
Strcat(emitlightobjbuf, " %s!");
|
||||
fmt = emitlightobjbuf;
|
||||
} else
|
||||
fmt = "The light sears %s!";
|
||||
} else {
|
||||
*whom = highc(*whom); /* "it" -> "It" */
|
||||
fmt = "%s is seared!";
|
||||
}
|
||||
/* note: s_suffix returns a modifiable buffer */
|
||||
if (!noncorporeal(mdat) && !amorphous(mdat))
|
||||
whom = strcat(s_suffix(whom), " flesh");
|
||||
pline(fmt, whom);
|
||||
}
|
||||
/* if a "no longer poisoned" message is coming, it will be last;
|
||||
obj->opoisoned was cleared above and any message referring to
|
||||
"poisoned <obj>" has now been given; we want just "<obj>" for
|
||||
|
||||
@@ -329,6 +329,8 @@ struct monst *mon;
|
||||
bonus += rnd(4);
|
||||
if (objects[otyp].oc_material == SILVER && mon_hates_silver(mon))
|
||||
bonus += rnd(20);
|
||||
if (artifact_light(otmp) && otmp->lamplit && hates_light(ptr))
|
||||
bonus += rnd(8);
|
||||
|
||||
/* if the weapon is going to get a double damage bonus, adjust
|
||||
this bonus so that effectively it's added after the doubling */
|
||||
|
||||
Reference in New Issue
Block a user