diff --git a/action/action.go b/action/action.go index 9a87fb4..427472c 100644 --- a/action/action.go +++ b/action/action.go @@ -47,14 +47,17 @@ type Action struct { UserSignIn *UserSignInPayload `json:"user_sign_in,omitempty"` UserSignOut *UserSignOutPayload `json:"user_sign_out,omitempty"` - AddPlayer *AddPlayerPayload `json:"add_player,omitempty"` - RemovePlayer *RemovePlayerPayload `json:"remove_player,omitempty"` - JoinWaitingRoom *JoinWaitingRoomPayload `json:"join_waiting_room,omitempty"` - ExitWaitingRoom *ExitWaitingRoomPayload `json:"exit_waiting_room,omitempty"` - StartRoom *StartRoomPayload `json:"start_room,omitempty"` - SyncState *SyncStatePayload `json:"sync_state,omitempty"` - SyncUsers *SyncUsersPayload `json:"sync_users,omitempty"` - SyncWaitingRoom *SyncWaitingRoomPayload `json:"sync_waiting_room,omitempty"` + AddPlayer *AddPlayerPayload `json:"add_player,omitempty"` + RemovePlayer *RemovePlayerPayload `json:"remove_player,omitempty"` + JoinVs6WaitingRoom *JoinVs6WaitingRoomPayload `json:"join_vs6_waiting_room,omitempty"` + ExitVs6WaitingRoom *ExitVs6WaitingRoomPayload `json:"exit_vs6_waiting_room,omitempty"` + JoinVs1WaitingRoom *JoinVs1WaitingRoomPayload `json:"join_vs1_waiting_room,omitempty"` + ExitVs1WaitingRoom *ExitVs1WaitingRoomPayload `json:"exit_vs1_waiting_room,omitempty"` + StartRoom *StartRoomPayload `json:"start_room,omitempty"` + SyncState *SyncStatePayload `json:"sync_state,omitempty"` + SyncUsers *SyncUsersPayload `json:"sync_users,omitempty"` + SyncVs6WaitingRoom *SyncVs6WaitingRoomPayload `json:"sync_vs6_waiting_room,omitempty"` + SyncVs1WaitingRoom *SyncVs1WaitingRoomPayload `json:"sync_vs1_waiting_room,omitempty"` } type CursorMovePayload struct { @@ -377,42 +380,42 @@ func NewUserSignUp(un string) *Action { } } -type JoinWaitingRoomPayload struct { +type JoinVs6WaitingRoomPayload struct { Username string } -func NewJoinWaitingRoom(un string) *Action { +func NewJoinVs6WaitingRoom(un string) *Action { return &Action{ - Type: JoinWaitingRoom, - JoinWaitingRoom: &JoinWaitingRoomPayload{ + Type: JoinVs6WaitingRoom, + JoinVs6WaitingRoom: &JoinVs6WaitingRoomPayload{ Username: un, }, } } -type ExitWaitingRoomPayload struct { +type ExitVs6WaitingRoomPayload struct { Username string } -func NewExitWaitingRoom(un string) *Action { +func NewExitVs6WaitingRoom(un string) *Action { return &Action{ - Type: ExitWaitingRoom, - ExitWaitingRoom: &ExitWaitingRoomPayload{ + Type: ExitVs6WaitingRoom, + ExitVs6WaitingRoom: &ExitVs6WaitingRoomPayload{ Username: un, }, } } -type SyncWaitingRoomPayload struct { +type SyncVs6WaitingRoomPayload struct { TotalPlayers int Size int Countdown int } -func NewSyncWaitingRoom(tp, s, cd int) *Action { +func NewSyncVs6WaitingRoom(tp, s, cd int) *Action { return &Action{ - Type: SyncWaitingRoom, - SyncWaitingRoom: &SyncWaitingRoomPayload{ + Type: SyncVs6WaitingRoom, + SyncVs6WaitingRoom: &SyncVs6WaitingRoomPayload{ TotalPlayers: tp, Size: s, Countdown: cd, @@ -420,6 +423,47 @@ func NewSyncWaitingRoom(tp, s, cd int) *Action { } } +type JoinVs1WaitingRoomPayload struct { + Username string +} + +func NewJoinVs1WaitingRoom(un string) *Action { + return &Action{ + Type: JoinVs1WaitingRoom, + JoinVs1WaitingRoom: &JoinVs1WaitingRoomPayload{ + Username: un, + }, + } +} + +type ExitVs1WaitingRoomPayload struct { + Username string +} + +func NewExitVs1WaitingRoom(un string) *Action { + return &Action{ + Type: ExitVs1WaitingRoom, + ExitVs1WaitingRoom: &ExitVs1WaitingRoomPayload{ + Username: un, + }, + } +} + +type SyncVs1WaitingRoomPayload struct { + TotalPlayers int + Size int +} + +func NewSyncVs1WaitingRoom(tp, s int) *Action { + return &Action{ + Type: SyncVs1WaitingRoom, + SyncVs1WaitingRoom: &SyncVs1WaitingRoomPayload{ + TotalPlayers: tp, + Size: s, + }, + } +} + type SyncStatePayload struct { Players *SyncStatePlayersPayload Lines *SyncStateLinesPayload diff --git a/action/type.go b/action/type.go index 8525d1b..626982f 100644 --- a/action/type.go +++ b/action/type.go @@ -28,8 +28,10 @@ const ( UserSignUp UserSignIn UserSignOut - JoinWaitingRoom - ExitWaitingRoom + JoinVs6WaitingRoom + ExitVs6WaitingRoom + JoinVs1WaitingRoom + ExitVs1WaitingRoom StartRoom ToggleStats VersionError @@ -49,5 +51,6 @@ const ( SyncState SyncUsers WaitRoomCountdownTick - SyncWaitingRoom + SyncVs6WaitingRoom + SyncVs1WaitingRoom ) diff --git a/action/type_string.go b/action/type_string.go index 3cffb48..b91f6e9 100644 --- a/action/type_string.go +++ b/action/type_string.go @@ -8,11 +8,11 @@ import ( "strings" ) -const _TypeName = "cursor_movecamera_zoomsummon_unitupdate_unitupdate_towertpsplace_towerremove_towerselect_towerselected_towerselected_tower_invaliddeselect_towerincome_tickwindow_resizingnavigate_tostart_gameopen_tower_menuclose_tower_menugo_homesign_up_erroruser_sign_upuser_sign_inuser_sign_outjoin_waiting_roomexit_waiting_roomstart_roomtoggle_statsversion_errorcreate_lobbydelete_lobbyjoin_lobbyadd_lobbiesselect_lobbyleave_lobbyupdate_lobbystart_lobbyadd_playerremove_playersync_statesync_userswait_room_countdown_ticksync_waiting_room" +const _TypeName = "cursor_movecamera_zoomsummon_unitupdate_unitupdate_towertpsplace_towerremove_towerselect_towerselected_towerselected_tower_invaliddeselect_towerincome_tickwindow_resizingnavigate_tostart_gameopen_tower_menuclose_tower_menugo_homesign_up_erroruser_sign_upuser_sign_inuser_sign_outjoin_vs6_waiting_roomexit_vs6_waiting_roomjoin_vs1_waiting_roomexit_vs1_waiting_roomstart_roomtoggle_statsversion_errorcreate_lobbydelete_lobbyjoin_lobbyadd_lobbiesselect_lobbyleave_lobbyupdate_lobbystart_lobbyadd_playerremove_playersync_statesync_userswait_room_countdown_ticksync_vs6_waiting_roomsync_vs1_waiting_room" -var _TypeIndex = [...]uint16{0, 11, 22, 33, 44, 56, 59, 70, 82, 94, 108, 130, 144, 155, 170, 181, 191, 206, 222, 229, 242, 254, 266, 279, 296, 313, 323, 335, 348, 360, 372, 382, 393, 405, 416, 428, 439, 449, 462, 472, 482, 506, 523} +var _TypeIndex = [...]uint16{0, 11, 22, 33, 44, 56, 59, 70, 82, 94, 108, 130, 144, 155, 170, 181, 191, 206, 222, 229, 242, 254, 266, 279, 300, 321, 342, 363, 373, 385, 398, 410, 422, 432, 443, 455, 466, 478, 489, 499, 512, 522, 532, 556, 577, 598} -const _TypeLowerName = "cursor_movecamera_zoomsummon_unitupdate_unitupdate_towertpsplace_towerremove_towerselect_towerselected_towerselected_tower_invaliddeselect_towerincome_tickwindow_resizingnavigate_tostart_gameopen_tower_menuclose_tower_menugo_homesign_up_erroruser_sign_upuser_sign_inuser_sign_outjoin_waiting_roomexit_waiting_roomstart_roomtoggle_statsversion_errorcreate_lobbydelete_lobbyjoin_lobbyadd_lobbiesselect_lobbyleave_lobbyupdate_lobbystart_lobbyadd_playerremove_playersync_statesync_userswait_room_countdown_ticksync_waiting_room" +const _TypeLowerName = "cursor_movecamera_zoomsummon_unitupdate_unitupdate_towertpsplace_towerremove_towerselect_towerselected_towerselected_tower_invaliddeselect_towerincome_tickwindow_resizingnavigate_tostart_gameopen_tower_menuclose_tower_menugo_homesign_up_erroruser_sign_upuser_sign_inuser_sign_outjoin_vs6_waiting_roomexit_vs6_waiting_roomjoin_vs1_waiting_roomexit_vs1_waiting_roomstart_roomtoggle_statsversion_errorcreate_lobbydelete_lobbyjoin_lobbyadd_lobbiesselect_lobbyleave_lobbyupdate_lobbystart_lobbyadd_playerremove_playersync_statesync_userswait_room_countdown_ticksync_vs6_waiting_roomsync_vs1_waiting_room" func (i Type) String() string { if i < 0 || i >= Type(len(_TypeIndex)-1) { @@ -48,28 +48,31 @@ func _TypeNoOp() { _ = x[UserSignUp-(20)] _ = x[UserSignIn-(21)] _ = x[UserSignOut-(22)] - _ = x[JoinWaitingRoom-(23)] - _ = x[ExitWaitingRoom-(24)] - _ = x[StartRoom-(25)] - _ = x[ToggleStats-(26)] - _ = x[VersionError-(27)] - _ = x[CreateLobby-(28)] - _ = x[DeleteLobby-(29)] - _ = x[JoinLobby-(30)] - _ = x[AddLobbies-(31)] - _ = x[SelectLobby-(32)] - _ = x[LeaveLobby-(33)] - _ = x[UpdateLobby-(34)] - _ = x[StartLobby-(35)] - _ = x[AddPlayer-(36)] - _ = x[RemovePlayer-(37)] - _ = x[SyncState-(38)] - _ = x[SyncUsers-(39)] - _ = x[WaitRoomCountdownTick-(40)] - _ = x[SyncWaitingRoom-(41)] + _ = x[JoinVs6WaitingRoom-(23)] + _ = x[ExitVs6WaitingRoom-(24)] + _ = x[JoinVs1WaitingRoom-(25)] + _ = x[ExitVs1WaitingRoom-(26)] + _ = x[StartRoom-(27)] + _ = x[ToggleStats-(28)] + _ = x[VersionError-(29)] + _ = x[CreateLobby-(30)] + _ = x[DeleteLobby-(31)] + _ = x[JoinLobby-(32)] + _ = x[AddLobbies-(33)] + _ = x[SelectLobby-(34)] + _ = x[LeaveLobby-(35)] + _ = x[UpdateLobby-(36)] + _ = x[StartLobby-(37)] + _ = x[AddPlayer-(38)] + _ = x[RemovePlayer-(39)] + _ = x[SyncState-(40)] + _ = x[SyncUsers-(41)] + _ = x[WaitRoomCountdownTick-(42)] + _ = x[SyncVs6WaitingRoom-(43)] + _ = x[SyncVs1WaitingRoom-(44)] } -var _TypeValues = []Type{CursorMove, CameraZoom, SummonUnit, UpdateUnit, UpdateTower, TPS, PlaceTower, RemoveTower, SelectTower, SelectedTower, SelectedTowerInvalid, DeselectTower, IncomeTick, WindowResizing, NavigateTo, StartGame, OpenTowerMenu, CloseTowerMenu, GoHome, SignUpError, UserSignUp, UserSignIn, UserSignOut, JoinWaitingRoom, ExitWaitingRoom, StartRoom, ToggleStats, VersionError, CreateLobby, DeleteLobby, JoinLobby, AddLobbies, SelectLobby, LeaveLobby, UpdateLobby, StartLobby, AddPlayer, RemovePlayer, SyncState, SyncUsers, WaitRoomCountdownTick, SyncWaitingRoom} +var _TypeValues = []Type{CursorMove, CameraZoom, SummonUnit, UpdateUnit, UpdateTower, TPS, PlaceTower, RemoveTower, SelectTower, SelectedTower, SelectedTowerInvalid, DeselectTower, IncomeTick, WindowResizing, NavigateTo, StartGame, OpenTowerMenu, CloseTowerMenu, GoHome, SignUpError, UserSignUp, UserSignIn, UserSignOut, JoinVs6WaitingRoom, ExitVs6WaitingRoom, JoinVs1WaitingRoom, ExitVs1WaitingRoom, StartRoom, ToggleStats, VersionError, CreateLobby, DeleteLobby, JoinLobby, AddLobbies, SelectLobby, LeaveLobby, UpdateLobby, StartLobby, AddPlayer, RemovePlayer, SyncState, SyncUsers, WaitRoomCountdownTick, SyncVs6WaitingRoom, SyncVs1WaitingRoom} var _TypeNameToValueMap = map[string]Type{ _TypeName[0:11]: CursorMove, @@ -118,44 +121,50 @@ var _TypeNameToValueMap = map[string]Type{ _TypeLowerName[254:266]: UserSignIn, _TypeName[266:279]: UserSignOut, _TypeLowerName[266:279]: UserSignOut, - _TypeName[279:296]: JoinWaitingRoom, - _TypeLowerName[279:296]: JoinWaitingRoom, - _TypeName[296:313]: ExitWaitingRoom, - _TypeLowerName[296:313]: ExitWaitingRoom, - _TypeName[313:323]: StartRoom, - _TypeLowerName[313:323]: StartRoom, - _TypeName[323:335]: ToggleStats, - _TypeLowerName[323:335]: ToggleStats, - _TypeName[335:348]: VersionError, - _TypeLowerName[335:348]: VersionError, - _TypeName[348:360]: CreateLobby, - _TypeLowerName[348:360]: CreateLobby, - _TypeName[360:372]: DeleteLobby, - _TypeLowerName[360:372]: DeleteLobby, - _TypeName[372:382]: JoinLobby, - _TypeLowerName[372:382]: JoinLobby, - _TypeName[382:393]: AddLobbies, - _TypeLowerName[382:393]: AddLobbies, - _TypeName[393:405]: SelectLobby, - _TypeLowerName[393:405]: SelectLobby, - _TypeName[405:416]: LeaveLobby, - _TypeLowerName[405:416]: LeaveLobby, - _TypeName[416:428]: UpdateLobby, - _TypeLowerName[416:428]: UpdateLobby, - _TypeName[428:439]: StartLobby, - _TypeLowerName[428:439]: StartLobby, - _TypeName[439:449]: AddPlayer, - _TypeLowerName[439:449]: AddPlayer, - _TypeName[449:462]: RemovePlayer, - _TypeLowerName[449:462]: RemovePlayer, - _TypeName[462:472]: SyncState, - _TypeLowerName[462:472]: SyncState, - _TypeName[472:482]: SyncUsers, - _TypeLowerName[472:482]: SyncUsers, - _TypeName[482:506]: WaitRoomCountdownTick, - _TypeLowerName[482:506]: WaitRoomCountdownTick, - _TypeName[506:523]: SyncWaitingRoom, - _TypeLowerName[506:523]: SyncWaitingRoom, + _TypeName[279:300]: JoinVs6WaitingRoom, + _TypeLowerName[279:300]: JoinVs6WaitingRoom, + _TypeName[300:321]: ExitVs6WaitingRoom, + _TypeLowerName[300:321]: ExitVs6WaitingRoom, + _TypeName[321:342]: JoinVs1WaitingRoom, + _TypeLowerName[321:342]: JoinVs1WaitingRoom, + _TypeName[342:363]: ExitVs1WaitingRoom, + _TypeLowerName[342:363]: ExitVs1WaitingRoom, + _TypeName[363:373]: StartRoom, + _TypeLowerName[363:373]: StartRoom, + _TypeName[373:385]: ToggleStats, + _TypeLowerName[373:385]: ToggleStats, + _TypeName[385:398]: VersionError, + _TypeLowerName[385:398]: VersionError, + _TypeName[398:410]: CreateLobby, + _TypeLowerName[398:410]: CreateLobby, + _TypeName[410:422]: DeleteLobby, + _TypeLowerName[410:422]: DeleteLobby, + _TypeName[422:432]: JoinLobby, + _TypeLowerName[422:432]: JoinLobby, + _TypeName[432:443]: AddLobbies, + _TypeLowerName[432:443]: AddLobbies, + _TypeName[443:455]: SelectLobby, + _TypeLowerName[443:455]: SelectLobby, + _TypeName[455:466]: LeaveLobby, + _TypeLowerName[455:466]: LeaveLobby, + _TypeName[466:478]: UpdateLobby, + _TypeLowerName[466:478]: UpdateLobby, + _TypeName[478:489]: StartLobby, + _TypeLowerName[478:489]: StartLobby, + _TypeName[489:499]: AddPlayer, + _TypeLowerName[489:499]: AddPlayer, + _TypeName[499:512]: RemovePlayer, + _TypeLowerName[499:512]: RemovePlayer, + _TypeName[512:522]: SyncState, + _TypeLowerName[512:522]: SyncState, + _TypeName[522:532]: SyncUsers, + _TypeLowerName[522:532]: SyncUsers, + _TypeName[532:556]: WaitRoomCountdownTick, + _TypeLowerName[532:556]: WaitRoomCountdownTick, + _TypeName[556:577]: SyncVs6WaitingRoom, + _TypeLowerName[556:577]: SyncVs6WaitingRoom, + _TypeName[577:598]: SyncVs1WaitingRoom, + _TypeLowerName[577:598]: SyncVs1WaitingRoom, } var _TypeNames = []string{ @@ -182,25 +191,28 @@ var _TypeNames = []string{ _TypeName[242:254], _TypeName[254:266], _TypeName[266:279], - _TypeName[279:296], - _TypeName[296:313], - _TypeName[313:323], - _TypeName[323:335], - _TypeName[335:348], - _TypeName[348:360], - _TypeName[360:372], - _TypeName[372:382], - _TypeName[382:393], - _TypeName[393:405], - _TypeName[405:416], - _TypeName[416:428], - _TypeName[428:439], - _TypeName[439:449], - _TypeName[449:462], - _TypeName[462:472], - _TypeName[472:482], - _TypeName[482:506], - _TypeName[506:523], + _TypeName[279:300], + _TypeName[300:321], + _TypeName[321:342], + _TypeName[342:363], + _TypeName[363:373], + _TypeName[373:385], + _TypeName[385:398], + _TypeName[398:410], + _TypeName[410:422], + _TypeName[422:432], + _TypeName[432:443], + _TypeName[443:455], + _TypeName[455:466], + _TypeName[466:478], + _TypeName[478:489], + _TypeName[489:499], + _TypeName[499:512], + _TypeName[512:522], + _TypeName[522:532], + _TypeName[532:556], + _TypeName[556:577], + _TypeName[577:598], } // TypeString retrieves an enum value from the enum constants string name. diff --git a/client/action.go b/client/action.go index 0c0c47f..5a26a5a 100644 --- a/client/action.go +++ b/client/action.go @@ -174,15 +174,29 @@ func (ac *ActionDispatcher) GoHome() { ac.Dispatch(gha) } -func (ac *ActionDispatcher) JoinWaitingRoom(un string) { - jwra := action.NewJoinWaitingRoom(un) +func (ac *ActionDispatcher) JoinVs6WaitingRoom(un string) { + jwra := action.NewJoinVs6WaitingRoom(un) wsSend(jwra) - ac.Dispatch(action.NewNavigateTo(utils.WaitingRoomRoute)) + ac.Dispatch(action.NewNavigateTo(utils.Vs6WaitingRoomRoute)) } -func (ac *ActionDispatcher) ExitWaitingRoom(un string) { - ewra := action.NewExitWaitingRoom(un) +func (ac *ActionDispatcher) ExitVs6WaitingRoom(un string) { + ewra := action.NewExitVs6WaitingRoom(un) + wsSend(ewra) + + ac.Dispatch(action.NewNavigateTo(utils.RootRoute)) +} + +func (ac *ActionDispatcher) JoinVs1WaitingRoom(un string) { + jwra := action.NewJoinVs1WaitingRoom(un) + wsSend(jwra) + + ac.Dispatch(action.NewNavigateTo(utils.Vs1WaitingRoomRoute)) +} + +func (ac *ActionDispatcher) ExitVs1WaitingRoom(un string) { + ewra := action.NewExitVs1WaitingRoom(un) wsSend(ewra) ac.Dispatch(action.NewNavigateTo(utils.RootRoute)) diff --git a/client/root.go b/client/root.go index d929e06..a885c04 100644 --- a/client/root.go +++ b/client/root.go @@ -130,7 +130,7 @@ func (rs *RootStore) buildUI() { ), ) - playBtnW := widget.NewButton( + playVs1BtnW := widget.NewButton( // set general widget options widget.ButtonOpts.WidgetOpts( widget.WidgetOpts.LayoutData(widget.RowLayoutData{ @@ -144,7 +144,7 @@ func (rs *RootStore) buildUI() { widget.ButtonOpts.Image(buttonImageL), // specify the button's text, the font face, and the color - widget.ButtonOpts.Text("Play", cutils.SmallFont, &widget.ButtonTextColor{ + widget.ButtonOpts.Text("Play v1", cutils.SmallFont, &widget.ButtonTextColor{ Idle: color.NRGBA{0xdf, 0xf4, 0xff, 0xff}, }), @@ -158,7 +158,39 @@ func (rs *RootStore) buildUI() { // add a handler that reacts to clicking the button widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) { - actionDispatcher.JoinWaitingRoom(rs.Store.Users.Username()) + actionDispatcher.JoinVs1WaitingRoom(rs.Store.Users.Username()) + }), + ) + + playVs6BtnW := widget.NewButton( + // set general widget options + widget.ButtonOpts.WidgetOpts( + widget.WidgetOpts.LayoutData(widget.RowLayoutData{ + Position: widget.RowLayoutPositionCenter, + Stretch: true, + MaxWidth: 150, + }), + ), + + // specify the images to sue + widget.ButtonOpts.Image(buttonImageL), + + // specify the button's text, the font face, and the color + widget.ButtonOpts.Text("Play v6", cutils.SmallFont, &widget.ButtonTextColor{ + Idle: color.NRGBA{0xdf, 0xf4, 0xff, 0xff}, + }), + + // specify that the button's text needs some padding for correct display + widget.ButtonOpts.TextPadding(widget.Insets{ + Left: 30, + Right: 30, + Top: 5, + Bottom: 5, + }), + + // add a handler that reacts to clicking the button + widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) { + actionDispatcher.JoinVs6WaitingRoom(rs.Store.Users.Username()) }), ) @@ -198,7 +230,8 @@ func (rs *RootStore) buildUI() { titleInputC.AddChild(titleW) titleInputC.AddChild(textPlayersW) - titleInputC.AddChild(playBtnW) + titleInputC.AddChild(playVs1BtnW) + titleInputC.AddChild(playVs6BtnW) titleInputC.AddChild(lobbiesBtnW) rootContainer.AddChild(titleInputC) diff --git a/client/router.go b/client/router.go index 9aa2e1a..41761c1 100644 --- a/client/router.go +++ b/client/router.go @@ -15,13 +15,14 @@ import ( type RouterStore struct { *flux.ReduceStore - game *Game - root *RootStore - signUp *SignUpStore - waitingRoom *WaitingRoomStore - lobbies *LobbiesView - newLobby *NewLobbyView - showLobby *ShowLobbyView + game *Game + root *RootStore + signUp *SignUpStore + vs6WaitingRoom *Vs6WaitingRoomStore + vs1WaitingRoom *Vs1WaitingRoomStore + lobbies *LobbiesView + newLobby *NewLobbyView + showLobby *ShowLobbyView logger *slog.Logger } @@ -30,15 +31,16 @@ type RouterState struct { Route string } -func NewRouterStore(d *flux.Dispatcher, su *SignUpStore, ros *RootStore, wr *WaitingRoomStore, g *Game, lv *LobbiesView, nlv *NewLobbyView, slv *ShowLobbyView, l *slog.Logger) *RouterStore { +func NewRouterStore(d *flux.Dispatcher, su *SignUpStore, ros *RootStore, wr6 *Vs6WaitingRoomStore, wr1 *Vs1WaitingRoomStore, g *Game, lv *LobbiesView, nlv *NewLobbyView, slv *ShowLobbyView, l *slog.Logger) *RouterStore { rs := &RouterStore{ - game: g, - root: ros, - signUp: su, - waitingRoom: wr, - lobbies: lv, - newLobby: nlv, - showLobby: slv, + game: g, + root: ros, + signUp: su, + vs6WaitingRoom: wr6, + vs1WaitingRoom: wr1, + lobbies: lv, + newLobby: nlv, + showLobby: slv, logger: l, } @@ -86,8 +88,10 @@ func (rs *RouterStore) Update() error { rs.signUp.Update() case utils.RootRoute: rs.root.Update() - case utils.WaitingRoomRoute: - rs.waitingRoom.Update() + case utils.Vs6WaitingRoomRoute: + rs.vs6WaitingRoom.Update() + case utils.Vs1WaitingRoomRoute: + rs.vs1WaitingRoom.Update() case utils.LobbiesRoute: rs.lobbies.Update() case utils.NewLobbyRoute: @@ -136,8 +140,10 @@ func (rs *RouterStore) Draw(screen *ebiten.Image) { rs.signUp.Draw(screen) case utils.RootRoute: rs.root.Draw(screen) - case utils.WaitingRoomRoute: - rs.waitingRoom.Draw(screen) + case utils.Vs6WaitingRoomRoute: + rs.vs6WaitingRoom.Draw(screen) + case utils.Vs1WaitingRoomRoute: + rs.vs1WaitingRoom.Draw(screen) case utils.LobbiesRoute: rs.lobbies.Draw(screen) case utils.NewLobbyRoute: diff --git a/client/v1_waiting_room.go b/client/v1_waiting_room.go new file mode 100644 index 0000000..55130c8 --- /dev/null +++ b/client/v1_waiting_room.go @@ -0,0 +1,169 @@ +package client + +import ( + "fmt" + "image/color" + "log/slog" + "time" + + "github.com/ebitenui/ebitenui" + "github.com/ebitenui/ebitenui/widget" + "github.com/hajimehoshi/ebiten/v2" + "github.com/xescugc/go-flux" + "github.com/xescugc/maze-wars/action" + cutils "github.com/xescugc/maze-wars/client/utils" + "github.com/xescugc/maze-wars/utils" +) + +type Vs1WaitingRoomStore struct { + *flux.ReduceStore + + Store *Store + Logger *slog.Logger + + ui *ebitenui.UI + textPlayersW *widget.Text +} + +type Vs1WaitingRoomState struct { + TotalPlayers int + Size int +} + +func NewVs1WaitingRoomStore(d *flux.Dispatcher, s *Store, l *slog.Logger) *Vs1WaitingRoomStore { + wr := &Vs1WaitingRoomStore{ + Store: s, + Logger: l, + } + wr.ReduceStore = flux.NewReduceStore(d, wr.Reduce, Vs1WaitingRoomState{}) + + wr.buildUI() + + return wr +} + +func (wr *Vs1WaitingRoomStore) Update() error { + b := time.Now() + defer utils.LogTime(wr.Logger, b, "waiting_room update") + + wr.ui.Update() + return nil +} + +func (wr *Vs1WaitingRoomStore) Draw(screen *ebiten.Image) { + b := time.Now() + defer utils.LogTime(wr.Logger, b, "waiting_room draw") + + wrstate := wr.GetState().(Vs1WaitingRoomState) + wr.textPlayersW.Label = fmt.Sprintf("%d/%d", wrstate.TotalPlayers, wrstate.Size) + wr.ui.Draw(screen) +} + +func (wr *Vs1WaitingRoomStore) Reduce(state, a interface{}) interface{} { + act, ok := a.(*action.Action) + if !ok { + return state + } + + wrtate, ok := state.(Vs1WaitingRoomState) + if !ok { + return state + } + + switch act.Type { + case action.SyncVs1WaitingRoom: + wrtate.TotalPlayers = act.SyncVs1WaitingRoom.TotalPlayers + wrtate.Size = act.SyncVs1WaitingRoom.Size + } + + return wrtate +} + +func (wr *Vs1WaitingRoomStore) buildUI() { + rootContainer := widget.NewContainer( + widget.ContainerOpts.Layout(widget.NewAnchorLayout()), + ) + + waitingRoomC := widget.NewContainer( + widget.ContainerOpts.Layout(widget.NewRowLayout( + widget.RowLayoutOpts.Direction(widget.DirectionVertical), + widget.RowLayoutOpts.Padding(widget.NewInsetsSimple(20)), + widget.RowLayoutOpts.Spacing(20), + )), + widget.ContainerOpts.WidgetOpts( + widget.WidgetOpts.LayoutData(widget.AnchorLayoutData{ + HorizontalPosition: widget.AnchorLayoutPositionCenter, + VerticalPosition: widget.AnchorLayoutPositionCenter, + StretchHorizontal: true, + StretchVertical: false, + }), + ), + ) + + wr.ui = &ebitenui.UI{ + Container: rootContainer, + } + + titleW := widget.NewText( + widget.TextOpts.Text("Waiting for player to join", cutils.NormalFont, color.White), + widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter), + widget.TextOpts.WidgetOpts( + widget.WidgetOpts.LayoutData(widget.RowLayoutData{ + Position: widget.RowLayoutPositionCenter, + Stretch: true, + }), + widget.WidgetOpts.MinSize(100, 100), + ), + ) + + textPlayersW := widget.NewText( + widget.TextOpts.Text("", cutils.SmallFont, color.White), + widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter), + widget.TextOpts.WidgetOpts( + widget.WidgetOpts.LayoutData(widget.RowLayoutData{ + Position: widget.RowLayoutPositionCenter, + Stretch: true, + }), + ), + ) + + buttonW := widget.NewButton( + // set general widget options + widget.ButtonOpts.WidgetOpts( + widget.WidgetOpts.LayoutData(widget.RowLayoutData{ + Position: widget.RowLayoutPositionCenter, + Stretch: false, + }), + ), + + // specify the images to sue + widget.ButtonOpts.Image(cutils.ButtonImage), + + // specify the button's text, the font face, and the color + widget.ButtonOpts.Text("EXIT", cutils.SmallFont, &widget.ButtonTextColor{ + Idle: color.NRGBA{0xdf, 0xf4, 0xff, 0xff}, + }), + + // specify that the button's text needs some padding for correct display + widget.ButtonOpts.TextPadding(widget.Insets{ + Left: 30, + Right: 30, + Top: 5, + Bottom: 5, + }), + + // add a handler that reacts to clicking the button + widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) { + actionDispatcher.ExitVs1WaitingRoom(wr.Store.Users.Username()) + }), + ) + + wr.textPlayersW = textPlayersW + + waitingRoomC.AddChild(titleW) + waitingRoomC.AddChild(textPlayersW) + waitingRoomC.AddChild(buttonW) + + rootContainer.AddChild(waitingRoomC) + +} diff --git a/client/waiting_room.go b/client/v6_waiting_room.go similarity index 80% rename from client/waiting_room.go rename to client/v6_waiting_room.go index b319757..61824a2 100644 --- a/client/waiting_room.go +++ b/client/v6_waiting_room.go @@ -15,7 +15,7 @@ import ( "github.com/xescugc/maze-wars/utils" ) -type WaitingRoomStore struct { +type Vs6WaitingRoomStore struct { *flux.ReduceStore Store *Store @@ -26,25 +26,25 @@ type WaitingRoomStore struct { textColdownW *widget.Text } -type WaitingRoomState struct { +type Vs6WaitingRoomState struct { TotalPlayers int Size int Countdown int } -func NewWaitingRoomStore(d *flux.Dispatcher, s *Store, l *slog.Logger) *WaitingRoomStore { - wr := &WaitingRoomStore{ +func NewVs6WaitingRoomStore(d *flux.Dispatcher, s *Store, l *slog.Logger) *Vs6WaitingRoomStore { + wr := &Vs6WaitingRoomStore{ Store: s, Logger: l, } - wr.ReduceStore = flux.NewReduceStore(d, wr.Reduce, WaitingRoomState{}) + wr.ReduceStore = flux.NewReduceStore(d, wr.Reduce, Vs6WaitingRoomState{}) wr.buildUI() return wr } -func (wr *WaitingRoomStore) Update() error { +func (wr *Vs6WaitingRoomStore) Update() error { b := time.Now() defer utils.LogTime(wr.Logger, b, "waiting_room update") @@ -52,38 +52,38 @@ func (wr *WaitingRoomStore) Update() error { return nil } -func (wr *WaitingRoomStore) Draw(screen *ebiten.Image) { +func (wr *Vs6WaitingRoomStore) Draw(screen *ebiten.Image) { b := time.Now() defer utils.LogTime(wr.Logger, b, "waiting_room draw") - wrstate := wr.GetState().(WaitingRoomState) + wrstate := wr.GetState().(Vs6WaitingRoomState) wr.textPlayersW.Label = fmt.Sprintf("%d/%d", wrstate.TotalPlayers, wrstate.Size) wr.textColdownW.Label = fmt.Sprintf("(%ds to reduce the size, minimum is 2)", wrstate.Countdown) wr.ui.Draw(screen) } -func (wr *WaitingRoomStore) Reduce(state, a interface{}) interface{} { +func (wr *Vs6WaitingRoomStore) Reduce(state, a interface{}) interface{} { act, ok := a.(*action.Action) if !ok { return state } - wrtate, ok := state.(WaitingRoomState) + wrtate, ok := state.(Vs6WaitingRoomState) if !ok { return state } switch act.Type { - case action.SyncWaitingRoom: - wrtate.TotalPlayers = act.SyncWaitingRoom.TotalPlayers - wrtate.Size = act.SyncWaitingRoom.Size - wrtate.Countdown = act.SyncWaitingRoom.Countdown + case action.SyncVs6WaitingRoom: + wrtate.TotalPlayers = act.SyncVs6WaitingRoom.TotalPlayers + wrtate.Size = act.SyncVs6WaitingRoom.Size + wrtate.Countdown = act.SyncVs6WaitingRoom.Countdown } return wrtate } -func (wr *WaitingRoomStore) buildUI() { +func (wr *Vs6WaitingRoomStore) buildUI() { rootContainer := widget.NewContainer( widget.ContainerOpts.Layout(widget.NewAnchorLayout()), ) @@ -109,7 +109,7 @@ func (wr *WaitingRoomStore) buildUI() { } titleW := widget.NewText( - widget.TextOpts.Text("Waiting for players to join", cutils.NormalFont, color.White), + widget.TextOpts.Text("Vs6Waiting for players to join", cutils.NormalFont, color.White), widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter), widget.TextOpts.WidgetOpts( widget.WidgetOpts.LayoutData(widget.RowLayoutData{ @@ -169,7 +169,7 @@ func (wr *WaitingRoomStore) buildUI() { // add a handler that reacts to clicking the button widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) { - actionDispatcher.ExitWaitingRoom(wr.Store.Users.Username()) + actionDispatcher.ExitVs6WaitingRoom(wr.Store.Users.Username()) }), ) diff --git a/client/wasm/main.go b/client/wasm/main.go index ceacbaa..a8284cc 100644 --- a/client/wasm/main.go +++ b/client/wasm/main.go @@ -76,12 +76,13 @@ func NewClient() js.Func { return fmt.Errorf("failed to initial SignUpStore: %w", err) } - wr := client.NewWaitingRoomStore(d, cls, l) + wr6 := client.NewVs6WaitingRoomStore(d, cls, l) + wr1 := client.NewVs1WaitingRoomStore(d, cls, l) lv := client.NewLobbiesView(cls, l) nlv := client.NewNewLobbyView(cls, l) slv := client.NewShowLobbyView(cls, l) - rs := client.NewRouterStore(d, u, ros, wr, g, lv, nlv, slv, l) + rs := client.NewRouterStore(d, u, ros, wr6, wr1, g, lv, nlv, slv, l) ctx := context.Background() // We need to run this in a goroutine so when it's compiled to WASM diff --git a/cmd/client/main.go b/cmd/client/main.go index 87c8901..f887291 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -91,13 +91,14 @@ var ( return fmt.Errorf("failed to initial SignUpStore: %w", err) } - wr := client.NewWaitingRoomStore(d, cls, l) + wr6 := client.NewVs6WaitingRoomStore(d, cls, l) + wr1 := client.NewVs1WaitingRoomStore(d, cls, l) lv := client.NewLobbiesView(cls, l) nlv := client.NewNewLobbyView(cls, l) slv := client.NewShowLobbyView(cls, l) - rs := client.NewRouterStore(d, su, ros, wr, g, lv, nlv, slv, l) + rs := client.NewRouterStore(d, su, ros, wr6, wr1, g, lv, nlv, slv, l) ctx := context.Background() err = client.New(ctx, ad, rs, opt) diff --git a/server/action.go b/server/action.go index 1f7479d..c97d2f2 100644 --- a/server/action.go +++ b/server/action.go @@ -21,7 +21,13 @@ type ActionDispatcher struct { ws WSConnector } -const noRoomID = "" +const ( + noRoomID = "" + + noVs = "no-vs" + vs1 = "vs1" + vs6 = "vs6" +) // NewActionDispatcher initializes the action dispatcher // with the give dispatcher @@ -41,10 +47,14 @@ func (ac *ActionDispatcher) Dispatch(a *action.Action) { defer utils.LogTime(ac.logger, b, "action dispatch", "action", a.Type) switch a.Type { - case action.JoinWaitingRoom: + case action.JoinVs6WaitingRoom: ac.dispatcher.Dispatch(a) - ac.startGame(noRoomID) + ac.startGame(vs6, noRoomID) + case action.JoinVs1WaitingRoom: + ac.dispatcher.Dispatch(a) + + ac.startGame(vs1, noRoomID) case action.DeleteLobby: l := ac.store.Lobbies.FindByID(a.DeleteLobby.LobbyID) ac.dispatcher.Dispatch(a) @@ -67,7 +77,7 @@ func (ac *ActionDispatcher) Dispatch(a *action.Action) { // * I start the room // * I delete the lobby ac.dispatcher.Dispatch(a) - ac.startGame(a.StartLobby.LobbyID) + ac.startGame(noVs, a.StartLobby.LobbyID) ac.dispatcher.Dispatch(action.NewDeleteLobby(a.StartLobby.LobbyID)) default: ac.dispatcher.Dispatch(a) @@ -110,12 +120,17 @@ func (ac *ActionDispatcher) notifyPlayersLobbyDeleted(uns map[string]bool) { } } -func (ac *ActionDispatcher) startGame(roid string) { +func (ac *ActionDispatcher) startGame(vs, roid string) { var rid = roid // If no rid is passed then the WR is the one chosen and // will only start if it has the number of players if rid == "" { - r := ac.store.Rooms.FindCurrentWaitingRoom() + var r *Room + if vs == vs6 { + r = ac.store.Rooms.FindCurrentVs6WaitingRoom() + } else if vs == vs1 { + r = ac.store.Rooms.FindCurrentVs1WaitingRoom() + } if r == nil || (len(r.Players) != r.Size) { return } @@ -151,7 +166,7 @@ func (ac *ActionDispatcher) WaitRoomCountdownTick() { wrcta := action.NewWaitRoomCountdownTick() ac.Dispatch(wrcta) - ac.startGame(noRoomID) + ac.startGame(vs6, noRoomID) } func (ac *ActionDispatcher) UserSignUp(un string) { @@ -173,9 +188,10 @@ func (ac *ActionDispatcher) UserSignOut(un string) { func (ac *ActionDispatcher) SyncState(rooms *RoomsStore) { ac.Dispatch(action.NewTPS(time.Now())) rms := rooms.List() - cwr := rooms.FindCurrentWaitingRoom() + cwvs6r := rooms.FindCurrentVs6WaitingRoom() + cwvs1r := rooms.FindCurrentVs1WaitingRoom() for _, r := range rms { - if cwr != nil && r.Name == cwr.Name { + if (cwvs6r != nil && r.Name == cwvs6r.Name) || (cwvs1r != nil && r.Name == cwvs1r.Name) { continue } for id, pc := range r.Players { @@ -267,11 +283,11 @@ func (ac *ActionDispatcher) SyncUsers(users *UsersStore) { } } -func (ac *ActionDispatcher) SyncWaitingRoom(rooms *RoomsStore) { +func (ac *ActionDispatcher) SyncVs6WaitingRoom(rooms *RoomsStore) { rstate := rooms.GetState().(RoomsState) - if rstate.CurrentWaitingRoom != "" { - cwr := rstate.Rooms[rstate.CurrentWaitingRoom] - swra := action.NewSyncWaitingRoom( + if rstate.CurrentVs6WaitingRoom != "" { + cwr := rstate.Rooms[rstate.CurrentVs6WaitingRoom] + swra := action.NewSyncVs6WaitingRoom( len(cwr.Players), cwr.Size, cwr.Countdown, @@ -285,6 +301,23 @@ func (ac *ActionDispatcher) SyncWaitingRoom(rooms *RoomsStore) { } } +func (ac *ActionDispatcher) SyncVs1WaitingRoom(rooms *RoomsStore) { + rstate := rooms.GetState().(RoomsState) + if rstate.CurrentVs1WaitingRoom != "" { + cwr := rstate.Rooms[rstate.CurrentVs1WaitingRoom] + swra := action.NewSyncVs1WaitingRoom( + len(cwr.Players), + cwr.Size, + ) + for _, p := range cwr.Players { + err := ac.ws.Write(context.Background(), p.Conn, swra) + if err != nil { + log.Fatal(err) + } + } + } +} + // SyncLobbies will just sync the info of each lobby to the players on it func (ac *ActionDispatcher) SyncLobbies(s *Store) { lbs := s.Lobbies.List() diff --git a/server/action_test.go b/server/action_test.go index e4071c3..dcfbcb3 100644 --- a/server/action_test.go +++ b/server/action_test.go @@ -99,7 +99,7 @@ func TestUserSignOut(t *testing.T) { }) } -func TestJoinWaitingRoom(t *testing.T) { +func TestJoinv6WaitingRoom(t *testing.T) { t.Run("Success", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -113,7 +113,7 @@ func TestJoinWaitingRoom(t *testing.T) { ad.UserSignUp(un) ad.UserSignIn(un, ra, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) u := &server.User{ @@ -126,8 +126,8 @@ func TestJoinWaitingRoom(t *testing.T) { us.Users[un] = u rs := roomsInitialState() - cwrid := s.Rooms.FindCurrentWaitingRoom().Name - rs.CurrentWaitingRoom = cwrid + cwrid := s.Rooms.FindCurrentv6WaitingRoom().Name + rs.Currentv6WaitingRoom = cwrid rs.Rooms[cwrid] = &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -163,9 +163,9 @@ func TestJoinWaitingRoom(t *testing.T) { ad.UserSignUp(un2) ad.UserSignIn(un2, ra2, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) - a = action.NewJoinWaitingRoom(un2) + a = action.NewJoinv6WaitingRoom(un2) ad.Dispatch(a) dbu, _ := s.Users.FindByUsername(un) @@ -187,8 +187,8 @@ func TestJoinWaitingRoom(t *testing.T) { us.Users[un2] = u2 rs := roomsInitialState() - cwrid := s.Rooms.FindCurrentWaitingRoom().Name - rs.CurrentWaitingRoom = cwrid + cwrid := s.Rooms.FindCurrentv6WaitingRoom().Name + rs.Currentv6WaitingRoom = cwrid rs.Rooms[cwrid] = &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -228,7 +228,7 @@ func TestWaitRoomCountdownTick(t *testing.T) { ad.UserSignUp(un) ad.UserSignIn(un, ra, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) a = action.NewWaitRoomCountdownTick() ad.Dispatch(a) @@ -243,8 +243,8 @@ func TestWaitRoomCountdownTick(t *testing.T) { us.Users[un] = u rs := roomsInitialState() - cwrid := s.Rooms.FindCurrentWaitingRoom().Name - rs.CurrentWaitingRoom = cwrid + cwrid := s.Rooms.FindCurrentv6WaitingRoom().Name + rs.Currentv6WaitingRoom = cwrid rs.Rooms[cwrid] = &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -277,7 +277,7 @@ func TestWaitRoomCountdownTick(t *testing.T) { ad.UserSignUp(un) ad.UserSignIn(un, ra, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) for i := 0; i < 11; i++ { @@ -295,8 +295,8 @@ func TestWaitRoomCountdownTick(t *testing.T) { us.Users[un] = u rs := roomsInitialState() - cwrid := s.Rooms.FindCurrentWaitingRoom().Name - rs.CurrentWaitingRoom = cwrid + cwrid := s.Rooms.FindCurrentv6WaitingRoom().Name + rs.Currentv6WaitingRoom = cwrid rs.Rooms[cwrid] = &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -317,7 +317,7 @@ func TestWaitRoomCountdownTick(t *testing.T) { }) } -func TestExitWaitingRoom(t *testing.T) { +func TestExitv6WaitingRoom(t *testing.T) { t.Run("Success2Players", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -335,11 +335,11 @@ func TestExitWaitingRoom(t *testing.T) { ad.UserSignUp(un2) ad.UserSignIn(un2, ra2, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) - a = action.NewJoinWaitingRoom(un2) + a = action.NewJoinv6WaitingRoom(un2) ad.Dispatch(a) - a = action.NewExitWaitingRoom(un) + a = action.NewExitv6WaitingRoom(un) ad.Dispatch(a) dbu, _ := s.Users.FindByUsername(un) u := &server.User{ @@ -360,8 +360,8 @@ func TestExitWaitingRoom(t *testing.T) { us.Users[un2] = u2 rs := roomsInitialState() - cwrid := s.Rooms.FindCurrentWaitingRoom().Name - rs.CurrentWaitingRoom = cwrid + cwrid := s.Rooms.FindCurrentv6WaitingRoom().Name + rs.Currentv6WaitingRoom = cwrid rs.Rooms[cwrid] = &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -403,10 +403,10 @@ func TestStartGame(t *testing.T) { for un, ra := range users { ad.UserSignUp(un) ad.UserSignIn(un, ra, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) if cwr == nil { - cwr = s.Rooms.FindCurrentWaitingRoom() + cwr = s.Rooms.FindCurrentv6WaitingRoom() } } @@ -464,10 +464,10 @@ func TestStartGame(t *testing.T) { for un, ra := range users { ad.UserSignUp(un) ad.UserSignIn(un, ra, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) if cwr == nil { - cwr = s.Rooms.FindCurrentWaitingRoom() + cwr = s.Rooms.FindCurrentv6WaitingRoom() } } @@ -492,7 +492,7 @@ func TestStartGame(t *testing.T) { rs := roomsInitialState() require.NotNil(t, cwr.Game) - rs.CurrentWaitingRoom = "" + rs.Currentv6WaitingRoom = "" rs.Rooms[cwr.Name] = &server.Room{ Name: cwr.Name, Players: make(map[string]server.PlayerConn), @@ -536,12 +536,12 @@ func TestRemovePlayer(t *testing.T) { ad.UserSignUp(un2) ad.UserSignIn(un2, ra2, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) - a = action.NewJoinWaitingRoom(un2) + a = action.NewJoinv6WaitingRoom(un2) ad.Dispatch(a) - cwr := s.Rooms.FindCurrentWaitingRoom() + cwr := s.Rooms.FindCurrentv6WaitingRoom() // Countdown from 6 users to 2 users for i := 1; i <= 44; i++ { @@ -608,12 +608,12 @@ func TestRemovePlayer(t *testing.T) { ad.UserSignUp(un2) ad.UserSignIn(un2, ra2, ws) - a := action.NewJoinWaitingRoom(un) + a := action.NewJoinv6WaitingRoom(un) ad.Dispatch(a) - a = action.NewJoinWaitingRoom(un2) + a = action.NewJoinv6WaitingRoom(un2) ad.Dispatch(a) - cwr := s.Rooms.FindCurrentWaitingRoom() + cwr := s.Rooms.FindCurrentv6WaitingRoom() // Countdown from 6 users to 2 users for i := 1; i <= 44; i++ { diff --git a/server/assets/wasm/maze-wars.wasm b/server/assets/wasm/maze-wars.wasm index fc76bd7..e306347 100755 Binary files a/server/assets/wasm/maze-wars.wasm and b/server/assets/wasm/maze-wars.wasm differ diff --git a/server/new.go b/server/new.go index 2586d8e..850cbe9 100644 --- a/server/new.go +++ b/server/new.go @@ -289,7 +289,8 @@ func startLoop(ctx context.Context, s *Store) { case <-secondTicker.C: actionDispatcher.IncomeTick(s.Rooms) actionDispatcher.WaitRoomCountdownTick() - actionDispatcher.SyncWaitingRoom(s.Rooms) + actionDispatcher.SyncVs6WaitingRoom(s.Rooms) + actionDispatcher.SyncVs1WaitingRoom(s.Rooms) actionDispatcher.SyncLobbies(s) case <-usersTicker.C: actionDispatcher.SyncUsers(s.Users) diff --git a/server/rooms.go b/server/rooms.go index 421ce96..cd6a067 100644 --- a/server/rooms.go +++ b/server/rooms.go @@ -22,8 +22,9 @@ type RoomsStore struct { } type RoomsState struct { - Rooms map[string]*Room - CurrentWaitingRoom string + Rooms map[string]*Room + CurrentVs6WaitingRoom string + CurrentVs1WaitingRoom string } type Room struct { @@ -74,12 +75,24 @@ func (rs *RoomsStore) List() []*Room { return rooms } -func (rs *RoomsStore) FindCurrentWaitingRoom() *Room { +func (rs *RoomsStore) FindCurrentVs6WaitingRoom() *Room { rs.mxRooms.RLock() defer rs.mxRooms.RUnlock() srooms := rs.GetState().(RoomsState) - r, ok := srooms.Rooms[srooms.CurrentWaitingRoom] + r, ok := srooms.Rooms[srooms.CurrentVs6WaitingRoom] + if !ok { + return nil + } + return r +} + +func (rs *RoomsStore) FindCurrentVs1WaitingRoom() *Room { + rs.mxRooms.RLock() + defer rs.mxRooms.RUnlock() + + srooms := rs.GetState().(RoomsState) + r, ok := srooms.Rooms[srooms.CurrentVs1WaitingRoom] if !ok { return nil } @@ -135,8 +148,11 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { } pcount++ } - if rid == rstate.CurrentWaitingRoom { - rstate.CurrentWaitingRoom = "" + if rid == rstate.CurrentVs6WaitingRoom { + rstate.CurrentVs6WaitingRoom = "" + } + if rid == rstate.CurrentVs1WaitingRoom { + rstate.CurrentVs1WaitingRoom = "" } g.Dispatch(action.NewStartGame()) case action.StartLobby: @@ -181,11 +197,11 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { if ok && u.CurrentRoomID != "" { removePlayer(&rstate, u.ID, u.CurrentRoomID) } - case action.JoinWaitingRoom: + case action.JoinVs6WaitingRoom: rs.mxRooms.Lock() defer rs.mxRooms.Unlock() - if rstate.CurrentWaitingRoom == "" { + if rstate.CurrentVs6WaitingRoom == "" { rid := uuid.Must(uuid.NewV4()) rstate.Rooms[rid.String()] = &Room{ Name: rid.String(), @@ -195,11 +211,34 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { Size: 6, Countdown: 10, } - rstate.CurrentWaitingRoom = rid.String() + rstate.CurrentVs6WaitingRoom = rid.String() + } + + us, _ := rs.Store.Users.FindByUsername(act.JoinVs6WaitingRoom.Username) + wr := rstate.Rooms[rstate.CurrentVs6WaitingRoom] + wr.Players[us.ID] = PlayerConn{ + Conn: us.Conn, + RemoteAddr: us.RemoteAddr, + } + wr.Connections[us.RemoteAddr] = us.ID + case action.JoinVs1WaitingRoom: + rs.mxRooms.Lock() + defer rs.mxRooms.Unlock() + + if rstate.CurrentVs1WaitingRoom == "" { + rid := uuid.Must(uuid.NewV4()) + rstate.Rooms[rid.String()] = &Room{ + Name: rid.String(), + Players: make(map[string]PlayerConn), + Connections: make(map[string]string), + + Size: 2, + } + rstate.CurrentVs1WaitingRoom = rid.String() } - us, _ := rs.Store.Users.FindByUsername(act.JoinWaitingRoom.Username) - wr := rstate.Rooms[rstate.CurrentWaitingRoom] + us, _ := rs.Store.Users.FindByUsername(act.JoinVs1WaitingRoom.Username) + wr := rstate.Rooms[rstate.CurrentVs1WaitingRoom] wr.Players[us.ID] = PlayerConn{ Conn: us.Conn, RemoteAddr: us.RemoteAddr, @@ -209,11 +248,11 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { rs.mxRooms.Lock() defer rs.mxRooms.Unlock() - if rstate.CurrentWaitingRoom == "" { + if rstate.CurrentVs6WaitingRoom == "" { break } - wr := rstate.Rooms[rstate.CurrentWaitingRoom] + wr := rstate.Rooms[rstate.CurrentVs6WaitingRoom] wr.Countdown-- if wr.Countdown == -1 { if wr.Size > 2 { @@ -223,18 +262,31 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { wr.Countdown = 0 } } - case action.ExitWaitingRoom: + case action.ExitVs6WaitingRoom: + rs.mxRooms.Lock() + defer rs.mxRooms.Unlock() + + us, _ := rs.Store.Users.FindByUsername(act.ExitVs6WaitingRoom.Username) + delete(rstate.Rooms[rstate.CurrentVs6WaitingRoom].Players, us.ID) + delete(rstate.Rooms[rstate.CurrentVs6WaitingRoom].Connections, us.RemoteAddr) + + // If there are no more players waiting remove the room + if len(rstate.Rooms[rstate.CurrentVs6WaitingRoom].Players) == 0 { + delete(rstate.Rooms, rstate.CurrentVs6WaitingRoom) + rstate.CurrentVs6WaitingRoom = "" + } + case action.ExitVs1WaitingRoom: rs.mxRooms.Lock() defer rs.mxRooms.Unlock() - us, _ := rs.Store.Users.FindByUsername(act.ExitWaitingRoom.Username) - delete(rstate.Rooms[rstate.CurrentWaitingRoom].Players, us.ID) - delete(rstate.Rooms[rstate.CurrentWaitingRoom].Connections, us.RemoteAddr) + us, _ := rs.Store.Users.FindByUsername(act.ExitVs1WaitingRoom.Username) + delete(rstate.Rooms[rstate.CurrentVs1WaitingRoom].Players, us.ID) + delete(rstate.Rooms[rstate.CurrentVs1WaitingRoom].Connections, us.RemoteAddr) // If there are no more players waiting remove the room - if len(rstate.Rooms[rstate.CurrentWaitingRoom].Players) == 0 { - delete(rstate.Rooms, rstate.CurrentWaitingRoom) - rstate.CurrentWaitingRoom = "" + if len(rstate.Rooms[rstate.CurrentVs1WaitingRoom].Players) == 0 { + delete(rstate.Rooms, rstate.CurrentVs1WaitingRoom) + rstate.CurrentVs1WaitingRoom = "" } default: @@ -244,7 +296,7 @@ func (rs *RoomsStore) Reduce(state, a interface{}) interface{} { // If no room means that is a broadcast if act.Room == "" { for _, r := range rstate.Rooms { - if r.Name != rstate.CurrentWaitingRoom { + if r.Name != rstate.CurrentVs6WaitingRoom && r.Name != rstate.CurrentVs1WaitingRoom { go r.Game.Dispatch(act) } } diff --git a/server/rooms_test.go b/server/rooms_test.go index 1864e55..7b65631 100644 --- a/server/rooms_test.go +++ b/server/rooms_test.go @@ -44,7 +44,7 @@ func TestRoom_List(t *testing.T) { RemoteAddr: ra, } - cwrid := s.Rooms.FindCurrentWaitingRoom().Name + cwrid := s.Rooms.FindCurrentVs6WaitingRoom().Name er := &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -64,7 +64,7 @@ func TestRoom_List(t *testing.T) { }) }) } -func TestRoom_FindCurrentWaitingRoom(t *testing.T) { +func TestRoom_FindCurrentVs6WaitingRoom(t *testing.T) { t.Run("Success", func(t *testing.T) { t.Run("Empty", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -72,7 +72,7 @@ func TestRoom_FindCurrentWaitingRoom(t *testing.T) { mwsc := mock.NewMockWSConnector(ctrl) _, s := initStore(mwsc) - assert.Nil(t, s.Rooms.FindCurrentWaitingRoom()) + assert.Nil(t, s.Rooms.FindCurrentVs6WaitingRoom()) }) t.Run("WithRoom", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -97,7 +97,7 @@ func TestRoom_FindCurrentWaitingRoom(t *testing.T) { RemoteAddr: ra, } - cwrid := s.Rooms.FindCurrentWaitingRoom().Name + cwrid := s.Rooms.FindCurrentVs6WaitingRoom().Name er := &server.Room{ Name: cwrid, Players: map[string]server.PlayerConn{ @@ -113,7 +113,7 @@ func TestRoom_FindCurrentWaitingRoom(t *testing.T) { Size: 6, Countdown: 10, } - assert.Equal(t, er, s.Rooms.FindCurrentWaitingRoom()) + assert.Equal(t, er, s.Rooms.FindCurrentVs6WaitingRoom()) }) }) } @@ -136,7 +136,7 @@ func TestRoom_GetNextID(t *testing.T) { a := action.NewJoinWaitingRoom(un) ad.Dispatch(a) - cwrid := s.Rooms.FindCurrentWaitingRoom().Name + cwrid := s.Rooms.FindCurrentVs6WaitingRoom().Name assert.Equal(t, 1, s.Rooms.GetNextID(cwrid)) un2 := "user name2" diff --git a/store/lines.go b/store/lines.go index 3332d2e..de53d4e 100644 --- a/store/lines.go +++ b/store/lines.go @@ -123,9 +123,6 @@ func (t *Tower) CanAttackUnit(u *Unit) bool { } func (t *Tower) CanAttack(tm time.Time) bool { - if t.LastAttack.IsZero() { - return true - } return tm.Sub(t.LastAttack) > time.Duration(int(tower.Towers[t.Type].AttackSpeed*float64(time.Second))) } @@ -368,9 +365,6 @@ func (u *Unit) CanAttack(tm time.Time) bool { if !u.HasAbility(ability.Attack) { return false } - if u.LastAttack.IsZero() { - return true - } return tm.Sub(u.LastAttack) > time.Duration(int(unit.Units[u.Type].AttackSpeed*float64(time.Second))) } @@ -574,7 +568,7 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} { Lives: 20, LineID: act.AddPlayer.LineID, Income: 25, - Gold: 40000, + Gold: 40, UnitUpdates: make(map[string]UnitUpdate), } @@ -695,6 +689,7 @@ func (ls *Lines) Reduce(state, a interface{}) interface{} { MovementSpeed: uu.Current.MovementSpeed, Bounty: uu.Current.Income, CreatedAt: time.Now(), + LastAttack: time.Now(), } if u.HasAbility(ability.Hybrid) { @@ -1285,10 +1280,11 @@ func (ls *Lines) changeUnitLine(lstate LinesState, u *Unit, nlid int) { func (ls *Lines) newTower(tt string, p *Player, o utils.Object) *Tower { ot := tower.Towers[tt] return &Tower{ - Object: o, - Type: tt, - LineID: p.LineID, - PlayerID: p.ID, - Health: ot.Health, + Object: o, + Type: tt, + LineID: p.LineID, + PlayerID: p.ID, + Health: ot.Health, + LastAttack: time.Now(), } } diff --git a/utils/routes.go b/utils/routes.go index 5b37083..314f393 100644 --- a/utils/routes.go +++ b/utils/routes.go @@ -1,11 +1,12 @@ package utils const ( - SignUpRoute = "sign_up" - RootRoute = "root" - GameRoute = "game" - WaitingRoomRoute = "waiting_room" - LobbiesRoute = "lobbies" - NewLobbyRoute = "new_lobby" - ShowLobbyRoute = "show_lobby" + SignUpRoute = "sign_up" + RootRoute = "root" + GameRoute = "game" + Vs6WaitingRoomRoute = "vs6_waiting_room" + Vs1WaitingRoomRoute = "vs1_waiting_room" + LobbiesRoute = "lobbies" + NewLobbyRoute = "new_lobby" + ShowLobbyRoute = "show_lobby" )