Decompose score and wakeMonster (refactor step 7)

score splits into scoreInsert/scoreLines/showScores; wakeMonster gains
meanWakes/medusaCatches/medusaGaze predicates and effect. Behavior and
RNG call order unchanged.
This commit is contained in:
2026-07-22 22:01:03 +07:00
parent 3e1c30c787
commit 8895db530d
2 changed files with 144 additions and 93 deletions

View File

@@ -124,22 +124,65 @@ func (g *RogueGame) wakeMonster(y, x int) *Monster {
panic("can't find monster in wake_monster") panic("can't find monster in wake_monster")
} }
ch := tp.Type
// Every time he sees a mean monster, it might start chasing him // Every time he sees a mean monster, it might start chasing him
if !tp.On(Awake) && g.rnd(3) != 0 && tp.On(Mean) && !tp.On(Held) && if g.meanWakes(tp) {
!p.IsWearing(RingStealth) && !p.On(Levitating) {
tp.Dest = &p.Pos tp.Dest = &p.Pos
tp.Flags.Set(Awake) tp.Flags.Set(Awake)
} }
if ch == 'M' && !p.On(Blind) && !p.On(Hallucinating) && if g.medusaCatches(tp) {
!tp.On(Found) && !tp.On(Cancelled) && tp.On(Awake) { g.medusaGaze(tp, y, x)
}
// Let greedy ones guard gold
if tp.On(Greedy) && !tp.On(Awake) {
tp.Flags.Set(Awake)
if p.Room.GoldVal != 0 {
tp.Dest = &p.Room.Gold
} else {
tp.Dest = &p.Pos
}
}
return tp
}
// meanWakes decides whether a sleeping mean monster starts the chase
// (monsters.c wake_monster). The waking roll happens for any sleeping
// monster, as in C.
func (g *RogueGame) meanWakes(tp *Monster) bool {
p := &g.Player
return !tp.On(Awake) && g.rnd(3) != 0 && tp.On(Mean) && !tp.On(Held) &&
!p.IsWearing(RingStealth) && !p.On(Levitating)
}
// medusaCatches reports an uncovered, awake medusa the hero can see
// (monsters.c wake_monster).
func (g *RogueGame) medusaCatches(tp *Monster) bool {
p := &g.Player
return tp.Type == 'M' && !p.On(Blind) && !p.On(Hallucinating) &&
!tp.On(Found) && !tp.On(Cancelled) && tp.On(Awake)
}
// medusaGaze confuses the hero when the medusa's gaze lands (the M
// block of monsters.c wake_monster).
func (g *RogueGame) medusaGaze(tp *Monster, y, x int) {
p := &g.Player
rp := p.Room rp := p.Room
if (rp != nil && !rp.Flags.Has(Dark)) || if (rp == nil || rp.Flags.Has(Dark)) &&
distance(y, x, p.Pos.Y, p.Pos.X) < LampDist { distance(y, x, p.Pos.Y, p.Pos.X) >= LampDist {
return
}
tp.Flags.Set(Found) tp.Flags.Set(Found)
if !g.save(VsMagic) { if g.save(VsMagic) {
return
}
if p.On(Confused) { if p.On(Confused) {
g.Lengthen(DUnconfuse, g.spread(HuhDuration)) g.Lengthen(DUnconfuse, g.spread(HuhDuration))
} else { } else {
@@ -156,21 +199,6 @@ func (g *RogueGame) wakeMonster(y, x int) *Monster {
} }
g.msg("s gaze has confused you") g.msg("s gaze has confused you")
}
}
}
// Let greedy ones guard gold
if tp.On(Greedy) && !tp.On(Awake) {
tp.Flags.Set(Awake)
if p.Room.GoldVal != 0 {
tp.Dest = &p.Room.Gold
} else {
tp.Dest = &p.Pos
}
}
return tp
} }
// givePack gives a pack to a monster if it deserves one (monsters.c // givePack gives a pack to a monster if it deserves one (monsters.c

View File

@@ -107,8 +107,23 @@ func (g *RogueGame) score(amount, flags int, monst byte) {
topTen := g.rdScore() topTen := g.rdScore()
// Insert her in list if need be // Insert her in list if need be
ins := -1 ins := -1
if !g.NoScore && flags >= 0 { if !g.NoScore && flags >= 0 {
ins = g.scoreInsert(topTen, amount, flags, monst)
}
lines, highlight := g.scoreLines(topTen, ins)
g.showScores(lines, highlight)
// Update the list file
if ins >= 0 {
g.wrScore(topTen)
}
}
// scoreInsert slots the new score into the top ten, honoring the
// one-score-per-losing-uid rule; -1 means it did not place (the
// insertion half of rip.c score).
func (g *RogueGame) scoreInsert(topTen []ScoreEnt, amount, flags int, monst byte) int {
uid := os.Getuid() uid := os.Getuid()
scp := len(topTen) scp := len(topTen)
@@ -126,7 +141,10 @@ func (g *RogueGame) score(amount, flags int, monst byte) {
} }
} }
if scp < len(topTen) { if scp >= len(topTen) {
return -1
}
sc2 := len(topTen) - 1 sc2 := len(topTen) - 1
if flags != 2 && !g.AllScore { if flags != 2 && !g.AllScore {
for i := scp; i < len(topTen); i++ { for i := scp; i < len(topTen); i++ {
@@ -157,11 +175,13 @@ func (g *RogueGame) score(amount, flags int, monst byte) {
Level: lvl, Level: lvl,
Time: time.Now().Unix(), Time: time.Now().Unix(),
} }
ins = scp
}
}
// Build the list display return scp
}
// scoreLines formats the scoreboard, noting which display line holds
// the freshly inserted score (the display half of rip.c score).
func (g *RogueGame) scoreLines(topTen []ScoreEnt, ins int) ([]string, int) {
label := "Rogueists" label := "Rogueists"
if g.AllScore { if g.AllScore {
label = "Scores" label = "Scores"
@@ -194,7 +214,20 @@ func (g *RogueGame) score(amount, flags int, monst byte) {
lines = append(lines, line) lines = append(lines, line)
} }
if g.scr != nil && g.scr.term != nil { return lines, highlight
}
// showScores prints the scoreboard on the screen when there is one,
// else to standard output (rip.c score).
func (g *RogueGame) showScores(lines []string, highlight int) {
if g.scr == nil || g.scr.term == nil {
for _, line := range lines {
_, _ = fmt.Fprintln(os.Stdout, line) // CLI output
}
return
}
g.clear() g.clear()
for i, line := range lines { for i, line := range lines {
@@ -210,16 +243,6 @@ func (g *RogueGame) score(amount, flags int, monst byte) {
} }
g.refresh() g.refresh()
} else {
for _, line := range lines {
_, _ = fmt.Fprintln(os.Stdout, line) // CLI output
}
}
// Update the list file
if ins >= 0 {
g.wrScore(topTen)
}
} }
// ShowScores implements the -s command line option: print the scoreboard // ShowScores implements the -s command line option: print the scoreboard