Commit Graph

91 Commits

Author SHA1 Message Date
PatR
993c3b303f some reformatting (4 of 4) 2024-09-05 16:49:42 -07:00
PatR
96787441e9 pauper tweaks
For 'pauper', most roles start without any skills.  However, strong
fighter types were starting with basic bare-handed combat/marital arts,
giving them a big advantage.  Knights were starting with basic riding,
which is probably useless now that they have to acquire a saddle to
use it (see below).  Take those initial skills away, producing an even
playing field.

Non-paupers get their initial skills without needing to spend any skill
credits (aka slots) on those.  Give paupers 2 starting credits that
they'll be able to use once they acquire suitable weapons or spells
and train them up, so that once they're reasonably developed they won't
lag in skills compared to non-paupers.

Pauper knights were still starting with a saddled pony.  Suppress the
saddle when the knight is a pauper.

Wizards start knowing a lot of spellbooks.  Pauper wizards shouldn't.

Give most roles advance knowledge of one low level spell or other item.
It won't benefit them unless/until they find the corresponding item.
2024-09-01 15:11:28 -07:00
PatR
0ce2439e82 github issue #1275: curses init vs pauper
Reported by ars3niy, the curses interface could behave strangely on
the first turn if the 'pauper' option/conduct was specified.

There isn't any definitive flag indicating whether or not the game
has started.  Since 'moves' has traditionally been initialized to 1
rather than to 0, there were several instances of
|  if (moves <= 1 && invent != NULL)
being used to determine the starting state on the assumption that
once hero has inventory, the game has begun.  Introduction of the
'pauper' option made the test for non-Null invent become unreliable.
For paupers, the program would behave as if the game hadn't started
yet until the player finally made a time-consuming move.

This changes compile-time initialization of 'moves' from 1 to 0,
then sets it to 1 when initial inventory would be bestowed (even
when 'pauper' inhibits that).  That's probably not the best place
for it, but testing for 'moves==0' now should produce an identical
effect as 'moves<=1 && invent!=NULL' used to accomplish.

It would have been much simpler just to give paupers 1 gold piece,
or perhaps one rock, in place of usual starting gear so that their
initial inventory wouldn't be empty, but the moves+invent way of
checking for start-of-play has always bothered me.

Should 'pauper' be preventing 'nethack -X' from giving its starting
wand of wishing?  Conducts and explore mode don't really overlap so
maybe it doesn't matter.

Fixes #1275
2024-08-31 14:08:04 -07:00
Pasi Kallinen
e645c0b4bb Allow starting game as pauper, without any inventory
And also without spells, skills, or preidentified items.
This also implies nudist.

Breaks saves and bones.
2024-08-29 20:51:13 +03:00
nhmall
6c0ae092c6 distinguish global variables that get written to savefile
The g? structs had a mix of variables that were written to
the savefile, and those that were not.

For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.

This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.

Details:

    gb.bases            -> svb.bases
    gb.bbubbles         -> svb.bbubbles
    gb.branches         -> svb.branches
    gc.context          -> svc.context
    gd.disco            -> svd.disco
    gd.dndest           -> svd.dndest
    gd.doors            -> svd.doors
    gd.doors_alloc      -> svd.doors_alloc
    gd.dungeon_topology -> svd.dungeon_topology
    gd.dungeons         -> svd.dungeons
    ge.exclusion_zones  -> sve.exclusion_zones
    gh.hackpid          -> svh.hackpid
    gi.inv_pos          -> svi.inv_pos
    gk.killer           -> svk.killer
    gl.lastseentyp      -> svl.lastseentyp
    gl.level            -> svl.level
    gl.level_info       -> svl.level_info
    gm.mapseenchn       -> svm.mapseenchn
    gm.moves            -> svm.moves
    gm.mvitals          -> svm.mvitals
    gn.n_dgns           -> svn.n_dgns
    gn.n_regions        -> svn.n_regions
    gn.nroom            -> svn.nroom
    go.oracle_cnt       -> svo.oracle_cnt
    gp.pl_character     -> svp.pl_character
    gp.pl_fruit         -> svp.pl_fruit
    gp.plname           -> svp.plname
    gp.program_state    -> svp.program_state
    gq.quest_status     -> svq.quest_status
    gr.rooms            -> svr.rooms
    gs.sp_levchn        -> svs.sp_levchn
    gs.spl_book         -> svs.spl_book
    gt.timer_id         -> svt.timer_id
    gt.tune             -> svt.tune
    gu.updest           -> svu.updest
    gx.xmax             -> svx.xmax
    gx.xmin             -> svx.xmin
    gy.ymax             -> svy.ymax
    gy.ymin             -> svy.ymin

Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
          gf.ftrap, gl.light_base, gt.timer_base
2024-07-13 14:57:50 -04:00
Pasi Kallinen
28ed8e7962 Unblind telepathy range
Unblind telepathy range depends on the number of telepathy granting
items worn.

Breaks saves.
2024-04-04 23:22:28 +03:00
PatR
19e985fa26 fix #K4123 - pair of u_init.c macros not used
W_MULTSTART and W_MULTEND were last used in nethack 2.3.
Time to finally Get rid of them.
2024-03-22 20:43:15 -07:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
nhmall
1f255dcd03 comment bit 2024-02-06 15:03:59 -05:00
nhmall
a62ded6d28 ini_inv_mkobj_filter() bit
The try count of 1000 is never going to be reached.

The obj result, if it were ever to be reached, would have
been unfiltered and potentially incorrect.

There is no harm in having the result, in that theoretical edge
case, not be one of the obj values that was intended to be
filtered out.

No practical change results from this, and pancake was used
because it is innocuous.
2024-02-06 14:33:16 -05:00
nhmall
8f35e33a2e follow-up nonnull in u_init.c
u_init.c had had assessments for nonnull arguments on
its local functions carried out already.

A couple of new static functions added earlier today immediately
dereference their args, so declare those as nonnull.

This also gives a more self-describing name to one arg.
2024-01-21 09:48:36 -05:00
Pasi Kallinen
f889478262 Split ini_inv obj wear/wield/learn 2024-01-21 14:34:21 +02:00
Pasi Kallinen
2f5851e394 Split ini_inv object field adjustments 2024-01-21 14:16:06 +02:00
Pasi Kallinen
f1bf2418ff Split ini_inv obj race substitutions 2024-01-21 14:02:09 +02:00
Pasi Kallinen
d2e7bfa6cd Split out ini_inv filtered mkobj 2024-01-21 13:46:20 +02:00
Pasi Kallinen
8615401278 Split out initial STR and CON boost if inventory too heavy 2024-01-21 12:51:46 +02:00
Pasi Kallinen
311e82a9cc Split init attr minor variation 2024-01-21 12:45:13 +02:00
Pasi Kallinen
1d4cdf09f6 Split u_init race specific stuff 2024-01-21 12:38:06 +02:00
Pasi Kallinen
2e56598779 Split u_init role specific stuff 2024-01-21 12:34:43 +02:00
Pasi Kallinen
8ee7b11ed6 Use TRUE or FALSE for booleans 2024-01-05 17:00:04 +02:00
nhmall
caf436934e NONNULLxxx for several files
src/date.c
src/mdlib.c
src/timeout.c
src/u_init.c
src/vault.c
src/version.c
src/windows.c
2023-12-27 20:11:59 -05:00
Pasi Kallinen
5dc94f3d83 Macro for picking random entry from array 2023-12-05 10:06:27 +02:00
nhmall
e4e8eea4e8 track the handedness of the hero
Don't make either LEFT_HANDED or RIGHT_HANDED be an advantage
or a disadvantage.

use suggested macros
2023-12-02 11:23:43 -05:00
Alex Smith
9d910773d0 Make starting inventory magic markers more likely, but fewer charges
In particular, Wizards now get a magic marker guaranteed (but with
fewer charges than magic markers naturally generate with). This is
intended to improve the game in two ways: it reduces the incentive
for startscumming, and it gives Wizards a method to gain an
additional low-level spell early if they wish (but the marker does
not have enough charges to get higher-level spells quickly using
this method).
2023-12-02 03:59:29 +00:00
PatR
1c94bdac89 blindness overhaul
I was working on this at the time 3.6.0 was released and set it aside
until later.  Later has finally arrived.  Redo the Blind, Blinded,
Blindfolded,&c macros to make more complete use of intrinsic property
handling.  Blinded was being treated as a number which could be added
to or subtracted from; now that has to be done via TIMEOUT mask
because it has FROMOUTSIDE (OPTIONS:blind) and FROMFORM (poly'd into
!haseyes() form) bits included.  Object definitions for blindfold and
towel now specify the BLINDED property; overriding blindness via the
Eyes of the Overworld is accomplished via props[BLINDED].blocked.

Code generated for the scores of Blind and !Blind tests throughout
the program should be smaller.

One bug that has been fixed is that putting on the Eyes of the
Overworld cured permanent blindness (from OPTIONS:blind).  The
u.uroleplay.blind flag was cleared and stayed so after taking them
off.  Putting the Eyes on still breaks blind-from-birth conduct but
now blindness will resume when they are removed.

This was untested at the time it was set aside and is only lightly
tested now.  A large number of the changes here are just to switch
from Blinded to BlindedTimeout for current timed value and to call
set_itimeout() for setting a new value.
2023-04-27 14:53:28 -07:00
PatR
8952ea9bb5 add Japanese item names to discoveries list
When playing as a Samurai, add things like "osaku" to the discoveries
list even though they don't have separate descriptions to be used
when not yet discovered.  Non-magic ones are pre-discovered and
players can now use the '\' command to figure out what things like
"tanko" mean without resorting to '/?'.

"wooden harp" has been getting changed to "koto (harp)"; make that be
| koto [wooden harp] (koto)
"magic harp" has been staying as "magic harp (harp)"; add it to the
list of Japanese item names.  Since it's magic it isn't pre-discovered.
Once discovered it becomes
| magic koto [magic harp] (koto)

Those two needed special case handling, none of the other items did
aside from forcing them to be discoverable when lacking descriptions.
The discoveries list now has things like
| wakizashi [short sword]
| naginata [glaive] (single-edged polearm)
| gunyoki [food ration]
if--and only if--the hero is a Samurai.
2023-01-18 22:00:57 -08: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
copperwater
7d27dca47f Fix a couple latent bugs with initial rings/other charged items
These bugs are currently latent only because no role's starting
inventory happens to satisfy the conditions under which it would show
up. This commit contains the xNetHack fixes for them.

Bug 1: if a role received a specific charged ring (versus a random
ring), it would be possible for that ring's charge to be <= 0, since the
code currently only caught this case for random rings. Move that clause
outside the if (UNDEF_TYP) clause.

Bug 2: non-ring oc_charged items of UNDEF_TYP that randomly rolled a
starting charge/enchantment <= 0 would always be enchanted, sometimes
very highly, because their enchantment was getting set to rne(3) by
hitting this case, which is only intended for rings as a comment
indicates. In particular, Archeologists' starting pick-axe would hit
this case after moving it out of the UNDEF_TYP block, but it would also
apply to any role receiving a random tool or weapon-tool at the start
of the game.
2022-08-15 09:00:18 +03:00
Kufat
296a3ac246 Merge scimitar skill into saber skill
Deleted scimitar skill, changed scimitar to use saber skill.
Adjusted Barbarian's max saber mastery basic->skilled for consistency
with former scimitar skill.
2022-07-23 23:11:13 -07:00
Pasi Kallinen
c09ae332c8 Valkyries start with a spear instead of a long sword
Long swords are overused, and Knights already start with a long sword.
No other roles start with a spear. Lawful Valks shouldn't have an easy
way to get Excalibur.

There's also historical precedence for valkyries with spears, see eg.
Wagner's Ring Cycle.

This makes Valks early game damage slightly lower, although dwarven spear
does the same damage to small monsters as long sword, and there should be
plenty of chances to get one from the mines. Spears can also be thrown.

This change has been done in several variants, eg. xNetHack and Fourk.
2022-07-12 23:05:46 +03:00
Matthew Everett
f2bef98dac Move check for starting L1 spellbook to include non-random spellbooks 2022-06-11 15:29:37 -07:00
nhmall
a8f0e91ddf replace leading tabs in several files 2022-05-30 12:09:35 -04:00
Pasi Kallinen
b172957831 Use macro for spell pw cost per spell level 2022-02-28 22:21:37 +02:00
Pasi Kallinen
33556788c3 Start with a level 1 spell and enough power
Ensure the first spell - if any - given to the hero in initial
inventory is level 1 - otherwise you can end up with a situation
where the hero knows level 3 spells, but won't have enough power
to cast them.

If the hero starts out with a spell, ensure enough power (5)
to cast that level 1 spell.
2022-02-22 12:26:06 +02:00
Pasi Kallinen
d452242af4 Adjust sleep spell, and monk starting spell
Tone down sleep level to 3 (hitting a monster does tend to wake
it up), and replace the random monk starting sleep spell with
confuse monster, which fits nicely with monk's bare-handed
fighting style.
2022-02-22 09:13:32 +02:00
Michael Meyer
f5e3bc3d96 Remove gendered mons indices from roles, races
There are no longer distinct gendered versions of monsters, so femalenum
is unused (i.e. set to NON_PM) for all roles and races. Take a pass at
removing all uses of/references to femalenum, and rename 'malenum' to
'mnum' since it no longer has any particular association with
gender or sex.
2022-01-14 13:51:26 -08:00
PatR
936be565d9 tracking peak maximum HP and energy
Keep track of the highest value that u.uhpmax and u.uenmax have
attained, in new u.uhppeak and u.uenpeak.  They aren't used for
anything yet.  u.mhmax (max HP while polymorphed) isn't interesting
enough to track.

Not save and bones compatible so increments EDITLEVEL.
2021-12-04 05:19:45 -08:00
PatR
bc856e9a55 tweaks to role-specific prediscovered objects
Characters who start out knowing non-magic armor should not know
cornuthaum and dunce cap.  (Which suggests that those probably
ought to be classified as magic.)

Take away knowledge of polearms from barbarians and valkyries.

Add knowledge of all bows/crossbows, arrows/bolts, and spears to
rangers.

Add knowledge of all daggers to rogues.  (Very minor; non-elves
recognize elven daggers and non-orcs recognize orcish daggers.)
2021-05-15 19:13:29 -07:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -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
PatR
3e9d8f9aa5 'showscore' vs containers
When SCORE_ON_BOTL is enabled, you could tell how much gold is
inside a container with unknown contents by having 'showsore' On
and watching how much the score changed on the status line when
picking the container up.
2020-11-21 17:37:01 -08:00
Pasi Kallinen
d6384f4061 Use enums instead of magic values 2020-11-15 19:32:21 +02:00
nhmall
ac9ba38449 file header bump from "NetHack 3.6" to "NetHack 3.7" 2020-08-03 22:07:36 -04:00
PatR
8f73f926b1 groundwork: u.twoweap manipulation
Toggle u.twoweap on or off in just one place.
2020-04-03 11:42:17 -07:00
Pasi Kallinen
5f9714bf92 Remove workarounds for ancient compilers 2020-04-03 08:21:08 +03:00
PatR
caaf1b375a randonly occurring Discworld novels
Give 'novel' a 1 in 1000 chance of being created in place of each
random spellbook (except for hero's initial inventory and NPC
priests' monster inventory and divine reward for prayer--those all
force regular spellbooks; statue contents aren't among the
exceptions--those books can now be novels).  Shop inventory (where
first book or scroll shop created is guaranteed one novel) hasn't
been touched.  If there is any other special spellbook handling
somewhere, I've overlooked it.
2020-01-12 11:00:38 -08:00
Pasi Kallinen
f83dede8e5 Fixes for degenerate RNG
Assume a degenerate RNG that always returns the same number.
With these fixes, the game starts and is almost playable.
There are still some places that will go into infinite loop, eg.
the mines level generation.
2020-01-06 11:48:19 +02:00
nhmall
a9c946a05f Merge branch 'NetHack-3.6' 2019-12-01 19:30:09 -05:00
nhmall
d2d40289e6 update and/or clarify some version references 2019-12-01 19:07:28 -05:00
nhmall
0d34f43830 remove STATIC_DCL, STATIC_OVL, STATIC_VAR, STATIC_PTR from core 2019-07-14 17:24:58 -04:00