Rename movement/world methods to idiomatic Go; remove all gotos
Refactor step 4. Renames (C breadcrumbs kept in doc comments): doMove→moveHero, beTrapped→springTrap, rndmove→randomStep, doRooms→digRooms, doPassages→digPassages, doMaze→digMaze, chgStr→changeStrength, doRun→startRun, moveStuff→finishMove, turnref→turnRefresh, moveMonst→moveMonster, doChase→chaseStep, setOldch→setOldChar, cansee→canSee, roomin→roomIn, runto→runTo, conn→connectRooms, putpass→putPassage, passnum→numberPassages, numpass→numberPassage, rndPos→randomPos, rndRoom→randomRoom, treasRoom→treasureRoom, accntMaze→accountMaze. All goto/label flows are gone: moveHero uses a retry loop with the PASSGO corner logic extracted into passageTurn; dispatch re-dispatches via a loop; chaseStep re-checks via a loop; saveGame uses a labeled prompt loop. Control flow and RNG call order are unchanged; suite green.
This commit is contained in:
499
game/command.go
499
game/command.go
@@ -151,270 +151,273 @@ func (g *RogueGame) command() {
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch runs one command character (the big switch in command.c,
|
||||
// including its `goto over` re-dispatch).
|
||||
// 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) {
|
||||
p := &g.Player
|
||||
|
||||
over:
|
||||
switch ch {
|
||||
case ',':
|
||||
var found *Object
|
||||
for {
|
||||
switch ch {
|
||||
case ',':
|
||||
var found *Object
|
||||
|
||||
for _, obj := range g.Level.Objects {
|
||||
if obj.Pos.Y == p.Pos.Y && obj.Pos.X == p.Pos.X {
|
||||
found = obj
|
||||
for _, obj := range g.Level.Objects {
|
||||
if obj.Pos.Y == p.Pos.Y && obj.Pos.X == p.Pos.X {
|
||||
found = obj
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found != nil {
|
||||
if !g.levitCheck() {
|
||||
g.pickUp(found.Kind.Glyph())
|
||||
}
|
||||
} else {
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("there is ")
|
||||
}
|
||||
|
||||
g.addmsgf("nothing here")
|
||||
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf(" to pick up")
|
||||
}
|
||||
|
||||
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 {
|
||||
ch = g.direction
|
||||
} else {
|
||||
ch += 'A' - CTRL('A')
|
||||
g.direction = ch
|
||||
}
|
||||
|
||||
continue // the C goto over: re-dispatch as the run command
|
||||
case 'F', 'f':
|
||||
if ch == 'F' {
|
||||
g.Kamikaze = true
|
||||
}
|
||||
|
||||
if !g.getDir() {
|
||||
g.After = false
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found != nil {
|
||||
if !g.levitCheck() {
|
||||
g.pickUp(found.Kind.Glyph())
|
||||
}
|
||||
} else {
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("there is ")
|
||||
}
|
||||
|
||||
g.addmsgf("nothing here")
|
||||
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf(" to pick up")
|
||||
}
|
||||
|
||||
g.endmsg()
|
||||
}
|
||||
case '!':
|
||||
g.shell()
|
||||
case 'h':
|
||||
g.doMove(0, -1)
|
||||
case 'j':
|
||||
g.doMove(1, 0)
|
||||
case 'k':
|
||||
g.doMove(-1, 0)
|
||||
case 'l':
|
||||
g.doMove(0, 1)
|
||||
case 'y':
|
||||
g.doMove(-1, -1)
|
||||
case 'u':
|
||||
g.doMove(-1, 1)
|
||||
case 'b':
|
||||
g.doMove(1, -1)
|
||||
case 'n':
|
||||
g.doMove(1, 1)
|
||||
case 'H':
|
||||
g.doRun('h')
|
||||
case 'J':
|
||||
g.doRun('j')
|
||||
case 'K':
|
||||
g.doRun('k')
|
||||
case 'L':
|
||||
g.doRun('l')
|
||||
case 'Y':
|
||||
g.doRun('y')
|
||||
case 'U':
|
||||
g.doRun('u')
|
||||
case 'B':
|
||||
g.doRun('b')
|
||||
case 'N':
|
||||
g.doRun('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 {
|
||||
ch = g.direction
|
||||
} else {
|
||||
ch += 'A' - CTRL('A')
|
||||
g.direction = ch
|
||||
}
|
||||
|
||||
goto over
|
||||
case 'F', 'f':
|
||||
if ch == 'F' {
|
||||
g.Kamikaze = true
|
||||
}
|
||||
|
||||
if !g.getDir() {
|
||||
g.After = false
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
g.Delta.Y += p.Pos.Y
|
||||
g.Delta.X += p.Pos.X
|
||||
|
||||
mp := g.Level.MonsterAt(g.Delta.Y, g.Delta.X)
|
||||
if mp == nil || (!g.seeMonst(mp) && !p.On(SenseMonsters)) {
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("I see ")
|
||||
}
|
||||
|
||||
g.msg("no monster there")
|
||||
g.After = false
|
||||
} else if g.diagOk(p.Pos, g.Delta) {
|
||||
g.ToDeath = true
|
||||
g.MaxHit = 0
|
||||
|
||||
mp.Flags.Set(Targeted)
|
||||
|
||||
g.RunCh = g.DirCh
|
||||
ch = g.DirCh
|
||||
|
||||
goto over
|
||||
}
|
||||
case 't':
|
||||
if !g.getDir() {
|
||||
g.After = false
|
||||
} 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
|
||||
|
||||
goto over
|
||||
}
|
||||
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.getDir() {
|
||||
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.getDir() {
|
||||
g.Delta.Y += p.Pos.Y
|
||||
g.Delta.X += p.Pos.X
|
||||
|
||||
fp := g.Level.FlagsAt(g.Delta.Y, g.Delta.X)
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("You have found ")
|
||||
}
|
||||
mp := g.Level.MonsterAt(g.Delta.Y, g.Delta.X)
|
||||
if mp == nil || (!g.seeMonst(mp) && !p.On(SenseMonsters)) {
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("I see ")
|
||||
}
|
||||
|
||||
switch {
|
||||
case g.Level.Char(g.Delta.Y, g.Delta.X) != Trap:
|
||||
g.msg("no trap there")
|
||||
case p.On(Hallucinating):
|
||||
g.msg("%s", g.data.trName[g.rnd(NumTrapTypes)])
|
||||
default:
|
||||
g.msg("%s", g.data.trName[*fp&FTrapMask])
|
||||
fp.Set(FSeen)
|
||||
g.msg("no monster there")
|
||||
g.After = false
|
||||
} else if g.diagOk(p.Pos, g.Delta) {
|
||||
g.ToDeath = true
|
||||
g.MaxHit = 0
|
||||
|
||||
mp.Flags.Set(Targeted)
|
||||
|
||||
g.RunCh = g.DirCh
|
||||
ch = g.DirCh
|
||||
|
||||
continue // the C goto over: fight by running at it
|
||||
}
|
||||
}
|
||||
case Escape: // escape
|
||||
g.DoorStop = false
|
||||
g.Count = 0
|
||||
g.After = false
|
||||
g.Again = false
|
||||
case 'm':
|
||||
g.MoveOn = true
|
||||
if !g.getDir() {
|
||||
case 't':
|
||||
if !g.getDir() {
|
||||
g.After = false
|
||||
} 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
|
||||
} else {
|
||||
ch = g.DirCh
|
||||
g.countCh = g.DirCh
|
||||
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.getDir() {
|
||||
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.getDir() {
|
||||
g.Delta.Y += p.Pos.Y
|
||||
g.Delta.X += p.Pos.X
|
||||
|
||||
goto over
|
||||
}
|
||||
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)
|
||||
fp := g.Level.FlagsAt(g.Delta.Y, g.Delta.X)
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("You have found ")
|
||||
}
|
||||
|
||||
switch {
|
||||
case g.Level.Char(g.Delta.Y, g.Delta.X) != Trap:
|
||||
g.msg("no trap there")
|
||||
case p.On(Hallucinating):
|
||||
g.msg("%s", g.data.trName[g.rnd(NumTrapTypes)])
|
||||
default:
|
||||
g.msg("%s", g.data.trName[*fp&FTrapMask])
|
||||
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.getDir() {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user