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:
nhmall
2018-09-22 14:08:28 -04:00
parent 6a86cafa90
commit bbb81700f5
7 changed files with 65 additions and 4 deletions

View File

@@ -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

View File

@@ -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 *));

View File

@@ -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) \

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 */