Commit Graph

225 Commits

Author SHA1 Message Date
PatR
70949a787e mplayer creation bestowing 0 gold pieces
Reported directly to devteam:  a fake player monster was petrified
and when creating its statue yielded "Calculating weight of 0 gold
pieces?".

Fake player monsters on the Astral Plane level were being created
with rn2(1000) gold pieces so had a 1 in 1000 chance of that being 0.
Gold gets created with a non-zero amount but the routine that gives
it to a monster sets the amount to the requested value.  That didn't
update the weight so didn't notice the 0.  Putting it into a container
(the statue) did recalculate the weight and did notice.

There was a choice between forcing a non-zero amount or allowing 0
and bypassing its creation and placement in monster's inventory.
I went with the latter.
2023-04-29 05:30:14 -07:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
Pasi Kallinen
fc7a32b86e Tutorial level
Add a tutorial level to teach commands to new players.
Very much a WIP.

Breaks save and bones compat.
2023-03-01 14:00:29 +02:00
Pasi Kallinen
ed7e344f00 Giants occasionally have a weapon 2023-01-24 20:54:39 +02:00
nhmall
02a48aa8cf split g into multiple structures
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.

It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.

Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.

To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.

A global variable named 'amulets', would be found in ga.
    ga.amulets
     ^ ^
A global varable named 'move', would be found in gm.
    gm.moves
     ^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
    gv.val_for_n_or_more
     ^ ^
A global variable named 'youmonst' would be found in gy.
    gy.youmonst
     ^ ^
2022-11-29 21:53:21 -05:00
PatR
5b0f4a2e6d more #tip, mostly container-to-container
Require a free hand when tipping a container into another container.
Presumeably you need to open the destination container and possibly
keep holding it open.

If you try to tip a carried container into an unknown bag of tricks,
apply the bag (once) instead of performing the tip.  (To 'open' the
destination as above.)  Possibly slightly confusing if bag is empty.

When tipping a container, always ask for the destination instead of
doing that only when carrying other containers.  Confirming floor
as destination can be annoying but having to do that sometimes and
skipping that sometimes is aggravating because it is error prone.
And floor is preselected so can be chosen with space or return.
(I wanted to change the selector letter for floor from '-' to '.'
and then keep '-' as an unseen group accelerator, but the latter
doesn't work for PICK_ONE so I've left '-' as-is.)

Don't display "monsters appear" after tipping a bag of tricks.
Monster creation gives feedback these days.  (Comparable to recent
"summon nasties" fix.)
2022-09-15 12:30:44 -07:00
nhmall
c548fff9e4 some spelling corrections
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.

behaviour  -> behavior
speach     -> speech
knowlege   -> knowledge
incrments  -> increments
stethscope -> stethoscope
staiway    -> stairway
arifact    -> artifact
extracing  -> extracting

The uses of "iff" were left alone.

Close #869
2022-09-08 10:54:11 -04:00
Pasi Kallinen
a9ca23e8f9 Random figurines are of harder monsters 2022-08-21 13:23:16 +03:00
Pasi Kallinen
953d43f5ac Monster known traps bit twiddling 2022-08-21 11:36:39 +03:00
Pasi Kallinen
9be2e581b7 Macros for checking is object artifact 2022-08-12 19:37:34 +03:00
Pasi Kallinen
07184c9640 Don't give fake Demonbanes to angels
Demonbane is a mace now, so trying to generate a long sword made
fake Demonbanes. Just don't give Demonbane at all to random angels.
2022-08-05 13:43:39 +03:00
PatR
e13e514556 fix broken migrating monster arrival
If the first monster on the migrating_mons list couldn't arrive and
was put back on the list to try again later, 'later' would happen
immediately and the program looped forever trying and failing to
bring that monster to the level.

Defer repeat attempts at migration until losedogs() has been through
the whole migrating_mons list.  mon_arrive() now populates a new
list called failed_arrivals and losedog() moves its contents, if any,
to migrating_mons prior to returning.
2022-07-28 00:51:18 -07:00
Pasi Kallinen
1ae2bc7063 Wielding a bec de corbin makes ravens generate peaceful 2022-07-17 09:04:15 +03:00
Pasi Kallinen
94c1e94d20 Move mtrack push and clear to separate functions 2022-07-16 18:43:22 +03:00
nhmall
3004cf2d34 be more consistent with coordinates 2022-07-02 09:10:03 -04:00
nhmall
30b557f7d5 change xchar to other typedefs
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.

This splits the uses of xchar into 3 different situations, and adjusts
their type and size:

                        xchar
                          |
               -----------------------
               |          |          |
            coordxy     xint16     xint8

coordxy: Actual x or y coordinates for various things (moved to 16-bits).

xint16:  Same data size as coordxy, but for non-coordinate use (16-bits).

xint8:   There are only a few use cases initially, where it was very
         plain to see that the variable could remain as 8-bits, rather
         than be bumped to 16-bits.  There are probably more such cases
         that could be changed after additional review.

Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.

This increments EDITLEVEL in patchlevel.h
2022-06-30 23:48:18 -04:00
PatR
174cac42a6 partial vampire fix
From a followup comment to a reddit post:  a vampire who has gained
levels loses them when reverting to base form.  This fixes the case
where it grows into a vampire lord; change the base form from plain
vampire to lord when that happens.

It does not fix the case where shapechanging to fog or bat or wolf
and then back to base form yields a new vampire or vampire lord
instead of the one that built itself up.  Mainly affects pet vampires
since wild oees don't tend to grow very much.
2022-06-25 11:26:05 -07:00
nhmall
9e6ac144b4 switch to using a flag parameter on newcham() 2022-05-28 19:35:48 -04:00
copperwater
84f4e53fde Use RANDOM_CLASS instead of magic number 0 for mksobj_at() 2022-05-27 21:42:25 -04:00
PatR
4fbda9ea34 dochugw(mon, X)
Reverse the sense of dochugw()'s new 'X' argument. Use True for the
usual case and False for the special case rather than the other way
around.

Call the special case variant when a monster teleports so that hero
stops occupation if the monster jumps to a position where it becomes
a threat.
2022-05-07 09:11:09 -07:00
PatR
f2f2644e30 busy hero ignoring monster threat
Fix the problem reported by entrez of a zombie corpse reviving and
crawling out of the ground while the hero was busy doing something
(searching, digging, &c) and having the hero fail to react and just
keep doing whatever the thing was because the zombie was already
inside the range where a monster changes from no-threat to threat.

Done in the monster creation routine so any new monster (including
one revived from a corpse) that is visible,&c will cause the hero's
action to be interrupted.  Teleport arrival probably needs this too.

Only interrupts an occupation, not other voluntary multi-turn
actitivy such as running or traveling.  That would be trivial to
change ['if (g.occupation...' to 'if ((g.occupation || multi > 0)...']
but I'm not sure whether it ought to be extended to that.
2022-05-06 18:30:06 -07:00
PatR
98eebb97d2 corpse gender
Reported by entrez.  Don't make 50% of neuter monsters be flagged as
female.  It doesn't matter for live monsters but gets inherited by
their corpses, where female and non-female corpses stack separately.
2022-04-21 03:31:32 -07:00
PatR
f0c7394968 git issue #717 - avoid putting monsters on scare \
monster and Elbereth unless there's no other choice.

Suggested by NetSysFire, don't create new monsters on top of scrolls
of scare monster.  Not mentioned in the suggestion:  unless they are
a type of monster that isn't affected by such scrolls.  This extends
it to teleport destination too.

Avoid placing a monster on a scroll of scare monster or on engraved
Elbereth if there are other locations available.  Only performed for
callers of goodpos() who explicitly request it, which at the moment
are makemon(), rloc(), and enexto().

Also, propagate 'mmflags_nht' to a bunch of places that were left
using long or unsigned for makemon() and goodpos() flags.  I didn't
attempt to be systematic about that though.

Implements #717
2022-04-01 05:09:58 -07:00
nhkeni
fc5e991b06 Add typedef mmflags_t to assure enough bits for all MM_* flags. 2022-03-17 17:14:12 -04:00
PatR
77dc522a62 artifact tracking again
Redo the recent artifact creation stuff by replacing several nearly
identical routines with one more general one.  Also adds a tracking
bit for one or two more creation methods.  That changed artiexist[]
from an array of structs holding 8 or less bits to one holding 9, so
bump EDITLEVEL in case the total size changed.
2022-03-12 17:25:54 -08:00
PatR
0effaf529a fix github issue #691 - non-lawful Angels \
get lawful artifacts

Reported by vultur-cadens, Angels can be given Sunsword or Demonbane
for starting equipment even when they aren't lawful so won't attempt
to use those.

This should fix it but it's a pain to test.

Closes #691
2022-03-07 15:12:12 -08:00
PatR
d37fa4138a found_artifact() groundwork
Lay groundwork for generating a log event when finding an artifact
on the floor or carried by a monster.  This part should not produce
any change in behavior.

Move g.artidisco[] and g.artiexist[] out of the instance_globals
struct back to local within artifact.c.  They are both initialized
at the start of a game (and only used in that file) so don't need
to be part of any bulk reinitialization if restart-instead-of-exit
ever gets implemented.

Convert artiexist[] from an array of booleans to an array of structs
containing a pair of bitfields.  artiexist[].exists is a direct
replacement for the boolean; artiexist[].found is new but not put to
any significant use yet.  If will be used to suppress the future
found-an-artifact event for cases where a more specific event (like
crowning or divine gift as #offer reward) is already produced.

Remove g.via_naming altogether and add an extra argument to oname()
calls to replace it.

Add an extra argument to artifact_exists() calls.
2022-03-07 02:06:55 -08:00
Pasi Kallinen
8e91320d2f Use u_at macro 2022-02-23 20:28:55 +02:00
Pasi Kallinen
51a5550a51 Hobbits getting a sling also get some ammo 2022-02-22 10:01:55 +02:00
Pasi Kallinen
91e2d3633e Use macro for a location next to hero 2022-02-12 11:05:10 +02:00
PatR
50d8463b71 <Mon> suddenly appears! vs ^G
For ^G, throttle the monster creation feedback.  Don't say "suddenly"
and don't exclaim the message, just say "<Mon> appears."  Also, use
Norep() so creating lots of similar monsters at once only gives a few
messages (just one unless varied by "next to you" vs "nearby" vs no
qualifier for farther away).  And for mimics created as objects or
furniture, report the sudden appearance of new object or furniture.
2022-02-07 15:55:04 -08:00
Pasi Kallinen
a990eae8ec perm_invent update when applying a bag of tricks 2022-01-09 16:40:35 +02:00
Pasi Kallinen
48bca11d67 Accessibility: give message for created monsters
Always give a message when creating a detected monster
during gameplay (as opposed to during level creation).
To prevent the message, use the MM_NOMSG flag for makemon.

Most places already handled their own messaging, but there
were some, such as bag of tricks, create monster magic
and random monsters created during gameplay that didn't.
2022-01-06 14:06:49 +02:00
PatR
7ccc195155 fix #K3496 - leash description when pet changes
If persistent inventory is displayed and contains an entry for a leash
attached to a pet and the pet's type or name changes, the perm_invent
window didn't get updated to reflect the new leash information:
 x - leash (attached to <mon>)
Report was for polymorph but applied to growing into bigger form and
to being (re-/un-)christened as well.
2021-12-19 09:30:07 -08:00
PatR
da859c5eb8 fix github issue #623 - soldiers and mattocks
Reported by eakaye.  Selection of equipment when creating a soldier
or watchperson can pick a polearm, but random selection among those
had a chance to choose dwarvish mattock which doesn't use polearms
skill and isn't appropriate for a human soldier or watchperson.
Not mentioned, but lance was in the same boat.

Change the selection to only pick something which uses polearms
skill, then make that moot by moving lance and dwarvish mattock out
of the midst of the polearms so that they're no longer candidates
for special case rejection.

A couple of other things which might have had a similar issue were
already ok.  Giving a polearm when creating a troll selects between
a few choices rather than among all the polearms.  And wishing for
"polearm" only considers items which use polearms skill.

While changing objects.h to reorder the two non-polearms, I removed
a bunch of tabs that were present in the scroll definitions.

EDITLEVEL is incremented due to objects[] reordering, so existing
save and bones files will be invalidated.

Fixes #623
2021-10-27 15:36:32 -07:00
PatR
b1d76a772f fix github issue #596 - wishing exploit
for helm of opposite alignment.

Discovered and described by vultur-cadens.

The #adjust command can be used to split an object stack and if the
shop price of the two halves are different, the new stack will have
its obj->o_id modified to make the prices the same.  That could be
used to tip off the player as to what the low bits of the next o_id
will be.  Since no time passes, no intervening activity such as
random creation of a new monster can take place, so the player could
wish for something that depends on o_id with some degree of control.
Matters mainly for helms of opposite alignment intended to be used
by neutral characters since the player isn't supposed to be able to
control that.  (Other items like T-shirt slogan text and candy bar
wrapper text had a similar issue but controlling those wouldn't have
had any tangible difference on play.)

The issue writeup suggested allowing the player to specify a helm's
alignment during a wish.  That would defeat the purpose of having
o_id affect the helm's behavior in an arbitrary but repeatable way
so is rejected.

I implemented this fix before seeing a followup comment that suggests
using a more sophisticated decision than 'obj->o_id % N' for the
arbitrary effect.  This just increments context.ident for the next
obj->o_id or mon->m_id by 1 or 2 instead of always by 1 and should
be adequate.  It also has the side-effect that two consecutive wishes
for helm of opposite alignment won't necessary give one for each of
the two possible 'polarities', even with no intervening activity by
monsters, reinforcing the lack of player control.

Minor bonus fix:  it moves the incrementing check for wrap-to-0 into
a single place instead of replicating that half a dozen times.  Ones
that should have been there for shop billing and for objects loaded
from bones files were missing.

Fixes #596
2021-09-30 13:08:27 -07:00
Pasi Kallinen
65b320de39 Start of movement tests
Adds the following lua functions:

- nh.pushkey("x")
    Pushes a key into the command queue. Support is spotty,
    currently only the keys handled in rhack.
- nh.doturn()
    Runs one turn of main loop, or if optional boolean param
    is true, until g.multi == 0
- nh.monster_generation(false)
    Disable monster generation, and kill off all monsters.

Adds a testmove.lua script to test hero movement. Currently
covers only hjklyubn and HJKLYUBN.
2021-07-28 19:19:40 +03:00
Pasi Kallinen
b5dd0f8986 Fix strange object mimic in shop sanity error
Shop population code set the mimic shape to strange object
without checking for protection from shape changers.
Let set_mimic_sym (via makemon) handle it correctly instead.
2021-06-26 13:03:28 +03:00
Pasi Kallinen
a1b765936f Boost HP of some golems
Idea from SporkHack by Derek Ray, but values are different.
2021-05-20 19:25:16 +03:00
Pasi Kallinen
2288452278 Monsters can see player resistances
If monsters see you resist something, generally elemental or magical
attack, or if they see you reflect an attack, they learn that and
will adjust their attack accordingly.

Originally from SporkHack, but this version comes via EvilHack with
some minor changes.
2021-05-17 20:01:11 +03:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
nhmall
772e876e44 incorporate some pmnames feedback
Also an update to a fixes37.0 entry
2020-12-26 19:07:19 -05:00
nhmall
0c3b9642e4 pmnames mons gender naming plus a window port interface change
add MALE, FEMALE, and gender-neutral names for individual monster species
to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the
MALE and FEMALE versions are not.

replace code uses of the mname field of permonst with one of the three
potentially-available gender-specific names.

consolidate some separate mons entries that differed only by species into a
single mons entry (caveman, cavewoman and priest,priestess etc.)

consolidate several "* lord" and "* queen/* king" monst entries into
their single species, and allow both genders on some where it makes some
sense (there is probably more work and cleanup to come out of this at some
point, and the chosen gender-neutral name variations are not cast in stone
if someone has better suggestions).

related function or macro additions:
    pmname(pm, gender) to get the gender variation of the permonst name. It
    guards against monsters that haven't got anything except NEUTRAL naming
    and falls back to the NEUTRAL version if FEMALE and MALE versions are
    missing.

    Ugender to obtain the current hero gender.
    Mgender(mtmp) to obtain the gender of a monster

While the code can safely refer directly to pmnames[NEUTRAL] safely in the
code because it always exists, the other two (pmnames[MALE] and
pmnames[FEMALE] may not exist so use:
    pmname(ptr, gidx)
      where -ptr is a permonst *
            -gidx is an index into the pmnames array field of the
             permonst struct
pmname() checks for a valid index and checks for null-pointers for
pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if
the pointer requested if the requested variation is unavailable, or if the
gidx is out-of-range.

Allow code to specify makemon flags to request female or male (via MM_MALE
and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't
distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't
override the pm M2_MALE and M2_FEMALE flags on a mons[] entry.

male and female tiles have been added to win/share/monsters.txt.
The majority are duplicated placeholders except for those that were
separate mons entries before. Perhaps someone will contribute artwork in the
future to make the male and female variations visually distinguishable.

tilemapping via has the MALE tile indexes in the glyph2tile[]
array produced at build time. If a window port has information that the
FEMALE tile is required, it just has to increment the index returned
from the glyph2tile[] array by 1.

statues already preserved gender of the monster through STATUE_FEMALE
and STATUE_MALE, so ensure that pmnames takes that into consideration.

I expect some refinement will be required after broad play-testing puts it to
the test.

    consolidate caveman,cavewoman and priest,priestess monst.c entries etc

This commit will require a bump of editlevel in patchlevel.h because it alters
the index numbers of the monsters due to the consolidation of some. Those
index numbers are saved in some other structures, even though the mons[] array
itself is not part of the savefile.

Window Port Interface Change

Also add a parameter to print_glyph to convey additional information beyond
the glyph to the window ports. Every single window port was calling back to
mapglyph for the information anyway, so just included it in the interface and
produce the information right in the display core.

The mapglyph() function uses will be eliminated, although there are still some
in the code yet to be dealt with.

win32, tty, x11, Qt, msdos window ports have all had adjustments done to
utilize the new parameter instead of calling mapglyph, but some of those
window ports have not been thoroughly tested since the changes.

Interface change additional info:

    print_glyph(window, x, y, glyph, bkglyph, *glyphmod)
            -- Print the glyph at (x,y) on the given window.  Glyphs are
               integers at the interface, mapped to whatever the window-
               port wants (symbol, font, color, attributes, ...there's
               a 1-1 map between glyphs and distinct things on the map).
            -- bkglyph is a background glyph for potential use by some
               graphical or tiled environments to allow the depiction
               to fall against a background consistent with the grid
               around x,y. If bkglyph is NO_GLYPH, then the parameter
               should be ignored (do nothing with it).
                -- glyphmod provides extended information about the glyph
               that window ports can use to enhance the display in
               various ways.
                    unsigned int glyphmod[NUM_GLYPHMOD]
               where:
                    glyphmod[GM_TTYCHAR]  is the text characters associated
                                          with the original NetHack display.

                    glyphmod[GM_FLAGS]    are the special flags that denote
                                          additional information that window
                                          ports can use.

                    glyphmod[GM_COLOR] is the text character
                                       color associated with the original
                                       NetHack display.

Support for including the glyphmod info in the display glyph buffer
alongside the glyph itself was added and is the default operation.
That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time.
With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod()
immediately prior to every print_glyph() call.
2020-12-26 11:23:23 -05:00
k21971
3d7a3fcc72 Fix: genetic engineers dropping Schroedinger's cat box.
Only quantum mechanics are supposed to have a chance of death-dropping the
Schroedinger's cat box.

Slash'Em already had this but it was missed when Genetic engineers were ported
over.
2020-12-07 22:42:24 +01:00
PatR
f43421ae3c create monster creating concealed mimic revisisted
commit 03d7d64d15:
| [...] but fixing this specific case is trivial.

Not trivial enough to avoid getting the details wrong.  An old
commit log message (58137a608a,
June of 2006) claimed that this was fixed for bag of tricks but
that was for monsters in general; mimics could still be wrong.
2020-11-22 00:32:11 -08:00
PatR
03d7d64d15 create monster creating concealed mimic
From an old bug report (sent directly to devteam, June of 2017):
wand or scroll of create monster becomes discovered if it makes
a mimic that is concealed as an object or as furniture within
the hero's view.  Fixing this in the general case [when does
seeing a mimic as something other than a monster mean that the
mimic is being seen?] is a massive can of worms, but fixing this
specific case is trivial.
2020-11-20 18:56:35 -08:00
Pasi Kallinen
6ec55a3624 Rework stairs structure
Use a linked list to store stair and ladder information, instead
of having fixed up/down stairs/ladders and a single "special" (branch)
stair.

Breaks saves and bones.

Adds information to migrating objects and monsters for the dungeon
and level where they are migrating from.
2020-11-13 20:27:17 +02:00
nhmall
ac9ba38449 file header bump from "NetHack 3.6" to "NetHack 3.7" 2020-08-03 22:07:36 -04:00
nhmall
6357505948 makemon and mkobj follow-up initialization bit 2020-07-31 10:00:14 -04:00
nhmall
8b2750ab60 lower the code upkeep for mextra and oextra pointer additions 2020-07-31 09:42:17 -04:00