Adopt house golangci-lint config; fix all approved-linter findings
.golangci.yml is the prompts-repo standard verbatim plus one approved
exception (paralleltest, sneak 2026-07-06). Roughly 1,500 findings
fixed:
- autofix sweep (wsl_v5/nlreturn/intrange/modernize formatting), with
the misspell autofix REVERTED where it rewrote authentic C game text
("missle vanishes" stays, with nolint and a comment)
- error handling: errcheck sites get real handling — saveFile now
closes explicitly and removes corrupt saves, scoreboard writes are
documented best-effort, err113 sentinel errors (ErrSaveOutOfDate,
ErrScreenTooSmall); panics allowed for unrecoverable states per
MEMORY.md policy
- gosec: real fixes (ParseInt for SEED, 0600 scorefile) and justified
per-line nolints for provably-bounded conversions (randomMonsterLetter
helper collapses eight rnd(26)+'A' sites)
- API tidying from linters: pointer receivers on flag types
(recvcheck), msg helpers renamed addmsgf/doaddf/Printwf/MvPrintwf
(goprintffuncname), myExit()/findFloor(monst)/mkGameInput(t) drop
always-constant params (unparam), gameEnd carries no status
- gocritic/staticcheck: if-else chains to switches, the pack.c
inventory filter untangled into matchesFilter, main.go split so
defers run before exit (exitAfterDefer, funlen)
- revive doc comments on all exported flag types/consts/methods
Remaining findings are confined to linters pending sneak's exception
decision (mnd, gochecknoglobals, cyclop, nestif, gocognit, exhaustive,
goconst, testpackage); TODO.md records the state. MEMORY.md added at
repo root as the project's agent working notes.
This commit is contained in:
56
game/move.go
56
game/move.go
@@ -13,10 +13,12 @@ func (g *RogueGame) doRun(ch byte) {
|
||||
// fighting, picking up, etc. (move.c do_move).
|
||||
func (g *RogueGame) doMove(dy, dx int) {
|
||||
p := &g.Player
|
||||
|
||||
g.Firstmove = false
|
||||
if g.NoMove > 0 {
|
||||
g.NoMove--
|
||||
g.msg("you are still stuck in the bear trap")
|
||||
|
||||
return
|
||||
}
|
||||
// Do a confused move (maybe)
|
||||
@@ -27,6 +29,7 @@ func (g *RogueGame) doMove(dy, dx int) {
|
||||
g.After = false
|
||||
g.Running = false
|
||||
g.ToDeath = false
|
||||
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@@ -37,19 +40,27 @@ over:
|
||||
// Check if he tried to move off the screen or make an illegal diagonal
|
||||
// move, and stop him if he did.
|
||||
hitBound := nh.X < 0 || nh.X >= NumCols || nh.Y <= 0 || nh.Y >= NumLines-1
|
||||
var ch byte
|
||||
var fl PlaceFlags
|
||||
|
||||
var (
|
||||
ch byte
|
||||
fl PlaceFlags
|
||||
)
|
||||
|
||||
if !hitBound {
|
||||
if !g.diagOk(p.Pos, nh) {
|
||||
g.After = false
|
||||
g.Running = false
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if g.Running && p.Pos == nh {
|
||||
g.After = false
|
||||
g.Running = false
|
||||
}
|
||||
|
||||
fl = *g.Level.FlagsAt(nh.Y, nh.X)
|
||||
|
||||
ch = g.Level.VisibleChar(nh.Y, nh.X)
|
||||
if !fl.Has(FReal) && ch == Floor {
|
||||
if !p.On(Levitating) {
|
||||
@@ -59,20 +70,25 @@ over:
|
||||
}
|
||||
} else if p.On(Held) && ch != 'F' {
|
||||
g.msg("you are being held")
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if hitBound {
|
||||
ch = ' ' // fall into the wall case below
|
||||
}
|
||||
|
||||
switch ch {
|
||||
case ' ', '|', '-':
|
||||
if g.Options.PassGo && g.Running && p.Room.Flags.Has(Gone) &&
|
||||
!p.On(Blind) {
|
||||
var b1, b2 bool
|
||||
|
||||
switch g.RunCh {
|
||||
case 'h', 'l':
|
||||
b1 = p.Pos.Y != 1 && g.turnOk(p.Pos.Y-1, p.Pos.X)
|
||||
|
||||
b2 = p.Pos.Y != NumLines-2 && g.turnOk(p.Pos.Y+1, p.Pos.X)
|
||||
if b1 != b2 {
|
||||
if b1 {
|
||||
@@ -82,13 +98,18 @@ over:
|
||||
g.RunCh = 'j'
|
||||
dy = 1
|
||||
}
|
||||
|
||||
dx = 0
|
||||
|
||||
g.turnref()
|
||||
|
||||
nh = Coord{Y: p.Pos.Y + dy, X: p.Pos.X + dx}
|
||||
|
||||
goto over
|
||||
}
|
||||
case 'j', 'k':
|
||||
b1 = p.Pos.X != 0 && g.turnOk(p.Pos.Y, p.Pos.X-1)
|
||||
|
||||
b2 = p.Pos.X != NumCols-1 && g.turnOk(p.Pos.Y, p.Pos.X+1)
|
||||
if b1 != b2 {
|
||||
if b1 {
|
||||
@@ -98,13 +119,18 @@ over:
|
||||
g.RunCh = 'l'
|
||||
dx = 1
|
||||
}
|
||||
|
||||
dy = 0
|
||||
|
||||
g.turnref()
|
||||
|
||||
nh = Coord{Y: p.Pos.Y + dy, X: p.Pos.X + dx}
|
||||
|
||||
goto over
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.Running = false
|
||||
g.After = false
|
||||
case Door:
|
||||
@@ -112,12 +138,14 @@ over:
|
||||
if g.Level.FlagsAt(p.Pos.Y, p.Pos.X).Has(FPassage) {
|
||||
g.enterRoom(nh)
|
||||
}
|
||||
|
||||
g.moveStuff(nh, fl)
|
||||
case Trap:
|
||||
tr := g.beTrapped(nh)
|
||||
if tr == TrapDoor || tr == TrapTeleport {
|
||||
return
|
||||
}
|
||||
|
||||
g.moveStuff(nh, fl)
|
||||
case Passage:
|
||||
// when you're in a corridor, you don't know if you're in a maze
|
||||
@@ -130,11 +158,13 @@ over:
|
||||
if !fl.Has(FReal) {
|
||||
g.beTrapped(p.Pos)
|
||||
}
|
||||
|
||||
g.moveStuff(nh, fl)
|
||||
default:
|
||||
if ch == Stairs {
|
||||
g.SeenStairs = true
|
||||
}
|
||||
|
||||
g.Running = false
|
||||
if isUpper(ch) || g.Level.MonsterAt(nh.Y, nh.X) != nil {
|
||||
g.fight(nh, p.CurWeapon, false)
|
||||
@@ -142,6 +172,7 @@ over:
|
||||
if ch != Stairs {
|
||||
g.Take = ch
|
||||
}
|
||||
|
||||
g.moveStuff(nh, fl)
|
||||
}
|
||||
}
|
||||
@@ -151,9 +182,11 @@ over:
|
||||
func (g *RogueGame) moveStuff(nh Coord, fl PlaceFlags) {
|
||||
p := &g.Player
|
||||
g.mvaddch(p.Pos.Y, p.Pos.X, g.floorAt())
|
||||
|
||||
if fl.Has(FPassage) && g.Level.Char(g.Oldpos.Y, g.Oldpos.X) == Door {
|
||||
g.leaveRoom(nh)
|
||||
}
|
||||
|
||||
p.Pos = nh
|
||||
}
|
||||
|
||||
@@ -161,17 +194,20 @@ func (g *RogueGame) moveStuff(nh Coord, fl PlaceFlags) {
|
||||
// (move.c turn_ok).
|
||||
func (g *RogueGame) turnOk(y, x int) bool {
|
||||
pp := g.Level.At(y, x)
|
||||
|
||||
return pp.Ch == Door || pp.Flags&(FReal|FPassage) == (FReal|FPassage)
|
||||
}
|
||||
|
||||
// turnref decides whether to refresh at a passage turning (move.c turnref).
|
||||
func (g *RogueGame) turnref() {
|
||||
p := &g.Player
|
||||
|
||||
pp := g.Level.At(p.Pos.Y, p.Pos.X)
|
||||
if !pp.Flags.Has(FSeen) {
|
||||
if g.Options.Jump {
|
||||
g.refresh()
|
||||
}
|
||||
|
||||
pp.Flags.Set(FSeen)
|
||||
}
|
||||
}
|
||||
@@ -182,6 +218,7 @@ func (g *RogueGame) doorOpen(rp *Room) {
|
||||
if rp.Flags.Has(Gone) {
|
||||
return
|
||||
}
|
||||
|
||||
for y := rp.Pos.Y; y < rp.Pos.Y+rp.Max.Y; y++ {
|
||||
for x := rp.Pos.X; x < rp.Pos.X+rp.Max.X; x++ {
|
||||
if isUpper(g.Level.VisibleChar(y, x)) {
|
||||
@@ -197,12 +234,14 @@ func (g *RogueGame) beTrapped(tc Coord) TrapKind {
|
||||
if p.On(Levitating) {
|
||||
return TrapRust // anything that's not a door or teleport
|
||||
}
|
||||
|
||||
g.Running = false
|
||||
g.Count = 0
|
||||
pp := g.Level.At(tc.Y, tc.X)
|
||||
pp.Ch = Trap
|
||||
tr := TrapKind(pp.Flags & FTrapMask)
|
||||
pp.Flags.Set(FSeen)
|
||||
|
||||
switch tr {
|
||||
case TrapDoor:
|
||||
g.Depth++
|
||||
@@ -238,6 +277,7 @@ func (g *RogueGame) beTrapped(tc Coord) TrapKind {
|
||||
}
|
||||
case TrapSleep:
|
||||
g.NoCommand += g.spread(5) // SLEEPTIME
|
||||
|
||||
p.Flags.Clear(Awake)
|
||||
g.msg("a strange white mist envelops you and you fall asleep")
|
||||
case TrapArrow:
|
||||
@@ -271,16 +311,20 @@ func (g *RogueGame) beTrapped(tc Coord) TrapKind {
|
||||
g.msg("a poisoned dart killed you")
|
||||
g.death('d')
|
||||
}
|
||||
|
||||
if !p.IsWearing(RingSustainStrength) && !g.save(VsPoison) {
|
||||
g.chgStr(-1)
|
||||
}
|
||||
|
||||
g.msg("a small dart just hit you in the shoulder")
|
||||
}
|
||||
case TrapRust:
|
||||
g.msg("a gush of water hits you on the head")
|
||||
g.rustArmor(p.CurArmor)
|
||||
}
|
||||
|
||||
g.flushType()
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
@@ -296,25 +340,32 @@ func (g *RogueGame) rndmove(who *Creature) Coord {
|
||||
if ret == who.Pos {
|
||||
return ret
|
||||
}
|
||||
|
||||
if !g.diagOk(who.Pos, ret) {
|
||||
return who.Pos
|
||||
}
|
||||
|
||||
ch := g.Level.VisibleChar(ret.Y, ret.X)
|
||||
if !stepOk(ch) {
|
||||
return who.Pos
|
||||
}
|
||||
|
||||
if ch == Scroll {
|
||||
var found *Object
|
||||
|
||||
for _, obj := range g.Level.Objects {
|
||||
if ret.Y == obj.Pos.Y && ret.X == obj.Pos.X {
|
||||
found = obj
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found != nil && found.ScrollKind() == ScrollScareMonster {
|
||||
return who.Pos
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -332,6 +383,7 @@ func (g *RogueGame) rustArmor(arm *Object) {
|
||||
}
|
||||
} else {
|
||||
arm.ArmorClass++
|
||||
|
||||
if !g.Options.Terse {
|
||||
g.msg("your armor appears to be weaker now. Oh my!")
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user