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() }