Convert quaff to a per-potion handler table (refactor step 7)

The quaff switch becomes gameData.quaffHandlers, a method-expression
table indexed by PotionKind; each case body moved verbatim into a
quaff* method. Effect order and RNG call sequence unchanged.
This commit is contained in:
2026-07-07 02:44:33 +02:00
parent acef593288
commit cc025eb808
2 changed files with 199 additions and 139 deletions

View File

@@ -41,145 +41,8 @@ func (g *RogueGame) quaff() {
g.leavePack(obj, false, false)
switch obj.PotionKind() {
case PotionConfusion:
g.applyPotionFuse(PotionConfusion, !trip)
case PotionPoison:
g.Items.Potions[PotionPoison].Know = true
if p.IsWearing(RingSustainStrength) {
g.msg("you feel momentarily sick")
} else {
g.changeStrength(-(g.rnd(3) + 1))
g.msg("you feel very sick now")
g.comeDown(0)
}
case PotionHealing:
g.Items.Potions[PotionHealing].Know = true
if p.Stats.HP += g.roll(p.Stats.Lvl, 4); p.Stats.HP > p.Stats.MaxHP {
p.Stats.MaxHP++
p.Stats.HP = p.Stats.MaxHP
}
g.sight(0)
g.msg("you begin to feel better")
case PotionGainStrength:
g.Items.Potions[PotionGainStrength].Know = true
g.changeStrength(1)
g.msg("you feel stronger, now. What bulging muscles!")
case PotionDetectMonsters:
p.Flags.Set(SenseMonsters)
g.Fuse(DTurnSee, 1, HuhDuration, After)
if !g.turnSee(false) {
g.msg("you have a %s feeling for a moment, then it passes",
g.chooseStr("normal", "strange"))
}
case PotionDetectMagic:
// Potion of magic detection. Show the potions and scrolls
show := false
if len(g.Level.Objects) > 0 {
g.scr.Hw.Clear()
for _, tp := range g.Level.Objects {
if g.isMagic(tp) {
show = true
g.scr.Hw.MvAddCh(tp.Pos.Y, tp.Pos.X, Magic)
g.Items.Potions[PotionDetectMagic].Know = true
}
}
for _, mp := range g.Level.Monsters {
for _, tp := range mp.Pack {
if g.isMagic(tp) {
show = true
g.scr.Hw.MvAddCh(mp.Pos.Y, mp.Pos.X, Magic)
}
}
}
}
if show {
g.Items.Potions[PotionDetectMagic].Know = true
g.showWin("You sense the presence of magic on this level.--More--")
} else {
g.msg("you have a %s feeling for a moment, then it passes",
g.chooseStr("normal", "strange"))
}
case PotionLSD:
if !trip {
if p.On(SenseMonsters) {
g.turnSee(false)
}
g.StartDaemon(DVisuals, 0, Before)
g.SeenStairs = g.seenStairs()
}
g.applyPotionFuse(PotionLSD, true)
case PotionSeeInvisible:
show := p.On(CanSeeInvisible)
g.applyPotionFuse(PotionSeeInvisible, false)
if !show {
g.invisOn()
}
g.sight(0)
case PotionRaiseLevel:
g.Items.Potions[PotionRaiseLevel].Know = true
g.msg("you suddenly feel much more skillful")
g.raiseLevel()
case PotionExtraHealing:
g.Items.Potions[PotionExtraHealing].Know = true
if p.Stats.HP += g.roll(p.Stats.Lvl, 8); p.Stats.HP > p.Stats.MaxHP {
if p.Stats.HP > p.Stats.MaxHP+p.Stats.Lvl+1 {
p.Stats.MaxHP++
}
p.Stats.MaxHP++
p.Stats.HP = p.Stats.MaxHP
}
g.sight(0)
g.comeDown(0)
g.msg("you begin to feel much better")
case PotionHaste:
g.Items.Potions[PotionHaste].Know = true
g.After = false
if g.addHaste(true) {
g.msg("you feel yourself moving much faster")
}
case PotionRestoreStrength:
if p.IsRing(Left, RingAddStrength) {
addStr(&p.Stats.Str, -p.CurRing[Left].Bonus)
}
if p.IsRing(Right, RingAddStrength) {
addStr(&p.Stats.Str, -p.CurRing[Right].Bonus)
}
if p.Stats.Str < p.MaxStats.Str {
p.Stats.Str = p.MaxStats.Str
}
if p.IsRing(Left, RingAddStrength) {
addStr(&p.Stats.Str, p.CurRing[Left].Bonus)
}
if p.IsRing(Right, RingAddStrength) {
addStr(&p.Stats.Str, p.CurRing[Right].Bonus)
}
g.msg("hey, this tastes great. It make you feel warm all over")
case PotionBlindness:
g.applyPotionFuse(PotionBlindness, true)
case PotionLevitation:
g.applyPotionFuse(PotionLevitation, true)
if h := g.data.quaffHandlers[obj.PotionKind()]; h != nil {
h(g, trip)
}
g.status()
@@ -187,6 +50,181 @@ func (g *RogueGame) quaff() {
g.callIt(&g.Items.Potions[obj.Which])
}
// The per-potion effect handlers, dispatched through
// gameData.quaffHandlers. Each is one case of the C quaff switch.
func (g *RogueGame) quaffConfusion(trip bool) {
g.applyPotionFuse(PotionConfusion, !trip)
}
func (g *RogueGame) quaffPoison(bool) {
g.Items.Potions[PotionPoison].Know = true
if g.Player.IsWearing(RingSustainStrength) {
g.msg("you feel momentarily sick")
} else {
g.changeStrength(-(g.rnd(3) + 1))
g.msg("you feel very sick now")
g.comeDown(0)
}
}
func (g *RogueGame) quaffHealing(bool) {
p := &g.Player
g.Items.Potions[PotionHealing].Know = true
if p.Stats.HP += g.roll(p.Stats.Lvl, 4); p.Stats.HP > p.Stats.MaxHP {
p.Stats.MaxHP++
p.Stats.HP = p.Stats.MaxHP
}
g.sight(0)
g.msg("you begin to feel better")
}
func (g *RogueGame) quaffGainStrength(bool) {
g.Items.Potions[PotionGainStrength].Know = true
g.changeStrength(1)
g.msg("you feel stronger, now. What bulging muscles!")
}
func (g *RogueGame) quaffDetectMonsters(bool) {
g.Player.Flags.Set(SenseMonsters)
g.Fuse(DTurnSee, 1, HuhDuration, After)
if !g.turnSee(false) {
g.msg("you have a %s feeling for a moment, then it passes",
g.chooseStr("normal", "strange"))
}
}
func (g *RogueGame) quaffDetectMagic(bool) {
// Potion of magic detection. Show the potions and scrolls
show := false
if len(g.Level.Objects) > 0 {
g.scr.Hw.Clear()
for _, tp := range g.Level.Objects {
if g.isMagic(tp) {
show = true
g.scr.Hw.MvAddCh(tp.Pos.Y, tp.Pos.X, Magic)
g.Items.Potions[PotionDetectMagic].Know = true
}
}
for _, mp := range g.Level.Monsters {
for _, tp := range mp.Pack {
if g.isMagic(tp) {
show = true
g.scr.Hw.MvAddCh(mp.Pos.Y, mp.Pos.X, Magic)
}
}
}
}
if show {
g.Items.Potions[PotionDetectMagic].Know = true
g.showWin("You sense the presence of magic on this level.--More--")
} else {
g.msg("you have a %s feeling for a moment, then it passes",
g.chooseStr("normal", "strange"))
}
}
func (g *RogueGame) quaffLSD(trip bool) {
p := &g.Player
if !trip {
if p.On(SenseMonsters) {
g.turnSee(false)
}
g.StartDaemon(DVisuals, 0, Before)
g.SeenStairs = g.seenStairs()
}
g.applyPotionFuse(PotionLSD, true)
}
func (g *RogueGame) quaffSeeInvisible(bool) {
show := g.Player.On(CanSeeInvisible)
g.applyPotionFuse(PotionSeeInvisible, false)
if !show {
g.invisOn()
}
g.sight(0)
}
func (g *RogueGame) quaffRaiseLevel(bool) {
g.Items.Potions[PotionRaiseLevel].Know = true
g.msg("you suddenly feel much more skillful")
g.raiseLevel()
}
func (g *RogueGame) quaffExtraHealing(bool) {
p := &g.Player
g.Items.Potions[PotionExtraHealing].Know = true
if p.Stats.HP += g.roll(p.Stats.Lvl, 8); p.Stats.HP > p.Stats.MaxHP {
if p.Stats.HP > p.Stats.MaxHP+p.Stats.Lvl+1 {
p.Stats.MaxHP++
}
p.Stats.MaxHP++
p.Stats.HP = p.Stats.MaxHP
}
g.sight(0)
g.comeDown(0)
g.msg("you begin to feel much better")
}
func (g *RogueGame) quaffHaste(bool) {
g.Items.Potions[PotionHaste].Know = true
g.After = false
if g.addHaste(true) {
g.msg("you feel yourself moving much faster")
}
}
func (g *RogueGame) quaffRestoreStrength(bool) {
p := &g.Player
if p.IsRing(Left, RingAddStrength) {
addStr(&p.Stats.Str, -p.CurRing[Left].Bonus)
}
if p.IsRing(Right, RingAddStrength) {
addStr(&p.Stats.Str, -p.CurRing[Right].Bonus)
}
if p.Stats.Str < p.MaxStats.Str {
p.Stats.Str = p.MaxStats.Str
}
if p.IsRing(Left, RingAddStrength) {
addStr(&p.Stats.Str, p.CurRing[Left].Bonus)
}
if p.IsRing(Right, RingAddStrength) {
addStr(&p.Stats.Str, p.CurRing[Right].Bonus)
}
g.msg("hey, this tastes great. It make you feel warm all over")
}
func (g *RogueGame) quaffBlindness(bool) {
g.applyPotionFuse(PotionBlindness, true)
}
func (g *RogueGame) quaffLevitation(bool) {
g.applyPotionFuse(PotionLevitation, true)
}
// raiseLevel: the guy just magically went up a level (potions.c
// raise_level).
func (g *RogueGame) raiseLevel() {

View File

@@ -122,6 +122,11 @@ type gameData struct {
// scoreReasons is the rip.c reason[] scoreboard strings.
scoreReasons [4]string
// quaffHandlers dispatches each potion kind to its effect method:
// the cases of the potions.c quaff switch. The bool is trip — was
// the hero hallucinating when the potion went down.
quaffHandlers [NumPotionTypes]func(g *RogueGame, trip bool)
}
// ripWall is the repeated blank wall line of the tombstone art.
@@ -587,6 +592,23 @@ func newGameData() *gameData {
"A total winner",
"killed with Amulet",
},
quaffHandlers: [NumPotionTypes]func(*RogueGame, bool){
PotionConfusion: (*RogueGame).quaffConfusion,
PotionLSD: (*RogueGame).quaffLSD,
PotionPoison: (*RogueGame).quaffPoison,
PotionGainStrength: (*RogueGame).quaffGainStrength,
PotionSeeInvisible: (*RogueGame).quaffSeeInvisible,
PotionHealing: (*RogueGame).quaffHealing,
PotionDetectMonsters: (*RogueGame).quaffDetectMonsters,
PotionDetectMagic: (*RogueGame).quaffDetectMagic,
PotionRaiseLevel: (*RogueGame).quaffRaiseLevel,
PotionExtraHealing: (*RogueGame).quaffExtraHealing,
PotionHaste: (*RogueGame).quaffHaste,
PotionRestoreStrength: (*RogueGame).quaffRestoreStrength,
PotionBlindness: (*RogueGame).quaffBlindness,
PotionLevitation: (*RogueGame).quaffLevitation,
},
}
}