diff --git a/game/potions.go b/game/potions.go index bf6ffc3..8d39e2b 100644 --- a/game/potions.go +++ b/game/potions.go @@ -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() { diff --git a/game/tables.go b/game/tables.go index bb2c4fc..3f44b0e 100644 --- a/game/tables.go +++ b/game/tables.go @@ -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, + }, } }