Skip to content

Commit

Permalink
tower: Rebalanced towers and added the new assets and updates
Browse files Browse the repository at this point in the history
  • Loading branch information
xescugc committed Jun 6, 2024
1 parent 4f4d3dc commit 7bcde6c
Show file tree
Hide file tree
Showing 16 changed files with 627 additions and 328 deletions.
17 changes: 9 additions & 8 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package action
import (
"time"

"github.com/xescugc/maze-wars/tower"
"github.com/xescugc/maze-wars/unit"
"github.com/xescugc/maze-wars/utils"
"github.com/xescugc/maze-wars/utils/graph"
Expand Down Expand Up @@ -468,8 +467,8 @@ type SyncStateTowerPayload struct {
Type string
LineID int
PlayerID string
Stats tower.Stats
Level int

LastAttack time.Time
}

type SyncStateUnitPayload struct {
Expand Down Expand Up @@ -554,16 +553,18 @@ func NewUpdateUnit(pid, t string) *Action {
}

type UpdateTowerPayload struct {
TowerID string
PlayerID string
TowerID string
PlayerID string
TowerType string
}

func NewUpdateTower(pid, tid string) *Action {
func NewUpdateTower(pid, tid, tt string) *Action {
return &Action{
Type: UpdateTower,
UpdateTower: &UpdateTowerPayload{
TowerID: tid,
PlayerID: pid,
TowerID: tid,
PlayerID: pid,
TowerType: tt,
},
}
}
Expand Down
6 changes: 3 additions & 3 deletions assets/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ var MonkeyBoxerFaceset_png []byte

// END UNITS

//go:embed towers.png
var Towers_png []byte

//go:embed TilesetHouse.png
var TilesetHouse_png []byte

Expand Down Expand Up @@ -102,9 +105,6 @@ var YesButton_png []byte
//go:embed NoButton.png
var NoButton_png []byte

//go:embed towers.json
var Towers_json []byte

//go:embed units.json
var Units_json []byte

Expand Down
16 changes: 0 additions & 16 deletions assets/towers.json

This file was deleted.

Binary file added assets/towers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions client/game/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ func (ac *ActionDispatcher) GoHome() {
}

// GoHome will move the camera to the current player home line
func (ac *ActionDispatcher) UpdateTower(pid, tid string) {
uta := action.NewUpdateTower(pid, tid)
func (ac *ActionDispatcher) UpdateTower(pid, tid, tt string) {
uta := action.NewUpdateTower(pid, tid, tt)
ac.wsSend(uta)
ac.Dispatch(uta)
}
149 changes: 107 additions & 42 deletions client/game/hud.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ type HUDStore struct {
bottomLeftContainer *widget.Container
towerMenuContainer *widget.Container
towerRemoveToolTip *widget.Text
towerUpdateToolTip *widget.Text
towerUpdateButton *widget.Button
towerUpdateToolTip1 *widget.Text
towerUpdateButton1 *widget.Button
towerUpdateToolTip2 *widget.Text
towerUpdateButton2 *widget.Button
}

// HUDState stores the HUD state
Expand All @@ -82,7 +84,12 @@ var (
towerKeybinds = make(map[string]ebiten.Key)

removeTowerKeybind = ebiten.KeyD
updateTowerKeybind = ebiten.KeyF

updateTowerKeybind1 = ebiten.KeyZ
updateTowerKeybind2 = ebiten.KeyX

rangeTowerKeybind = ebiten.KeyQ
meleeTowerKeybind = ebiten.KeyW
)

func init() {
Expand All @@ -95,14 +102,8 @@ func init() {
unitKeybinds[u.Type.String()] = k
}

for _, t := range tower.Towers {
var k ebiten.Key
err := k.UnmarshalText([]byte(t.Keybind))
if err != nil {
panic(err)
}
towerKeybinds[t.Type.String()] = k
}
towerKeybinds[tower.Range1.String()] = rangeTowerKeybind
towerKeybinds[tower.Melee1.String()] = meleeTowerKeybind
}

// NewHUDStore creates a new HUDStore with the Dispatcher d and the Game g
Expand Down Expand Up @@ -199,8 +200,12 @@ func (hs *HUDStore) Update() error {
actionDispatcher.RemoveTower(cp.ID, hst.OpenTowerMenu.ID)
actionDispatcher.CloseTowerMenu()
}
if inpututil.IsKeyJustPressed(updateTowerKeybind) {
actionDispatcher.UpdateTower(cp.ID, hst.OpenTowerMenu.ID)
tw := tower.Towers[hst.OpenTowerMenu.Type]
if len(tw.Updates) >= 1 && inpututil.IsKeyJustPressed(updateTowerKeybind1) {
actionDispatcher.UpdateTower(cp.ID, hst.OpenTowerMenu.ID, tw.Updates[0].String())
}
if len(tw.Updates) >= 2 && inpututil.IsKeyJustPressed(updateTowerKeybind2) {
actionDispatcher.UpdateTower(cp.ID, hst.OpenTowerMenu.ID, tw.Updates[1].String())
}
}
if hst.SelectedTower != nil {
Expand Down Expand Up @@ -326,19 +331,28 @@ func (hs *HUDStore) Draw(screen *ebiten.Image) {
if hst.OpenTowerMenu != nil {
// TODO: Add the keybind to the tooltip
hs.bottomLeftContainer.GetWidget().Visibility = widget.Visibility_Show
tu := tower.FindUpdateByLevel(hst.OpenTowerMenu.Type, hst.OpenTowerMenu.Level+1)
tc := tower.FindUpdateByLevel(hst.OpenTowerMenu.Type, hst.OpenTowerMenu.Level)
removeTowerGoldReturn := tower.Towers[hst.OpenTowerMenu.Type].Gold / 2
if tc != nil {
removeTowerGoldReturn = tc.UpdateCost / 2
}
// Where there is no more updates we disable the button
if tu == nil {
hs.towerUpdateButton.GetWidget().Disabled = true
hs.towerUpdateToolTip.Label = towerUpdateLimit
tu := tower.Towers[hst.OpenTowerMenu.Type].Updates
if len(tu) == 0 {
hs.towerUpdateButton1.GetWidget().Visibility = widget.Visibility_Hide
hs.towerUpdateButton2.GetWidget().Visibility = widget.Visibility_Hide
} else {
hs.towerUpdateButton.GetWidget().Disabled = cp.Gold < tu.UpdateCost
hs.towerUpdateToolTip.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tu.UpdateCost, tu.Stats.Damage, updateTowerKeybind)
if len(tu) >= 1 {
tw := tower.Towers[tu[0].String()]
hs.towerUpdateButton1.Image = cutils.ButtonImageFromImage(imagesCache.Get(tw.FacesetKey()))
hs.towerUpdateButton1.GetWidget().Visibility = widget.Visibility_Show
hs.towerUpdateButton1.GetWidget().Disabled = cp.Gold < tw.Gold
hs.towerUpdateToolTip1.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, updateTowerKeybind1)
hs.towerUpdateButton2.GetWidget().Visibility = widget.Visibility_Hide
}
if len(tu) >= 2 {
tw := tower.Towers[tu[1].String()]
hs.towerUpdateButton2.Image = cutils.ButtonImageFromImage(imagesCache.Get(tw.FacesetKey()))
hs.towerUpdateButton2.GetWidget().Visibility = widget.Visibility_Show
hs.towerUpdateButton2.GetWidget().Disabled = cp.Gold < tw.Gold
hs.towerUpdateToolTip2.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, updateTowerKeybind2)
}
}
hs.towerRemoveToolTip.Label = fmt.Sprintf(towerRemoveToolTipTmpl, removeTowerGoldReturn, removeTowerKeybind)
} else {
Expand Down Expand Up @@ -468,14 +482,7 @@ func sortedUnits() []*unit.Unit {
}

func sortedTowers() []*tower.Tower {
ts := make([]*tower.Tower, 0, 0)
for _, t := range tower.Towers {
ts = append(ts, t)
}
sort.Slice(ts, func(i, j int) bool {
return ts[i].Type > ts[j].Type
})
return ts
return tower.FirstTowers
}

func (hs *HUDStore) buildUI() {
Expand Down Expand Up @@ -738,9 +745,13 @@ func (hs *HUDStore) buildUI() {
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(color.NRGBA{R: 170, G: 170, B: 230, A: 255})),
)

kb := rangeTowerKeybind
if t.Type == tower.Melee1 {
kb = meleeTowerKeybind
}
toolTxt := widget.NewText(
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
widget.TextOpts.Text(fmt.Sprintf("Gold: %d\nRange: %.0f\nDamage: %.0f\nTargets: %s\nKeybind: %s", t.Gold, t.Range, t.Damage, t.Targets, t.Keybind), cutils.SmallFont, color.White),
widget.TextOpts.Text(fmt.Sprintf("Gold: %d\nRange: %.0f\nDamage: %.0f\nTargets: %s\nKeybind: %s", t.Gold, t.Range, t.Damage, t.Targets, kb), cutils.SmallFont, color.White),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.MinSize(100, 0)),
)
tooltipContainer.AddChild(toolTxt)
Expand Down Expand Up @@ -1031,29 +1042,78 @@ func (hs *HUDStore) guiBottomLeft() *widget.Container {
towerMenuC.AddChild(rbtn)

// Update button
updateToolTipContainer := widget.NewContainer(
updateToolTipContainer1 := widget.NewContainer(
widget.ContainerOpts.Layout(widget.NewRowLayout(widget.RowLayoutOpts.Direction(widget.DirectionVertical))),
widget.ContainerOpts.AutoDisableChildren(),
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(color.NRGBA{R: 170, G: 170, B: 230, A: 255})),
)

updateToolTxt := widget.NewText(
updateToolTxt1 := widget.NewText(
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, updateTowerKeybind), cutils.SmallFont, color.White),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, updateTowerKeybind1), cutils.SmallFont, color.White),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.MinSize(100, 0)),
)
hs.towerUpdateToolTip = updateToolTxt
updateToolTipContainer.AddChild(updateToolTxt)
hs.towerUpdateToolTip1 = updateToolTxt1
updateToolTipContainer1.AddChild(updateToolTxt1)

ubtn1 := widget.NewButton(
// set general widget options
widget.ButtonOpts.WidgetOpts(
widget.WidgetOpts.LayoutData(widget.GridLayoutData{
MaxWidth: 38,
MaxHeight: 38,
}),
widget.WidgetOpts.ToolTip(widget.NewToolTip(
widget.ToolTipOpts.Content(updateToolTipContainer1),
//widget.WidgetToolTipOpts.Delay(1*time.Second),
widget.ToolTipOpts.Offset(stdimage.Point{-5, 5}),
widget.ToolTipOpts.Position(widget.TOOLTIP_POS_WIDGET),
//When the Position is set to TOOLTIP_POS_WIDGET, you can configure where it opens with the optional parameters below
//They will default to what you see below if you do not provide them
widget.ToolTipOpts.WidgetOriginHorizontal(widget.TOOLTIP_ANCHOR_END),
widget.ToolTipOpts.WidgetOriginVertical(widget.TOOLTIP_ANCHOR_END),
widget.ToolTipOpts.ContentOriginHorizontal(widget.TOOLTIP_ANCHOR_END),
widget.ToolTipOpts.ContentOriginVertical(widget.TOOLTIP_ANCHOR_START),
)),
),
// specify the images to sue
widget.ButtonOpts.Image(cutils.ButtonImageFromImage(imagesCache.Get(arrowImageKey))),

// add a handler that reacts to clicking the button
widget.ButtonOpts.ClickedHandler(func() func(args *widget.ButtonClickedEventArgs) {
return func(args *widget.ButtonClickedEventArgs) {
cp := hs.game.Store.Lines.FindCurrentPlayer()
// I know which is the current open one
// I'll have 2 buttons so I can know the position
// that it was selected to update
tomid := hs.GetState().(HUDState).OpenTowerMenu.ID
actionDispatcher.UpdateTower(cp.ID, tomid, "TODO")
}
}()),
)

ubtn := widget.NewButton(
updateToolTipContainer2 := widget.NewContainer(
widget.ContainerOpts.Layout(widget.NewRowLayout(widget.RowLayoutOpts.Direction(widget.DirectionVertical))),
widget.ContainerOpts.AutoDisableChildren(),
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(color.NRGBA{R: 170, G: 170, B: 230, A: 255})),
)

updateToolTxt2 := widget.NewText(
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, updateTowerKeybind2), cutils.SmallFont, color.White),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.MinSize(100, 0)),
)
hs.towerUpdateToolTip2 = updateToolTxt2
updateToolTipContainer2.AddChild(updateToolTxt2)
ubtn2 := widget.NewButton(
// set general widget options
widget.ButtonOpts.WidgetOpts(
widget.WidgetOpts.LayoutData(widget.GridLayoutData{
MaxWidth: 38,
MaxHeight: 38,
}),
widget.WidgetOpts.ToolTip(widget.NewToolTip(
widget.ToolTipOpts.Content(updateToolTipContainer),
widget.ToolTipOpts.Content(updateToolTipContainer2),
//widget.WidgetToolTipOpts.Delay(1*time.Second),
widget.ToolTipOpts.Offset(stdimage.Point{-5, 5}),
widget.ToolTipOpts.Position(widget.TOOLTIP_POS_WIDGET),
Expand All @@ -1072,16 +1132,21 @@ func (hs *HUDStore) guiBottomLeft() *widget.Container {
widget.ButtonOpts.ClickedHandler(func() func(args *widget.ButtonClickedEventArgs) {
return func(args *widget.ButtonClickedEventArgs) {
cp := hs.game.Store.Lines.FindCurrentPlayer()
// I know which is the current open one
// I'll have 2 buttons so I can know the position
// that it was selected to update
tomid := hs.GetState().(HUDState).OpenTowerMenu.ID
actionDispatcher.UpdateTower(cp.ID, tomid)
actionDispatcher.UpdateTower(cp.ID, tomid, "TODO")
}
}()),
)
towerMenuC.AddChild(ubtn)
towerMenuC.AddChild(ubtn1)
towerMenuC.AddChild(ubtn2)
bottomLeftContainer.AddChild(towerMenuC)
hs.bottomLeftContainer = bottomLeftContainer
hs.towerMenuContainer = towerMenuC
hs.towerUpdateButton = ubtn
hs.towerUpdateButton1 = ubtn1
hs.towerUpdateButton2 = ubtn2

return bottomLeftContainer
}
8 changes: 8 additions & 0 deletions client/game/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (
lifeBarProgressKey = "life-bar-progress"
lifeBarUnderKey = "life-bar-under"
shieldBarProgressKey = "shield-bar-progress"

towersKey = "towers-key"
)

// ImagesCache is a simple cache for all the images, so instead
Expand Down Expand Up @@ -96,6 +98,12 @@ func init() {
panic(err)
}
imagesCache.images[shieldBarProgressKey] = ebiten.NewImageFromImage(sbpi)

atpi, _, err := image.Decode(bytes.NewReader(assets.Towers_png))
if err != nil {
panic(err)
}
imagesCache.images[towersKey] = ebiten.NewImageFromImage(atpi)
}

// Get will return the image from 'key', if it does not
Expand Down
7 changes: 0 additions & 7 deletions client/game/lines.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@ package game

import (
"bytes"
"fmt"
"image"
"image/color"
"time"

"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/text"
"github.com/xescugc/maze-wars/assets"
cutils "github.com/xescugc/maze-wars/client/utils"
"github.com/xescugc/maze-wars/store"
"github.com/xescugc/maze-wars/unit/buff"
"github.com/xescugc/maze-wars/utils"
Expand Down Expand Up @@ -75,9 +71,6 @@ func (ls *Lines) DrawTower(screen *ebiten.Image, c *CameraStore, t *store.Tower)
op.GeoM.Translate(float64(t.X-cs.X), float64(t.Y-cs.Y))
op.GeoM.Scale(cs.Zoom, cs.Zoom)
screen.DrawImage(imagesCache.Get(t.FacetKey()), op)
if t.Level != 1 {
text.Draw(screen, fmt.Sprintf("%d", t.Level), cutils.SmallFont, int(t.X-cs.X)+8, int(t.Y-cs.Y)+24, color.White)
}
}

func (ls *Lines) DrawUnit(screen *ebiten.Image, c *CameraStore, u *store.Unit) {
Expand Down
1 change: 1 addition & 0 deletions server/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ func (ac *ActionDispatcher) SyncState(rooms *RoomsStore) {
Winner: ap.Winner,
UnitUpdates: make(map[string]action.SyncStatePlayerUnitUpdatePayload),
}
// TODO: Make it concurrently safe
for t, uu := range ap.UnitUpdates {
uspp.UnitUpdates[t] = action.SyncStatePlayerUnitUpdatePayload(uu)
}
Expand Down
Binary file modified server/assets/wasm/maze-wars.wasm
Binary file not shown.
Loading

0 comments on commit 7bcde6c

Please sign in to comment.