Merge remote-tracking branch 'origin/NetHack-3.6.0'

This commit is contained in:
keni
2016-07-04 20:17:43 -04:00
25 changed files with 358 additions and 134 deletions
+33 -4
View File
@@ -570,9 +570,23 @@ Figure 2
Go in that direction until you hit a wall or run into something. Go in that direction until you hit a wall or run into something.
.lp m[yuhjklbn] .lp m[yuhjklbn]
Prefix: move without picking up objects or fighting (even if you remember Prefix: move without picking up objects or fighting (even if you remember
a monster there) a monster there).
.lp ""
A few non-movement commands use the `m' prefix to request operating
via menu (to temporarily override the
.op menustyle:Traditional
option).
Primarily useful for `,' (pickup) when there is only one class of
objects present (where there won't be any ``what kinds of objects?'' prompt,
so no opportunity to answer `m' at that prompt).
.lp ""
A few other commands (eat food, offer sacrifice, apply tinning-kit) use
the `m' prefix to skip checking for applicable objects on the floor
and go straight to checking inventory,
or (for ``#loot'' to remove a saddle),
skip containers and go straight to adjacent monsters.
.lp F[yuhjklbn] .lp F[yuhjklbn]
Prefix: fight a monster (even if you only guess one is there) Prefix: fight a monster (even if you only guess one is there).
.lp M[yuhjklbn] .lp M[yuhjklbn]
Prefix: move far, no pickup. Prefix: move far, no pickup.
.lp "g[yuhjklbn] .lp "g[yuhjklbn]
@@ -640,6 +654,11 @@ D%u - drop only unpaid food.
Kick something (usually a door). Kick something (usually a door).
.lp e .lp e
Eat food. Eat food.
.lp ""
Normally checks for edible item(s) on the floor, then if none are found
or none are chosen, checks for edible item(s) in inventory.
Precede `e' with the `m' prefix to bypass attempting to eat
anything off the floor.
.\" Make sure Elbereth is not hyphenated below, the exact spelling matters .\" Make sure Elbereth is not hyphenated below, the exact spelling matters
.hw Elbereth .hw Elbereth
.lp E .lp E
@@ -928,6 +947,8 @@ Kick something.
.lp #loot .lp #loot
Loot a box or bag on the floor beneath you, or the saddle Loot a box or bag on the floor beneath you, or the saddle
from a steed standing next to you. from a steed standing next to you.
Precede with the `m' prefix to skip containers at your location
and go directly to removing a saddle.
.lp #monster .lp #monster
Use a monster's special ability (when polymorphed into monster form). Use a monster's special ability (when polymorphed into monster form).
.lp #name .lp #name
@@ -1286,13 +1307,21 @@ have the right equipment and skill. Convincing a wild beast to let
you saddle it up is difficult to say the least. Many a dungeoneer you saddle it up is difficult to say the least. Many a dungeoneer
has had to resort to magic and wizardry in order to forge the alliance. has had to resort to magic and wizardry in order to forge the alliance.
Once you do have the beast under your control however, you can Once you do have the beast under your control however, you can
easily climb in and out of the saddle with the `#ride' command. Lead easily climb in and out of the saddle with the ``#ride'' command. Lead
the beast around the dungeon when riding, in the same manner as the beast around the dungeon when riding, in the same manner as
you would move yourself. It is the beast that you will see displayed you would move yourself. It is the beast that you will see displayed
on the map. on the map.
.pg .pg
Riding skill is managed by the `#enhance' command. See the section Riding skill is managed by the ``#enhance'' command. See the section
on Weapon proficiency for more information about that. on Weapon proficiency for more information about that.
.pg
Use the `a' (apply) command and pick a saddle in your inventory to
attempt to put that saddle on an adjacent creature. If successful,
it will be transferred to that creature's inventory.
.pg
Use the ``#loot'' command while adjacent to a saddled creature to
try to remove the saddle from that creature. If successful, it will
be transferred to your inventory.
.hn 2 .hn 2
Bones levels Bones levels
.pg .pg
+36 -5
View File
@@ -690,10 +690,24 @@ Go in that direction until you hit a wall or run into something.
%.lp %.lp
\item[\tb{m[yuhjklbn]}] \item[\tb{m[yuhjklbn]}]
Prefix: move without picking up objects or fighting (even if you remember Prefix: move without picking up objects or fighting (even if you remember
a monster there) a monster there).\\
%.lp ""
A few non-movement commands use the `{\tt m}' prefix to request operating
via menu (to temporarily override the
{\it menustyle:Traditional\/}
option).
Primarily useful for `{\tt ,}' (pickup) when there is only one class of
objects present (where there won't be any ``what kinds of objects?'' prompt,
so no opportunity to answer `{\tt m}' at that prompt).\\
%.lp ""
A few other commands (eat food, offer sacrifice, apply tinning-kit) use
the `{\tt m}' prefix to skip checking for applicable objects on the floor
and go straight to checking inventory,
or (for ``{\tt \#loot}'' to remove a saddle),
skip containers and go straight to adjacent monsters.
%.lp %.lp
\item[\tb{F[yuhjklbn]}] \item[\tb{F[yuhjklbn]}]
Prefix: fight a monster (even if you only guess one is there) Prefix: fight a monster (even if you only guess one is there).
%.lp %.lp
\item[\tb{M[yuhjklbn]}] \item[\tb{M[yuhjklbn]}]
Prefix: Move far, no pickup. Prefix: Move far, no pickup.
@@ -775,7 +789,12 @@ the bless\-ed/\-un\-curs\-ed/\-curs\-ed groups may be typed.\\
Kick something (usually a door). Kick something (usually a door).
%.lp %.lp
\item[\tb{e}] \item[\tb{e}]
Eat food. Eat food.\\
%.lp ""
Normally checks for edible item(s) on the floor, then if none are found
or none are chosen, checks for edible item(s) in inventory.
Precede `{\tt e}' with the `{\tt m}' prefix to bypass attempting to eat
anything off the floor.
%.lp %.lp
% Make sure Elbereth is not hyphenated below, the exact spelling matters. % Make sure Elbereth is not hyphenated below, the exact spelling matters.
% (Only specified here to parallel Guidebook.mn; use of \tt font implicity % (Only specified here to parallel Guidebook.mn; use of \tt font implicity
@@ -1119,6 +1138,8 @@ Kick something.
\item[\tb{\#loot}] \item[\tb{\#loot}]
Loot a box or bag on the floor beneath you, or the saddle Loot a box or bag on the floor beneath you, or the saddle
from a steed standing next to you. from a steed standing next to you.
Precede with the `{\tt m}' prefix to skip containers at your location
and go directly to removing a saddle.
%.lp %.lp
\item[\tb{\#monster}] \item[\tb{\#monster}]
Use a monster's special ability (when polymorphed into monster form). Use a monster's special ability (when polymorphed into monster form).
@@ -1574,15 +1595,25 @@ have the right equipment and skill. Convincing a wild beast to let
you saddle it up is difficult to say the least. Many a dungeoneer you saddle it up is difficult to say the least. Many a dungeoneer
has had to resort to magic and wizardry in order to forge the alliance. has had to resort to magic and wizardry in order to forge the alliance.
Once you do have the beast under your control however, you can Once you do have the beast under your control however, you can
easily climb in and out of the saddle with the `{\tt \#ride}' command. Lead easily climb in and out of the saddle with the ``{\tt \#ride}'' command. Lead
the beast around the dungeon when riding, in the same manner as the beast around the dungeon when riding, in the same manner as
you would move yourself. It is the beast that you will see displayed you would move yourself. It is the beast that you will see displayed
on the map. on the map.
%.pg %.pg
Riding skill is managed by the `{\tt \#enhance}' command. See the section Riding skill is managed by the ``{\tt \#enhance}'' command. See the section
on Weapon proficiency for more information about that. on Weapon proficiency for more information about that.
%.pg
Use the `{\tt a}' (apply) command and pick a saddle in your inventory to
attempt to put that saddle on an adjacent creature. If successful,
it will be transferred to that creature's inventory.
%.pg
Use the ``{\tt \#loot}'' command while adjacent to a saddled creature to
try to remove the saddle from that creature. If successful, it will
be transferred to your inventory.
%.hn 2 %.hn 2
\subsection*{Bones levels} \subsection*{Bones levels}
+14
View File
@@ -302,6 +302,16 @@ conduct: wishing for an artifact and not getting it because it already exists
avoid ring of poison resistance as starting equipment for orcish wizard avoid ring of poison resistance as starting equipment for orcish wizard
gelatinous cube shouldn't be able to eat a scroll of scare monster gelatinous cube shouldn't be able to eat a scroll of scare monster
make fireballs or cones of cold cast a skilled or higher not go through walls make fireballs or cones of cold cast a skilled or higher not go through walls
prevent flying monsters from hovering over unreachable underwater objects
lembas wafer gives increased nutrition to elves, reduced nutrition to orcs;
cram ration gives increase nutrition to dwarves
when #tip's terse object drop format got interrupted by a regular message,
it continued using "obj2, obj3, ..." for subsequent objects, where
the sentence grammar no longer made sense (the interrupting message
still follows the comma of a partial sentence--attempting to fix that
seems hopeless; leaving it is better than always using verbose format)
for #tip inside shop, credit was incorrectly given for spilled gold if that
gold's stale location coordinates didn't happen to be inside the shop
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -322,6 +332,7 @@ when picking a destination for #jump, '$' to show valid dest. is more accurate
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
----------------------------------------- -----------------------------------------
tiles: wrinkled spellbook had a spurious brown pixel on far right edge of tile
tty: M-N gave "Unknown command 'M-" with "'." finishing the sentence on the tty: M-N gave "Unknown command 'M-" with "'." finishing the sentence on the
line below it, leaving bogus '.' displayed on the top row of the map line below it, leaving bogus '.' displayed on the top row of the map
tty: specifying all four of role, race, gender, and alignment still prompted tty: specifying all four of role, race, gender, and alignment still prompted
@@ -337,6 +348,8 @@ tty: if color is disabled and use_inverse is enabled, display lava in inverse
tty: if "--More--" was written to leftmost column (beginning of second line) tty: if "--More--" was written to leftmost column (beginning of second line)
while hero was swallowed, cursor would end up in wrong place (at end while hero was swallowed, cursor would end up in wrong place (at end
of status line instead back on map) after message line was cleared of status line instead back on map) after message line was cleared
tty: long message lines which wrap when shown on the top line might be
re-displayed incorrectly by ^P for msg_window={full,combo,reverse}
unix/X11: in top level Makefile, some commented out definitions of VARDATND unix/X11: in top level Makefile, some commented out definitions of VARDATND
misspelled pilemark.xbm (as pilemark.xpm) misspelled pilemark.xbm (as pilemark.xpm)
unix: options file with CR+LF line ends and an invalid option line resulted in unix: options file with CR+LF line ends and an invalid option line resulted in
@@ -365,6 +378,7 @@ X11: support pre-selected entries in menu windows
X11: make the extended command menu be easier to use and look a little nicer X11: make the extended command menu be easier to use and look a little nicer
X11: make the getline text entry widget display a bigger text entry area X11: make the getline text entry widget display a bigger text entry area
X11: color didn't work when the map was displayed as text rather than tiles X11: color didn't work when the map was displayed as text rather than tiles
X11: use grayscale monster tiles for statues
General New Features General New Features
+1
View File
@@ -382,6 +382,7 @@ extern NEARDATA struct instance_flags iflags;
#define PLNMSG_TOWER_OF_FLAME 2 /* scroll of fire */ #define PLNMSG_TOWER_OF_FLAME 2 /* scroll of fire */
#define PLNMSG_CAUGHT_IN_EXPLOSION 3 /* explode() feedback */ #define PLNMSG_CAUGHT_IN_EXPLOSION 3 /* explode() feedback */
#define PLNMSG_OBJ_GLOWS 4 /* "the <obj> glows <color>" */ #define PLNMSG_OBJ_GLOWS 4 /* "the <obj> glows <color>" */
#define PLNMSG_OBJNAM_ONLY 5 /* xname/doname only, for #tip */
/* Usage: /* Usage:
* pline("some message"); * pline("some message");
* pline: vsprintf + putstr + iflags.last_msg = PLNMSG_UNKNOWN; * pline: vsprintf + putstr + iflags.last_msg = PLNMSG_UNKNOWN;
+12 -4
View File
@@ -193,10 +193,18 @@
(vegan(ptr) \ (vegan(ptr) \
|| ((ptr)->mlet == S_PUDDING && (ptr) != &mons[PM_BLACK_PUDDING])) || ((ptr)->mlet == S_PUDDING && (ptr) != &mons[PM_BLACK_PUDDING]))
/* monkeys are tameable via bananas but not pacifiable via food,
otherwise their theft attack could be nullified too easily;
dogs and cats can be tamed by anything they like to eat and are
pacified by any other food;
horses can be tamed by always-veggy food or lichen corpses but
not tamed or pacified by other corpses or tins of veggy critters */
#define befriend_with_obj(ptr, obj) \ #define befriend_with_obj(ptr, obj) \
(((obj)->oclass == FOOD_CLASS && is_domestic(ptr)) \ (((ptr) == &mons[PM_MONKEY] || (ptr) == &mons[PM_APE]) \
|| ((obj)->otyp == BANANA && \ ? (obj)->otyp == BANANA \
((ptr) == &mons[PM_MONKEY] \ : (is_domestic(ptr) && (obj)->oclass == FOOD_CLASS \
|| (ptr) == &mons[PM_APE]))) && ((ptr)->mlet != S_UNICORN \
|| objects[(obj)->otyp].oc_material == VEGGY \
|| ((obj)->otyp == CORPSE && (obj)->corpsenm == PM_LICHEN))))
#endif /* MONDATA_H */ #endif /* MONDATA_H */
+9
View File
@@ -3445,11 +3445,20 @@ boolean initial;
Cmd.move_SW = Cmd.dirchars[7]; Cmd.move_SW = Cmd.dirchars[7];
} }
/* non-movement commands which accept 'm' prefix to request menu operation */
STATIC_OVL boolean STATIC_OVL boolean
accept_menu_prefix(cmd_func) accept_menu_prefix(cmd_func)
int NDECL((*cmd_func)); int NDECL((*cmd_func));
{ {
if (cmd_func == dopickup || cmd_func == dotip if (cmd_func == dopickup || cmd_func == dotip
/* eat, #offer, and apply tinning-kit all use floorfood() to pick
an item on floor or in invent; 'm' skips picking from floor
(ie, inventory only) rather than request use of menu operation */
|| cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply
/* 'm' for removing saddle from adjacent monster without checking
for containers at <u.ux,u.uy> */
|| cmd_func == doloot
/* 'm' prefix allowed for some extended commands */
|| cmd_func == doextcmd || cmd_func == doextlist) || cmd_func == doextcmd || cmd_func == doextlist)
return TRUE; return TRUE;
return FALSE; return FALSE;
+2 -2
View File
@@ -814,8 +814,8 @@ register struct obj *obj;
case CARROT: case CARROT:
return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD; return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
case BANANA: case BANANA:
return (mptr->mlet == S_YETI) return (mptr->mlet == S_YETI && herbi)
? DOGFOOD ? DOGFOOD /* for monkey and ape (tameable), sasquatch */
: (herbi || starving) : (herbi || starving)
? ACCFOOD ? ACCFOOD
: MANFOOD; : MANFOOD;
+44 -11
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 eat.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.169 $ */ /* NetHack 3.6 eat.c $NHDT-Date: 1467028559 2016/06/27 11:55:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.171 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -13,6 +13,7 @@ STATIC_PTR int NDECL(unfaint);
STATIC_DCL const char *FDECL(food_xname, (struct obj *, BOOLEAN_P)); STATIC_DCL const char *FDECL(food_xname, (struct obj *, BOOLEAN_P));
STATIC_DCL void FDECL(choke, (struct obj *)); STATIC_DCL void FDECL(choke, (struct obj *));
STATIC_DCL void NDECL(recalc_wt); STATIC_DCL void NDECL(recalc_wt);
STATIC_DCL unsigned FDECL(obj_nutrition, (struct obj *));
STATIC_DCL struct obj *FDECL(touchfood, (struct obj *)); STATIC_DCL struct obj *FDECL(touchfood, (struct obj *));
STATIC_DCL void NDECL(do_reset_eat); STATIC_DCL void NDECL(do_reset_eat);
STATIC_DCL void FDECL(done_eating, (BOOLEAN_P)); STATIC_DCL void FDECL(done_eating, (BOOLEAN_P));
@@ -296,6 +297,32 @@ reset_eat()
return; return;
} }
/* base nutrition of a food-class object */
STATIC_OVL unsigned
obj_nutrition(otmp)
struct obj *otmp;
{
unsigned nut = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
: otmp->globby ? otmp->owt
: (unsigned) objects[otmp->otyp].oc_nutrition;
if (otmp->otyp == LEMBAS_WAFER) {
if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
nut += nut / 4; /* 800 -> 1000 */
else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
nut -= nut / 4; /* 800 -> 600 */
/* prevent polymorph making a partly eaten wafer
become more nutritious than an untouched one */
if (otmp->oeaten >= nut)
otmp->oeaten = (otmp->oeaten < objects[LEMBAS_WAFER].oc_nutrition)
? (nut - 1) : nut;
} else if (otmp->otyp == CRAM_RATION) {
if (maybe_polyd(is_dwarf(youmonst.data), Race_if(PM_DWARF)))
nut += nut / 6; /* 600 -> 700 */
}
return nut;
}
STATIC_OVL struct obj * STATIC_OVL struct obj *
touchfood(otmp) touchfood(otmp)
struct obj *otmp; struct obj *otmp;
@@ -310,9 +337,7 @@ struct obj *otmp;
if (!otmp->oeaten) { if (!otmp->oeaten) {
costly_alteration(otmp, COST_BITE); costly_alteration(otmp, COST_BITE);
otmp->oeaten = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit otmp->oeaten = obj_nutrition(otmp);
: otmp->globby ? otmp->owt
: (unsigned) objects[otmp->otyp].oc_nutrition;
} }
if (carried(otmp)) { if (carried(otmp)) {
@@ -1741,6 +1766,15 @@ struct obj *otmp;
make_vomiting((long) rn1(context.victual.reqtime, 14), FALSE); make_vomiting((long) rn1(context.victual.reqtime, 14), FALSE);
} }
break; break;
case LEMBAS_WAFER:
if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) {
pline("%s", "!#?&* elf kibble!");
break;
} else if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF))) {
pline("A little goes a long way.");
break;
}
goto give_feedback;
case MEATBALL: case MEATBALL:
case MEAT_STICK: case MEAT_STICK:
case HUGE_CHUNK_OF_MEAT: case HUGE_CHUNK_OF_MEAT:
@@ -2368,6 +2402,7 @@ doeat()
if (u.uedibility) { if (u.uedibility) {
int res = edibility_prompts(otmp); int res = edibility_prompts(otmp);
if (res) { if (res) {
Your( Your(
"%s stops tingling and your sense of smell returns to normal.", "%s stops tingling and your sense of smell returns to normal.",
@@ -2577,9 +2612,7 @@ doeat()
} }
/* re-calc the nutrition */ /* re-calc the nutrition */
basenutrit = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit basenutrit = (int) obj_nutrition(otmp);
: otmp->globby ? otmp->owt
: (unsigned) objects[otmp->otyp].oc_nutrition;
debugpline3( debugpline3(
"before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d", "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d",
@@ -2974,7 +3007,8 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */ offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
/* if we can't touch floor objects then use invent food only */ /* if we can't touch floor objects then use invent food only */
if (!can_reach_floor(TRUE) || (feeding && u.usteed) if (iflags.menu_requested /* command was preceded by 'm' prefix */
|| !can_reach_floor(TRUE) || (feeding && u.usteed)
|| (is_pool_or_lava(u.ux, u.uy) || (is_pool_or_lava(u.ux, u.uy)
&& (Wwalking || is_clinger(youmonst.data) && (Wwalking || is_clinger(youmonst.data)
|| (Flying && !Breathless)))) || (Flying && !Breathless))))
@@ -3085,10 +3119,9 @@ struct obj *obj;
{ {
long uneaten_amt, full_amount; long uneaten_amt, full_amount;
/* get full_amount first; obj_nutrition() might modify obj->oeaten */
full_amount = (long) obj_nutrition(obj);
uneaten_amt = (long) obj->oeaten; uneaten_amt = (long) obj->oeaten;
full_amount = (long) ((obj->otyp == CORPSE) ? mons[obj->corpsenm].cnutrit
: obj->globby ? obj->owt
: (unsigned) objects[obj->otyp].oc_nutrition);
if (uneaten_amt > full_amount) { if (uneaten_amt > full_amount) {
impossible( impossible(
"partly eaten food (%ld) more nutritious than untouched food (%ld)", "partly eaten food (%ld) more nutritious than untouched food (%ld)",
+10 -4
View File
@@ -979,15 +979,21 @@ not_special:
* mpickstuff() as well. * mpickstuff() as well.
*/ */
if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) { if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
/* don't get stuck circling around an object that's /* don't get stuck circling around object that's
underneath underneath an immobile or hidden monster;
an immobile or hidden monster; paralysis victims paralysis victims excluded */
excluded */
if ((mtoo = m_at(xx, yy)) != 0 if ((mtoo = m_at(xx, yy)) != 0
&& (mtoo->msleeping || mtoo->mundetected && (mtoo->msleeping || mtoo->mundetected
|| (mtoo->mappearance && !mtoo->iswiz) || (mtoo->mappearance && !mtoo->iswiz)
|| !mtoo->data->mmove)) || !mtoo->data->mmove))
continue; continue;
/* the mfndpos() test for whether to allow a move to a
water location accepts flyers, but they can't reach
underwater objects, so being able to move to a spot
is insufficient for deciding whether to do so */
if ((is_pool(xx, yy) && !is_swimmer(ptr))
|| (is_lava(xx, yy) && !likes_lava(ptr)))
continue;
if (((likegold && otmp->oclass == COIN_CLASS) if (((likegold && otmp->oclass == COIN_CLASS)
|| (likeobjs && index(practical, otmp->oclass) || (likeobjs && index(practical, otmp->oclass)
+4 -2
View File
@@ -1923,16 +1923,18 @@ struct permonst _mons2[] = {
/* /*
* Apelike beasts * Apelike beasts
*/ */
/* tameable via banana; does not grow up into ape...
not flagged as domestic, so no guilt penalty for eating non-pet one */
MON("monkey", S_YETI, LVL(2, 12, 6, 0, 0), (G_GENO | 1), MON("monkey", S_YETI, LVL(2, 12, 6, 0, 0), (G_GENO | 1),
A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_BITE, AD_PHYS, 1, 3), NO_ATTK, A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_BITE, AD_PHYS, 1, 3), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(100, 50, MS_GROWL, MZ_SMALL), 0, 0, SIZ(100, 50, MS_GROWL, MZ_SMALL), 0, 0,
M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY), M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY),
MON("ape", S_YETI, LVL(4, 12, 6, 0, 0), (G_GENO | G_SGROUP | 2), MON("ape", S_YETI, LVL(4, 12, 6, 0, 0), (G_GENO | G_SGROUP | 2),
A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3),
ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK), ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(1100, 500, MS_GROWL, MZ_LARGE), 0, 0, SIZ(1100, 500, MS_GROWL, MZ_LARGE), 0, 0,
M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, M2_STRONG, M3_INFRAVISIBLE, M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, M2_STRONG, M3_INFRAVISIBLE,
CLR_BROWN), CLR_BROWN),
MON("owlbear", S_YETI, LVL(5, 12, 5, 0, 0), (G_GENO | 3), MON("owlbear", S_YETI, LVL(5, 12, 5, 0, 0), (G_GENO | 3),
A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_CLAW, AD_PHYS, 1, 6), A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_CLAW, AD_PHYS, 1, 6),
+22 -25
View File
@@ -414,6 +414,24 @@ boolean verbose; /* give message(s) even when you can't see what happened */
return 0; return 0;
} }
#define MT_FLIGHTCHECK(pre) \
(/* missile hits edge of screen */ \
!isok(bhitpos.x + dx, bhitpos.y + dy) \
/* missile hits the wall */ \
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) \
/* missile hit closed door */ \
|| closed_door(bhitpos.x + dx, bhitpos.y + dy) \
/* missile might hit iron bars */ \
/* the random chance for small objects hitting bars is */ \
/* skipped when reaching them at point blank range */ \
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS \
&& hits_bars(&singleobj, \
bhitpos.x, bhitpos.y, \
bhitpos.x + dx, bhitpos.y + dy, \
((pre) ? 0 : !rn2(5)), 0)) \
/* Thrown objects "sink" */ \
|| (!(pre) && IS_SINK(levl[bhitpos.x][bhitpos.y].typ)))
void void
m_throw(mon, x, y, dx, dy, range, obj) m_throw(mon, x, y, dx, dy, range, obj)
struct monst *mon; /* launching monster */ struct monst *mon; /* launching monster */
@@ -471,17 +489,7 @@ struct obj *obj; /* missile (or stack providing it) */
} }
} }
/* pre-check for doors, walls and boundaries. if (MT_FLIGHTCHECK(TRUE)) {
Also need to pre-check for bars regardless of direction;
the random chance for small objects hitting bars is
skipped when reaching them at point blank range */
if (!isok(bhitpos.x + dx, bhitpos.y + dy)
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ)
|| closed_door(bhitpos.x + dx, bhitpos.y + dy)
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS
&& hits_bars(&singleobj,
bhitpos.x, bhitpos.y,
bhitpos.x + dx, bhitpos.y + dy, 0, 0))) {
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
return; return;
} }
@@ -611,20 +619,7 @@ struct obj *obj; /* missile (or stack providing it) */
} }
} }
if (!range /* reached end of path */ if (!range /* reached end of path */
/* missile hits edge of screen */ || MT_FLIGHTCHECK(FALSE)) {
|| !isok(bhitpos.x + dx, bhitpos.y + dy)
/* missile hits the wall */
|| IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ)
/* missile hit closed door */
|| closed_door(bhitpos.x + dx, bhitpos.y + dy)
/* missile might hit iron bars */
|| (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS
&& hits_bars(&singleobj,
bhitpos.x, bhitpos.y,
bhitpos.x + dx, bhitpos.y + dy,
!rn2(5), 0))
/* Thrown objects "sink" */
|| IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
if (singleobj) { /* hits_bars might have destroyed it */ if (singleobj) { /* hits_bars might have destroyed it */
if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y) if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y)
|| (archer && canseemon(archer)))) || (archer && canseemon(archer))))
@@ -648,6 +643,8 @@ struct obj *obj; /* missile (or stack providing it) */
} }
} }
#undef MT_FLIGHTCHECK
/* Monster throws item at another monster */ /* Monster throws item at another monster */
int int
thrwmm(mtmp, mtarg) thrwmm(mtmp, mtarg)
+30 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 pager.c $NHDT-Date: 1465114189 2016/06/05 08:09:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.107 $ */ /* NetHack 3.6 pager.c $NHDT-Date: 1466638086 2016/06/22 23:28:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.111 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1307,6 +1307,35 @@ doidtrap()
return 0; return 0;
} }
/*
Implements a rudimentary if/elif/else/endif interpretor and use
conditionals in dat/cmdhelp to describe what command each keystroke
currently invokes, so that there isn't a lot of "(debug mode only)"
and "(if number_pad is off)" cluttering the feedback that the user
sees. (The conditionals add quite a bit of clutter to the raw data
but users don't see that. number_pad produces a lot of conditional
commands: basic letters vs digits, 'g' vs 'G' for '5', phone
keypad vs normal layout of digits, and QWERTZ keyboard swap between
y/Y/^Y/M-y/M-Y/M-^Y and z/Z/^Z/M-z/M-Z/M-^Z.)
The interpretor understands
'&#' for comment,
'&? option' for 'if' (also '&? !option'
or '&? option=value[,value2,...]'
or '&? !option=value[,value2,...]'),
'&: option' for 'elif' (with argument variations same as 'if';
any number of instances for each 'if'),
'&:' for 'else' (also '&: #comment';
0 or 1 instance for a given 'if'), and
'&.' for 'endif' (also '&. #comment'; required for each 'if').
The option handling is a bit of a mess, with no generality for
which options to deal with and only a comma separated list of
integer values for the '=value' part. number_pad is the only
supported option that has a value; the few others (wizard/debug,
rest_on_space, #if SHELL, #if SUSPEND) are booleans.
*/
STATIC_DCL void STATIC_DCL void
whatdoes_help() whatdoes_help()
{ {
+59 -22
View File
@@ -1630,7 +1630,7 @@ doloot()
char qbuf[BUFSZ]; char qbuf[BUFSZ];
int prev_inquiry = 0; int prev_inquiry = 0;
boolean prev_loot = FALSE; boolean prev_loot = FALSE;
int num_conts; int num_conts = 0;
abort_looting = FALSE; abort_looting = FALSE;
@@ -1653,13 +1653,30 @@ doloot()
cc.x = u.ux; cc.x = u.ux;
cc.y = u.uy; cc.y = u.uy;
lootcont: if (iflags.menu_requested)
goto lootmon;
lootcont:
if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) { if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
boolean anyfound = FALSE; boolean anyfound = FALSE;
if (!able_to_loot(cc.x, cc.y, TRUE)) if (!able_to_loot(cc.x, cc.y, TRUE))
return 0; return 0;
if (Blind && !uarmg) {
/* if blind and without gloves, attempting to #loot at the
location of a cockatrice corpse is fatal before asking
whether to manipulate any containers */
for (nobj = sobj_at(CORPSE, cc.x, cc.y); nobj;
nobj = nxtobj(nobj, CORPSE, TRUE))
if (will_feel_cockatrice(nobj, FALSE)) {
feel_cockatrice(nobj, FALSE);
/* if life-saved (or poly'd into stone golem),
terminate attempt to loot */
return 1;
}
}
if (num_conts > 1) { if (num_conts > 1) {
/* use a menu to loot many containers */ /* use a menu to loot many containers */
int n, i; int n, i;
@@ -1722,9 +1739,11 @@ lootcont:
} else if (IS_GRAVE(levl[cc.x][cc.y].typ)) { } else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
You("need to dig up the grave to effectively loot it..."); You("need to dig up the grave to effectively loot it...");
} }
/* /*
* 3.3.1 introduced directional looting for some things. * 3.3.1 introduced directional looting for some things.
*/ */
lootmon:
if (c != 'y' && mon_beside(u.ux, u.uy)) { if (c != 'y' && mon_beside(u.ux, u.uy)) {
if (!get_adjacent_loc("Loot in what direction?", if (!get_adjacent_loc("Loot in what direction?",
"Invalid loot location", u.ux, u.uy, &cc)) "Invalid loot location", u.ux, u.uy, &cc))
@@ -2883,20 +2902,27 @@ tipcontainer(box)
struct obj *box; /* or bag */ struct obj *box; /* or bag */
{ {
xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */ xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */
boolean empty_it = FALSE, boolean empty_it = FALSE, maybeshopgoods;
/* Shop handling: can't rely on the container's own unpaid
or no_charge status because contents might differ with it. /* box is either held or on floor at hero's spot; no need to check for
A carried container's contents will be flagged as unpaid nesting; when held, we need to update its location to match hero's;
or not, as appropriate, and need no special handling here. for floor, the coordinate updating is redundant */
Items owned by the hero get sold to the shop without if (get_obj_location(box, &ox, &oy, 0))
confirmation as with other uncontrolled drops. A floor box->ox = ox, box->oy = oy;
container's contents will be marked no_charge if owned by
hero, otherwise they're owned by the shop. By passing /* Shop handling: can't rely on the container's own unpaid
the contents through shop billing, they end up getting or no_charge status because contents might differ with it.
treated the same as in the carried case. We do so one A carried container's contents will be flagged as unpaid
item at a time instead of doing whole container at once or not, as appropriate, and need no special handling here.
to reduce the chance of exhausting shk's billing capacity. */ Items owned by the hero get sold to the shop without
maybeshopgoods = !carried(box) && costly_spot(ox, oy); confirmation as with other uncontrolled drops. A floor
container's contents will be marked no_charge if owned by
hero, otherwise they're owned by the shop. By passing
the contents through shop billing, they end up getting
treated the same as in the carried case. We do so one
item at a time instead of doing whole container at once
to reduce the chance of exhausting shk's billing capacity. */
maybeshopgoods = !carried(box) && costly_spot(box->ox, box->oy);
/* caveat: this assumes that cknown, lknown, olocked, and otrapped /* caveat: this assumes that cknown, lknown, olocked, and otrapped
fields haven't been overloaded to mean something special for the fields haven't been overloaded to mean something special for the
@@ -2959,7 +2985,7 @@ struct obj *box; /* or bag */
if (empty_it) { if (empty_it) {
struct obj *otmp, *nobj; struct obj *otmp, *nobj;
boolean verbose = FALSE, highdrop = !can_reach_floor(TRUE), boolean terse, highdrop = !can_reach_floor(TRUE),
altarizing = IS_ALTAR(levl[ox][oy].typ), altarizing = IS_ALTAR(levl[ox][oy].typ),
cursed_mbag = (Is_mbag(box) && box->cursed); cursed_mbag = (Is_mbag(box) && box->cursed);
int held = carried(box); int held = carried(box);
@@ -2967,20 +2993,27 @@ struct obj *box; /* or bag */
if (u.uswallow) if (u.uswallow)
highdrop = altarizing = FALSE; highdrop = altarizing = FALSE;
terse = !(highdrop || altarizing || costly_spot(box->ox, box->oy));
box->cknown = 1; box->cknown = 1;
/* Terse formatting is
* "Objects spill out: obj1, obj2, obj3, ..., objN."
* If any other messages intervene between objects, we revert to
* "ObjK drops to the floor.", "ObjL drops to the floor.", &c.
*/
pline("%s out%c", pline("%s out%c",
box->cobj->nobj ? "Objects spill" : "An object spills", box->cobj->nobj ? "Objects spill" : "An object spills",
!(highdrop || altarizing) ? ':' : '.'); terse ? ':' : '.');
for (otmp = box->cobj; otmp; otmp = nobj) { for (otmp = box->cobj; otmp; otmp = nobj) {
nobj = otmp->nobj; nobj = otmp->nobj;
obj_extract_self(otmp); obj_extract_self(otmp);
otmp->ox = box->ox, otmp->oy = box->oy;
if (box->otyp == ICE_BOX) { if (box->otyp == ICE_BOX) {
removed_from_icebox(otmp); /* resume rotting for corpse */ removed_from_icebox(otmp); /* resume rotting for corpse */
} else if (cursed_mbag && !rn2(13)) { } else if (cursed_mbag && !rn2(13)) {
loss += mbag_item_gone(held, otmp); loss += mbag_item_gone(held, otmp);
/* abbreviated drop format is no longer appropriate */ /* abbreviated drop format is no longer appropriate */
verbose = TRUE; terse = FALSE;
continue; continue;
} }
@@ -2993,14 +3026,18 @@ struct obj *box; /* or bag */
/* might break or fall down stairs; handles altars itself */ /* might break or fall down stairs; handles altars itself */
hitfloor(otmp); hitfloor(otmp);
} else { } else {
if (altarizing) if (altarizing) {
doaltarobj(otmp); doaltarobj(otmp);
else if (verbose) } else if (!terse) {
pline("%s %s to the %s.", Doname2(otmp), pline("%s %s to the %s.", Doname2(otmp),
otense(otmp, "drop"), surface(ox, oy)); otense(otmp, "drop"), surface(ox, oy));
else } else {
pline("%s%c", doname(otmp), nobj ? ',' : '.'); pline("%s%c", doname(otmp), nobj ? ',' : '.');
iflags.last_msg = PLNMSG_OBJNAM_ONLY;
}
dropy(otmp); dropy(otmp);
if (iflags.last_msg != PLNMSG_OBJNAM_ONLY)
terse = FALSE; /* terse formatting has been interrupted */
} }
if (maybeshopgoods) if (maybeshopgoods)
iflags.suppress_price--; /* reset */ iflags.suppress_price--; /* reset */
+4 -3
View File
@@ -2130,9 +2130,10 @@ boolean unpaid_only;
return price; return price;
} }
/* count amount of gold inside container 'obj' and any nested containers */
long long
contained_gold(obj) contained_gold(obj)
register struct obj *obj; struct obj *obj;
{ {
register struct obj *otmp; register struct obj *otmp;
register long value = 0L; register long value = 0L;
@@ -2867,12 +2868,12 @@ xchar x, y;
boolean isgold = (obj->oclass == COIN_CLASS); boolean isgold = (obj->oclass == COIN_CLASS);
boolean only_partially_your_contents = FALSE; boolean only_partially_your_contents = FALSE;
if (!*u.ushops) /* do cheapest exclusion test first */
return;
if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp)) if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
return; return;
if (!costly_spot(x, y)) if (!costly_spot(x, y))
return; return;
if (!*u.ushops)
return;
if (obj->unpaid && !container && !isgold) { if (obj->unpaid && !container && !isgold) {
sub_one_frombill(obj, shkp); sub_one_frombill(obj, shkp);
+7 -5
View File
@@ -43,7 +43,7 @@ STATIC_DCL int NDECL(throwspell);
STATIC_DCL void NDECL(cast_protection); STATIC_DCL void NDECL(cast_protection);
STATIC_DCL void FDECL(spell_backfire, (int)); STATIC_DCL void FDECL(spell_backfire, (int));
STATIC_DCL const char *FDECL(spelltypemnemonic, (int)); STATIC_DCL const char *FDECL(spelltypemnemonic, (int));
STATIC_DCL boolean FDECL(spell_hurtle_step, (genericptr_t, int, int)); STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
/* The roles[] table lists the role-specific values for tuning /* The roles[] table lists the role-specific values for tuning
* percent_success(). * percent_success().
@@ -1181,12 +1181,14 @@ boolean atme;
return 1; return 1;
} }
/*ARGSUSED*/
STATIC_OVL boolean STATIC_OVL boolean
spell_hurtle_step(arg, x, y) spell_aim_step(arg, x, y)
genericptr_t arg; genericptr_t arg UNUSED;
int x, y; int x, y;
{ {
if (!isok(x,y)) return FALSE; if (!isok(x,y))
return FALSE;
if (!ZAP_POS(levl[x][y].typ) if (!ZAP_POS(levl[x][y].typ)
&& !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN))) && !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
return FALSE; return FALSE;
@@ -1233,7 +1235,7 @@ throwspell()
uc.x = u.ux; uc.x = u.ux;
uc.y = u.uy; uc.y = u.uy;
walk_path(&uc, &cc, spell_hurtle_step, NULL); walk_path(&uc, &cc, spell_aim_step, (genericptr_t) 0);
u.dx = cc.x; u.dx = cc.x;
u.dy = cc.y; u.dy = cc.y;
+4 -2
View File
@@ -31,9 +31,11 @@ all: $(VARDAT) spec_levs quest_levs dungeon
(cd ../util ; $(MAKE) tile2bmp) (cd ../util ; $(MAKE) tile2bmp)
x11tiles: ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ x11tiles: ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \
../win/share/other.txt ../win/share/other.txt \
../win/share/monsters.txt
../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \
../win/share/other.txt ../win/share/other.txt \
-grayscale ../win/share/monsters.txt
beostiles: ../util/tile2beos ../win/share/monsters.txt \ beostiles: ../util/tile2beos ../win/share/monsters.txt \
../win/share/objects.txt \ ../win/share/objects.txt \
+9 -2
View File
@@ -177,7 +177,7 @@ char **argv;
header.per_row = TILES_PER_ROW; header.per_row = TILES_PER_ROW;
if (argc == 1) { if (argc == 1) {
Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]); Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...] [-grayscale txt_fileN]\n", argv[0]);
exit(1); exit(1);
} }
@@ -190,8 +190,15 @@ char **argv;
/* don't leave garbage at end of partial row */ /* don't leave garbage at end of partial row */
(void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes)); (void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes));
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "-grayscale", 10)) {
set_grayscale(TRUE);
if (i < (argc - 1)) i++;
} else {
set_grayscale(FALSE);
}
process_file(argv[i]); process_file(argv[i]);
}
Fprintf(stderr, "Total tiles: %ld\n", header.ntiles); Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
/* round size up to the end of the row */ /* round size up to the end of the row */
+1 -1
View File
@@ -7108,7 +7108,7 @@ Z = (195, 195, 195)
..KKAKKAAKKKOAA. ..KKAKKAAKKKOAA.
.JKKKAAAKKKOKA.. .JKKKAAAKKKOKA..
.KKKKKKKKKLOAA.. .KKKKKKKKKLOAA..
.KOOLKKKKKOKA..K .KOOLKKKKKOKA...
..JKOOKKKKOAA... ..JKOOKKKKOAA...
....JKLOOOKA.... ....JKLOOOKA....
......JJKKAA.... ......JJKKAA....
+3 -1
View File
@@ -57,8 +57,10 @@ boolean read_text_tile(pixel[TILE_Y][TILE_X]);
boolean write_text_tile(pixel[TILE_Y][TILE_X]); boolean write_text_tile(pixel[TILE_Y][TILE_X]);
writes tile writes tile
There are two additional shared routines provided for writers: There are some additional shared routines provided for writers:
void set_grayscale(boolean g);
do grayscale color substitutions when reading the tile text file
void init_colormap(); void init_colormap();
initialize the output colormap from the input one initialize the output colormap from the input one
must be called before opening output file as colormap is part of header must be called before opening output file as colormap is part of header
+2 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 tile.h $NHDT-Date: 1432512803 2015/05/25 00:13:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ /* NetHack 3.6 tile.h $NHDT-Date: 1466687973 2016/06/23 13:19:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.12 $ */
typedef unsigned char pixval; typedef unsigned char pixval;
typedef struct pixel_s { typedef struct pixel_s {
@@ -35,6 +35,7 @@ extern boolean FDECL(read_text_tile, (pixel(*) [TILE_X]));
extern boolean FDECL(write_text_tile, (pixel(*) [TILE_X])); extern boolean FDECL(write_text_tile, (pixel(*) [TILE_X]));
extern int NDECL(fclose_text_file); extern int NDECL(fclose_text_file);
extern void FDECL(set_grayscale, (int));
extern void NDECL(init_colormap); extern void NDECL(init_colormap);
extern void NDECL(merge_colormap); extern void NDECL(merge_colormap);
+1 -13
View File
@@ -237,6 +237,7 @@ char *argv[];
} }
initflag = 1; initflag = 1;
} }
set_grayscale(pass == 3);
/* printf("Colormap initialized\n"); */ /* printf("Colormap initialized\n"); */
while (read_text_tile(tilepixels)) { while (read_text_tile(tilepixels)) {
build_bmptile(tilepixels); build_bmptile(tilepixels);
@@ -327,11 +328,6 @@ BITMAPINFOHEADER *pbmih;
pbmih->biClrImportant = (DWORD) 0; pbmih->biClrImportant = (DWORD) 0;
} }
static int graymappings[] = {
/* . A B C D E F G H I J K L M N O P */
0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14
};
static void static void
build_bmptile(pixels) build_bmptile(pixels)
pixel (*pixels)[TILE_X]; pixel (*pixels)[TILE_X];
@@ -351,14 +347,6 @@ pixel (*pixels)[TILE_X];
Fprintf(stderr, "color not in colormap!\n"); Fprintf(stderr, "color not in colormap!\n");
y = (MAX_Y - 1) - (cur_y + yoffset); y = (MAX_Y - 1) - (cur_y + yoffset);
apply_color = cur_color; apply_color = cur_color;
if (pass == 3) {
/* map to shades of gray */
if (cur_color > (SIZE(graymappings) - 1))
Fprintf(stderr, "Gray mapping issue %d %d.\n", cur_color,
SIZE(graymappings) - 1);
else
apply_color = graymappings[cur_color];
}
#if BITCOUNT == 4 #if BITCOUNT == 4
x = (cur_x / 2) + xoffset; x = (cur_x / 2) + xoffset;
bmp.packtile[y][x] = cur_x % 2 bmp.packtile[y][x] = cur_x % 2
+1 -1
View File
@@ -21,7 +21,7 @@ extern void FDECL(exit, (int));
#endif #endif
#endif #endif
#if defined(MSDOS) || defined(WIN32) #if defined(MSDOS) || defined(WIN32) || defined(X11_GRAPHICS)
#define STATUES_LOOK_LIKE_MONSTERS #define STATUES_LOOK_LIKE_MONSTERS
#endif #endif
+22 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 tiletext.c $NHDT-Date: 1454464783 2016/02/03 01:59:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.12 $ */ /* NetHack 3.6 tiletext.c $NHDT-Date: 1466687974 2016/06/23 13:19:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.14 $ */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
#include "config.h" #include "config.h"
@@ -37,6 +37,20 @@ static void FDECL(write_txttile, (FILE *, pixel (*)[TILE_X]));
"%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.] = " \ "%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.] = " \
"(%d, %d, %d) " "(%d, %d, %d) "
static int grayscale = 0;
/* grayscale color mapping */
static const int graymappings[] = {
/* . A B C D E F G H I J K L M N O P */
0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14
};
void
set_grayscale(g)
int g;
{
grayscale = g;
}
static void static void
read_text_colormap(txtfile) read_text_colormap(txtfile)
FILE *txtfile; FILE *txtfile;
@@ -135,6 +149,13 @@ pixel (*pixels)[TILE_X];
return FALSE; return FALSE;
} }
k = color_index[(int) c[0]]; k = color_index[(int) c[0]];
if (grayscale) {
if (k > (SIZE(graymappings) - 1))
Fprintf(stderr, "Gray mapping issue %d > %d.\n", k,
SIZE(graymappings) - 1);
else
k = graymappings[k];
}
if (k == -1) if (k == -1)
Fprintf(stderr, "color %c not in colormap!\n", c[0]); Fprintf(stderr, "color %c not in colormap!\n", c[0]);
else { else {
+8 -9
View File
@@ -8,7 +8,6 @@
#include "tcap.h" #include "tcap.h"
#include "wintty.h" #include "wintty.h"
#include <ctype.h>
#ifndef C /* this matches src/cmd.c */ #ifndef C /* this matches src/cmd.c */
#define C(c) (0x1f & (c)) #define C(c) (0x1f & (c))
@@ -48,8 +47,7 @@ tty_doprev_message()
do { do {
morc = 0; morc = 0;
if (cw->maxcol == cw->maxrow) { if (cw->maxcol == cw->maxrow) {
ttyDisplay->dismiss_more = ttyDisplay->dismiss_more = C('p'); /* ^P ok at --More-- */
C('p'); /* <ctrl/P> allowed at --More-- */
redotoplin(toplines); redotoplin(toplines);
cw->maxcol--; cw->maxcol--;
if (cw->maxcol < 0) if (cw->maxcol < 0)
@@ -57,8 +55,7 @@ tty_doprev_message()
if (!cw->data[cw->maxcol]) if (!cw->data[cw->maxcol])
cw->maxcol = cw->maxrow; cw->maxcol = cw->maxrow;
} else if (cw->maxcol == (cw->maxrow - 1)) { } else if (cw->maxcol == (cw->maxrow - 1)) {
ttyDisplay->dismiss_more = ttyDisplay->dismiss_more = C('p'); /* ^P ok at --More-- */
C('p'); /* <ctrl/P> allowed at --More-- */
redotoplin(cw->data[cw->maxcol]); redotoplin(cw->data[cw->maxcol]);
cw->maxcol--; cw->maxcol--;
if (cw->maxcol < 0) if (cw->maxcol < 0)
@@ -130,6 +127,7 @@ redotoplin(str)
const char *str; const char *str;
{ {
int otoplin = ttyDisplay->toplin; int otoplin = ttyDisplay->toplin;
home(); home();
if (*str & 0x80) { if (*str & 0x80) {
/* kludge for the / command, the only time we ever want a */ /* kludge for the / command, the only time we ever want a */
@@ -251,10 +249,11 @@ register const char *bp;
(void) strncpy(toplines, bp, TBUFSZ); (void) strncpy(toplines, bp, TBUFSZ);
toplines[TBUFSZ - 1] = 0; toplines[TBUFSZ - 1] = 0;
for (tl = toplines; n0 >= CO;) { for (tl = toplines; n0 >= CO; ) {
otl = tl; otl = tl;
for (tl += CO - 1; tl != otl && !isspace(*tl); --tl) for (tl += CO - 1; tl != otl; --tl)
; if (*tl == ' ')
break;
if (tl == otl) { if (tl == otl) {
/* Eek! A huge token. Try splitting after it. */ /* Eek! A huge token. Try splitting after it. */
tl = index(otl, ' '); tl = index(otl, ' ');
@@ -299,7 +298,7 @@ char c;
break; break;
default: default:
if (ttyDisplay->curx == CO - 1) if (ttyDisplay->curx == CO - 1)
topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */ topl_putsym('\n'); /* 1 <= curx < CO; avoid CO */
#ifdef WIN32CON #ifdef WIN32CON
(void) putchar(c); (void) putchar(c);
#endif #endif
+20 -15
View File
@@ -2443,22 +2443,27 @@ compress_str(str)
const char *str; const char *str;
{ {
static char cbuf[BUFSZ]; static char cbuf[BUFSZ];
/* compress in case line too long */
if ((int) strlen(str) >= CO) {
register const char *bp0 = str;
register char *bp1 = cbuf;
/* compress out consecutive spaces if line is too long;
topline wrapping converts space at wrap point into newline,
we reverse that here */
if ((int) strlen(str) >= CO || index(str, '\n')) {
register const char *bp0 = str;
char c, nxtc, *bp1 = cbuf, *endbp1 = &cbuf[sizeof cbuf - 1];
cbuf[0] = cbuf[sizeof cbuf - 1] = '\0'; /* superfluous */
nxtc = (*bp0 == '\n') ? ' ' : *bp0;
do { do {
#ifdef CLIPPING c = nxtc;
if (*bp0 != ' ' || bp0[1] != ' ') nxtc = bp0[1];
#else if (nxtc == '\n')
if (*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ') nxtc = ' ';
#endif if (c != ' ' || nxtc != ' ')
*bp1++ = *bp0; *bp1++ = c;
} while (*bp0++); } while (*bp0++ && bp1 < endbp1);
} else str = cbuf;
return str; }
return cbuf; return str;
} }
void void
@@ -2601,7 +2606,7 @@ const char *str;
} }
if (cw->data[cw->cury]) if (cw->data[cw->cury])
free((genericptr_t) cw->data[cw->cury]); free((genericptr_t) cw->data[cw->cury]);
n0 = strlen(str) + 1; n0 = (long) strlen(str) + 1L;
ob = cw->data[cw->cury] = (char *) alloc((unsigned) n0 + 1); ob = cw->data[cw->cury] = (char *) alloc((unsigned) n0 + 1);
*ob++ = (char) (attr + 1); /* avoid nuls, for convenience */ *ob++ = (char) (attr + 1); /* avoid nuls, for convenience */
Strcpy(ob, str); Strcpy(ob, str);