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:
86
game/misc.go
86
game/misc.go
@@ -10,20 +10,24 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
hero := p.Pos
|
||||
passcount := 0
|
||||
rp := p.Room
|
||||
|
||||
if g.Oldpos != hero {
|
||||
g.eraseLamp(g.Oldpos, g.Oldrp)
|
||||
g.Oldpos = hero
|
||||
g.Oldrp = rp
|
||||
}
|
||||
|
||||
ey := hero.Y + 1
|
||||
ex := hero.X + 1
|
||||
sx := hero.X - 1
|
||||
sy := hero.Y - 1
|
||||
|
||||
sumhero, diffhero := 0, 0
|
||||
if g.DoorStop && !g.Firstmove && g.Running {
|
||||
sumhero = hero.Y + hero.X
|
||||
diffhero = hero.Y - hero.X
|
||||
}
|
||||
|
||||
pp := g.Level.At(hero.Y, hero.X)
|
||||
pch := pp.Ch
|
||||
pfl := pp.Flags
|
||||
@@ -32,10 +36,12 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
if y <= 0 || y >= NumLines-1 {
|
||||
continue
|
||||
}
|
||||
|
||||
for x := sx; x <= ex; x++ {
|
||||
if x < 0 || x >= NumCols {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.On(Blind) {
|
||||
if y == hero.Y && x == hero.X {
|
||||
continue
|
||||
@@ -43,16 +49,19 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
}
|
||||
|
||||
pp := g.Level.At(y, x)
|
||||
|
||||
ch := pp.Ch
|
||||
if ch == ' ' { // nothing need be done with a ' '
|
||||
continue
|
||||
}
|
||||
|
||||
fp := &pp.Flags
|
||||
if pch != Door && ch != Door {
|
||||
if (pfl & FPassage) != (*fp & FPassage) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (fp.Has(FPassage) || ch == Door) && (pfl.Has(FPassage) || pch == Door) {
|
||||
if hero.X != x && hero.Y != y &&
|
||||
!stepOk(g.Level.Char(y, hero.X)) && !stepOk(g.Level.Char(hero.Y, x)) {
|
||||
@@ -61,25 +70,30 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
}
|
||||
|
||||
tp := pp.Monst
|
||||
if tp == nil {
|
||||
|
||||
switch {
|
||||
case tp == nil:
|
||||
ch = g.tripCh(y, x, ch)
|
||||
} else if p.On(SenseMonsters) && tp.On(Invisible) {
|
||||
case p.On(SenseMonsters) && tp.On(Invisible):
|
||||
if g.DoorStop && !g.Firstmove {
|
||||
g.Running = false
|
||||
}
|
||||
|
||||
continue
|
||||
} else {
|
||||
default:
|
||||
if wakeup {
|
||||
g.wakeMonster(y, x)
|
||||
}
|
||||
|
||||
if g.seeMonst(tp) {
|
||||
if p.On(Hallucinating) {
|
||||
ch = byte(g.rnd(26) + 'A')
|
||||
ch = g.randomMonsterLetter()
|
||||
} else {
|
||||
ch = tp.Disguise
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if p.On(Blind) && (y != hero.Y || x != hero.X) {
|
||||
continue
|
||||
}
|
||||
@@ -129,6 +143,7 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
switch ch {
|
||||
case Door:
|
||||
if x == hero.X || y == hero.Y {
|
||||
@@ -145,9 +160,11 @@ func (g *RogueGame) look(wakeup bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if g.DoorStop && !g.Firstmove && passcount > 1 {
|
||||
g.Running = false
|
||||
}
|
||||
|
||||
if !g.Running || !g.Options.Jump {
|
||||
g.mvaddch(hero.Y, hero.X, PlayerCh)
|
||||
}
|
||||
@@ -165,26 +182,30 @@ func (g *RogueGame) tripCh(y, x int, ch byte) byte {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// eraseLamp erases the area shown by a lamp in a dark room
|
||||
// (misc.c erase_lamp).
|
||||
func (g *RogueGame) eraseLamp(pos Coord, rp *Room) {
|
||||
if !(g.Options.SeeFloor && rp.Flags&(Gone|Dark) == Dark &&
|
||||
!g.Player.On(Blind)) {
|
||||
if !g.Options.SeeFloor || rp.Flags&(Gone|Dark) != Dark ||
|
||||
g.Player.On(Blind) {
|
||||
return
|
||||
}
|
||||
|
||||
ey := pos.Y + 1
|
||||
ex := pos.X + 1
|
||||
|
||||
sy := pos.Y - 1
|
||||
for x := pos.X - 1; x <= ex; x++ {
|
||||
for y := sy; y <= ey; y++ {
|
||||
if y == g.Player.Pos.Y && x == g.Player.Pos.X {
|
||||
continue
|
||||
}
|
||||
|
||||
g.move(y, x)
|
||||
|
||||
if g.inch() == Floor {
|
||||
g.addch(' ')
|
||||
}
|
||||
@@ -198,6 +219,7 @@ func (g *RogueGame) showFloor() bool {
|
||||
if g.Player.Room.Flags&(Gone|Dark) == Dark && !g.Player.On(Blind) {
|
||||
return g.Options.SeeFloor
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -208,6 +230,7 @@ func (g *RogueGame) findObj(y, x int) *Object {
|
||||
return obj
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -217,34 +240,43 @@ func (g *RogueGame) eat() {
|
||||
if obj == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if obj.Kind != KindFood {
|
||||
if !g.Options.Terse {
|
||||
g.msg("ugh, you would get ill if you ate that")
|
||||
} else {
|
||||
g.msg("that's Inedible!")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
p := &g.Player
|
||||
if p.FoodLeft < 0 {
|
||||
p.FoodLeft = 0
|
||||
}
|
||||
|
||||
if p.FoodLeft += HungerTime - 200 + g.rnd(400); p.FoodLeft > StomachSize {
|
||||
p.FoodLeft = StomachSize
|
||||
}
|
||||
|
||||
p.HungryState = 0
|
||||
if obj == p.CurWeapon {
|
||||
p.CurWeapon = nil
|
||||
}
|
||||
if obj.Which == 1 {
|
||||
|
||||
switch {
|
||||
case obj.Which == 1:
|
||||
g.msg("my, that was a yummy %s", g.Fruit)
|
||||
} else if g.rnd(100) > 70 {
|
||||
case g.rnd(100) > 70:
|
||||
p.Stats.Exp++
|
||||
|
||||
g.msg("%s, this food tastes awful", g.chooseStr("bummer", "yuk"))
|
||||
g.checkLevel()
|
||||
} else {
|
||||
default:
|
||||
g.msg("%s, that tasted good", g.chooseStr("oh, wow", "yum"))
|
||||
}
|
||||
|
||||
g.leavePack(obj, false, false)
|
||||
}
|
||||
|
||||
@@ -252,19 +284,23 @@ func (g *RogueGame) eat() {
|
||||
// check_level).
|
||||
func (g *RogueGame) checkLevel() {
|
||||
p := &g.Player
|
||||
|
||||
var i int
|
||||
for i = 0; eLevels[i] != 0; i++ {
|
||||
if eLevels[i] > p.Stats.Exp {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
i++
|
||||
olevel := p.Stats.Lvl
|
||||
|
||||
p.Stats.Lvl = i
|
||||
if i > olevel {
|
||||
add := g.roll(i-olevel, 10)
|
||||
p.Stats.MaxHP += add
|
||||
p.Stats.HP += add
|
||||
|
||||
g.msg("welcome to level %d", i)
|
||||
}
|
||||
}
|
||||
@@ -275,15 +311,19 @@ func (g *RogueGame) chgStr(amt int) {
|
||||
if amt == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
p := &g.Player
|
||||
addStr(&p.Stats.Str, amt)
|
||||
|
||||
comp := p.Stats.Str
|
||||
if p.IsRing(Left, RingAddStrength) {
|
||||
addStr(&comp, -p.CurRing[Left].Bonus)
|
||||
}
|
||||
|
||||
if p.IsRing(Right, RingAddStrength) {
|
||||
addStr(&comp, -p.CurRing[Right].Bonus)
|
||||
}
|
||||
|
||||
if comp > p.MaxStats.Str {
|
||||
p.MaxStats.Str = comp
|
||||
}
|
||||
@@ -303,15 +343,20 @@ func (g *RogueGame) addHaste(potion bool) bool {
|
||||
p := &g.Player
|
||||
if p.On(Hasted) {
|
||||
g.NoCommand += g.rnd(8)
|
||||
|
||||
p.Flags.Clear(Awake | Hasted)
|
||||
g.Extinguish(DNohaste)
|
||||
g.msg("you faint from exhaustion")
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
p.Flags.Set(Hasted)
|
||||
|
||||
if potion {
|
||||
g.Fuse(DNohaste, 0, g.rnd(4)+4, After)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -330,10 +375,12 @@ func vowelstr(str string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch str[0] {
|
||||
case 'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U':
|
||||
return "n"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -343,15 +390,19 @@ func (g *RogueGame) isCurrent(obj *Object) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
p := &g.Player
|
||||
if obj == p.CurArmor || obj == p.CurWeapon ||
|
||||
obj == p.CurRing[Left] || obj == p.CurRing[Right] {
|
||||
if !g.Options.Terse {
|
||||
g.addmsg("That's already ")
|
||||
g.addmsgf("That's already ")
|
||||
}
|
||||
|
||||
g.msg("in use")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -367,8 +418,10 @@ func (g *RogueGame) getDir() bool {
|
||||
prompt = "which direction? "
|
||||
g.msg("%s", prompt)
|
||||
}
|
||||
|
||||
for {
|
||||
gotit := true
|
||||
|
||||
switch g.DirCh = g.readchar(); g.DirCh {
|
||||
case 'h', 'H':
|
||||
g.Delta = Coord{X: -1, Y: 0}
|
||||
@@ -389,30 +442,38 @@ func (g *RogueGame) getDir() bool {
|
||||
case Escape:
|
||||
g.LastDir = 0
|
||||
g.resetLast()
|
||||
|
||||
return false
|
||||
default:
|
||||
g.Msgs.Mpos = 0
|
||||
g.msg("%s", prompt)
|
||||
|
||||
gotit = false
|
||||
}
|
||||
|
||||
if gotit {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
g.DirCh = toLower(g.DirCh)
|
||||
g.LastDir = g.DirCh
|
||||
g.lastDelt = g.Delta
|
||||
}
|
||||
|
||||
if g.Player.On(Confused) && g.rnd(5) == 0 {
|
||||
for {
|
||||
g.Delta.Y = g.rnd(3) - 1
|
||||
|
||||
g.Delta.X = g.rnd(3) - 1
|
||||
if g.Delta.Y != 0 || g.Delta.X != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.Msgs.Mpos = 0
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -422,6 +483,7 @@ func (g *RogueGame) callIt(info *ObjInfo) {
|
||||
info.Guess = ""
|
||||
} else if info.Guess == "" {
|
||||
g.msg("%s", g.chooseTerse("call it: ", "what do you want to call it? "))
|
||||
|
||||
buf := ""
|
||||
if g.getStr(&buf, g.scr.Std) == Norm {
|
||||
if buf != "" {
|
||||
@@ -445,6 +507,7 @@ func (g *RogueGame) rndThing() byte {
|
||||
} else {
|
||||
i = g.rnd(len(thingList) - 1)
|
||||
}
|
||||
|
||||
return thingList[i]
|
||||
}
|
||||
|
||||
@@ -454,6 +517,7 @@ func (g *RogueGame) chooseStr(ts, ns string) string {
|
||||
if g.Player.On(Hallucinating) {
|
||||
return ts
|
||||
}
|
||||
|
||||
return ns
|
||||
}
|
||||
|
||||
@@ -463,8 +527,10 @@ func unctrl(ch byte) string {
|
||||
if ch < ' ' {
|
||||
return "^" + string(ch+'@')
|
||||
}
|
||||
|
||||
if ch == 0x7f {
|
||||
return "^?"
|
||||
}
|
||||
|
||||
return string(ch)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user