diff options
Diffstat (limited to 'go/ui/freeMapControl.go')
| -rw-r--r-- | go/ui/freeMapControl.go | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/go/ui/freeMapControl.go b/go/ui/freeMapControl.go new file mode 100644 index 00000000..574208d2 --- /dev/null +++ b/go/ui/freeMapControl.go @@ -0,0 +1,204 @@ +package ui + +import ( + "log" + + "github.com/hajimehoshi/ebiten/v2" + + "muhq.space/muhqs-game/go/game" +) + +type pannedPermanent struct { + WidgetBase + p game.Permanent +} + +func NewPannedPermanent(x, y int, p game.Permanent) *pannedPermanent { + pp := &pannedPermanent{NewWidgetBase(x, y, PERMANENT_WIDTH, PERMANENT_HEIGHT), p} + pp.renderImpl = func() *ebiten.Image { return pp.render() } + log.Printf("create new panned permanent") + return pp +} + +func (pp *pannedPermanent) move(pan *pan) { + pp.X, pp.Y = ebiten.TouchPosition(pan.id) +} + +func (pp *pannedPermanent) render() *ebiten.Image { + if pp.img == nil { + pp.img = getPermanentSymbol(pp.p, 0) + } + return pp.img +} + +type FreeMapControl struct { + Collection + Mv *MapView + gameState *game.LocalState + storeView *PocList + storesOnMap bool + choice Widget + pannedPermanent *pannedPermanent +} + +func NewFreeMapControl(g *game.LocalState) *FreeMapControl { + mc := &FreeMapControl{gameState: g} + mc.Mv = NewMapView(g) + mc.Mv.RegisterHandler("click", func(x, y int) { + if obj := mc.Mv.FindObjectAt(x, y); obj != nil { + mc.handleSelection(obj, x, y) + } + }) + mc.AddWidget(mc.Mv) + + storeTiles := g.Map().FilterTiles(func(t *game.Tile) bool { return t.Type == game.TileTypes.Store }) + mc.storesOnMap = len(storeTiles) > 0 + + return mc +} + +func (mc *FreeMapControl) showStore(x, y int, tile *game.Tile) { + mc.storeView = NewPocList(x, y, mc.gameState.Map().StoreOn(tile.Position)) + mc.AddWidget(mc.storeView) +} + +func (mc *FreeMapControl) hideStore() { + mc.RemoveWidget(mc.storeView) + mc.storeView = nil +} + +func (mc *FreeMapControl) addChoice(choice Widget) { + if mc.choice != nil { + mc.removeChoice() + } + mc.choice = choice + mc.AddWidget(choice) +} + +func (mc *FreeMapControl) removeChoice() { + mc.RemoveWidget(mc.choice) + mc.choice = nil +} + +func (mc *FreeMapControl) addCreatePermanentChoice(x, y int, kind game.CardType, tile *game.Tile) { + choices := []interface{}{"undefined"} + // TODO: add all fitting choices from the player decks + onclick := func(c *Choice, x, y int) { + mc.Mv.ClearPermanentsHighlights() + mc.removeChoice() + // choice := choices[c.GetChoosen(x, y)] + // mc.gameState.NewPerm(choice, tile) + } + mc.addChoice(NewChoice(x, y, choices, onclick)) +} + +func (mc *FreeMapControl) addPermanentChoice(x, y int, p game.Permanent) { + choices := []interface{}{"move", "destroy"} + onclick := func(c *Choice, x, y int) { + mc.Mv.ClearPermanentsHighlights() + mc.removeChoice() + switch choices[c.GetChoosen(x, y)] { + case "move": + case "destroy": + mc.gameState.RemovePermanent(p) + } + } + mc.addChoice(NewChoice(x, y, choices, onclick)) +} + +func (mc *FreeMapControl) handleSelection(obj interface{}, x, y int) { + // Hide the store if the user selected something else + if mc.storeView != nil { + mc.hideStore() + } + + switch obj := obj.(type) { + case *game.Tile: + // TODO: incoorperate the store view intobthe tile choice + if mc.storesOnMap && obj.Type == game.TileTypes.Store { + + mc.showStore(x, y, obj) + } else if obj.Permanent != nil { + // Permanent action + mc.Mv.AddHighlightPermanent(obj.Permanent, HighlightSelectionColor) + mc.addPermanentChoice(x, y, obj.Permanent) + } else { + mc.Mv.ClearTileHighlights() + mc.Mv.AddHighlightTile(obj, HighlightSelectionColor) + // Create permanent + choices := []interface{}{"unit", "artifact", "neutralize"} + onclick := func(c *Choice, x, y int) { + mc.Mv.ClearTileHighlights() + mc.removeChoice() + switch choices[c.GetChoosen(x, y)] { + // TODO: create permanents + case "unit": + mc.addCreatePermanentChoice(x, y, game.CardTypes.Unit, obj) + case "artifact": + mc.addCreatePermanentChoice(x, y, game.CardTypes.Artifact, obj) + case "neutralize": + obj.Neutralize() + mc.Mv.ForceRedraw() + mc.removeChoice() + log.Printf("Neutralize %p at\n", obj, obj.Position) + } + } + mc.addChoice(NewChoice(x, y, choices, onclick)) + + } + log.Printf("%s selected at %d %d\n", obj, x, y) + case game.Permanent: + mc.addPermanentChoice(x, y, obj) + } +} + +func (mc *FreeMapControl) handlePanning() { + pan := TouchManager.pan + if pan != nil { + if mc.pannedPermanent != nil { + mc.pannedPermanent.move(pan) + } else if perm, ok := mc.Mv.FindObjectAt(pan.originX, pan.originY).(game.Permanent); ok { + x, y := ebiten.TouchPosition(pan.id) + mc.pannedPermanent = NewPannedPermanent(x, y, perm) + mc.AddWidget(mc.pannedPermanent) + } + } else if mc.pannedPermanent != nil { + pp := mc.pannedPermanent + o := mc.Mv.FindObjectAt(pp.X, pp.Y) + if tile, ok := o.(*game.Tile); ok { + log.Printf("drop panned permanet on %s\n", tile) + mc.gameState.MovePermanent(pp.p, tile) + mc.Mv.ForceRedraw() + } + mc.RemoveWidget(mc.pannedPermanent) + mc.pannedPermanent = nil + } +} + +func (mc *FreeMapControl) Update() error { + c := mc.choice + if err := mc.Collection.Update(); err != nil { + return err + } + + // The Choice has already handled the Update + if c != mc.choice { + return nil + } + + mc.handlePanning() + + return nil +} + +func (mc *FreeMapControl) Scale(s float64) { + mc.Mv.Scale(s) +} + +// Hide and cancel all control elements +func (mc *FreeMapControl) CancelControl() { + mc.Mv.ClearPermanentsHighlights() + mc.Mv.ClearTileHighlights() + mc.hideStore() + mc.removeChoice() +} |
