diff --git a/package.json b/package.json index 9b57343..74a0590 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.13.3", + "version": "0.13.4", "private": true, "devDependencies": { "dateformat": "^3.0.3", diff --git a/src/client/haxe/ru/m/tankz/network/NetworkManager.hx b/src/client/haxe/ru/m/tankz/network/NetworkManager.hx index 17f495f..e926c73 100644 --- a/src/client/haxe/ru/m/tankz/network/NetworkManager.hx +++ b/src/client/haxe/ru/m/tankz/network/NetworkManager.hx @@ -90,7 +90,7 @@ class NetworkManager { } public function joinGame(gameId:Int, restore:Bool = false):Void { - connection.send(new Request().setRoom(new RoomRequest().setJoin(new JoinRequest().setGameId(gameId)))); + connection.send(new Request().setRoom(new RoomRequest().setJoin(new JoinRequest().setGameId(gameId).setRestore(restore)))); } public function selectSlot(slot:SlotProto):Void { diff --git a/src/client/haxe/ru/m/tankz/view/network/RoomFrame.yaml b/src/client/haxe/ru/m/tankz/view/network/RoomFrame.yaml index 4a7dc2c..448f44f 100644 --- a/src/client/haxe/ru/m/tankz/view/network/RoomFrame.yaml +++ b/src/client/haxe/ru/m/tankz/view/network/RoomFrame.yaml @@ -3,6 +3,7 @@ views: - $type: haxework.view.VGroupView skinId: container geometry.padding: 20 + layout.margin: 10 views: - id: header $type: haxework.view.LabelView diff --git a/src/client/haxe/ru/m/tankz/view/network/RoomListFrame.hx b/src/client/haxe/ru/m/tankz/view/network/RoomListFrame.hx index bb2e998..40f0c26 100644 --- a/src/client/haxe/ru/m/tankz/view/network/RoomListFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/network/RoomListFrame.hx @@ -1,5 +1,6 @@ package ru.m.tankz.view.network; +import ru.m.tankz.view.popup.CreateGamePopup; import haxework.view.frame.FrameSwitcher; import haxework.view.list.VListView; import haxework.view.VGroupView; @@ -27,7 +28,11 @@ import ru.m.tankz.proto.room.RoomProto; } private function create():Void { - network.createGame("classic", 0); + CreateGamePopup.instance.show().then(function(result) { + if (result != null) { + network.createGame(result.type, result.level); + } + }); } private function onRoomList(data:Array):Void { diff --git a/src/client/haxe/ru/m/tankz/view/network/SlotItemView.hx b/src/client/haxe/ru/m/tankz/view/network/SlotItemView.hx index 37f70fe..fca088f 100644 --- a/src/client/haxe/ru/m/tankz/view/network/SlotItemView.hx +++ b/src/client/haxe/ru/m/tankz/view/network/SlotItemView.hx @@ -3,6 +3,7 @@ package ru.m.tankz.view.network; import haxework.view.HGroupView; import haxework.view.LabelView; import haxework.view.list.ListView; +import ru.m.tankz.network.NetworkManager; import ru.m.tankz.proto.room.RoomSlotProto; @:template class SlotItemView extends HGroupView implements IListItemView { @@ -12,9 +13,12 @@ import ru.m.tankz.proto.room.RoomSlotProto; @:view var label:LabelView; + @:provide static var network:NetworkManager; + private function set_data(value:RoomSlotProto):RoomSlotProto { data = value; label.text = '${value.slot.team}-${value.slot.index} ${value.hasUser() ? value.user.name : '(NONE)'}'; + label.skinId = (value.hasUser() && value.user.uuid == network.user.uuid) ? "text.box.active" : "text.box"; return data; } diff --git a/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx new file mode 100644 index 0000000..bd4f991 --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx @@ -0,0 +1,72 @@ +package ru.m.tankz.view.popup; + +import haxework.view.DataView; +import haxework.view.popup.PopupView; +import haxework.view.ToggleButtonView; +import ru.m.tankz.bundle.IConfigBundle; +import ru.m.tankz.Type; + +private typedef Result = { + var type:GameType; + var level:LevelId; +} + +@:template class CreateGamePopup extends PopupView { + + @:view("type") var typeView:DataView; + @:view("level") var levelView:DataView; + + @:provide var configBundle:IConfigBundle; + + private var type:GameType; + private var level:LevelId; + + override private function onShow():Void { + super.onShow(); + onGameTypeSelect(0, "classic", typeView.dataViews[0]); + } + + private function submit():Void { + close({type:type, level:level}); + } + + private function gameTypeViewFactory(index:Int, type:GameType):ToggleButtonView { + var result = new ToggleButtonView(); + result.skinId = "button.simple"; + result.text = type; + result.on = type == this.type; + return result; + } + + private function onGameTypeSelect(index:Int, value:GameType, view:ToggleButtonView):Void { + this.type = value; + for (v in typeView.dataViews) { + v.on = v == view; + } + levelView.data = [for (i in 0...configBundle.get(type).game.levels) i]; + onLevelSelect(0, 0, levelView.dataViews[0]); + } + + private function levelViewFactory(index:Int, value:LevelId):ToggleButtonView { + var result = new ToggleButtonView(); + result.skinId = "button.level"; + result.text = Std.string(value); + return result; + } + + private function onLevelSelect(index:Int, level:LevelId, view:ToggleButtonView):Void { + this.level = level; + for (v in levelView.dataViews) { + v.on = v == view; + } + } + + public static var instance(get, null):CreateGamePopup; + + private static function get_instance():CreateGamePopup { + if (instance == null) { + instance = new CreateGamePopup(); + } + return instance; + } +} diff --git a/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.yaml b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.yaml new file mode 100644 index 0000000..4642d70 --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.yaml @@ -0,0 +1,68 @@ +--- +layout.hAlign: center +layout.vAlign: middle +view: + $type: haxework.view.VGroupView + layout.hAlign: center + geometry.size.width: 600 + skinId: window + views: + - $type: haxework.view.HGroupView + geometry.size.width: 100% + geometry.padding: 10 + layout.vAlign: middle + views: + - id: name + $type: haxework.view.LabelView + geometry.size.width: 100% + geometry.margin.left: 10 + layout.hAlign: left + skinId: text + text: New game + - $type: haxework.view.ButtonView + skinId: window.close + +onPress: $code:reject('close') + - $type: haxework.view.VGroupView + geometry.size.width: 100% + geometry.padding: 20 + layout.margin: 5 + layout.hAlign: center + views: + - $type: haxework.view.LabelView + geometry.size.width: 100% + skinId: text + text: Type + - id: type + $type: haxework.view.DataView + layout: + $type: haxework.view.layout.HorizontalLayout + margin: 10 + factory: $this:gameTypeViewFactory + +onItemSelect: $this:onGameTypeSelect + data: + - "classic" + - "dota" + - "death" + - $type: haxework.view.LabelView + geometry.size.width: 100% + skinId: text + text: Level + - id: level + $type: haxework.view.DataView + geometry.size.width: 100% + layout: + $type: haxework.view.layout.TailLayout + rowSize: 10 + margin: 5 + factory: $this:levelViewFactory + +onItemSelect: $this:onLevelSelect + geometry.padding: 10 + - $type: haxework.view.HGroupView + layout.hAlign: center + layout.margin: 5 + skinId: panel + views: + - $type: haxework.view.ButtonView + skinId: button.simple + text: Create + +onPress: $code:submit() diff --git a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx index c7262d7..a42f600 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx +++ b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx @@ -8,7 +8,7 @@ import haxework.view.popup.PopupView; import ru.m.tankz.config.Config; import ru.m.tankz.game.GameProgress; -typedef Result = { +private typedef Result = { var control:ControlPreset; var preset:GamePreset; } diff --git a/src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml b/src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml index bccd258..47dcf94 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml +++ b/src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml @@ -42,12 +42,14 @@ view: geometry.size.width: 100% skinId: text text: Password + visible: false - id: password $type: haxework.view.InputView textField.displayAsPassword: true geometry.size.width: 100% geometry.size.height: 28 skinId: text.box + visible: false - id: error $type: haxework.view.TextView geometry.size.width: 100% diff --git a/src/common/proto/room.proto b/src/common/proto/room.proto index 038d188..831f289 100644 --- a/src/common/proto/room.proto +++ b/src/common/proto/room.proto @@ -28,6 +28,7 @@ message CreateRequest { message JoinRequest { int32 gameId = 1; + bool restore = 2; } message LeaveRequest { diff --git a/src/server/haxe/ru/m/tankz/server/session/GameSession.hx b/src/server/haxe/ru/m/tankz/server/session/GameSession.hx index c03296a..da26f54 100644 --- a/src/server/haxe/ru/m/tankz/server/session/GameSession.hx +++ b/src/server/haxe/ru/m/tankz/server/session/GameSession.hx @@ -92,6 +92,12 @@ class GameSession extends ProtoSession implements GameManager } else if (request.room.hasJoin()) { gameId = request.room.join.gameId; gameManager.join(gameId, user); + var game = gameManager.gamesById[gameId]; + if (request.room.join.restore && game.room.game.started) { + for (event in game.restore()) { + send(new Response().setGameEvent(new GameEventResponse().setTime(0).setEvent(Serializer.run(event)))); + } + } } else if (request.room.hasLeave()) { gameManager.leave(user); } else if (request.room.hasSlot()) {