Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
@@ -570,9 +570,23 @@ Figure 2
|
||||
Go in that direction until you hit a wall or run into something.
|
||||
.lp m[yuhjklbn]
|
||||
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]
|
||||
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]
|
||||
Prefix: move far, no pickup.
|
||||
.lp "g[yuhjklbn]
|
||||
@@ -640,6 +654,11 @@ D%u - drop only unpaid food.
|
||||
Kick something (usually a door).
|
||||
.lp e
|
||||
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
|
||||
.hw Elbereth
|
||||
.lp E
|
||||
@@ -928,6 +947,8 @@ Kick something.
|
||||
.lp #loot
|
||||
Loot a box or bag on the floor beneath you, or the saddle
|
||||
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
|
||||
Use a monster's special ability (when polymorphed into monster form).
|
||||
.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
|
||||
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
|
||||
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
|
||||
you would move yourself. It is the beast that you will see displayed
|
||||
on the map.
|
||||
.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.
|
||||
.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
|
||||
Bones levels
|
||||
.pg
|
||||
|
||||
@@ -690,10 +690,24 @@ Go in that direction until you hit a wall or run into something.
|
||||
%.lp
|
||||
\item[\tb{m[yuhjklbn]}]
|
||||
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
|
||||
\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
|
||||
\item[\tb{M[yuhjklbn]}]
|
||||
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).
|
||||
%.lp
|
||||
\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
|
||||
% Make sure Elbereth is not hyphenated below, the exact spelling matters.
|
||||
% (Only specified here to parallel Guidebook.mn; use of \tt font implicity
|
||||
@@ -1119,6 +1138,8 @@ Kick something.
|
||||
\item[\tb{\#loot}]
|
||||
Loot a box or bag on the floor beneath you, or the saddle
|
||||
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
|
||||
\item[\tb{\#monster}]
|
||||
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
|
||||
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
|
||||
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
|
||||
you would move yourself. It is the beast that you will see displayed
|
||||
on the map.
|
||||
|
||||
%.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.
|
||||
|
||||
%.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
|
||||
\subsection*{Bones levels}
|
||||
|
||||
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
@@ -322,6 +332,7 @@ when picking a destination for #jump, '$' to show valid dest. is more accurate
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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)
|
||||
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
|
||||
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
|
||||
misspelled pilemark.xbm (as pilemark.xpm)
|
||||
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 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: use grayscale monster tiles for statues
|
||||
|
||||
|
||||
General New Features
|
||||
|
||||
@@ -382,6 +382,7 @@ extern NEARDATA struct instance_flags iflags;
|
||||
#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>" */
|
||||
#define PLNMSG_OBJNAM_ONLY 5 /* xname/doname only, for #tip */
|
||||
/* Usage:
|
||||
* pline("some message");
|
||||
* pline: vsprintf + putstr + iflags.last_msg = PLNMSG_UNKNOWN;
|
||||
|
||||
@@ -193,10 +193,18 @@
|
||||
(vegan(ptr) \
|
||||
|| ((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) \
|
||||
(((obj)->oclass == FOOD_CLASS && is_domestic(ptr)) \
|
||||
|| ((obj)->otyp == BANANA && \
|
||||
((ptr) == &mons[PM_MONKEY] \
|
||||
|| (ptr) == &mons[PM_APE])))
|
||||
(((ptr) == &mons[PM_MONKEY] || (ptr) == &mons[PM_APE]) \
|
||||
? (obj)->otyp == BANANA \
|
||||
: (is_domestic(ptr) && (obj)->oclass == FOOD_CLASS \
|
||||
&& ((ptr)->mlet != S_UNICORN \
|
||||
|| objects[(obj)->otyp].oc_material == VEGGY \
|
||||
|| ((obj)->otyp == CORPSE && (obj)->corpsenm == PM_LICHEN))))
|
||||
|
||||
#endif /* MONDATA_H */
|
||||
|
||||
@@ -3445,11 +3445,20 @@ boolean initial;
|
||||
Cmd.move_SW = Cmd.dirchars[7];
|
||||
}
|
||||
|
||||
/* non-movement commands which accept 'm' prefix to request menu operation */
|
||||
STATIC_OVL boolean
|
||||
accept_menu_prefix(cmd_func)
|
||||
int NDECL((*cmd_func));
|
||||
{
|
||||
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)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
@@ -814,8 +814,8 @@ register struct obj *obj;
|
||||
case CARROT:
|
||||
return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
|
||||
case BANANA:
|
||||
return (mptr->mlet == S_YETI)
|
||||
? DOGFOOD
|
||||
return (mptr->mlet == S_YETI && herbi)
|
||||
? DOGFOOD /* for monkey and ape (tameable), sasquatch */
|
||||
: (herbi || starving)
|
||||
? ACCFOOD
|
||||
: MANFOOD;
|
||||
|
||||
55
src/eat.c
55
src/eat.c
@@ -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. */
|
||||
/* 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 void FDECL(choke, (struct obj *));
|
||||
STATIC_DCL void NDECL(recalc_wt);
|
||||
STATIC_DCL unsigned FDECL(obj_nutrition, (struct obj *));
|
||||
STATIC_DCL struct obj *FDECL(touchfood, (struct obj *));
|
||||
STATIC_DCL void NDECL(do_reset_eat);
|
||||
STATIC_DCL void FDECL(done_eating, (BOOLEAN_P));
|
||||
@@ -296,6 +297,32 @@ reset_eat()
|
||||
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 *
|
||||
touchfood(otmp)
|
||||
struct obj *otmp;
|
||||
@@ -310,9 +337,7 @@ struct obj *otmp;
|
||||
|
||||
if (!otmp->oeaten) {
|
||||
costly_alteration(otmp, COST_BITE);
|
||||
otmp->oeaten = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
|
||||
: otmp->globby ? otmp->owt
|
||||
: (unsigned) objects[otmp->otyp].oc_nutrition;
|
||||
otmp->oeaten = obj_nutrition(otmp);
|
||||
}
|
||||
|
||||
if (carried(otmp)) {
|
||||
@@ -1741,6 +1766,15 @@ struct obj *otmp;
|
||||
make_vomiting((long) rn1(context.victual.reqtime, 14), FALSE);
|
||||
}
|
||||
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 MEAT_STICK:
|
||||
case HUGE_CHUNK_OF_MEAT:
|
||||
@@ -2368,6 +2402,7 @@ doeat()
|
||||
|
||||
if (u.uedibility) {
|
||||
int res = edibility_prompts(otmp);
|
||||
|
||||
if (res) {
|
||||
Your(
|
||||
"%s stops tingling and your sense of smell returns to normal.",
|
||||
@@ -2577,9 +2612,7 @@ doeat()
|
||||
}
|
||||
|
||||
/* re-calc the nutrition */
|
||||
basenutrit = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
|
||||
: otmp->globby ? otmp->owt
|
||||
: (unsigned) objects[otmp->otyp].oc_nutrition;
|
||||
basenutrit = (int) obj_nutrition(otmp);
|
||||
|
||||
debugpline3(
|
||||
"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 */
|
||||
|
||||
/* 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)
|
||||
&& (Wwalking || is_clinger(youmonst.data)
|
||||
|| (Flying && !Breathless))))
|
||||
@@ -3085,10 +3119,9 @@ struct obj *obj;
|
||||
{
|
||||
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;
|
||||
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) {
|
||||
impossible(
|
||||
"partly eaten food (%ld) more nutritious than untouched food (%ld)",
|
||||
|
||||
@@ -979,15 +979,21 @@ not_special:
|
||||
* mpickstuff() as well.
|
||||
*/
|
||||
if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
|
||||
/* don't get stuck circling around an object that's
|
||||
underneath
|
||||
an immobile or hidden monster; paralysis victims
|
||||
excluded */
|
||||
/* don't get stuck circling around object that's
|
||||
underneath an immobile or hidden monster;
|
||||
paralysis victims excluded */
|
||||
if ((mtoo = m_at(xx, yy)) != 0
|
||||
&& (mtoo->msleeping || mtoo->mundetected
|
||||
|| (mtoo->mappearance && !mtoo->iswiz)
|
||||
|| !mtoo->data->mmove))
|
||||
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)
|
||||
|| (likeobjs && index(practical, otmp->oclass)
|
||||
|
||||
@@ -1923,16 +1923,18 @@ struct permonst _mons2[] = {
|
||||
/*
|
||||
* 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),
|
||||
A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_BITE, AD_PHYS, 1, 3), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
|
||||
@@ -414,6 +414,24 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
||||
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
|
||||
m_throw(mon, x, y, dx, dy, range, obj)
|
||||
struct monst *mon; /* launching monster */
|
||||
@@ -471,17 +489,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
|
||||
/* pre-check for doors, walls and boundaries.
|
||||
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))) {
|
||||
if (MT_FLIGHTCHECK(TRUE)) {
|
||||
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
|
||||
return;
|
||||
}
|
||||
@@ -611,20 +619,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
if (!range /* reached end of path */
|
||||
/* 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 */
|
||||
|| (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)) {
|
||||
|| MT_FLIGHTCHECK(FALSE)) {
|
||||
if (singleobj) { /* hits_bars might have destroyed it */
|
||||
if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y)
|
||||
|| (archer && canseemon(archer))))
|
||||
@@ -648,6 +643,8 @@ struct obj *obj; /* missile (or stack providing it) */
|
||||
}
|
||||
}
|
||||
|
||||
#undef MT_FLIGHTCHECK
|
||||
|
||||
/* Monster throws item at another monster */
|
||||
int
|
||||
thrwmm(mtmp, mtarg)
|
||||
|
||||
31
src/pager.c
31
src/pager.c
@@ -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. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1307,6 +1307,35 @@ doidtrap()
|
||||
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
|
||||
whatdoes_help()
|
||||
{
|
||||
|
||||
81
src/pickup.c
81
src/pickup.c
@@ -1630,7 +1630,7 @@ doloot()
|
||||
char qbuf[BUFSZ];
|
||||
int prev_inquiry = 0;
|
||||
boolean prev_loot = FALSE;
|
||||
int num_conts;
|
||||
int num_conts = 0;
|
||||
|
||||
abort_looting = FALSE;
|
||||
|
||||
@@ -1653,13 +1653,30 @@ doloot()
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
|
||||
lootcont:
|
||||
if (iflags.menu_requested)
|
||||
goto lootmon;
|
||||
|
||||
lootcont:
|
||||
if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
|
||||
boolean anyfound = FALSE;
|
||||
|
||||
if (!able_to_loot(cc.x, cc.y, TRUE))
|
||||
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) {
|
||||
/* use a menu to loot many containers */
|
||||
int n, i;
|
||||
@@ -1722,9 +1739,11 @@ lootcont:
|
||||
} else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
|
||||
You("need to dig up the grave to effectively loot it...");
|
||||
}
|
||||
|
||||
/*
|
||||
* 3.3.1 introduced directional looting for some things.
|
||||
*/
|
||||
lootmon:
|
||||
if (c != 'y' && mon_beside(u.ux, u.uy)) {
|
||||
if (!get_adjacent_loc("Loot in what direction?",
|
||||
"Invalid loot location", u.ux, u.uy, &cc))
|
||||
@@ -2883,20 +2902,27 @@ tipcontainer(box)
|
||||
struct obj *box; /* or bag */
|
||||
{
|
||||
xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */
|
||||
boolean empty_it = FALSE,
|
||||
/* Shop handling: can't rely on the container's own unpaid
|
||||
or no_charge status because contents might differ with it.
|
||||
A carried container's contents will be flagged as unpaid
|
||||
or not, as appropriate, and need no special handling here.
|
||||
Items owned by the hero get sold to the shop without
|
||||
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(ox, oy);
|
||||
boolean empty_it = FALSE, maybeshopgoods;
|
||||
|
||||
/* box is either held or on floor at hero's spot; no need to check for
|
||||
nesting; when held, we need to update its location to match hero's;
|
||||
for floor, the coordinate updating is redundant */
|
||||
if (get_obj_location(box, &ox, &oy, 0))
|
||||
box->ox = ox, box->oy = oy;
|
||||
|
||||
/* Shop handling: can't rely on the container's own unpaid
|
||||
or no_charge status because contents might differ with it.
|
||||
A carried container's contents will be flagged as unpaid
|
||||
or not, as appropriate, and need no special handling here.
|
||||
Items owned by the hero get sold to the shop without
|
||||
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
|
||||
fields haven't been overloaded to mean something special for the
|
||||
@@ -2959,7 +2985,7 @@ struct obj *box; /* or bag */
|
||||
|
||||
if (empty_it) {
|
||||
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),
|
||||
cursed_mbag = (Is_mbag(box) && box->cursed);
|
||||
int held = carried(box);
|
||||
@@ -2967,20 +2993,27 @@ struct obj *box; /* or bag */
|
||||
|
||||
if (u.uswallow)
|
||||
highdrop = altarizing = FALSE;
|
||||
terse = !(highdrop || altarizing || costly_spot(box->ox, box->oy));
|
||||
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",
|
||||
box->cobj->nobj ? "Objects spill" : "An object spills",
|
||||
!(highdrop || altarizing) ? ':' : '.');
|
||||
terse ? ':' : '.');
|
||||
for (otmp = box->cobj; otmp; otmp = nobj) {
|
||||
nobj = otmp->nobj;
|
||||
obj_extract_self(otmp);
|
||||
otmp->ox = box->ox, otmp->oy = box->oy;
|
||||
|
||||
if (box->otyp == ICE_BOX) {
|
||||
removed_from_icebox(otmp); /* resume rotting for corpse */
|
||||
} else if (cursed_mbag && !rn2(13)) {
|
||||
loss += mbag_item_gone(held, otmp);
|
||||
/* abbreviated drop format is no longer appropriate */
|
||||
verbose = TRUE;
|
||||
terse = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2993,14 +3026,18 @@ struct obj *box; /* or bag */
|
||||
/* might break or fall down stairs; handles altars itself */
|
||||
hitfloor(otmp);
|
||||
} else {
|
||||
if (altarizing)
|
||||
if (altarizing) {
|
||||
doaltarobj(otmp);
|
||||
else if (verbose)
|
||||
} else if (!terse) {
|
||||
pline("%s %s to the %s.", Doname2(otmp),
|
||||
otense(otmp, "drop"), surface(ox, oy));
|
||||
else
|
||||
} else {
|
||||
pline("%s%c", doname(otmp), nobj ? ',' : '.');
|
||||
iflags.last_msg = PLNMSG_OBJNAM_ONLY;
|
||||
}
|
||||
dropy(otmp);
|
||||
if (iflags.last_msg != PLNMSG_OBJNAM_ONLY)
|
||||
terse = FALSE; /* terse formatting has been interrupted */
|
||||
}
|
||||
if (maybeshopgoods)
|
||||
iflags.suppress_price--; /* reset */
|
||||
|
||||
@@ -2130,9 +2130,10 @@ boolean unpaid_only;
|
||||
return price;
|
||||
}
|
||||
|
||||
/* count amount of gold inside container 'obj' and any nested containers */
|
||||
long
|
||||
contained_gold(obj)
|
||||
register struct obj *obj;
|
||||
struct obj *obj;
|
||||
{
|
||||
register struct obj *otmp;
|
||||
register long value = 0L;
|
||||
@@ -2867,12 +2868,12 @@ xchar x, y;
|
||||
boolean isgold = (obj->oclass == COIN_CLASS);
|
||||
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))
|
||||
return;
|
||||
if (!costly_spot(x, y))
|
||||
return;
|
||||
if (!*u.ushops)
|
||||
return;
|
||||
|
||||
if (obj->unpaid && !container && !isgold) {
|
||||
sub_one_frombill(obj, shkp);
|
||||
|
||||
12
src/spell.c
12
src/spell.c
@@ -43,7 +43,7 @@ STATIC_DCL int NDECL(throwspell);
|
||||
STATIC_DCL void NDECL(cast_protection);
|
||||
STATIC_DCL void FDECL(spell_backfire, (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
|
||||
* percent_success().
|
||||
@@ -1181,12 +1181,14 @@ boolean atme;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC_OVL boolean
|
||||
spell_hurtle_step(arg, x, y)
|
||||
genericptr_t arg;
|
||||
spell_aim_step(arg, x, y)
|
||||
genericptr_t arg UNUSED;
|
||||
int x, y;
|
||||
{
|
||||
if (!isok(x,y)) return FALSE;
|
||||
if (!isok(x,y))
|
||||
return FALSE;
|
||||
if (!ZAP_POS(levl[x][y].typ)
|
||||
&& !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
|
||||
return FALSE;
|
||||
@@ -1233,7 +1235,7 @@ throwspell()
|
||||
uc.x = u.ux;
|
||||
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.dy = cc.y;
|
||||
|
||||
@@ -31,9 +31,11 @@ all: $(VARDAT) spec_levs quest_levs dungeon
|
||||
(cd ../util ; $(MAKE) tile2bmp)
|
||||
|
||||
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 \
|
||||
../win/share/other.txt
|
||||
../win/share/other.txt \
|
||||
-grayscale ../win/share/monsters.txt
|
||||
|
||||
beostiles: ../util/tile2beos ../win/share/monsters.txt \
|
||||
../win/share/objects.txt \
|
||||
|
||||
@@ -177,7 +177,7 @@ char **argv;
|
||||
header.per_row = TILES_PER_ROW;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -190,8 +190,15 @@ char **argv;
|
||||
/* don't leave garbage at end of partial row */
|
||||
(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]);
|
||||
}
|
||||
Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
|
||||
|
||||
/* round size up to the end of the row */
|
||||
|
||||
@@ -7108,7 +7108,7 @@ Z = (195, 195, 195)
|
||||
..KKAKKAAKKKOAA.
|
||||
.JKKKAAAKKKOKA..
|
||||
.KKKKKKKKKLOAA..
|
||||
.KOOLKKKKKOKA..K
|
||||
.KOOLKKKKKOKA...
|
||||
..JKOOKKKKOAA...
|
||||
....JKLOOOKA....
|
||||
......JJKKAA....
|
||||
|
||||
@@ -57,8 +57,10 @@ boolean read_text_tile(pixel[TILE_Y][TILE_X]);
|
||||
boolean write_text_tile(pixel[TILE_Y][TILE_X]);
|
||||
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();
|
||||
initialize the output colormap from the input one
|
||||
must be called before opening output file as colormap is part of header
|
||||
|
||||
@@ -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 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 int NDECL(fclose_text_file);
|
||||
|
||||
extern void FDECL(set_grayscale, (int));
|
||||
extern void NDECL(init_colormap);
|
||||
extern void NDECL(merge_colormap);
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ char *argv[];
|
||||
}
|
||||
initflag = 1;
|
||||
}
|
||||
set_grayscale(pass == 3);
|
||||
/* printf("Colormap initialized\n"); */
|
||||
while (read_text_tile(tilepixels)) {
|
||||
build_bmptile(tilepixels);
|
||||
@@ -327,11 +328,6 @@ BITMAPINFOHEADER *pbmih;
|
||||
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
|
||||
build_bmptile(pixels)
|
||||
pixel (*pixels)[TILE_X];
|
||||
@@ -351,14 +347,6 @@ pixel (*pixels)[TILE_X];
|
||||
Fprintf(stderr, "color not in colormap!\n");
|
||||
y = (MAX_Y - 1) - (cur_y + yoffset);
|
||||
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
|
||||
x = (cur_x / 2) + xoffset;
|
||||
bmp.packtile[y][x] = cur_x % 2
|
||||
|
||||
@@ -21,7 +21,7 @@ extern void FDECL(exit, (int));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) || defined(WIN32)
|
||||
#if defined(MSDOS) || defined(WIN32) || defined(X11_GRAPHICS)
|
||||
#define STATUES_LOOK_LIKE_MONSTERS
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
#include "config.h"
|
||||
@@ -37,6 +37,20 @@ static void FDECL(write_txttile, (FILE *, pixel (*)[TILE_X]));
|
||||
"%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.] = " \
|
||||
"(%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
|
||||
read_text_colormap(txtfile)
|
||||
FILE *txtfile;
|
||||
@@ -135,6 +149,13 @@ pixel (*pixels)[TILE_X];
|
||||
return FALSE;
|
||||
}
|
||||
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)
|
||||
Fprintf(stderr, "color %c not in colormap!\n", c[0]);
|
||||
else {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "tcap.h"
|
||||
#include "wintty.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef C /* this matches src/cmd.c */
|
||||
#define C(c) (0x1f & (c))
|
||||
@@ -48,8 +47,7 @@ tty_doprev_message()
|
||||
do {
|
||||
morc = 0;
|
||||
if (cw->maxcol == cw->maxrow) {
|
||||
ttyDisplay->dismiss_more =
|
||||
C('p'); /* <ctrl/P> allowed at --More-- */
|
||||
ttyDisplay->dismiss_more = C('p'); /* ^P ok at --More-- */
|
||||
redotoplin(toplines);
|
||||
cw->maxcol--;
|
||||
if (cw->maxcol < 0)
|
||||
@@ -57,8 +55,7 @@ tty_doprev_message()
|
||||
if (!cw->data[cw->maxcol])
|
||||
cw->maxcol = cw->maxrow;
|
||||
} else if (cw->maxcol == (cw->maxrow - 1)) {
|
||||
ttyDisplay->dismiss_more =
|
||||
C('p'); /* <ctrl/P> allowed at --More-- */
|
||||
ttyDisplay->dismiss_more = C('p'); /* ^P ok at --More-- */
|
||||
redotoplin(cw->data[cw->maxcol]);
|
||||
cw->maxcol--;
|
||||
if (cw->maxcol < 0)
|
||||
@@ -130,6 +127,7 @@ redotoplin(str)
|
||||
const char *str;
|
||||
{
|
||||
int otoplin = ttyDisplay->toplin;
|
||||
|
||||
home();
|
||||
if (*str & 0x80) {
|
||||
/* kludge for the / command, the only time we ever want a */
|
||||
@@ -251,10 +249,11 @@ register const char *bp;
|
||||
(void) strncpy(toplines, bp, TBUFSZ);
|
||||
toplines[TBUFSZ - 1] = 0;
|
||||
|
||||
for (tl = toplines; n0 >= CO;) {
|
||||
for (tl = toplines; n0 >= CO; ) {
|
||||
otl = tl;
|
||||
for (tl += CO - 1; tl != otl && !isspace(*tl); --tl)
|
||||
;
|
||||
for (tl += CO - 1; tl != otl; --tl)
|
||||
if (*tl == ' ')
|
||||
break;
|
||||
if (tl == otl) {
|
||||
/* Eek! A huge token. Try splitting after it. */
|
||||
tl = index(otl, ' ');
|
||||
@@ -299,7 +298,7 @@ char c;
|
||||
break;
|
||||
default:
|
||||
if (ttyDisplay->curx == CO - 1)
|
||||
topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */
|
||||
topl_putsym('\n'); /* 1 <= curx < CO; avoid CO */
|
||||
#ifdef WIN32CON
|
||||
(void) putchar(c);
|
||||
#endif
|
||||
|
||||
@@ -2443,22 +2443,27 @@ compress_str(str)
|
||||
const char *str;
|
||||
{
|
||||
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 {
|
||||
#ifdef CLIPPING
|
||||
if (*bp0 != ' ' || bp0[1] != ' ')
|
||||
#else
|
||||
if (*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
|
||||
#endif
|
||||
*bp1++ = *bp0;
|
||||
} while (*bp0++);
|
||||
} else
|
||||
return str;
|
||||
return cbuf;
|
||||
c = nxtc;
|
||||
nxtc = bp0[1];
|
||||
if (nxtc == '\n')
|
||||
nxtc = ' ';
|
||||
if (c != ' ' || nxtc != ' ')
|
||||
*bp1++ = c;
|
||||
} while (*bp0++ && bp1 < endbp1);
|
||||
str = cbuf;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2601,7 +2606,7 @@ const char *str;
|
||||
}
|
||||
if (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++ = (char) (attr + 1); /* avoid nuls, for convenience */
|
||||
Strcpy(ob, str);
|
||||
|
||||
Reference in New Issue
Block a user