Decompose command.go; command keys become a handler table (step 7)
The ordinary command keys move into gameData.commandHandlers (method expressions and small literals); dispatchKey keeps only re-dispatching prefixes (runCommand/fightCommand/repeatCommand/moveOnCommand) and the wizard fallthrough. command() splits into playTurn/turnUpkeep/ readCommand/executeCommand/countPrefix/ringTurnEffects; search gains searchSpot/searchFloor; help gains helpOne/helpAll/helpLines; call gains callTarget/callPrelude; wizardCommand splits in two plus wizardKit; uLevel and current flatten to early returns. command.go is complexity-clean. Behavior and RNG call order unchanged.
This commit is contained in:
782
game/command.go
782
game/command.go
@@ -16,6 +16,70 @@ func (g *RogueGame) command() {
|
|||||||
g.DoFuses(Before)
|
g.DoFuses(Before)
|
||||||
|
|
||||||
for ; ntimes > 0; ntimes-- {
|
for ; ntimes > 0; ntimes-- {
|
||||||
|
g.playTurn()
|
||||||
|
|
||||||
|
if !g.After {
|
||||||
|
ntimes++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.DoDaemons(After)
|
||||||
|
g.DoFuses(After)
|
||||||
|
|
||||||
|
g.ringTurnEffects(Left)
|
||||||
|
g.ringTurnEffects(Right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ringTurnEffects fires the per-turn ring powers on one hand: searching
|
||||||
|
// searches, teleportation teleports on 1 turn in 50 (the tail of
|
||||||
|
// command.c command).
|
||||||
|
func (g *RogueGame) ringTurnEffects(hand int) {
|
||||||
|
p := &g.Player
|
||||||
|
if p.IsRing(hand, RingSearching) {
|
||||||
|
g.search()
|
||||||
|
} else if p.IsRing(hand, RingTeleportation) && g.rnd(50) == 0 {
|
||||||
|
g.teleport()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// playTurn runs one full player turn: upkeep, one command, and pickup
|
||||||
|
// (the body of the command.c command loop).
|
||||||
|
func (g *RogueGame) playTurn() {
|
||||||
|
p := &g.Player
|
||||||
|
|
||||||
|
g.turnUpkeep()
|
||||||
|
|
||||||
|
var ch byte
|
||||||
|
|
||||||
|
if g.NoCommand == 0 {
|
||||||
|
ch = g.readCommand()
|
||||||
|
} else {
|
||||||
|
ch = '.'
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.NoCommand != 0 {
|
||||||
|
if g.NoCommand--; g.NoCommand == 0 {
|
||||||
|
p.Flags.Set(Awake)
|
||||||
|
g.msg("you can move again")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g.executeCommand(ch)
|
||||||
|
}
|
||||||
|
// If he ran into something to take, let him pick it up.
|
||||||
|
if g.Take != 0 {
|
||||||
|
g.pickUp(g.Take)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !g.Running {
|
||||||
|
g.DoorStop = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// turnUpkeep redraws and resets per-turn state before a command is read
|
||||||
|
// (the top of the command.c command loop).
|
||||||
|
func (g *RogueGame) turnUpkeep() {
|
||||||
|
p := &g.Player
|
||||||
|
|
||||||
g.Again = false
|
g.Again = false
|
||||||
if g.HasHit {
|
if g.HasHit {
|
||||||
g.endmsg()
|
g.endmsg()
|
||||||
@@ -47,59 +111,35 @@ func (g *RogueGame) command() {
|
|||||||
if g.Wizard {
|
if g.Wizard {
|
||||||
g.NoScore = true
|
g.NoScore = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ch byte
|
// readCommand picks the next command character: run/count repeats or
|
||||||
|
// fresh input (the read block of command.c command).
|
||||||
if g.NoCommand == 0 {
|
func (g *RogueGame) readCommand() byte {
|
||||||
switch {
|
switch {
|
||||||
case g.Running || g.ToDeath:
|
case g.Running || g.ToDeath:
|
||||||
ch = g.RunCh
|
return g.RunCh
|
||||||
case g.Count != 0:
|
case g.Count != 0:
|
||||||
ch = g.countCh
|
return g.countCh
|
||||||
default:
|
default:
|
||||||
ch = g.readchar()
|
ch := g.readchar()
|
||||||
|
|
||||||
g.MoveOn = false
|
g.MoveOn = false
|
||||||
if g.Msgs.Mpos != 0 { // erase message if its there
|
if g.Msgs.Mpos != 0 { // erase message if its there
|
||||||
g.msg("")
|
g.msg("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ch
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ch = '.'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.NoCommand != 0 {
|
// executeCommand runs one read command with the repeat-count prefix and
|
||||||
if g.NoCommand--; g.NoCommand == 0 {
|
// the repeat-history bookkeeping (the execute block of command.c
|
||||||
p.Flags.Set(Awake)
|
// command).
|
||||||
g.msg("you can move again")
|
func (g *RogueGame) executeCommand(ch byte) {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// check for prefixes
|
// check for prefixes
|
||||||
g.newCount = false
|
g.newCount = false
|
||||||
if isDigit(ch) {
|
ch = g.countPrefix(ch)
|
||||||
g.Count = 0
|
|
||||||
|
|
||||||
g.newCount = true
|
|
||||||
for isDigit(ch) {
|
|
||||||
g.Count = min(g.Count*10+int(ch-'0'), 255)
|
|
||||||
|
|
||||||
ch = g.readchar()
|
|
||||||
}
|
|
||||||
|
|
||||||
g.countCh = ch
|
|
||||||
// turn off count for commands which don't make sense
|
|
||||||
// to repeat
|
|
||||||
switch ch {
|
|
||||||
case CTRL('B'), CTRL('H'), CTRL('J'), CTRL('K'),
|
|
||||||
CTRL('L'), CTRL('N'), CTRL('U'), CTRL('Y'),
|
|
||||||
'.', 'a', 'b', 'h', 'j', 'k', 'l', 'm', 'n', 'q',
|
|
||||||
'r', 's', 't', 'u', 'y', 'z', 'B', 'C', 'H', 'I',
|
|
||||||
'J', 'K', 'L', 'N', 'U', 'Y',
|
|
||||||
CTRL('D'), CTRL('A'):
|
|
||||||
default:
|
|
||||||
g.Count = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// execute a command
|
// execute a command
|
||||||
if g.Count != 0 && !g.Running {
|
if g.Count != 0 && !g.Running {
|
||||||
g.Count--
|
g.Count--
|
||||||
@@ -121,44 +161,136 @@ func (g *RogueGame) command() {
|
|||||||
g.DoorStop = false
|
g.DoorStop = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If he ran into something to take, let him pick it up.
|
|
||||||
if g.Take != 0 {
|
// countPrefix consumes a numeric repeat-count prefix and returns the
|
||||||
g.pickUp(g.Take)
|
// command character that follows it (command.c).
|
||||||
|
func (g *RogueGame) countPrefix(ch byte) byte {
|
||||||
|
if !isDigit(ch) {
|
||||||
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
if !g.Running {
|
g.Count = 0
|
||||||
g.DoorStop = false
|
|
||||||
|
g.newCount = true
|
||||||
|
for isDigit(ch) {
|
||||||
|
g.Count = min(g.Count*10+int(ch-'0'), 255)
|
||||||
|
|
||||||
|
ch = g.readchar()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !g.After {
|
g.countCh = ch
|
||||||
ntimes++
|
// turn off count for commands which don't make sense to repeat
|
||||||
}
|
switch ch {
|
||||||
|
case CTRL('B'), CTRL('H'), CTRL('J'), CTRL('K'),
|
||||||
|
CTRL('L'), CTRL('N'), CTRL('U'), CTRL('Y'),
|
||||||
|
'.', 'a', 'b', 'h', 'j', 'k', 'l', 'm', 'n', 'q',
|
||||||
|
'r', 's', 't', 'u', 'y', 'z', 'B', 'C', 'H', 'I',
|
||||||
|
'J', 'K', 'L', 'N', 'U', 'Y',
|
||||||
|
CTRL('D'), CTRL('A'):
|
||||||
|
default:
|
||||||
|
g.Count = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
g.DoDaemons(After)
|
return ch
|
||||||
g.DoFuses(After)
|
|
||||||
|
|
||||||
if p.IsRing(Left, RingSearching) {
|
|
||||||
g.search()
|
|
||||||
} else if p.IsRing(Left, RingTeleportation) && g.rnd(50) == 0 {
|
|
||||||
g.teleport()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.IsRing(Right, RingSearching) {
|
// dispatch runs one command character, re-running dispatchKey when it
|
||||||
g.search()
|
// asks (the C `goto over` re-dispatch in command.c).
|
||||||
} else if p.IsRing(Right, RingTeleportation) && g.rnd(50) == 0 {
|
|
||||||
g.teleport()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dispatch runs one command character (the big switch in command.c; the
|
|
||||||
// loop stands in for its `goto over` re-dispatch).
|
|
||||||
func (g *RogueGame) dispatch(ch byte) {
|
func (g *RogueGame) dispatch(ch byte) {
|
||||||
|
for {
|
||||||
|
newCh, again := g.dispatchKey(ch)
|
||||||
|
if !again {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = newCh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispatchKey runs one command character (the big switch of command.c).
|
||||||
|
// A true second result asks dispatch to run once more with the returned
|
||||||
|
// key.
|
||||||
|
func (g *RogueGame) dispatchKey(ch byte) (byte, bool) {
|
||||||
|
if h, ok := g.data.commandHandlers[ch]; ok {
|
||||||
|
h(g)
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ch {
|
||||||
|
case CTRL('H'), CTRL('J'), CTRL('K'), CTRL('L'),
|
||||||
|
CTRL('Y'), CTRL('U'), CTRL('B'), CTRL('N'):
|
||||||
|
return g.runCommand(ch)
|
||||||
|
case 'F', 'f':
|
||||||
|
return g.fightCommand(ch)
|
||||||
|
case 'a':
|
||||||
|
return g.repeatCommand()
|
||||||
|
case 'm':
|
||||||
|
return g.moveOnCommand()
|
||||||
|
default:
|
||||||
|
g.After = false
|
||||||
|
if g.Wizard {
|
||||||
|
g.wizardCommand(ch)
|
||||||
|
} else {
|
||||||
|
g.illcom(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// runCommand handles the ctrl-direction run-until-adjacent prefix; the
|
||||||
|
// returned key re-dispatches as the matching run command (command.c).
|
||||||
|
func (g *RogueGame) runCommand(ch byte) (byte, bool) {
|
||||||
|
if !g.Player.On(Blind) {
|
||||||
|
g.DoorStop = true
|
||||||
|
g.Firstmove = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.Count != 0 && !g.newCount {
|
||||||
|
ch = g.direction
|
||||||
|
} else {
|
||||||
|
ch += 'A' - CTRL('A')
|
||||||
|
g.direction = ch
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch, true // the C goto over: re-dispatch as the run command
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeatCommand handles 'a': replay the last command by re-dispatching
|
||||||
|
// it (command.c).
|
||||||
|
func (g *RogueGame) repeatCommand() (byte, bool) {
|
||||||
|
if g.LastComm == 0 {
|
||||||
|
g.msg("you haven't typed a command yet")
|
||||||
|
g.After = false
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Again = true
|
||||||
|
|
||||||
|
return g.LastComm, true // the C goto over: replay the last command
|
||||||
|
}
|
||||||
|
|
||||||
|
// moveOnCommand handles 'm': move without picking up; the direction key
|
||||||
|
// re-dispatches (command.c).
|
||||||
|
func (g *RogueGame) moveOnCommand() (byte, bool) {
|
||||||
|
g.MoveOn = true
|
||||||
|
if !g.promptDirection() {
|
||||||
|
g.After = false
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
g.countCh = g.DirCh
|
||||||
|
|
||||||
|
return g.DirCh, true // the C goto over: move onto it without pickup
|
||||||
|
}
|
||||||
|
|
||||||
|
// pickupCommand handles ',': pick up whatever is here (command.c).
|
||||||
|
func (g *RogueGame) pickupCommand() {
|
||||||
p := &g.Player
|
p := &g.Player
|
||||||
|
|
||||||
for {
|
|
||||||
switch ch {
|
|
||||||
case ',':
|
|
||||||
var found *Object
|
var found *Object
|
||||||
|
|
||||||
for _, obj := range g.Level.Objects {
|
for _, obj := range g.Level.Objects {
|
||||||
@@ -173,7 +305,10 @@ func (g *RogueGame) dispatch(ch byte) {
|
|||||||
if !g.levitCheck() {
|
if !g.levitCheck() {
|
||||||
g.pickUp(found.Kind.Glyph())
|
g.pickUp(found.Kind.Glyph())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !g.Options.Terse {
|
if !g.Options.Terse {
|
||||||
g.addmsgf("there is ")
|
g.addmsgf("there is ")
|
||||||
}
|
}
|
||||||
@@ -186,56 +321,11 @@ func (g *RogueGame) dispatch(ch byte) {
|
|||||||
|
|
||||||
g.endmsg()
|
g.endmsg()
|
||||||
}
|
}
|
||||||
case '!':
|
|
||||||
g.shell()
|
|
||||||
case 'h':
|
|
||||||
g.moveHero(0, -1)
|
|
||||||
case 'j':
|
|
||||||
g.moveHero(1, 0)
|
|
||||||
case 'k':
|
|
||||||
g.moveHero(-1, 0)
|
|
||||||
case 'l':
|
|
||||||
g.moveHero(0, 1)
|
|
||||||
case 'y':
|
|
||||||
g.moveHero(-1, -1)
|
|
||||||
case 'u':
|
|
||||||
g.moveHero(-1, 1)
|
|
||||||
case 'b':
|
|
||||||
g.moveHero(1, -1)
|
|
||||||
case 'n':
|
|
||||||
g.moveHero(1, 1)
|
|
||||||
case 'H':
|
|
||||||
g.startRun('h')
|
|
||||||
case 'J':
|
|
||||||
g.startRun('j')
|
|
||||||
case 'K':
|
|
||||||
g.startRun('k')
|
|
||||||
case 'L':
|
|
||||||
g.startRun('l')
|
|
||||||
case 'Y':
|
|
||||||
g.startRun('y')
|
|
||||||
case 'U':
|
|
||||||
g.startRun('u')
|
|
||||||
case 'B':
|
|
||||||
g.startRun('b')
|
|
||||||
case 'N':
|
|
||||||
g.startRun('n')
|
|
||||||
case CTRL('H'), CTRL('J'), CTRL('K'), CTRL('L'),
|
|
||||||
CTRL('Y'), CTRL('U'), CTRL('B'), CTRL('N'):
|
|
||||||
if !p.On(Blind) {
|
|
||||||
g.DoorStop = true
|
|
||||||
g.Firstmove = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if g.Count != 0 && !g.newCount {
|
// fightCommand handles the f/F fight prefix; a true again asks dispatch
|
||||||
ch = g.direction
|
// to rerun with the direction key (command.c).
|
||||||
} else {
|
func (g *RogueGame) fightCommand(ch byte) (byte, bool) {
|
||||||
ch += 'A' - CTRL('A')
|
p := &g.Player
|
||||||
g.direction = ch
|
|
||||||
}
|
|
||||||
|
|
||||||
continue // the C goto over: re-dispatch as the run command
|
|
||||||
case 'F', 'f':
|
|
||||||
if ch == 'F' {
|
if ch == 'F' {
|
||||||
g.Kamikaze = true
|
g.Kamikaze = true
|
||||||
}
|
}
|
||||||
@@ -243,7 +333,7 @@ func (g *RogueGame) dispatch(ch byte) {
|
|||||||
if !g.promptDirection() {
|
if !g.promptDirection() {
|
||||||
g.After = false
|
g.After = false
|
||||||
|
|
||||||
break
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
g.Delta.Y += p.Pos.Y
|
g.Delta.Y += p.Pos.Y
|
||||||
@@ -264,103 +354,23 @@ func (g *RogueGame) dispatch(ch byte) {
|
|||||||
mp.Flags.Set(Targeted)
|
mp.Flags.Set(Targeted)
|
||||||
|
|
||||||
g.RunCh = g.DirCh
|
g.RunCh = g.DirCh
|
||||||
ch = g.DirCh
|
|
||||||
|
|
||||||
continue // the C goto over: fight by running at it
|
return g.DirCh, true // the C goto over: fight by running at it
|
||||||
}
|
}
|
||||||
case 't':
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// identifyTrapCommand handles '^': name the trap in a direction
|
||||||
|
// (command.c).
|
||||||
|
func (g *RogueGame) identifyTrapCommand() {
|
||||||
|
p := &g.Player
|
||||||
|
|
||||||
|
g.After = false
|
||||||
if !g.promptDirection() {
|
if !g.promptDirection() {
|
||||||
g.After = false
|
return
|
||||||
} else {
|
|
||||||
g.missile(g.Delta.Y, g.Delta.X)
|
|
||||||
}
|
}
|
||||||
case 'a':
|
|
||||||
if g.LastComm == 0 {
|
|
||||||
g.msg("you haven't typed a command yet")
|
|
||||||
g.After = false
|
|
||||||
} else {
|
|
||||||
ch = g.LastComm
|
|
||||||
g.Again = true
|
|
||||||
|
|
||||||
continue // the C goto over: replay the last command
|
|
||||||
}
|
|
||||||
case 'q':
|
|
||||||
g.quaff()
|
|
||||||
case 'Q':
|
|
||||||
g.After = false
|
|
||||||
g.QComm = true
|
|
||||||
g.quit(0)
|
|
||||||
g.QComm = false
|
|
||||||
case 'i':
|
|
||||||
g.After = false
|
|
||||||
g.inventory(p.Pack, 0)
|
|
||||||
case 'I':
|
|
||||||
g.After = false
|
|
||||||
g.pickyInven()
|
|
||||||
case 'd':
|
|
||||||
g.dropIt()
|
|
||||||
case 'r':
|
|
||||||
g.readScroll()
|
|
||||||
case 'e':
|
|
||||||
g.eat()
|
|
||||||
case 'w':
|
|
||||||
g.wield()
|
|
||||||
case 'W':
|
|
||||||
g.wear()
|
|
||||||
case 'T':
|
|
||||||
g.takeOff()
|
|
||||||
case 'P':
|
|
||||||
g.ringOn()
|
|
||||||
case 'R':
|
|
||||||
g.ringOff()
|
|
||||||
case 'o':
|
|
||||||
g.option()
|
|
||||||
g.After = false
|
|
||||||
case 'c':
|
|
||||||
g.call()
|
|
||||||
g.After = false
|
|
||||||
case '>':
|
|
||||||
g.After = false
|
|
||||||
g.dLevel()
|
|
||||||
case '<':
|
|
||||||
g.After = false
|
|
||||||
g.uLevel()
|
|
||||||
case '?':
|
|
||||||
g.After = false
|
|
||||||
g.help()
|
|
||||||
case '/':
|
|
||||||
g.After = false
|
|
||||||
g.identify()
|
|
||||||
case 's':
|
|
||||||
g.search()
|
|
||||||
case 'z':
|
|
||||||
if g.promptDirection() {
|
|
||||||
g.doZap()
|
|
||||||
} else {
|
|
||||||
g.After = false
|
|
||||||
}
|
|
||||||
case 'D':
|
|
||||||
g.After = false
|
|
||||||
g.discovered()
|
|
||||||
case CTRL('P'):
|
|
||||||
g.After = false
|
|
||||||
g.msg("%s", g.Msgs.Huh)
|
|
||||||
case CTRL('R'):
|
|
||||||
g.After = false
|
|
||||||
g.refresh()
|
|
||||||
case 'v':
|
|
||||||
g.After = false
|
|
||||||
g.msg("version %s. (mctesq was here)", Release)
|
|
||||||
case 'S':
|
|
||||||
g.After = false
|
|
||||||
g.saveGame()
|
|
||||||
case '.':
|
|
||||||
// rest command
|
|
||||||
case ' ':
|
|
||||||
g.After = false // "legal" illegal command
|
|
||||||
case '^':
|
|
||||||
g.After = false
|
|
||||||
if g.promptDirection() {
|
|
||||||
g.Delta.Y += p.Pos.Y
|
g.Delta.Y += p.Pos.Y
|
||||||
g.Delta.X += p.Pos.X
|
g.Delta.X += p.Pos.X
|
||||||
|
|
||||||
@@ -379,47 +389,6 @@ func (g *RogueGame) dispatch(ch byte) {
|
|||||||
fp.Set(FSeen)
|
fp.Set(FSeen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Escape: // escape
|
|
||||||
g.DoorStop = false
|
|
||||||
g.Count = 0
|
|
||||||
g.After = false
|
|
||||||
g.Again = false
|
|
||||||
case 'm':
|
|
||||||
g.MoveOn = true
|
|
||||||
if !g.promptDirection() {
|
|
||||||
g.After = false
|
|
||||||
} else {
|
|
||||||
ch = g.DirCh
|
|
||||||
g.countCh = g.DirCh
|
|
||||||
|
|
||||||
continue // the C goto over: move onto it without pickup
|
|
||||||
}
|
|
||||||
case ')':
|
|
||||||
g.current(p.CurWeapon, "wielding", "")
|
|
||||||
case ']':
|
|
||||||
g.current(p.CurArmor, "wearing", "")
|
|
||||||
case '=':
|
|
||||||
g.current(p.CurRing[Left], "wearing",
|
|
||||||
g.chooseTerse("(L)", "on left hand"))
|
|
||||||
g.current(p.CurRing[Right], "wearing",
|
|
||||||
g.chooseTerse("(R)", "on right hand"))
|
|
||||||
case '@':
|
|
||||||
g.StatMsg = true
|
|
||||||
g.status()
|
|
||||||
g.StatMsg = false
|
|
||||||
g.After = false
|
|
||||||
default:
|
|
||||||
g.After = false
|
|
||||||
if g.Wizard {
|
|
||||||
g.wizardCommand(ch)
|
|
||||||
} else {
|
|
||||||
g.illcom(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wizardCommand handles the MASTER debug commands (command.c).
|
// wizardCommand handles the MASTER debug commands (command.c).
|
||||||
func (g *RogueGame) wizardCommand(ch byte) {
|
func (g *RogueGame) wizardCommand(ch byte) {
|
||||||
@@ -444,6 +413,17 @@ func (g *RogueGame) wizardCommand(ch byte) {
|
|||||||
g.NewLevel()
|
g.NewLevel()
|
||||||
case CTRL('F'):
|
case CTRL('F'):
|
||||||
g.showMap()
|
g.showMap()
|
||||||
|
default:
|
||||||
|
g.wizardDebugCommand(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wizardDebugCommand handles the rest of the MASTER debug commands
|
||||||
|
// (command.c).
|
||||||
|
func (g *RogueGame) wizardDebugCommand(ch byte) {
|
||||||
|
p := &g.Player
|
||||||
|
|
||||||
|
switch ch {
|
||||||
case CTRL('T'):
|
case CTRL('T'):
|
||||||
g.teleport()
|
g.teleport()
|
||||||
case CTRL('E'):
|
case CTRL('E'):
|
||||||
@@ -457,6 +437,19 @@ func (g *RogueGame) wizardCommand(ch byte) {
|
|||||||
item.Charges = 10000
|
item.Charges = 10000
|
||||||
}
|
}
|
||||||
case CTRL('I'):
|
case CTRL('I'):
|
||||||
|
g.wizardKit()
|
||||||
|
case '*':
|
||||||
|
g.prList()
|
||||||
|
default:
|
||||||
|
g.illcom(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wizardKit levels the wizard up and equips him (the ^I case of the
|
||||||
|
// command.c wizard switch).
|
||||||
|
func (g *RogueGame) wizardKit() {
|
||||||
|
p := &g.Player
|
||||||
|
|
||||||
for range 9 {
|
for range 9 {
|
||||||
g.raiseLevel()
|
g.raiseLevel()
|
||||||
}
|
}
|
||||||
@@ -476,11 +469,6 @@ func (g *RogueGame) wizardCommand(ch byte) {
|
|||||||
obj.Count = 1
|
obj.Count = 1
|
||||||
p.CurArmor = obj
|
p.CurArmor = obj
|
||||||
g.addPack(obj, true)
|
g.addPack(obj, true)
|
||||||
case '*':
|
|
||||||
g.prList()
|
|
||||||
default:
|
|
||||||
g.illcom(ch)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// illcom reports an illegal command (command.c illcom).
|
// illcom reports an illegal command (command.c illcom).
|
||||||
@@ -514,9 +502,24 @@ func (g *RogueGame) search() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if g.searchSpot(y, x, probinc) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
g.look(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// searchSpot tries to reveal one hidden thing next to the hero: a
|
||||||
|
// secret door, a hidden trap, or a secret passage (the loop body of
|
||||||
|
// command.c search). It reports whether something was found.
|
||||||
|
func (g *RogueGame) searchSpot(y, x, probinc int) bool {
|
||||||
fp := g.Level.FlagsAt(y, x)
|
fp := g.Level.FlagsAt(y, x)
|
||||||
if fp.Has(FReal) {
|
if fp.Has(FReal) {
|
||||||
continue
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
foundone := false
|
foundone := false
|
||||||
@@ -532,24 +535,7 @@ func (g *RogueGame) search() {
|
|||||||
|
|
||||||
foundone = true
|
foundone = true
|
||||||
case Floor:
|
case Floor:
|
||||||
if g.rnd(2+probinc) != 0 {
|
foundone = g.searchFloor(fp, y, x, probinc)
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Level.SetChar(y, x, Trap)
|
|
||||||
|
|
||||||
if !g.Options.Terse {
|
|
||||||
g.addmsgf("you found ")
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.On(Hallucinating) {
|
|
||||||
g.msg("%s", g.data.trName[g.rnd(NumTrapTypes)])
|
|
||||||
} else {
|
|
||||||
g.msg("%s", g.data.trName[*fp&FTrapMask])
|
|
||||||
fp.Set(FSeen)
|
|
||||||
}
|
|
||||||
|
|
||||||
foundone = true
|
|
||||||
case ' ':
|
case ' ':
|
||||||
if g.rnd(3+probinc) != 0 {
|
if g.rnd(3+probinc) != 0 {
|
||||||
break
|
break
|
||||||
@@ -561,19 +547,36 @@ func (g *RogueGame) search() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if foundone {
|
if foundone {
|
||||||
found = true
|
|
||||||
|
|
||||||
fp.Set(FReal)
|
fp.Set(FReal)
|
||||||
|
|
||||||
g.Count = 0
|
g.Count = 0
|
||||||
g.Running = false
|
g.Running = false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return foundone
|
||||||
}
|
}
|
||||||
|
|
||||||
if found {
|
// searchFloor reveals a hidden trap underfoot and names it (the FLOOR
|
||||||
g.look(false)
|
// arm of command.c search).
|
||||||
|
func (g *RogueGame) searchFloor(fp *PlaceFlags, y, x, probinc int) bool {
|
||||||
|
if g.rnd(2+probinc) != 0 {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.Level.SetChar(y, x, Trap)
|
||||||
|
|
||||||
|
if !g.Options.Terse {
|
||||||
|
g.addmsgf("you found ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.Player.On(Hallucinating) {
|
||||||
|
g.msg("%s", g.data.trName[g.rnd(NumTrapTypes)])
|
||||||
|
} else {
|
||||||
|
g.msg("%s", g.data.trName[*fp&FTrapMask])
|
||||||
|
fp.Set(FSeen)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// help gives single character help, or the whole mess if he wants it
|
// help gives single character help, or the whole mess if he wants it
|
||||||
@@ -585,6 +588,17 @@ func (g *RogueGame) help() {
|
|||||||
// If it's not a *, print the right help string or an error if he
|
// If it's not a *, print the right help string or an error if he
|
||||||
// typed a funny character.
|
// typed a funny character.
|
||||||
if helpch != '*' {
|
if helpch != '*' {
|
||||||
|
g.helpOne(helpch)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.helpAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpOne prints the help line for a single key, or an error for a
|
||||||
|
// funny character (command.c help).
|
||||||
|
func (g *RogueGame) helpOne(helpch byte) {
|
||||||
g.move(0, 0)
|
g.move(0, 0)
|
||||||
|
|
||||||
for _, strp := range g.data.helpStr {
|
for _, strp := range g.data.helpStr {
|
||||||
@@ -598,27 +612,12 @@ func (g *RogueGame) help() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.msg("unknown character '%s'", unctrl(helpch))
|
g.msg("unknown character '%s'", unctrl(helpch))
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Here we print help for everything, then wait before we return to
|
|
||||||
// command mode.
|
|
||||||
numprint := 0
|
|
||||||
|
|
||||||
for _, strp := range g.data.helpStr {
|
|
||||||
if strp.Print {
|
|
||||||
numprint++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if numprint&1 == 1 { // round odd numbers up
|
// helpAll prints help for everything in two columns, then waits before
|
||||||
numprint++
|
// returning to command mode (command.c help).
|
||||||
}
|
func (g *RogueGame) helpAll() {
|
||||||
|
numprint := g.helpLines()
|
||||||
numprint /= 2
|
|
||||||
if numprint > NumLines-1 {
|
|
||||||
numprint = NumLines - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
hw := g.scr.Hw
|
hw := g.scr.Hw
|
||||||
hw.Clear()
|
hw.Clear()
|
||||||
@@ -655,6 +654,29 @@ func (g *RogueGame) help() {
|
|||||||
g.refresh()
|
g.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helpLines counts how many rows the two-column help listing needs
|
||||||
|
// (command.c help).
|
||||||
|
func (g *RogueGame) helpLines() int {
|
||||||
|
numprint := 0
|
||||||
|
|
||||||
|
for _, strp := range g.data.helpStr {
|
||||||
|
if strp.Print {
|
||||||
|
numprint++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if numprint&1 == 1 { // round odd numbers up
|
||||||
|
numprint++
|
||||||
|
}
|
||||||
|
|
||||||
|
numprint /= 2
|
||||||
|
if numprint > NumLines-1 {
|
||||||
|
numprint = NumLines - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return numprint
|
||||||
|
}
|
||||||
|
|
||||||
// identify tells the player what a certain thing is (command.c identify).
|
// identify tells the player what a certain thing is (command.c identify).
|
||||||
func (g *RogueGame) identify() {
|
func (g *RogueGame) identify() {
|
||||||
g.msg("what do you want identified? ")
|
g.msg("what do you want identified? ")
|
||||||
@@ -706,8 +728,18 @@ func (g *RogueGame) uLevel() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.Level.Char(g.Player.Pos.Y, g.Player.Pos.X) == Stairs {
|
if g.Level.Char(g.Player.Pos.Y, g.Player.Pos.X) != Stairs {
|
||||||
if g.HasAmulet {
|
g.msg("I see no way up")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !g.HasAmulet {
|
||||||
|
g.msg("your way is magically blocked")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
g.Depth--
|
g.Depth--
|
||||||
if g.Depth == 0 {
|
if g.Depth == 0 {
|
||||||
g.totalWinner()
|
g.totalWinner()
|
||||||
@@ -715,12 +747,6 @@ func (g *RogueGame) uLevel() {
|
|||||||
|
|
||||||
g.NewLevel()
|
g.NewLevel()
|
||||||
g.msg("you feel a wrenching sensation in your gut")
|
g.msg("you feel a wrenching sensation in your gut")
|
||||||
} else {
|
|
||||||
g.msg("your way is magically blocked")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g.msg("I see no way up")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// levitCheck checks whether she's levitating, and if she is, prints an
|
// levitCheck checks whether she's levitating, and if she is, prints an
|
||||||
@@ -744,63 +770,14 @@ func (g *RogueGame) call() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
op, elsewise, guess, ok := g.callTarget(obj)
|
||||||
op *ObjInfo
|
if !ok {
|
||||||
elsewise string
|
|
||||||
know *bool
|
|
||||||
guess *string
|
|
||||||
)
|
|
||||||
|
|
||||||
it := &g.Items
|
|
||||||
|
|
||||||
switch obj.Kind {
|
|
||||||
case KindRing:
|
|
||||||
op = &it.Rings[obj.Which]
|
|
||||||
elsewise = it.RingStones[obj.Which]
|
|
||||||
case KindPotion:
|
|
||||||
op = &it.Potions[obj.Which]
|
|
||||||
elsewise = it.PotColors[obj.Which]
|
|
||||||
case KindScroll:
|
|
||||||
op = &it.Scrolls[obj.Which]
|
|
||||||
elsewise = it.ScrNames[obj.Which]
|
|
||||||
case KindWand:
|
|
||||||
op = &it.Sticks[obj.Which]
|
|
||||||
elsewise = it.WandMade[obj.Which]
|
|
||||||
case KindFood:
|
|
||||||
g.msg("you can't call that anything")
|
|
||||||
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
guess = &obj.Label
|
|
||||||
elsewise = obj.Label
|
|
||||||
}
|
|
||||||
|
|
||||||
fromGuess := false
|
|
||||||
|
|
||||||
if op != nil {
|
|
||||||
know = &op.Know
|
|
||||||
|
|
||||||
guess = &op.Guess
|
|
||||||
if *guess != "" {
|
|
||||||
elsewise = *guess
|
|
||||||
fromGuess = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fromGuess = elsewise != "" && elsewise == *guess
|
|
||||||
}
|
|
||||||
|
|
||||||
if know != nil && *know {
|
|
||||||
g.msg("that has already been identified")
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if fromGuess {
|
elsewise, guess, ok = g.callPrelude(op, elsewise, guess)
|
||||||
if !g.Options.Terse {
|
if !ok {
|
||||||
g.addmsgf("Was ")
|
return
|
||||||
}
|
|
||||||
|
|
||||||
g.msg("called \"%s\"", elsewise)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g.msg("%s", g.chooseTerse("call it: ", "what do you want to call it? "))
|
g.msg("%s", g.chooseTerse("call it: ", "what do you want to call it? "))
|
||||||
@@ -811,10 +788,82 @@ func (g *RogueGame) call() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// callTarget picks what a call names: the lore record for identifiable
|
||||||
|
// kinds, the object's own label otherwise; ok is false for food (the
|
||||||
|
// switch of command.c call).
|
||||||
|
func (g *RogueGame) callTarget(obj *Object) (*ObjInfo, string, *string, bool) {
|
||||||
|
it := &g.Items
|
||||||
|
|
||||||
|
switch obj.Kind {
|
||||||
|
case KindRing:
|
||||||
|
return &it.Rings[obj.Which], it.RingStones[obj.Which], nil, true
|
||||||
|
case KindPotion:
|
||||||
|
return &it.Potions[obj.Which], it.PotColors[obj.Which], nil, true
|
||||||
|
case KindScroll:
|
||||||
|
return &it.Scrolls[obj.Which], it.ScrNames[obj.Which], nil, true
|
||||||
|
case KindWand:
|
||||||
|
return &it.Sticks[obj.Which], it.WandMade[obj.Which], nil, true
|
||||||
|
case KindFood:
|
||||||
|
g.msg("you can't call that anything")
|
||||||
|
|
||||||
|
return nil, "", nil, false
|
||||||
|
default:
|
||||||
|
return nil, obj.Label, &obj.Label, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// callPrelude resolves the item's current name, reporting a previous
|
||||||
|
// guess; ok is false when the item is already identified (command.c
|
||||||
|
// call).
|
||||||
|
func (g *RogueGame) callPrelude(op *ObjInfo, elsewise string, guess *string) (string, *string, bool) {
|
||||||
|
fromGuess := false
|
||||||
|
|
||||||
|
if op != nil {
|
||||||
|
if op.Know {
|
||||||
|
g.msg("that has already been identified")
|
||||||
|
|
||||||
|
return "", nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
guess = &op.Guess
|
||||||
|
if *guess != "" {
|
||||||
|
elsewise = *guess
|
||||||
|
fromGuess = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fromGuess = elsewise != "" && elsewise == *guess
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromGuess {
|
||||||
|
if !g.Options.Terse {
|
||||||
|
g.addmsgf("Was ")
|
||||||
|
}
|
||||||
|
|
||||||
|
g.msg("called \"%s\"", elsewise)
|
||||||
|
}
|
||||||
|
|
||||||
|
return elsewise, guess, true
|
||||||
|
}
|
||||||
|
|
||||||
// current prints the current weapon/armor (command.c current).
|
// current prints the current weapon/armor (command.c current).
|
||||||
func (g *RogueGame) current(cur *Object, how, where string) {
|
func (g *RogueGame) current(cur *Object, how, where string) {
|
||||||
g.After = false
|
g.After = false
|
||||||
if cur != nil {
|
if cur == nil {
|
||||||
|
if !g.Options.Terse {
|
||||||
|
g.addmsgf("you are ")
|
||||||
|
}
|
||||||
|
|
||||||
|
g.addmsgf("%s nothing", how)
|
||||||
|
|
||||||
|
if where != "" {
|
||||||
|
g.addmsgf(" %s", where)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.endmsg()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !g.Options.Terse {
|
if !g.Options.Terse {
|
||||||
g.addmsgf("you are %s (", how)
|
g.addmsgf("you are %s (", how)
|
||||||
}
|
}
|
||||||
@@ -828,19 +877,6 @@ func (g *RogueGame) current(cur *Object, how, where string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.endmsg()
|
g.endmsg()
|
||||||
} else {
|
|
||||||
if !g.Options.Terse {
|
|
||||||
g.addmsgf("you are ")
|
|
||||||
}
|
|
||||||
|
|
||||||
g.addmsgf("%s nothing", how)
|
|
||||||
|
|
||||||
if where != "" {
|
|
||||||
g.addmsgf(" %s", where)
|
|
||||||
}
|
|
||||||
|
|
||||||
g.endmsg()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shell lets them escape for a while (main.c shell). The terminal decides
|
// shell lets them escape for a while (main.c shell). The terminal decides
|
||||||
|
|||||||
139
game/tables.go
139
game/tables.go
@@ -142,6 +142,11 @@ type gameData struct {
|
|||||||
// lands, indexed by monster letter - 'A': the cases of the fight.c
|
// lands, indexed by monster letter - 'A': the cases of the fight.c
|
||||||
// attack switch. A true return means the monster removed itself.
|
// attack switch. A true return means the monster removed itself.
|
||||||
hitHandlers [26]func(g *RogueGame, mp *Monster, mname string) bool
|
hitHandlers [26]func(g *RogueGame, mp *Monster, mname string) bool
|
||||||
|
|
||||||
|
// commandHandlers dispatches the ordinary command keys: the simple
|
||||||
|
// cases of the big command.c switch. Keys that re-dispatch (runs,
|
||||||
|
// fight, repeat, move-on) and wizard keys stay in dispatchKey.
|
||||||
|
commandHandlers map[byte]func(g *RogueGame)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ripWall is the repeated blank wall line of the tombstone art.
|
// ripWall is the repeated blank wall line of the tombstone art.
|
||||||
@@ -672,6 +677,140 @@ func newGameData() *gameData {
|
|||||||
'V' - 'A': (*RogueGame).hitLifeDrainer,
|
'V' - 'A': (*RogueGame).hitLifeDrainer,
|
||||||
'W' - 'A': (*RogueGame).hitLifeDrainer,
|
'W' - 'A': (*RogueGame).hitLifeDrainer,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
commandHandlers: map[byte]func(*RogueGame){
|
||||||
|
',': (*RogueGame).pickupCommand,
|
||||||
|
'!': (*RogueGame).shell,
|
||||||
|
'h': func(g *RogueGame) { g.moveHero(0, -1) },
|
||||||
|
'j': func(g *RogueGame) { g.moveHero(1, 0) },
|
||||||
|
'k': func(g *RogueGame) { g.moveHero(-1, 0) },
|
||||||
|
'l': func(g *RogueGame) { g.moveHero(0, 1) },
|
||||||
|
'y': func(g *RogueGame) { g.moveHero(-1, -1) },
|
||||||
|
'u': func(g *RogueGame) { g.moveHero(-1, 1) },
|
||||||
|
'b': func(g *RogueGame) { g.moveHero(1, -1) },
|
||||||
|
'n': func(g *RogueGame) { g.moveHero(1, 1) },
|
||||||
|
'H': func(g *RogueGame) { g.startRun('h') },
|
||||||
|
'J': func(g *RogueGame) { g.startRun('j') },
|
||||||
|
'K': func(g *RogueGame) { g.startRun('k') },
|
||||||
|
'L': func(g *RogueGame) { g.startRun('l') },
|
||||||
|
'Y': func(g *RogueGame) { g.startRun('y') },
|
||||||
|
'U': func(g *RogueGame) { g.startRun('u') },
|
||||||
|
'B': func(g *RogueGame) { g.startRun('b') },
|
||||||
|
'N': func(g *RogueGame) { g.startRun('n') },
|
||||||
|
't': func(g *RogueGame) {
|
||||||
|
if !g.promptDirection() {
|
||||||
|
g.After = false
|
||||||
|
} else {
|
||||||
|
g.missile(g.Delta.Y, g.Delta.X)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'q': (*RogueGame).quaff,
|
||||||
|
'Q': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.QComm = true
|
||||||
|
g.quit(0)
|
||||||
|
g.QComm = false
|
||||||
|
},
|
||||||
|
'i': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.inventory(g.Player.Pack, 0)
|
||||||
|
},
|
||||||
|
'I': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.pickyInven()
|
||||||
|
},
|
||||||
|
'd': (*RogueGame).dropIt,
|
||||||
|
'r': (*RogueGame).readScroll,
|
||||||
|
'e': (*RogueGame).eat,
|
||||||
|
'w': (*RogueGame).wield,
|
||||||
|
'W': (*RogueGame).wear,
|
||||||
|
'T': (*RogueGame).takeOff,
|
||||||
|
'P': (*RogueGame).ringOn,
|
||||||
|
'R': (*RogueGame).ringOff,
|
||||||
|
'o': func(g *RogueGame) {
|
||||||
|
g.option()
|
||||||
|
g.After = false
|
||||||
|
},
|
||||||
|
'c': func(g *RogueGame) {
|
||||||
|
g.call()
|
||||||
|
g.After = false
|
||||||
|
},
|
||||||
|
'>': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.dLevel()
|
||||||
|
},
|
||||||
|
'<': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.uLevel()
|
||||||
|
},
|
||||||
|
'?': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.help()
|
||||||
|
},
|
||||||
|
'/': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.identify()
|
||||||
|
},
|
||||||
|
's': (*RogueGame).search,
|
||||||
|
'z': func(g *RogueGame) {
|
||||||
|
if g.promptDirection() {
|
||||||
|
g.doZap()
|
||||||
|
} else {
|
||||||
|
g.After = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'D': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.discovered()
|
||||||
|
},
|
||||||
|
CTRL('P'): func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.msg("%s", g.Msgs.Huh)
|
||||||
|
},
|
||||||
|
CTRL('R'): func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.refresh()
|
||||||
|
},
|
||||||
|
'v': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.msg("version %s. (mctesq was here)", Release)
|
||||||
|
},
|
||||||
|
'S': func(g *RogueGame) {
|
||||||
|
g.After = false
|
||||||
|
g.saveGame()
|
||||||
|
},
|
||||||
|
'.': func(*RogueGame) {
|
||||||
|
// rest command
|
||||||
|
},
|
||||||
|
' ': func(g *RogueGame) {
|
||||||
|
g.After = false // "legal" illegal command
|
||||||
|
},
|
||||||
|
'^': (*RogueGame).identifyTrapCommand,
|
||||||
|
Escape: func(g *RogueGame) {
|
||||||
|
g.DoorStop = false
|
||||||
|
g.Count = 0
|
||||||
|
g.After = false
|
||||||
|
g.Again = false
|
||||||
|
},
|
||||||
|
')': func(g *RogueGame) {
|
||||||
|
g.current(g.Player.CurWeapon, "wielding", "")
|
||||||
|
},
|
||||||
|
']': func(g *RogueGame) {
|
||||||
|
g.current(g.Player.CurArmor, "wearing", "")
|
||||||
|
},
|
||||||
|
'=': func(g *RogueGame) {
|
||||||
|
g.current(g.Player.CurRing[Left], "wearing",
|
||||||
|
g.chooseTerse("(L)", "on left hand"))
|
||||||
|
g.current(g.Player.CurRing[Right], "wearing",
|
||||||
|
g.chooseTerse("(R)", "on right hand"))
|
||||||
|
},
|
||||||
|
'@': func(g *RogueGame) {
|
||||||
|
g.StatMsg = true
|
||||||
|
g.status()
|
||||||
|
g.StatMsg = false
|
||||||
|
g.After = false
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user