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
This commit is contained in:
374
game/types.go
Normal file
374
game/types.go
Normal file
@@ -0,0 +1,374 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user