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:
135
game/chase.go
135
game/chase.go
@@ -13,12 +13,12 @@ func (g *RogueGame) runners(int) {
|
||||
origPos := tp.Pos
|
||||
|
||||
wastarget := tp.On(Targeted)
|
||||
if g.moveMonst(tp) == -1 {
|
||||
if g.moveMonster(tp) == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if tp.On(Flying) && distCp(g.Player.Pos, tp.Pos) >= 3 {
|
||||
if g.moveMonst(tp) == -1 {
|
||||
if g.moveMonster(tp) == -1 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -37,17 +37,17 @@ func (g *RogueGame) runners(int) {
|
||||
}
|
||||
}
|
||||
|
||||
// moveMonst executes a single turn of running for a monster (chase.c
|
||||
// moveMonster executes a single turn of running for a monster (chase.c
|
||||
// move_monst). Returns -1 if the monster died or left the level.
|
||||
func (g *RogueGame) moveMonst(tp *Monster) int {
|
||||
func (g *RogueGame) moveMonster(tp *Monster) int {
|
||||
if !tp.On(Slowed) || tp.Turn {
|
||||
if g.doChase(tp) == -1 {
|
||||
if g.chaseStep(tp) == -1 {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
if tp.On(Hasted) {
|
||||
if g.doChase(tp) == -1 {
|
||||
if g.chaseStep(tp) == -1 {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,8 @@ func (g *RogueGame) moveMonst(tp *Monster) int {
|
||||
func (g *RogueGame) relocate(th *Monster, newLoc Coord) {
|
||||
if newLoc != th.Pos {
|
||||
g.mvaddch(th.Pos.Y, th.Pos.X, th.OldCh)
|
||||
th.Room = g.roomin(newLoc)
|
||||
g.setOldch(th, newLoc)
|
||||
th.Room = g.roomIn(newLoc)
|
||||
g.setOldChar(th, newLoc)
|
||||
oroom := th.Room
|
||||
g.Level.SetMonsterAt(th.Pos.Y, th.Pos.X, nil)
|
||||
|
||||
@@ -86,9 +86,9 @@ func (g *RogueGame) relocate(th *Monster, newLoc Coord) {
|
||||
}
|
||||
}
|
||||
|
||||
// doChase makes one thing chase another (chase.c do_chase). Returns -1 if
|
||||
// the chaser died in the attempt.
|
||||
func (g *RogueGame) doChase(th *Monster) int {
|
||||
// chaseStep makes one thing chase another (chase.c do_chase). Returns -1
|
||||
// if the chaser died in the attempt.
|
||||
func (g *RogueGame) chaseStep(th *Monster) int {
|
||||
p := &g.Player
|
||||
stoprun := false // true means we are there
|
||||
mindist := 32767
|
||||
@@ -102,59 +102,62 @@ func (g *RogueGame) doChase(th *Monster) int {
|
||||
if th.Dest == &p.Pos {
|
||||
ree = p.Room
|
||||
} else {
|
||||
ree = g.roomin(*th.Dest)
|
||||
ree = g.roomIn(*th.Dest)
|
||||
}
|
||||
// We don't count doors as inside rooms for this routine
|
||||
door := g.Level.Char(th.Pos.Y, th.Pos.X) == Door
|
||||
|
||||
var this Coord
|
||||
|
||||
over:
|
||||
// If the object of our desire is in a different room, and we are not
|
||||
// in a corridor, run to the door nearest to our goal.
|
||||
if rer != ree {
|
||||
for i := range rer.Exits {
|
||||
curdist := distCp(*th.Dest, rer.Exits[i])
|
||||
if curdist < mindist {
|
||||
this = rer.Exits[i]
|
||||
mindist = curdist
|
||||
for {
|
||||
// If the object of our desire is in a different room, and we are
|
||||
// not in a corridor, run to the door nearest to our goal.
|
||||
if rer != ree {
|
||||
for i := range rer.Exits {
|
||||
curdist := distCp(*th.Dest, rer.Exits[i])
|
||||
if curdist < mindist {
|
||||
this = rer.Exits[i]
|
||||
mindist = curdist
|
||||
}
|
||||
}
|
||||
|
||||
if door {
|
||||
rer = &g.Level.Passages[*g.Level.FlagsAt(th.Pos.Y, th.Pos.X)&FPassNum]
|
||||
door = false
|
||||
|
||||
continue // the C goto over: redo with the passage as room
|
||||
}
|
||||
} else {
|
||||
this = *th.Dest
|
||||
// For dragons check and see if (a) the hero is on a straight
|
||||
// line from it, and (b) that it is within shooting distance,
|
||||
// but outside of striking range.
|
||||
if th.Type == 'D' && (th.Pos.Y == p.Pos.Y || th.Pos.X == p.Pos.X ||
|
||||
abs(th.Pos.Y-p.Pos.Y) == abs(th.Pos.X-p.Pos.X)) &&
|
||||
distCp(th.Pos, p.Pos) <= BoltLength*BoltLength &&
|
||||
!th.On(Cancelled) && g.rnd(dragonShot) == 0 {
|
||||
g.Delta.Y = sign(p.Pos.Y - th.Pos.Y)
|
||||
|
||||
g.Delta.X = sign(p.Pos.X - th.Pos.X)
|
||||
if g.HasHit {
|
||||
g.endmsg()
|
||||
}
|
||||
|
||||
g.fireBolt(th.Pos, &g.Delta, "flame")
|
||||
g.Running = false
|
||||
g.Count = 0
|
||||
|
||||
g.Quiet = 0
|
||||
if g.ToDeath && !th.On(Targeted) {
|
||||
g.ToDeath = false
|
||||
g.Kamikaze = false
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
if door {
|
||||
rer = &g.Level.Passages[*g.Level.FlagsAt(th.Pos.Y, th.Pos.X)&FPassNum]
|
||||
door = false
|
||||
|
||||
goto over
|
||||
}
|
||||
} else {
|
||||
this = *th.Dest
|
||||
// For dragons check and see if (a) the hero is on a straight line
|
||||
// from it, and (b) that it is within shooting distance, but
|
||||
// outside of striking range.
|
||||
if th.Type == 'D' && (th.Pos.Y == p.Pos.Y || th.Pos.X == p.Pos.X ||
|
||||
abs(th.Pos.Y-p.Pos.Y) == abs(th.Pos.X-p.Pos.X)) &&
|
||||
distCp(th.Pos, p.Pos) <= BoltLength*BoltLength &&
|
||||
!th.On(Cancelled) && g.rnd(dragonShot) == 0 {
|
||||
g.Delta.Y = sign(p.Pos.Y - th.Pos.Y)
|
||||
|
||||
g.Delta.X = sign(p.Pos.X - th.Pos.X)
|
||||
if g.HasHit {
|
||||
g.endmsg()
|
||||
}
|
||||
|
||||
g.fireBolt(th.Pos, &g.Delta, "flame")
|
||||
g.Running = false
|
||||
g.Count = 0
|
||||
|
||||
g.Quiet = 0
|
||||
if g.ToDeath && !th.On(Targeted) {
|
||||
g.ToDeath = false
|
||||
g.Kamikaze = false
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
break
|
||||
}
|
||||
// This now contains what we want to run to this time so we run to it.
|
||||
// If we hit it we either want to fight it or stop running
|
||||
@@ -214,7 +217,7 @@ func (g *RogueGame) chase(tp *Monster, ee Coord) bool {
|
||||
if (tp.On(Confused) && g.rnd(5) != 0) || (tp.Type == 'P' && g.rnd(5) == 0) ||
|
||||
(tp.Type == 'B' && g.rnd(2) == 0) {
|
||||
// get a valid random move
|
||||
g.chRet = g.rndmove(&tp.Creature)
|
||||
g.chRet = g.randomStep(&tp.Creature)
|
||||
curdist = distCp(g.chRet, ee)
|
||||
// Small chance that it will become un-confused
|
||||
if g.rnd(20) == 0 {
|
||||
@@ -294,8 +297,8 @@ func (g *RogueGame) chase(tp *Monster, ee Coord) bool {
|
||||
return curdist != 0 && g.chRet != p.Pos
|
||||
}
|
||||
|
||||
// setOldch sets the oldch character for the monster (chase.c set_oldch).
|
||||
func (g *RogueGame) setOldch(tp *Monster, cp Coord) {
|
||||
// setOldChar sets the oldch character for the monster (chase.c set_oldch).
|
||||
func (g *RogueGame) setOldChar(tp *Monster, cp Coord) {
|
||||
if tp.Pos == cp {
|
||||
return
|
||||
}
|
||||
@@ -341,8 +344,8 @@ func (g *RogueGame) seeMonst(mp *Monster) bool {
|
||||
return !mp.Room.Flags.Has(Dark)
|
||||
}
|
||||
|
||||
// runto sets a monster running after the hero (chase.c runto).
|
||||
func (g *RogueGame) runto(runner Coord) {
|
||||
// runTo sets a monster running after the hero (chase.c runto).
|
||||
func (g *RogueGame) runTo(runner Coord) {
|
||||
tp := g.Level.MonsterAt(runner.Y, runner.X)
|
||||
if tp == nil {
|
||||
return
|
||||
@@ -353,9 +356,9 @@ func (g *RogueGame) runto(runner Coord) {
|
||||
tp.Dest = g.findDest(tp)
|
||||
}
|
||||
|
||||
// roomin finds what room some coordinates are in; nil means they aren't in
|
||||
// roomIn finds what room some coordinates are in; nil means they aren't in
|
||||
// any room (chase.c roomin).
|
||||
func (g *RogueGame) roomin(cp Coord) *Room {
|
||||
func (g *RogueGame) roomIn(cp Coord) *Room {
|
||||
fp := *g.Level.FlagsAt(cp.Y, cp.X)
|
||||
if fp.Has(FPassage) {
|
||||
return &g.Level.Passages[fp&FPassNum]
|
||||
@@ -387,9 +390,9 @@ func (g *RogueGame) diagOk(sp, ep Coord) bool {
|
||||
return stepOk(g.Level.Char(ep.Y, sp.X)) && stepOk(g.Level.Char(sp.Y, ep.X))
|
||||
}
|
||||
|
||||
// cansee returns true if the hero can see a certain coordinate (chase.c
|
||||
// canSee returns true if the hero can see a certain coordinate (chase.c
|
||||
// cansee).
|
||||
func (g *RogueGame) cansee(y, x int) bool {
|
||||
func (g *RogueGame) canSee(y, x int) bool {
|
||||
p := &g.Player
|
||||
if p.On(Blind) {
|
||||
return false
|
||||
@@ -408,7 +411,7 @@ func (g *RogueGame) cansee(y, x int) bool {
|
||||
}
|
||||
// We can only see if the hero is in the same room as the coordinate
|
||||
// and the room is lit, or if it is close.
|
||||
rer := g.roomin(Coord{X: x, Y: y})
|
||||
rer := g.roomIn(Coord{X: x, Y: y})
|
||||
|
||||
return rer == p.Room && !rer.Flags.Has(Dark)
|
||||
}
|
||||
@@ -426,7 +429,7 @@ func (g *RogueGame) findDest(tp *Monster) *Coord {
|
||||
continue
|
||||
}
|
||||
|
||||
if g.roomin(obj.Pos) == tp.Room && g.rnd(100) < prob {
|
||||
if g.roomIn(obj.Pos) == tp.Room && g.rnd(100) < prob {
|
||||
claimed := false
|
||||
|
||||
for _, other := range g.Level.Monsters {
|
||||
|
||||
Reference in New Issue
Block a user