mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2025-05-05 14:55:10 +01:00
Fix altar display in mapseen
Previously, #overview would show the altar's god as being to your god if it's of your alignment (regardless of the altar's actual god), and doesn't show anything about the altar's god/alignment otherwise. This commit makes it always show the altar's correct god if all altars on the level are to the same god. mapseen-related stuff is moved from dungeon.h to mapseen.h, to avoid a circular makedefs -> dungeon.h -> gnames.h -> makedefs dependency. gnames.h needs to be included for MAX_GOD.
This commit is contained in:
parent
f71eded468
commit
36727f4dac
4 changed files with 150 additions and 89 deletions
|
@ -317,85 +317,4 @@ struct linfo {
|
|||
|
||||
};
|
||||
|
||||
/* types and structures for dungeon map recording
|
||||
*
|
||||
* It is designed to eliminate the need for an external notes file for some of
|
||||
* the more mundane dungeon elements. "Where was the last altar I passed?" etc...
|
||||
* Presumably the character can remember this sort of thing even if, months
|
||||
* later in real time picking up an old save game, I can't.
|
||||
*
|
||||
* To be consistent, one can assume that this map is in the player's mind and
|
||||
* has no physical correspondence (eliminating illiteracy/blind/hands/hands free
|
||||
* concerns.) Therefore, this map is not exaustive nor detailed ("some fountains").
|
||||
* This makes it also subject to player conditions (amnesia).
|
||||
*/
|
||||
|
||||
/* Because clearly Nethack needs more ways to specify alignment */
|
||||
#define Align2msa(x) ((x) == A_LAWFUL ? MSA_LAWFUL : \
|
||||
(x) == A_NEUTRAL ? MSA_NEUTRAL : \
|
||||
(x) == A_CHAOTIC ? MSA_CHAOTIC : \
|
||||
(x) == A_NONE ? MSA_UNALI : \
|
||||
(x) == A_VOID ? MSA_VOID : \
|
||||
MSA_MULTI)
|
||||
#define Msa2align(x) ((x) == MSA_LAWFUL ? A_LAWFUL : \
|
||||
(x) == MSA_NEUTRAL ? A_NEUTRAL : \
|
||||
(x) == MSA_CHAOTIC ? A_CHAOTIC : \
|
||||
(x) == MSA_UNALI ? A_NONE : \
|
||||
(x) == MSA_VOID ? A_VOID : \
|
||||
A_NONE) /* A_NONE is technically bad and overlaps with MSA_UNALI */
|
||||
|
||||
#define MSA_MULTI 0 /* multiple alignments */
|
||||
#define MSA_LAWFUL 1
|
||||
#define MSA_NEUTRAL 2
|
||||
#define MSA_CHAOTIC 3
|
||||
#define MSA_UNALI 4
|
||||
#define MSA_VOID 5
|
||||
|
||||
typedef struct mapseen_feat {
|
||||
/* feature knowledge that must be calculated from levl array */
|
||||
Bitfield(nfount, 2);
|
||||
Bitfield(nforge, 2);
|
||||
Bitfield(nsink, 2);
|
||||
Bitfield(naltar, 2);
|
||||
Bitfield(msalign, 3); /* corresponds to MSA_* above */
|
||||
Bitfield(ngrave, 2);
|
||||
Bitfield(nthrone, 2);
|
||||
Bitfield(ntree, 2);
|
||||
/* water, lava, ice are too verbose so commented out for now */
|
||||
/*
|
||||
Bitfield(water, 1);
|
||||
Bitfield(lava, 1);
|
||||
Bitfield(ice, 1);
|
||||
*/
|
||||
|
||||
/* calculated from rooms array */
|
||||
Bitfield(nshop, 2);
|
||||
Bitfield(nmorgue, 2);
|
||||
Bitfield(ntemple, 2);
|
||||
Bitfield(shoptype, 5);
|
||||
|
||||
Bitfield(forgot, 1); /* player has forgotten about this level? */
|
||||
} mapseen_feat;
|
||||
|
||||
/* for mapseen->rooms */
|
||||
#define MSR_SEEN 1
|
||||
|
||||
/* what the player knows about a single dungeon level */
|
||||
/* initialized in mklev() */
|
||||
typedef struct mapseen {
|
||||
struct mapseen *next; /* next map in the chain */
|
||||
branch *br; /* knows about branch via taking it in goto_level */
|
||||
d_level lev; /* corresponding dungeon level */
|
||||
|
||||
mapseen_feat feat;
|
||||
|
||||
/* custom naming */
|
||||
char *custom;
|
||||
unsigned custom_lth;
|
||||
|
||||
/* maybe this should just be in struct mkroom? */
|
||||
schar rooms[(MAXNROFROOMS+1)*2];
|
||||
} mapseen;
|
||||
|
||||
|
||||
#endif /* DUNGEON_H */
|
||||
|
|
75
include/mapseen.h
Normal file
75
include/mapseen.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* SPDX-License-Identifier: NGPL */
|
||||
|
||||
#ifndef MAPSEEN_H
|
||||
#define MAPSEEN_H
|
||||
|
||||
#include "gnames.h"
|
||||
|
||||
/*
|
||||
* This has to be in its own header to avoid a circular makedefs ->
|
||||
* dungeon.h -> gnames.h -> makedefs dependency. gnames.h needs to be
|
||||
* included for MAX_GOD.
|
||||
*/
|
||||
|
||||
/* types and structures for dungeon map recording
|
||||
*
|
||||
* It is designed to eliminate the need for an external notes file for some of
|
||||
* the more mundane dungeon elements. "Where was the last altar I passed?" etc...
|
||||
* Presumably the character can remember this sort of thing even if, months
|
||||
* later in real time picking up an old save game, I can't.
|
||||
*
|
||||
* To be consistent, one can assume that this map is in the player's mind and
|
||||
* has no physical correspondence (eliminating illiteracy/blind/hands/hands free
|
||||
* concerns.) Therefore, this map is not exaustive nor detailed ("some fountains").
|
||||
* This makes it also subject to player conditions (amnesia).
|
||||
*/
|
||||
|
||||
typedef struct mapseen_feat {
|
||||
/* feature knowledge that must be calculated from levl array */
|
||||
Bitfield(nfount, 2);
|
||||
Bitfield(nforge, 2);
|
||||
Bitfield(nsink, 2);
|
||||
Bitfield(naltar, 2);
|
||||
Bitfield(ngrave, 2);
|
||||
Bitfield(nthrone, 2);
|
||||
Bitfield(ntree, 2);
|
||||
/* water, lava, ice are too verbose so commented out for now */
|
||||
/*
|
||||
Bitfield(water, 1);
|
||||
Bitfield(lava, 1);
|
||||
Bitfield(ice, 1);
|
||||
*/
|
||||
|
||||
/* calculated from rooms array */
|
||||
Bitfield(nshop, 2);
|
||||
Bitfield(nmorgue, 2);
|
||||
Bitfield(ntemple, 2);
|
||||
Bitfield(shoptype, 5);
|
||||
|
||||
Bitfield(forgot, 1); /* player has forgotten about this level? */
|
||||
|
||||
#define MSGODS_ARRAY_SIZE (MAX_GOD/8+1)
|
||||
unsigned int msgods[MSGODS_ARRAY_SIZE];
|
||||
} mapseen_feat;
|
||||
|
||||
/* for mapseen->rooms */
|
||||
#define MSR_SEEN 1
|
||||
|
||||
/* what the player knows about a single dungeon level */
|
||||
/* initialized in mklev() */
|
||||
typedef struct mapseen {
|
||||
struct mapseen *next; /* next map in the chain */
|
||||
branch *br; /* knows about branch via taking it in goto_level */
|
||||
d_level lev; /* corresponding dungeon level */
|
||||
|
||||
mapseen_feat feat;
|
||||
|
||||
/* custom naming */
|
||||
char *custom;
|
||||
unsigned custom_lth;
|
||||
|
||||
/* maybe this should just be in struct mkroom? */
|
||||
schar rooms[(MAXNROFROOMS+1)*2];
|
||||
} mapseen;
|
||||
|
||||
#endif /* MAPSEEN_H */
|
|
@ -101,4 +101,41 @@ void foo VA_DECL(int, arg) --macro expansion has a hidden opening brace
|
|||
# endif /* __GNUC__ */
|
||||
#endif /* __has_include(<stdckdint.h>) */
|
||||
|
||||
/*
|
||||
* If we don't have C23 <stdbit.h>, fall back to GCC
|
||||
* __builtin_popcount and C11 _Generic. If we don't have that either,
|
||||
* fall back to Brian Kernighan's algorithm and C11 _Generic.
|
||||
*/
|
||||
#if __has_include(<stdbit.h>)
|
||||
# include <stdbit.h>
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define stdc_count_ones_uc(n) (unsigned char)__builtin_popcount((unsigned char)(n))
|
||||
# define stdc_count_ones_us(n) (unsigned short)__builtin_popcount((unsigned short)(n))
|
||||
# define stdc_count_ones_ui(n) __builtin_popcount((n))
|
||||
# define stdc_count_ones_ul(n) __builtin_popcountl((n))
|
||||
# define stdc_count_ones_ull(n) __builtin_popcountll((n))
|
||||
# else
|
||||
# define DEFINE_STDC_COUNT_ONES(suffix, type) \
|
||||
static inline type stdc_count_ones_##suffix(type n) { \
|
||||
int count = 0; \
|
||||
while (n) { n &= n-1; count++; } \
|
||||
return count; \
|
||||
}
|
||||
DEFINE_STDC_COUNT_ONES(uc, unsigned char)
|
||||
DEFINE_STDC_COUNT_ONES(us, unsigned short)
|
||||
DEFINE_STDC_COUNT_ONES(ui, unsigned int)
|
||||
DEFINE_STDC_COUNT_ONES(ul, unsigned long)
|
||||
DEFINE_STDC_COUNT_ONES(ull, unsigned long long)
|
||||
# undef DEFINE_STDC_COUNT_ONES
|
||||
# endif /* __GNUC__ */
|
||||
#define stdc_count_ones(n) \
|
||||
_Generic((n), \
|
||||
unsigned char: stdc_count_ones_uc((n)), \
|
||||
unsigned short: stdc_count_ones_us((n)), \
|
||||
unsigned int: stdc_count_ones_ui((n)), \
|
||||
unsigned long: stdc_count_ones_ul((n)), \
|
||||
unsigned long long: stdc_count_ones_ull((n)))
|
||||
#endif /* __has_include(<stdbit.h>) */
|
||||
|
||||
#endif /* TRADSTDC_H */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "dgn_file.h"
|
||||
#include "dlb.h"
|
||||
#include "display.h"
|
||||
#include "mapseen.h"
|
||||
|
||||
|
||||
//define DUNGEON_FILE "dungeon"
|
||||
|
@ -2258,6 +2259,34 @@ donamelevel(void)
|
|||
return MOVE_CANCELLED;
|
||||
}
|
||||
|
||||
boolean
|
||||
check_msgod(mapseen *mptr, int godnum)
|
||||
{
|
||||
if(godnum >= MAX_GOD || godnum < 1){
|
||||
impossible("Attempting to check god number %d in mapseen?", godnum);
|
||||
return FALSE;
|
||||
}
|
||||
return !!(mptr->feat.msgods[(godnum-1)/32] & (0x1L << ((godnum-1)%32)));
|
||||
}
|
||||
|
||||
void
|
||||
add_msgod(mapseen *mptr, int godnum)
|
||||
{
|
||||
if(godnum >= MAX_GOD || godnum < 1){
|
||||
impossible("Attempting to set god number %d in mapseen?", godnum);
|
||||
}
|
||||
mptr->feat.msgods[(godnum-1)/32] |= (0x1L << ((godnum-1)%32));
|
||||
}
|
||||
|
||||
int
|
||||
count_msgods(mapseen *mptr)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < MSGODS_ARRAY_SIZE; i++)
|
||||
count += stdc_count_ones(mptr->feat.msgods[i]);
|
||||
return count;
|
||||
}
|
||||
|
||||
/* find the particular mapseen object in the chain */
|
||||
/* may return 0 */
|
||||
static mapseen *
|
||||
|
@ -2574,11 +2603,7 @@ recalc_mapseen(void)
|
|||
mptr->feat.nsink = min(mptr->feat.nsink + 1, 3);
|
||||
break;
|
||||
case ALTAR:
|
||||
if (!mptr->feat.naltar)
|
||||
mptr->feat.msalign = Align2msa(a_align(x,y));
|
||||
else if (mptr->feat.msalign != Align2msa(a_align(x,y)))
|
||||
mptr->feat.msalign = MSA_MULTI;
|
||||
|
||||
add_msgod(mptr, god_at_altar(x,y));
|
||||
mptr->feat.naltar = min(mptr->feat.naltar + 1, 3);
|
||||
break;
|
||||
}
|
||||
|
@ -2874,9 +2899,14 @@ print_mapseen(winid win, mapseen *mptr, boolean printdun)
|
|||
ADDNTOBUF("altar", mptr->feat.naltar)
|
||||
else
|
||||
ADDNTOBUF("temple", mptr->feat.ntemple)
|
||||
/* and print out altar's god if they are all to your god */
|
||||
if ((mptr->feat.ntemple || mptr->feat.naltar) && (Msa2align(mptr->feat.msalign) == u.ualign.type))
|
||||
Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
|
||||
/* and print out altar's god if they are all to one god */
|
||||
if ((mptr->feat.ntemple || mptr->feat.naltar) && count_msgods(mptr) == 1) {
|
||||
int godnum;
|
||||
for (godnum = 1; godnum < MAX_GOD; godnum++)
|
||||
if (check_msgod(mptr, godnum))
|
||||
break;
|
||||
Sprintf(eos(buf), " to %s", godname(godnum));
|
||||
}
|
||||
|
||||
ADDNTOBUF("fountain", mptr->feat.nfount)
|
||||
ADDNTOBUF("forge", mptr->feat.nforge)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue