75 lines
2.4 KiB
Go
75 lines
2.4 KiB
Go
package westworldwithmessaging
|
|
|
|
// Elsa is the miner's wife, introduced in this section of the book.
|
|
// She's built the exact same way Miner is: embed *BaseGameEntity for
|
|
// her ID, own a *StateMachine[Elsa] and delegate all state
|
|
// bookkeeping to it. This is the payoff of making State[T] and
|
|
// StateMachine[T] generic earlier - Elsa reuses both unchanged,
|
|
// just with the blank slot filled in as Elsa instead of Miner.
|
|
type Elsa struct {
|
|
*BaseGameEntity
|
|
|
|
stateMachine *StateMachine[Elsa]
|
|
|
|
// cooking tracks whether there's already a stew in the oven, so
|
|
// CookStew.Enter doesn't put a second one in or send a second
|
|
// reminder message to herself.
|
|
cooking bool
|
|
}
|
|
|
|
// NewElsa sets up Elsa's state machine: DoHousework is her ordinary,
|
|
// everyday state, and WifesGlobalState is what checks - every single
|
|
// tick, no matter what she's currently doing - whether nature is
|
|
// calling. That's exactly why it has to be a global state rather
|
|
// than logic inside DoHousework: the book says "Elsa may feel the
|
|
// call of nature during any state and at any time," and a global
|
|
// state's Execute runs regardless of the current state.
|
|
func NewElsa(id int) *Elsa {
|
|
e := &Elsa{
|
|
BaseGameEntity: NewBaseGameEntity(id),
|
|
}
|
|
|
|
e.stateMachine = NewStateMachine(e)
|
|
e.stateMachine.SetCurrentState(DoHousework())
|
|
e.stateMachine.SetGlobalState(WifesGlobalState())
|
|
|
|
// Register with the entity manager automatically, same reasoning
|
|
// as NewMiner - one less manual step for every caller to remember.
|
|
EntityMgr.RegisterEntity(e)
|
|
|
|
return e
|
|
}
|
|
|
|
// FSM returns Elsa's state machine.
|
|
func (e *Elsa) FSM() *StateMachine[Elsa] {
|
|
return e.stateMachine
|
|
}
|
|
|
|
// Cooking reports whether there's already a stew in the oven.
|
|
func (e *Elsa) Cooking() bool {
|
|
return e.cooking
|
|
}
|
|
|
|
// SetCooking updates whether there's a stew in the oven.
|
|
func (e *Elsa) SetCooking(v bool) {
|
|
e.cooking = v
|
|
}
|
|
|
|
// Update satisfies the Entity interface (alongside the ID() method
|
|
// borrowed from BaseGameEntity) and just delegates to the state
|
|
// machine, same shape as Miner.Update.
|
|
func (e *Elsa) Update() {
|
|
e.stateMachine.Update()
|
|
}
|
|
|
|
// ChangeState forwards to the state machine, same as Miner.ChangeState.
|
|
func (e *Elsa) ChangeState(newState State[Elsa]) {
|
|
e.stateMachine.ChangeState(newState)
|
|
}
|
|
|
|
// HandleMessage forwards to the state machine, same as
|
|
// Miner.HandleMessage.
|
|
func (e *Elsa) HandleMessage(msg Telegram) bool {
|
|
return e.stateMachine.HandleMessage(msg)
|
|
}
|