Decompose daemons.go; daemon dispatch becomes a table (step 7)
runDaemon's switch becomes gameData.daemonHandlers (the C d_func function pointers restored as method expressions); stomach splits into stomachFaint/stomachDigest; visuals gains visualMonsters. daemons.go is complexity-clean. Behavior and RNG call order unchanged.
This commit is contained in:
145
game/daemons.go
145
game/daemons.go
@@ -5,38 +5,14 @@ package game
|
||||
|
||||
// runDaemon invokes the callback named by id (the call through d_func in C).
|
||||
func (g *RogueGame) runDaemon(id DaemonID, arg int) {
|
||||
switch id {
|
||||
case DRollwand:
|
||||
g.rollwand(arg)
|
||||
case DDoctor:
|
||||
g.doctor(arg)
|
||||
case DStomach:
|
||||
g.stomach(arg)
|
||||
case DRunners:
|
||||
g.runners(arg)
|
||||
case DSwander:
|
||||
g.swander(arg)
|
||||
case DNohaste:
|
||||
g.nohaste(arg)
|
||||
case DUnconfuse:
|
||||
g.unconfuse(arg)
|
||||
case DUnsee:
|
||||
g.unsee(arg)
|
||||
case DSight:
|
||||
g.sight(arg)
|
||||
case DVisuals:
|
||||
g.visuals(arg)
|
||||
case DComeDown:
|
||||
g.comeDown(arg)
|
||||
case DLand:
|
||||
g.land(arg)
|
||||
case DTurnSee:
|
||||
g.turnSee(arg != 0)
|
||||
default:
|
||||
// Callbacks are added to this switch as their subsystems are
|
||||
// ported; reaching one that isn't here is a porting bug.
|
||||
h := g.data.daemonHandlers[id]
|
||||
if h == nil {
|
||||
// Handlers are added to the table as their subsystems are
|
||||
// ported; reaching one that isn't there is a porting bug.
|
||||
panic("daemon not yet ported")
|
||||
}
|
||||
|
||||
h(g, arg)
|
||||
}
|
||||
|
||||
// doctor is the healing daemon that restores hit points after rest
|
||||
@@ -141,50 +117,9 @@ func (g *RogueGame) stomach(int) {
|
||||
|
||||
origHungry := p.HungryState
|
||||
if p.FoodLeft <= 0 {
|
||||
if p.FoodLeft--; p.FoodLeft < -StarveTime {
|
||||
g.death('s')
|
||||
}
|
||||
// the hero is fainting
|
||||
if g.NoCommand != 0 || g.rnd(5) != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
g.NoCommand += g.rnd(8) + 4
|
||||
p.HungryState = 3
|
||||
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("%s", g.chooseStr(
|
||||
"the munchies overpower your motor capabilities. ",
|
||||
"you feel too weak from lack of food. "))
|
||||
}
|
||||
|
||||
g.msg("%s", g.chooseStr("You freak out", "You faint"))
|
||||
g.stomachFaint()
|
||||
} else {
|
||||
oldfood := p.FoodLeft
|
||||
|
||||
amulet := 0
|
||||
if g.HasAmulet {
|
||||
amulet = 1
|
||||
}
|
||||
|
||||
p.FoodLeft -= g.ringEat(Left) + g.ringEat(Right) + 1 - amulet
|
||||
|
||||
if p.FoodLeft < MoreTime && oldfood >= MoreTime {
|
||||
p.HungryState = 2
|
||||
|
||||
g.msg("%s", g.chooseStr(
|
||||
"the munchies are interfering with your motor capabilities",
|
||||
"you are starting to feel weak"))
|
||||
} else if p.FoodLeft < 2*MoreTime && oldfood >= 2*MoreTime {
|
||||
p.HungryState = 1
|
||||
|
||||
if g.Options.Terse {
|
||||
g.msg("%s", g.chooseStr("getting the munchies", "getting hungry"))
|
||||
} else {
|
||||
g.msg("%s", g.chooseStr("you are getting the munchies",
|
||||
"you are starting to get hungry"))
|
||||
}
|
||||
}
|
||||
g.stomachDigest()
|
||||
}
|
||||
|
||||
if p.HungryState != origHungry {
|
||||
@@ -196,6 +131,61 @@ func (g *RogueGame) stomach(int) {
|
||||
}
|
||||
}
|
||||
|
||||
// stomachFaint starves and possibly faints an empty-stomached hero (the
|
||||
// no-food arm of daemons.c stomach).
|
||||
func (g *RogueGame) stomachFaint() {
|
||||
p := &g.Player
|
||||
if p.FoodLeft--; p.FoodLeft < -StarveTime {
|
||||
g.death('s')
|
||||
}
|
||||
// the hero is fainting
|
||||
if g.NoCommand != 0 || g.rnd(5) != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
g.NoCommand += g.rnd(8) + 4
|
||||
p.HungryState = 3
|
||||
|
||||
if !g.Options.Terse {
|
||||
g.addmsgf("%s", g.chooseStr(
|
||||
"the munchies overpower your motor capabilities. ",
|
||||
"you feel too weak from lack of food. "))
|
||||
}
|
||||
|
||||
g.msg("%s", g.chooseStr("You freak out", "You faint"))
|
||||
}
|
||||
|
||||
// stomachDigest burns food and reports growing hunger (the fed arm of
|
||||
// daemons.c stomach).
|
||||
func (g *RogueGame) stomachDigest() {
|
||||
p := &g.Player
|
||||
oldfood := p.FoodLeft
|
||||
|
||||
amulet := 0
|
||||
if g.HasAmulet {
|
||||
amulet = 1
|
||||
}
|
||||
|
||||
p.FoodLeft -= g.ringEat(Left) + g.ringEat(Right) + 1 - amulet
|
||||
|
||||
if p.FoodLeft < MoreTime && oldfood >= MoreTime {
|
||||
p.HungryState = 2
|
||||
|
||||
g.msg("%s", g.chooseStr(
|
||||
"the munchies are interfering with your motor capabilities",
|
||||
"you are starting to feel weak"))
|
||||
} else if p.FoodLeft < 2*MoreTime && oldfood >= 2*MoreTime {
|
||||
p.HungryState = 1
|
||||
|
||||
if g.Options.Terse {
|
||||
g.msg("%s", g.chooseStr("getting the munchies", "getting hungry"))
|
||||
} else {
|
||||
g.msg("%s", g.chooseStr("you are getting the munchies",
|
||||
"you are starting to get hungry"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comeDown takes the hero down off her acid trip (daemons.c come_down).
|
||||
func (g *RogueGame) comeDown(int) {
|
||||
p := &g.Player
|
||||
@@ -242,7 +232,6 @@ func (g *RogueGame) comeDown(int) {
|
||||
// visuals changes the characters for the player while hallucinating
|
||||
// (daemons.c visuals).
|
||||
func (g *RogueGame) visuals(int) {
|
||||
p := &g.Player
|
||||
if !g.After || (g.Running && g.Options.Jump) {
|
||||
return
|
||||
}
|
||||
@@ -259,7 +248,13 @@ func (g *RogueGame) visuals(int) {
|
||||
}
|
||||
|
||||
// change the monsters
|
||||
seemonst := p.On(SenseMonsters)
|
||||
g.visualMonsters()
|
||||
}
|
||||
|
||||
// visualMonsters redraws the monsters through the hallucination (the
|
||||
// monster loop of daemons.c visuals).
|
||||
func (g *RogueGame) visualMonsters() {
|
||||
seemonst := g.Player.On(SenseMonsters)
|
||||
|
||||
for _, tp := range g.Level.Monsters {
|
||||
g.move(tp.Pos.Y, tp.Pos.X)
|
||||
|
||||
@@ -151,6 +151,10 @@ type gameData struct {
|
||||
// trapHandlers dispatches each sprung trap to its effect method:
|
||||
// the cases of the move.c be_trapped switch.
|
||||
trapHandlers [NumTrapTypes]func(g *RogueGame, tc Coord)
|
||||
|
||||
// daemonHandlers dispatches DaemonIDs to their callbacks: the C
|
||||
// d_func function pointers (daemons.c / daemon.c).
|
||||
daemonHandlers [DTurnSee + 1]func(g *RogueGame, arg int)
|
||||
}
|
||||
|
||||
// ripWall is the repeated blank wall line of the tombstone art.
|
||||
@@ -826,6 +830,24 @@ func newGameData() *gameData {
|
||||
TrapRust: (*RogueGame).trapRust,
|
||||
TrapMystery: (*RogueGame).trapMystery,
|
||||
},
|
||||
|
||||
daemonHandlers: [DTurnSee + 1]func(*RogueGame, int){
|
||||
DRollwand: (*RogueGame).rollwand,
|
||||
DDoctor: (*RogueGame).doctor,
|
||||
DStomach: (*RogueGame).stomach,
|
||||
DRunners: (*RogueGame).runners,
|
||||
DSwander: (*RogueGame).swander,
|
||||
DNohaste: (*RogueGame).nohaste,
|
||||
DUnconfuse: (*RogueGame).unconfuse,
|
||||
DUnsee: (*RogueGame).unsee,
|
||||
DSight: (*RogueGame).sight,
|
||||
DVisuals: (*RogueGame).visuals,
|
||||
DComeDown: (*RogueGame).comeDown,
|
||||
DLand: (*RogueGame).land,
|
||||
DTurnSee: func(g *RogueGame, arg int) {
|
||||
g.turnSee(arg != 0)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user