Files
rgoue/game/types.go
sneak 7fa2048402 go: port foundation — types, RNG, tables, daemon scheduler
Module sneak.berlin/go/rogue, package game:
- types.go: all rogue.h constants, flag types, Coord/Stats/Room/ObjInfo
- creature.go/object.go: the THING union split into Creature (Player/
  Monster) and Object; slices replace the C linked lists
- level.go: Place map with the C column-major layout and chat/flat/moat/
  winat access methods
- tables.go: extern.c + init.c data (bestiary, item tables, name pools)
- rng.go: the exact C LCG (seed*11109+13849), golden-tested against a
  compiled C reference for seed compatibility
- init.go: per-game item appearance randomization (init.c)
- daemon.go/daemons.go: scheduler with DaemonID replacing function
  pointers (ids match the C save format's mapping)
- game.go: RogueGame holds all former globals; NewGame constructor
2026-07-06 18:46:22 +02:00

375 lines
8.7 KiB
Go

// Package game is a Go port of Rogue 5.4.4 ("Exploring the Dungeons of
// Doom", Michael Toy, Ken Arnold and Glenn Wichman, 1980-1999).
//
// The port is function-by-function faithful to the C sources kept in the
// repository root; ARCHITECTURE.md documents both the original program and
// the design of this port. All formerly-global state lives on the RogueGame
// type.
package game
// Maximum number of different things (rogue.h)
const (
MaxRooms = 9
MaxThings = 9
MaxObj = 9
MaxPack = 23
MaxTraps = 10
AmuletLevel = 26
NumThings = 7 // number of types of things
MaxPass = 13 // upper limit on number of passages
NumLines = 24
NumCols = 80
StatLine = NumLines - 1
BoreLevel = 50
MaxStr = 1024 // maximum length of strings
MaxLines = 32 // maximum number of screen lines used
MaxCols = 80 // maximum number of screen columns used
)
// Return values for get functions (rogue.h)
const (
Norm = 0 // normal exit
Quit = 1 // quit option setting
Minus = 2 // back up one option
)
// Inventory types (rogue.h)
const (
InvOver = 0
InvSlow = 1
InvClear = 2
)
// Things that appear on the screens (rogue.h). These byte values serve both
// as map characters and as Object.Type discriminators, exactly as in C.
const (
Passage byte = '#'
Door byte = '+'
Floor byte = '.'
PlayerCh byte = '@'
Trap byte = '^'
Stairs byte = '%'
Gold byte = '*'
Potion byte = '!'
Scroll byte = '?'
Magic byte = '$'
Food byte = ':'
Weapon byte = ')'
Armor byte = ']'
Amulet byte = ','
Ring byte = '='
Stick byte = '/'
)
// Pseudo-types for item-selection prompts (rogue.h)
const (
Callable = -1
RorS = -2
)
// Various constants (rogue.h)
const (
HealTime = 30
HuhDuration = 20
SeeDuration = 850
HungerTime = 1300
MoreTime = 150
StomachSize = 2000
StarveTime = 850
Escape = 27
Left = 0
Right = 1
BoltLength = 6
LampDist = 3
MaxDaemons = 20
MaxInp = 50 // options.c: max string entered by the user
MaxNameLen = 40 // init.c MAXNAME: max chars in a generated scroll name
)
// Save against things (rogue.h)
const (
VsPoison = 0
VsParalyzation = 0
VsDeath = 0
VsBreath = 2
VsMagic = 3
)
// Flags for rooms (rogue.h)
type RoomFlags int16
const (
IsDark RoomFlags = 1 << iota // room is dark
IsGone // room is gone (a corridor)
IsMaze // room is a maze
)
func (f RoomFlags) Has(b RoomFlags) bool { return f&b != 0 }
func (f *RoomFlags) Set(b RoomFlags) { *f |= b }
func (f *RoomFlags) Clear(b RoomFlags) { *f &^= b }
// Flags for objects (rogue.h)
type ObjFlags int32
const (
IsCursed ObjFlags = 1 << iota // object is cursed
IsKnow // player knows details about the object
IsMissl // object is a missile type
IsMany // object comes in groups
ObjIsFound // object has been seen (ISFOUND shares the bit with creatures)
IsProt // armor is permanently protected
)
func (f ObjFlags) Has(b ObjFlags) bool { return f&b != 0 }
func (f *ObjFlags) Set(b ObjFlags) { *f |= b }
func (f *ObjFlags) Clear(b ObjFlags) { *f &^= b }
// Flags for creatures (rogue.h). The C bit collisions are deliberate and
// preserved: one name of each pair applies to monsters, the other to the
// hero, and they never coexist on one creature.
type CreatureFlags int32
const (
CanHuh CreatureFlags = 0o000001 // creature can confuse
CanSee CreatureFlags = 0o000002 // creature can see invisible creatures
IsBlind CreatureFlags = 0o000004 // creature is blind
IsCanc CreatureFlags = 0o000010 // creature has special qualities cancelled
IsLevit CreatureFlags = 0o000010 // hero is levitating
IsFound CreatureFlags = 0o000020 // creature has been seen
IsGreed CreatureFlags = 0o000040 // creature runs to protect gold
IsHaste CreatureFlags = 0o000100 // creature has been hastened
IsTarget CreatureFlags = 0o000200 // creature is the target of an 'f' command
IsHeld CreatureFlags = 0o000400 // creature has been held
IsHuh CreatureFlags = 0o001000 // creature is confused
IsInvis CreatureFlags = 0o002000 // creature is invisible
IsMean CreatureFlags = 0o004000 // creature can wake when player enters room
IsHalu CreatureFlags = 0o004000 // hero is on acid trip
IsRegen CreatureFlags = 0o010000 // creature can regenerate
IsRun CreatureFlags = 0o020000 // creature is running at the player
SeeMonst CreatureFlags = 0o040000 // hero can detect unseen monsters
IsFly CreatureFlags = 0o040000 // creature can fly
IsSlow CreatureFlags = 0o100000 // creature has been slowed
)
func (f CreatureFlags) Has(b CreatureFlags) bool { return f&b != 0 }
func (f *CreatureFlags) Set(b CreatureFlags) { *f |= b }
func (f *CreatureFlags) Clear(b CreatureFlags) { *f &^= b }
// Flags for the level map (rogue.h)
type PlaceFlags uint8
const (
FPass PlaceFlags = 0x80 // is a passageway
FSeen PlaceFlags = 0x40 // have seen this spot before
FDropped PlaceFlags = 0x20 // object was dropped here
FLocked PlaceFlags = 0x20 // door is locked
FReal PlaceFlags = 0x10 // what you see is what you get
FPNum PlaceFlags = 0x0f // passage number mask
FTMask PlaceFlags = 0x07 // trap number mask
)
func (f PlaceFlags) Has(b PlaceFlags) bool { return f&b != 0 }
func (f *PlaceFlags) Set(b PlaceFlags) { *f |= b }
func (f *PlaceFlags) Clear(b PlaceFlags) { *f &^= b }
// Trap types (rogue.h)
const (
TDoor = 0
TArrow = 1
TSleep = 2
TBear = 3
TTelep = 4
TDart = 5
TRust = 6
TMyst = 7
NTraps = 8
)
// Potion types (rogue.h)
const (
PConfuse = iota
PLSD
PPoison
PStrength
PSeeInvis
PHealing
PMFind
PTFind
PRaise
PXHeal
PHaste
PRestore
PBlind
PLevit
MaxPotions
)
// Scroll types (rogue.h)
const (
SConfuse = iota
SMap
SHold
SSleep
SArmor
SIDPotion
SIDScroll
SIDWeapon
SIDArmor
SIDRorS
SScare
SFDet
STelep
SEnch
SCreate
SRemove
SAggr
SProtect
MaxScrolls
)
// Weapon types (rogue.h)
const (
Mace = iota
Sword
Bow
Arrow
Dagger
TwoSword
Dart
Shiraken
Spear
Flame // fake entry for dragon breath (ick)
MaxWeapons = Flame
)
// Armor types (rogue.h)
const (
Leather = iota
RingMail
StuddedLeather
ScaleMail
ChainMail
SplintMail
BandedMail
PlateMail
MaxArmors
)
// Ring types (rogue.h)
const (
RProtect = iota
RAddStr
RSustStr
RSearch
RSeeInvis
RNop
RAggr
RAddHit
RAddDam
RRegen
RDigest
RTeleport
RStealth
RSustArm
MaxRings
)
// Rod/Wand/Staff types (rogue.h)
const (
WsLight = iota
WsInvis
WsElect
WsFire
WsCold
WsPolymorph
WsMissile
WsHasteM
WsSlowM
WsDrain
WsNop
WsTelAway
WsTelTo
WsCancel
MaxSticks
)
// Coord is a position on the level (rogue.h coord). A value type: the C
// ce(a,b) macro is plain == here.
type Coord struct {
X, Y int
}
// Stats describes a fighting being (rogue.h struct stats).
type Stats struct {
Str int // strength (s_str; 3..31)
Exp int // experience
Lvl int // level of mastery
Arm int // armor class
HP int // hit points (s_hpt)
Dmg string // damage dice, e.g. "1x4/1x2"
MaxHP int
}
// Room describes a room or passage network (rogue.h struct room).
type Room struct {
Pos Coord // upper left corner
Max Coord // size of room
Gold Coord // where the gold is
GoldVal int // how much the gold is worth
Flags RoomFlags
Exits []Coord // where the exits are (r_exit[12]/r_nexits)
}
// MonsterKind is a bestiary entry (rogue.h struct monster).
type MonsterKind struct {
Name string // what to call the monster
Carry int // probability of carrying something
Flags CreatureFlags
Stats Stats // initial stats
}
// ObjInfo describes one object class: its real name, generation
// probability, score worth, and per-game identification state
// (rogue.h struct obj_info).
type ObjInfo struct {
Name string
Prob int
Worth int
Guess string
Know bool
}
// Stone is a ring stone with its worth (rogue.h STONE).
type Stone struct {
Name string
Value int
}
// CTRL maps a letter to its control character, as the C CTRL() macro.
func CTRL(c byte) byte { return c & 0o37 }
// IsMult reports whether an object type stacks in the pack (rogue.h ISMULT).
func IsMult(typ byte) bool { return typ == Potion || typ == Scroll || typ == Food }
// distance returns the squared distance between two points (chase.c dist).
func distance(y1, x1, y2, x2 int) int {
dx := x2 - x1
dy := y2 - y1
return dx*dx + dy*dy
}
// distCp is dist_cp from chase.c.
func distCp(c1, c2 Coord) int { return distance(c1.Y, c1.X, c2.Y, c2.X) }
// sign is misc.c sign(): -1, 0 or 1.
func sign(nm int) int {
switch {
case nm < 0:
return -1
case nm > 0:
return 1
}
return 0
}