Sunsword redux (trunk only)

This started out as a one line change.  After I saw someone in the
newsgroup mention that Sunsword's light was inferior to that of a lamp,
I decided to make it work better (than in 3.4.3, that is, becoming the
same brightness as a lamp) when blessed and worse when cursed (useless to
hero but still visible if wielded by a monster).  But then it needed to
change light radius when its curse/bless state changed, and it needed
message feedback when doing so, and that got kind of complicated.  I
wouldn't have bothered if I'd known what I was getting into, but I don't
want to throw it away now that I've done all this work....

     Sunsword now gives a light radius of 3 when blessed (same as a lit
lamp), radius of 2 when uncursed (same as a lit candle and as it has been
providing since added in 3.4.0), and a radius of 1 when cursed (nearly
but not completely useless, as mentioned above).  Also, it now "shines"
rather than "glows" since we usually use the latter for temporary effects.
This commit is contained in:
nethack.rankin
2009-01-24 01:44:29 +00:00
parent e6b2d5c33d
commit b12d8522c5
10 changed files with 156 additions and 28 deletions

View File

@@ -300,6 +300,7 @@ message sequencing for fatal explosions was confusing if feedback was given
for carried items being destroyed
when dipping something in holy/unholy water, only learn its new bless/curse
state if hero sees it glow
describe lit Sunsword as shining rather than glowing
Platform- and/or Interface-Specific Fixes
@@ -419,6 +420,7 @@ streamline old ^X output and integrate it with enlightenment feedback;
eating disenchanter corpses is now considered risky
make '[' command more precise when poly'd hero has embedded dragon scales/mail
fainting while wielding a cockatrice corpse will be fatal
Sunsword's light radius depends on its curse/bless state
Platform- and/or Interface-Specific New Features

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)extern.h 3.5 2008/01/30 */
/* SCCS Id: @(#)extern.h 3.5 2009/01/20 */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -974,7 +974,10 @@ E boolean FDECL(obj_sheds_light, (struct obj *));
E boolean FDECL(obj_is_burning, (struct obj *));
E void FDECL(obj_split_light_source, (struct obj *, struct obj *));
E void FDECL(obj_merge_light_sources, (struct obj *,struct obj *));
E void FDECL(obj_adjust_light_radius, (struct obj *,int));
E int FDECL(candle_light_range, (struct obj *));
E int FDECL(arti_light_radius, (struct obj *));
E const char *FDECL(arti_light_description, (struct obj *));
#ifdef WIZARD
E int NDECL(wiz_light_sources);
#endif

View File

@@ -326,6 +326,7 @@ extern NEARDATA struct instance_flags iflags;
#define PLNMSG_ONE_ITEM_HERE 1 /* "you see <single item> here" */
#define PLNMSG_TOWER_OF_FLAME 2 /* scroll of fire */
#define PLNMSG_CAUGHT_IN_EXPLOSION 3 /* explode() feedback */
#define PLNMSG_OBJ_GLOWS 4 /* "the <obj> glows <color>" */
/* runmode options */
#define RUN_TPORT 0 /* don't update display until movement stops */

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)light.c 3.5 2006/07/08 */
/* SCCS Id: @(#)light.c 3.5 2009/01/20 */
/* Copyright (c) Dean Luick, 1994 */
/* NetHack may be freely redistributed. See license for details. */
@@ -538,6 +538,23 @@ struct obj *src, *dest;
}
}
/* light source `obj' is being made brighter or dimmer */
void
obj_adjust_light_radius(obj, new_radius)
struct obj *obj;
int new_radius;
{
light_source *ls;
for (ls = light_base; ls; ls = ls->next)
if (ls->type == LS_OBJECT && ls->id.a_obj == obj) {
if (new_radius != ls->range) vision_full_recalc = 1;
ls->range = new_radius;
return;
}
impossible("obj_adjust_light_radius: can't find %s", xname(obj));
}
/* Candlelight is proportional to the number of candles;
minimum range is 2 rather than 1 for playability. */
int
@@ -579,6 +596,41 @@ struct obj *obj;
return radius;
}
/* light emitting artifact's range depends upon its curse/bless state */
int
arti_light_radius(obj)
struct obj *obj;
{
/*
* Used by begin_burn() when setting up a new light source
* (obj->lamplit will already be set by this point) and
* also by bless()/unbless()/uncurse()/curse() to decide
* whether to call obj_adjust_light_radius().
*/
/* sanity check [simplifies usage by bless()/curse()/&c] */
if (!obj->lamplit || !artifact_light(obj)) return 0;
/* cursed radius of 1 is not noticeable for an item that's
carried by the hero but is if it's carried by a monster
or left lit on the floor (not applicable for Sunsword) */
return (obj->blessed ? 3 : !obj->cursed ? 2 : 1);
}
/* adverb describing lit artifact's light; depends on curse/bless state */
const char *
arti_light_description(obj)
struct obj *obj;
{
switch (arti_light_radius(obj)) {
case 3: return "brilliantly"; /* blessed */
case 2: return "brightly"; /* uncursed */
case 1: return "dimly"; /* cursed */
default: break;
}
return "strangely";
}
#ifdef WIZARD
int

View File

@@ -1,10 +1,11 @@
/* SCCS Id: @(#)mkobj.c 3.5 2008/07/20 */
/* SCCS Id: @(#)mkobj.c 3.5 2009/01/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
STATIC_DCL void FDECL(mkbox_cnts,(struct obj *));
STATIC_DCL void FDECL(maybe_adjust_light, (struct obj *,int));
STATIC_DCL void FDECL(obj_timer_checks,(struct obj *, XCHAR_P, XCHAR_P, int));
STATIC_DCL void FDECL(container_weight, (struct obj *));
STATIC_DCL struct obj *FDECL(save_mtraits, (struct obj *, struct monst *));
@@ -976,13 +977,61 @@ start_corpse_timeout(body)
(void) start_timer(when, TIMER_OBJECT, action, obj_to_any(body));
}
STATIC_OVL void
maybe_adjust_light(obj, old_range)
struct obj *obj;
int old_range;
{
char buf[BUFSZ];
xchar ox, oy;
int new_range = arti_light_radius(obj),
delta = new_range - old_range;
/* radius of light emitting artifact varies by curse/bless state
so will change after blessing or cursing */
if (delta) {
obj_adjust_light_radius(obj, new_range);
/* simplifying assumptions: hero is wielding this object;
artifacts have to be in use to emit light and monsters'
gear won't change bless or curse state */
if (!Blind && get_obj_location(obj, &ox, &oy, 0)) {
*buf = '\0';
if (iflags.last_msg == PLNMSG_OBJ_GLOWS)
/* we just saw "The <obj> glows <color>." from dipping */
Strcpy(buf, (obj->quan == 1L) ? "It" : "They");
else if (carried(obj) || cansee(ox, oy))
Strcpy(buf, Yname2(obj));
if (*buf) {
/* initial activation says "dimly" if cursed,
"brightly" if uncursed, and "brilliantly" if blessed;
when changing intensity, using "less brightly" is
straightforward for dimming, but we need "brighter"
rather than "more brightly" for brightening; ugh */
pline("%s %s %s%s.",
buf, otense(obj, "shine"),
(abs(delta) > 1) ? "much " : "",
(delta > 0) ? "brighter" : "less brightly");
}
}
}
}
/*
* bless(), curse(), unbless(), uncurse() -- any relevant message
* about glowing amber/black/&c should be delivered prior to calling
* these routines to make the actual curse/bless state change.
*/
void
bless(otmp)
register struct obj *otmp;
{
int old_light = 0;
#ifdef GOLDOBJ
if (otmp->oclass == COIN_CLASS) return;
#endif
if (otmp->lamplit) old_light = arti_light_radius(otmp);
otmp->cursed = 0;
otmp->blessed = 1;
if (carried(otmp) && confers_luck(otmp))
@@ -991,6 +1040,7 @@ register struct obj *otmp;
otmp->owt = weight(otmp);
else if (otmp->otyp == FIGURINE && otmp->timed)
(void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
if (otmp->lamplit) maybe_adjust_light(otmp, old_light);
return;
}
@@ -998,20 +1048,27 @@ void
unbless(otmp)
register struct obj *otmp;
{
int old_light = 0;
if (otmp->lamplit) old_light = arti_light_radius(otmp);
otmp->blessed = 0;
if (carried(otmp) && confers_luck(otmp))
set_moreluck();
else if (otmp->otyp == BAG_OF_HOLDING)
otmp->owt = weight(otmp);
if (otmp->lamplit) maybe_adjust_light(otmp, old_light);
}
void
curse(otmp)
register struct obj *otmp;
{
int old_light = 0;
#ifdef GOLDOBJ
if (otmp->oclass == COIN_CLASS) return;
#endif
if (otmp->lamplit) old_light = arti_light_radius(otmp);
otmp->blessed = 0;
otmp->cursed = 1;
/* welded two-handed weapon interferes with some armor removal */
@@ -1031,6 +1088,7 @@ register struct obj *otmp;
&& (carried(otmp) || mcarried(otmp)))
attach_fig_transform_timeout(otmp);
}
if (otmp->lamplit) maybe_adjust_light(otmp, old_light);
return;
}
@@ -1038,6 +1096,9 @@ void
uncurse(otmp)
register struct obj *otmp;
{
int old_light = 0;
if (otmp->lamplit) old_light = arti_light_radius(otmp);
otmp->cursed = 0;
if (carried(otmp) && confers_luck(otmp))
set_moreluck();
@@ -1045,6 +1106,7 @@ register struct obj *otmp;
otmp->owt = weight(otmp);
else if (otmp->otyp == FIGURINE && otmp->timed)
(void) stop_timer(FIG_TRANSFORM, obj_to_any(otmp));
if (otmp->lamplit) maybe_adjust_light(otmp, old_light);
return;
}

View File

@@ -1092,6 +1092,7 @@ const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */
pline("%s with %s aura.", objphrase, an(glowcolor));
else
pline("%s %s.", objphrase, glowcolor);
iflags.last_msg = PLNMSG_OBJ_GLOWS;
targobj->bknown = !Hallucination;
}
/* potions of water are the only shop goods whose price depends

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)pray.c 3.5 2008/10/09 */
/* SCCS Id: @(#)pray.c 3.5 2009/01/23 */
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */
@@ -431,13 +431,14 @@ decurse:
impossible("fix_worst_trouble: nothing to uncurse.");
return;
}
uncurse(otmp);
if (!Blind || (otmp == ublindf && Blindfolded_only)) {
pline("%s %s.", what ? what :
(const char *)Yobjnam2(otmp, "softly glow"),
hcolor(NH_AMBER));
iflags.last_msg = PLNMSG_OBJ_GLOWS;
otmp->bknown = TRUE;
}
uncurse(otmp);
update_inventory();
break;
case TROUBLE_POISONED:
@@ -480,12 +481,12 @@ decurse:
#ifdef STEED
case TROUBLE_SADDLE:
otmp = which_armor(u.usteed, W_SADDLE);
uncurse(otmp);
if (!Blind) {
pline("%s %s.", Yobjnam2(otmp, "softly glow"),
hcolor(NH_AMBER));
otmp->bknown = TRUE;
}
uncurse(otmp);
break;
#endif
}
@@ -908,23 +909,27 @@ pleased(g_align)
otense(uwep, "are"));
if (uwep->cursed) {
uncurse(uwep);
uwep->bknown = TRUE;
if (!Blind)
if (!Blind) {
pline("%s %s%s.", Yobjnam2(uwep, "softly glow"),
hcolor(NH_AMBER), repair_buf);
else You_feel("the power of %s over %s.",
u_gname(), yname(uwep));
iflags.last_msg = PLNMSG_OBJ_GLOWS;
} else
You_feel("the power of %s over %s.",
u_gname(), yname(uwep));
uncurse(uwep);
uwep->bknown = TRUE;
*repair_buf = '\0';
} else if (!uwep->blessed) {
bless(uwep);
uwep->bknown = TRUE;
if (!Blind)
if (!Blind) {
pline("%s with %s aura%s.",
Yobjnam2(uwep, "softly glow"),
an(hcolor(NH_LIGHT_BLUE)), repair_buf);
else You_feel("the blessing of %s over %s.",
u_gname(), yname(uwep));
iflags.last_msg = PLNMSG_OBJ_GLOWS;
} else
You_feel("the blessing of %s over %s.",
u_gname(), yname(uwep));
bless(uwep);
uwep->bknown = TRUE;
*repair_buf = '\0';
}
@@ -993,13 +998,14 @@ pleased(g_align)
an(hcolor(NH_LIGHT_BLUE)));
for(otmp=invent; otmp; otmp=otmp->nobj) {
if (otmp->cursed) {
uncurse(otmp);
if (!Blind) {
pline("%s %s.", Yobjnam2(otmp, "softly glow"),
hcolor(NH_AMBER));
iflags.last_msg = PLNMSG_OBJ_GLOWS;
otmp->bknown = TRUE;
++any;
}
uncurse(otmp);
}
}
if (any) update_inventory();

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)timeout.c 3.5 2007/03/15 */
/* SCCS Id: @(#)timeout.c 3.5 2009/01/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1145,7 +1145,7 @@ begin_burn(obj, already_lit)
if (artifact_light(obj)) {
obj->lamplit = 1;
do_timer = FALSE;
radius = 2;
radius = arti_light_radius(obj);
} else {
impossible("begin burn: unexpected %s", xname(obj));
turns = obj->age;

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)weapon.c 3.5 2008/05/07 */
/* SCCS Id: @(#)weapon.c 3.5 2009/01/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -706,9 +706,9 @@ register struct monst *mon;
if (artifact_light(obj) && !obj->lamplit) {
begin_burn(obj, FALSE);
if (canseemon(mon))
pline("%s brilliantly in %s %s!",
Tobjnam(obj, "glow"),
s_suffix(mon_nam(mon)), mbodypart(mon,HAND));
pline("%s %s in %s %s!", Tobjnam(obj, "shine"),
arti_light_description(obj),
s_suffix(mon_nam(mon)), mbodypart(mon,HAND));
}
obj->owornmask = W_WEP;
return 1;
@@ -1352,7 +1352,7 @@ register struct obj *obj;
if (artifact_light(obj) && obj->lamplit) {
end_burn(obj, FALSE);
if (canseemon(mon))
pline("%s in %s %s %s glowing.", The(xname(obj)),
pline("%s in %s %s %s shining.", The(xname(obj)),
s_suffix(mon_nam(mon)), mbodypart(mon,HAND),
otense(obj, "stop"));
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)wield.c 3.5 2007/02/07 */
/* SCCS Id: @(#)wield.c 3.5 2009/01/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -94,7 +94,7 @@ register struct obj *obj;
setworn(obj, W_WEP);
if (uwep == obj && artifact_light(olduwep) && olduwep->lamplit) {
end_burn(olduwep, FALSE);
if (!Blind) pline("%s glowing.", Tobjnam(olduwep, "stop"));
if (!Blind) pline("%s shining.", Tobjnam(olduwep, "stop"));
}
/* Note: Explicitly wielding a pick-axe will not give a "bashing"
* message. Wielding one via 'a'pplying it will.
@@ -190,7 +190,8 @@ struct obj *wep;
if (artifact_light(wep) && !wep->lamplit) {
begin_burn(wep, FALSE);
if (!Blind)
pline("%s to glow brilliantly!", Tobjnam(wep, "begin"));
pline("%s to shine %s!", Tobjnam(wep, "begin"),
arti_light_description(wep));
}
#if 0
@@ -574,7 +575,7 @@ uwepgone()
if (uwep) {
if (artifact_light(uwep) && uwep->lamplit) {
end_burn(uwep, FALSE);
if (!Blind) pline("%s glowing.", Tobjnam(uwep, "stop"));
if (!Blind) pline("%s shining.", Tobjnam(uwep, "stop"));
}
setworn((struct obj *)0, W_WEP);
unweapon = TRUE;