From 13d01293f67265358e65e31523b33f0752e2118a Mon Sep 17 00:00:00 2001 From: shmyga Date: Mon, 8 Apr 2019 14:53:44 +0300 Subject: [PATCH] [common] diffilicity presets support --- src/client/haxe/ru/m/skin/ButtonSVGSkin.hx | 1 + src/client/haxe/ru/m/tankz/Style.hx | 33 ++++++++ .../haxe/ru/m/tankz/bundle/LevelBundle.hx | 8 +- .../m/tankz/control/ClientControlFactory.hx | 1 - .../haxe/ru/m/tankz/storage/GameStorage.hx | 4 +- src/client/haxe/ru/m/tankz/view/LevelFrame.hx | 31 ++++--- .../haxe/ru/m/tankz/view/ResultFrame.hx | 18 ++--- .../m/tankz/view/classic/ClassicGamePanel.hx | 2 +- .../haxe/ru/m/tankz/view/common/GameFrame.hx | 2 +- .../ru/m/tankz/view/death/DeathGamePanel.hx | 2 +- .../ru/m/tankz/view/dota/DotaGamePanel.hx | 2 +- .../haxe/ru/m/tankz/view/popup/LevelPopup.hx | 31 +++++-- .../ru/m/tankz/view/popup/LevelPopup.yaml | 14 ++-- .../resources/image/icon/frown-open-solid.svg | 1 + .../resources/image/icon/sad-cry-solid.svg | 1 + .../resources/image/icon/smile-solid.svg | 1 + src/common/haxe/ru/m/tankz/Type.hx | 3 +- .../haxe/ru/m/tankz/bundle/ILevelBundle.hx | 3 +- src/common/haxe/ru/m/tankz/config/Config.hx | 5 +- src/common/haxe/ru/m/tankz/control/Control.hx | 6 -- .../haxe/ru/m/tankz/control/Controller.hx | 26 ++++++ src/common/haxe/ru/m/tankz/game/Game.hx | 12 +-- .../haxe/ru/m/tankz/game/GameProgress.hx | 35 ++++++-- src/common/haxe/ru/m/tankz/game/GameState.hx | 23 +++--- src/common/resources/classic/config.yaml | 80 +++++++++++-------- src/common/resources/death/config.yaml | 7 +- src/common/resources/dota/config.yaml | 23 +++--- .../tankz/server/bundle/ServerLevelBundle.hx | 5 +- 28 files changed, 248 insertions(+), 132 deletions(-) create mode 100644 src/client/resources/image/icon/frown-open-solid.svg create mode 100644 src/client/resources/image/icon/sad-cry-solid.svg create mode 100644 src/client/resources/image/icon/smile-solid.svg create mode 100644 src/common/haxe/ru/m/tankz/control/Controller.hx diff --git a/src/client/haxe/ru/m/skin/ButtonSVGSkin.hx b/src/client/haxe/ru/m/skin/ButtonSVGSkin.hx index bb225ab..619d39d 100644 --- a/src/client/haxe/ru/m/skin/ButtonSVGSkin.hx +++ b/src/client/haxe/ru/m/skin/ButtonSVGSkin.hx @@ -28,6 +28,7 @@ class ButtonSVGSkin implements ISkin { svgs.set(ButtonState.UP, buildSVG(color)); svgs.set(ButtonState.DOWN, buildSVG(ColorUtil.diff(color, -24))); svgs.set(ButtonState.OVER, buildSVG(ColorUtil.diff(color, 24))); + svgs.set(ButtonState.DISABLED, buildSVG(ColorUtil.grey(color))); } public function draw(view:ButtonView):Void { diff --git a/src/client/haxe/ru/m/tankz/Style.hx b/src/client/haxe/ru/m/tankz/Style.hx index 3657306..bd0bb27 100644 --- a/src/client/haxe/ru/m/tankz/Style.hx +++ b/src/client/haxe/ru/m/tankz/Style.hx @@ -134,5 +134,38 @@ class Style { Skin.size(64, 64), new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), lightColor), ]); + + resources.skin.put("preset.easy", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/smile-solid.svg"), lightColor), + ]); + resources.skin.put("preset.normal", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/frown-open-solid.svg"), lightColor), + ]); + resources.skin.put("preset.hard", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/sad-cry-solid.svg"), lightColor), + ]); + resources.skin.put("preset.default", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), lightColor), + ]); + resources.skin.put("preset.easy.complete", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/smile-solid.svg"), 0x337733), + ]); + resources.skin.put("preset.normal.complete", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/frown-open-solid.svg"), 0x337733), + ]); + resources.skin.put("preset.hard.complete", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/sad-cry-solid.svg"), 0x337733), + ]); + resources.skin.put("preset.default.complete", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), 0x337733), + ]); } } diff --git a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx index 71de1b3..b611900 100644 --- a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx +++ b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx @@ -11,12 +11,12 @@ class LevelBundle implements ILevelBundle { public function new() {} - public function get(type:GameType, config:Config, level:Int):LevelConfig { - var key = '${type}:${level}'; + public function get(type:GameType, config:Config, levelId:LevelId):LevelConfig { + var key = '${type}:${levelId}'; if (!cache.exists(key)) { - var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(level)}.txt'); + var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(levelId)}.txt'); cache[key] = LevelUtil.loads(config, data); - cache[key].index = level; + cache[key].id = levelId; } return cache[key]; } diff --git a/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx b/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx index 93ac0dc..9dcec88 100644 --- a/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx +++ b/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx @@ -2,7 +2,6 @@ package ru.m.tankz.control; import ru.m.tankz.bot.StupidBotControl; import ru.m.tankz.bot.HardBotControl; -import ru.m.tankz.control.Control.Controller; import ru.m.tankz.Type; class ClientControlFactory implements IControlFactory { diff --git a/src/client/haxe/ru/m/tankz/storage/GameStorage.hx b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx index b24b888..ff0fbdb 100644 --- a/src/client/haxe/ru/m/tankz/storage/GameStorage.hx +++ b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx @@ -6,8 +6,10 @@ import ru.m.tankz.Type.GameType; class GameStorage extends SharedObjectStorage { + private static inline var VERSION = 1; + public function new() { - super("game"); + super('game_${VERSION}'); } public function get(type:GameType):GameProgress { diff --git a/src/client/haxe/ru/m/tankz/view/LevelFrame.hx b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx index 5aaa9cf..19acf93 100644 --- a/src/client/haxe/ru/m/tankz/view/LevelFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx @@ -1,6 +1,5 @@ package ru.m.tankz.view; -import haxework.resources.IResources; import haxework.view.ButtonView; import haxework.view.DataView; import haxework.view.frame.FrameSwitcher; @@ -13,6 +12,7 @@ import ru.m.tankz.preset.ClassicGame; import ru.m.tankz.preset.DeathGame; import ru.m.tankz.preset.DotaGame; import ru.m.tankz.storage.GameStorage; +import ru.m.tankz.Type; import ru.m.tankz.view.classic.ClassicGameFrame; import ru.m.tankz.view.death.DeathGameFrame; import ru.m.tankz.view.dota.DotaGameFrame; @@ -22,10 +22,9 @@ import ru.m.tankz.view.popup.LevelPopup; public static inline var ID = "level"; @:view var header:LabelView; - @:view var levels:DataView; + @:view var levels:DataView; @:provide var state:GameState; - @:provide var resources:IResources; @:provide var switcher:FrameSwitcher; @:provide var levelBundle:ILevelBundle; @:provide var storage:GameStorage; @@ -37,8 +36,9 @@ import ru.m.tankz.view.popup.LevelPopup; levels.data = [for (i in 0...state.config.game.levels) i]; } - private function start(level:LevelConfig):Void { - state.level = level.index; + private function start(level:LevelConfig, preset:GamePreset):Void { + state.levelId = level.id; + state.presetId = preset.id; switcher.change(switch state.type { case ClassicGame.TYPE: ClassicGameFrame.ID; case DotaGame.TYPE: DotaGameFrame.ID; @@ -47,22 +47,29 @@ import ru.m.tankz.view.popup.LevelPopup; }); } - private function levelViewFactory(index:Int, level:Int):ButtonView { + private function levelViewFactory(index:Int, levelId:LevelId):ButtonView { + var progress = storage.get(state.type); var result = new ButtonView(); result.skinId = "button.level"; - result.text = '${level}'; - result.disabled = !storage.get(state.type).isLevelAvailable(level); + var presetsLine = [for (p in state.config.presets) progress.isPresetCompleted(levelId, p.id) ? '*' : '_'].join(''); + result.text = '${levelId}\n${presetsLine}'; + result.disabled = !progress.isLevelAvailable(levelId); return result; } - private function onLevelSelect(index:Int, level:Int, view:ButtonView):Void { - if (!storage.get(state.type).isLevelAvailable(level)) { + private function onLevelSelect(index:Int, levelId:LevelId, view:ButtonView):Void { + if (!storage.get(state.type).isLevelAvailable(levelId)) { return; } if (levelPopup == null) { levelPopup = new LevelPopup(); } - levelPopup.level = levelBundle.get(state.type, state.config, level); - levelPopup.show().then(start).catchError(function(_) {}); + var level = levelBundle.get(state.type, state.config, levelId); + levelPopup.setData( + level, + state.config.presets, + storage.get(state.type) + ); + levelPopup.show().then(function(preset) start(level, preset)).catchError(function(_) {}); } } diff --git a/src/client/haxe/ru/m/tankz/view/ResultFrame.hx b/src/client/haxe/ru/m/tankz/view/ResultFrame.hx index 2dba4ec..6c32953 100644 --- a/src/client/haxe/ru/m/tankz/view/ResultFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/ResultFrame.hx @@ -1,17 +1,16 @@ package ru.m.tankz.view; -import haxework.view.LabelView; import haxework.view.ButtonView; import haxework.view.DataView; import haxework.view.frame.FrameSwitcher; +import haxework.view.LabelView; import haxework.view.VGroupView; -import ru.m.tankz.control.Control; -import ru.m.tankz.view.classic.ClassicGameFrame; -import ru.m.tankz.view.common.LifeView; -import ru.m.tankz.view.dota.DotaGameFrame; import ru.m.tankz.game.GameState; import ru.m.tankz.preset.ClassicGame; import ru.m.tankz.preset.DotaGame; +import ru.m.tankz.view.classic.ClassicGameFrame; +import ru.m.tankz.view.common.LifeView; +import ru.m.tankz.view.dota.DotaGameFrame; @:template class ResultFrame extends VGroupView { public static var ID(default, never):String = "result"; @@ -37,11 +36,8 @@ import ru.m.tankz.preset.DotaGame; } public function onShow() { - resultView.data = Lambda.array(Lambda.filter(resultState.players, function(player:PlayerState):Bool return switch player.controller { - case HUMAN(_): true; - case _: false; - })); - levelLabel.text = 'Level ${resultState.level}'; + resultView.data = Lambda.array(resultState.players); + levelLabel.text = 'Level ${resultState.levelId}'; nextButton.visible = state != null; } @@ -54,6 +50,6 @@ import ru.m.tankz.preset.DotaGame; } private function close() { - frames.change(StartFrame.ID); + frames.change(LevelFrame.ID); } } diff --git a/src/client/haxe/ru/m/tankz/view/classic/ClassicGamePanel.hx b/src/client/haxe/ru/m/tankz/view/classic/ClassicGamePanel.hx index dfff1fa..0c002e6 100644 --- a/src/client/haxe/ru/m/tankz/view/classic/ClassicGamePanel.hx +++ b/src/client/haxe/ru/m/tankz/view/classic/ClassicGamePanel.hx @@ -19,7 +19,7 @@ import ru.m.tankz.view.common.LifeView; private var player2Id:PlayerId = new PlayerId(ClassicGame.HUMAN, 1); public function onGameStart(state:GameState):Void { - level.text = 'Level ${state.level}'; + level.text = 'Level ${state.levelId}'; } public function onGameChange(state:GameState):Void { diff --git a/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx index b1c9941..161ced2 100644 --- a/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx @@ -81,7 +81,7 @@ class GameFrame extends GroupView { case Some(s): // ToDo: var progress = storage.get(game.type); - progress.completeLevel(result.level); + progress.completeLevel(result.levelId, result.presetId); storage.set(progress); s; case None: null; diff --git a/src/client/haxe/ru/m/tankz/view/death/DeathGamePanel.hx b/src/client/haxe/ru/m/tankz/view/death/DeathGamePanel.hx index 2422ff2..de000a9 100644 --- a/src/client/haxe/ru/m/tankz/view/death/DeathGamePanel.hx +++ b/src/client/haxe/ru/m/tankz/view/death/DeathGamePanel.hx @@ -14,7 +14,7 @@ import ru.m.tankz.view.common.LifeView; @:view var players:DataView; public function onGameStart(state:GameState):Void { - level.text = 'Level ${state.level}'; + level.text = 'Level ${state.levelId}'; players.data = Lambda.array(state.players); } diff --git a/src/client/haxe/ru/m/tankz/view/dota/DotaGamePanel.hx b/src/client/haxe/ru/m/tankz/view/dota/DotaGamePanel.hx index 5c7ef4f..29a1a70 100644 --- a/src/client/haxe/ru/m/tankz/view/dota/DotaGamePanel.hx +++ b/src/client/haxe/ru/m/tankz/view/dota/DotaGamePanel.hx @@ -14,7 +14,7 @@ import ru.m.tankz.view.common.LifeView; @:view var level:LabelView; public function onGameStart(state:GameState):Void { - level.text = 'Level ${state.level}'; + level.text = 'Level ${state.levelId}'; } public function onGameChange(state:GameState):Void { 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 60497bb..ae1a998 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx +++ b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx @@ -1,20 +1,37 @@ package ru.m.tankz.view.popup; +import haxework.view.ButtonView; +import haxework.view.DataView; import haxework.view.LabelView; import haxework.view.popup.PopupView; import ru.m.tankz.config.Config; +import ru.m.tankz.game.GameProgress; -@:template class LevelPopup extends PopupView { +@:template class LevelPopup extends PopupView { - public var level(default, set):LevelConfig; + private var level:LevelConfig; + private var progress:GameProgress; @:view var name:LabelView; + @:view("presets") var presetsView:DataView; - private function set_level(value:LevelConfig):LevelConfig { - if (level != value) { - level = value; - name.text = '${level.index}. ${level.name != null ? level.name : "#"}'; + public function setData(level:LevelConfig, presets:Array, progress:GameProgress):Void { + this.level = level; + this.progress = progress; + name.text = '${level.id}. ${level.name != null ? level.name : "#"}'; + presetsView.data = presets; + } + + private function presetViewFactory(index:Int, value:GamePreset):ButtonView { + var result = new ButtonView(); + result.skinId = 'preset.${value.name}${progress.isPresetCompleted(level.id, value.id) ? '.complete' : ''}'; + result.disabled = !progress.isPresetAvailable(level.id, value.id); + return result; + } + + private function onPresetSelect(value:GamePreset):Void { + if (progress.isPresetAvailable(level.id, value.id)) { + close(value); } - return level; } } diff --git a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.yaml b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.yaml index 64c0f14..f868fc0 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.yaml +++ b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.yaml @@ -14,10 +14,12 @@ view: geometry.padding: [20, 15] - $type: haxework.view.SpriteView geometry.size.height: 100% - - $type: haxework.view.HGroupView - layout.hAlign: center + - id: presets + $type: haxework.view.DataView + factory: $this:presetViewFactory + +onDataSelect: $this:onPresetSelect + layout: + $type: haxework.view.layout.HorizontalLayout + hAlign: center + margin: 5 skinId: panel - views: - - $type: haxework.view.ButtonView - skinId: button.start - +onPress: $code:close(level) diff --git a/src/client/resources/image/icon/frown-open-solid.svg b/src/client/resources/image/icon/frown-open-solid.svg new file mode 100644 index 0000000..8e6fa18 --- /dev/null +++ b/src/client/resources/image/icon/frown-open-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/client/resources/image/icon/sad-cry-solid.svg b/src/client/resources/image/icon/sad-cry-solid.svg new file mode 100644 index 0000000..135d603 --- /dev/null +++ b/src/client/resources/image/icon/sad-cry-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/client/resources/image/icon/smile-solid.svg b/src/client/resources/image/icon/smile-solid.svg new file mode 100644 index 0000000..91e480f --- /dev/null +++ b/src/client/resources/image/icon/smile-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/common/haxe/ru/m/tankz/Type.hx b/src/common/haxe/ru/m/tankz/Type.hx index decbcd9..ab424a9 100644 --- a/src/common/haxe/ru/m/tankz/Type.hx +++ b/src/common/haxe/ru/m/tankz/Type.hx @@ -37,4 +37,5 @@ abstract PlayerId(Array) { } } -typedef PresetId = String; +typedef LevelId = Int; +typedef PresetId = Int; diff --git a/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx b/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx index 4a05504..5d52878 100644 --- a/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx +++ b/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx @@ -3,7 +3,6 @@ package ru.m.tankz.bundle; import ru.m.tankz.config.Config; import ru.m.tankz.Type; - interface ILevelBundle { - public function get(type:GameType, config:Config, level:Int):LevelConfig; + public function get(type:GameType, config:Config, levelId:LevelId):LevelConfig; } diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 978aff1..e1fb6ce 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -75,7 +75,7 @@ typedef PlayerConfig = { @:optional var protect:Float; @:optional var life:Int; @:optional var color:Color; - @:optional var human:Int; + @:optional var control:String; } typedef EagleConfig = { @@ -93,11 +93,12 @@ typedef TeamConfig = { typedef GamePreset = { var id:PresetId; + var name:String; var teams:Array; } typedef LevelConfig = { - @:optional var index:Int; + @:optional var id:LevelId; var data:Array; @:optional var name:String; @:optional var points:Array; diff --git a/src/common/haxe/ru/m/tankz/control/Control.hx b/src/common/haxe/ru/m/tankz/control/Control.hx index 65ff842..46a83bd 100644 --- a/src/common/haxe/ru/m/tankz/control/Control.hx +++ b/src/common/haxe/ru/m/tankz/control/Control.hx @@ -13,12 +13,6 @@ enum TankAction { SHOT; } -enum Controller { - NONE; - HUMAN(index:Int); - BOT(type:String); -} - class Control { public var playerId(default, null):PlayerId; public var tankId(default, default):Int; diff --git a/src/common/haxe/ru/m/tankz/control/Controller.hx b/src/common/haxe/ru/m/tankz/control/Controller.hx new file mode 100644 index 0000000..cce3cec --- /dev/null +++ b/src/common/haxe/ru/m/tankz/control/Controller.hx @@ -0,0 +1,26 @@ +package ru.m.tankz.control; + +enum Controller { + NONE; + HUMAN(index:Int); + BOT(type:String); +} + +abstract AController(Controller) { + + public inline function new(value:Controller) { + this = value; + } + + @:from public static function fromString(value:String):AController { + return new AController(switch value.split("-") { + case ["human", index]: HUMAN(Std.parseInt(index)); + case ["bot", type]: BOT(type); + case _: NONE; + }); + } + + @:to public inline function toController():Controller { + return this; + } +} diff --git a/src/common/haxe/ru/m/tankz/game/Game.hx b/src/common/haxe/ru/m/tankz/game/Game.hx index 115f518..9db9428 100644 --- a/src/common/haxe/ru/m/tankz/game/Game.hx +++ b/src/common/haxe/ru/m/tankz/game/Game.hx @@ -1,11 +1,11 @@ package ru.m.tankz.game; +import ru.m.tankz.control.Controller.AController; import haxe.ds.Option; import haxe.Timer; import haxework.signal.Signal; import ru.m.geom.Point; import ru.m.tankz.bundle.IConfigBundle; -import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.config.Config; import ru.m.tankz.control.Control; import ru.m.tankz.control.IControlFactory; @@ -62,7 +62,6 @@ class Game extends GameDispatcher { private var points:Array; @:provide var configBundle:IConfigBundle; - @:provide var levelBundle:ILevelBundle; @:provide var controlFactory:IControlFactory; public function new(type:GameType) { @@ -109,7 +108,7 @@ class Game extends GameDispatcher { public function start(state:GameState):Void { this.state = state; this.winner = null; - var level:LevelConfig = levelBundle.get(type, config, state.level); + var level:LevelConfig = state.level; points = level.points != null ? level.points : config.points; engine.map.setData(level.data); teams = new Map(); @@ -118,10 +117,7 @@ class Game extends GameDispatcher { var team:Team = new Team(teamConfig, teamPoints, state.teams[teamConfig.id]); teams[team.id] = team; for (player in team.players.iterator()) { - if (player.state.controller == NONE) { - player.state.controller = BOT("hard"); - } - var control = controlFactory.build(player.id, player.state.controller); + var control = controlFactory.build(player.id, AController.fromString(player.config.control)); L.d(TAG, 'control(${player.id} - ${control})'); if (control != null) { player.control = control; @@ -288,7 +284,7 @@ class Game extends GameDispatcher { return Option.None; } } - var level = this.state.level + 1; + var level = this.state.levelId + 1; if (level >= config.game.levels) level = 0; return Option.Some(new GameState(type, state.presetId, level, state)); } diff --git a/src/common/haxe/ru/m/tankz/game/GameProgress.hx b/src/common/haxe/ru/m/tankz/game/GameProgress.hx index 9f96b12..0291a73 100644 --- a/src/common/haxe/ru/m/tankz/game/GameProgress.hx +++ b/src/common/haxe/ru/m/tankz/game/GameProgress.hx @@ -1,22 +1,45 @@ package ru.m.tankz.game; -import ru.m.tankz.Type.GameType; +import ru.m.tankz.Type; + +typedef LevelResult = { + +} + +typedef LevelProgress = { + var id:LevelId; + var presets:Map; +} class GameProgress { public var type(default, null):GameType; - private var completed(default, null):Map; + private var completed(default, null):Map; public function new(type:GameType) { this.type = type; this.completed = new Map(); } - public function isLevelAvailable(level:Int):Bool { - return level == 0 || completed.get(level - 1); + public function isLevelAvailable(levelId:LevelId):Bool { + return levelId == 0 || completed.exists(levelId - 1); } - public function completeLevel(level:Int):Void { - completed.set(level, true); + public function isPresetAvailable(levelId:LevelId, presetId:PresetId):Bool { + return presetId == 0 || completed.exists(levelId) && completed.get(levelId).presets.get(presetId - 1) != null; + } + + public function isPresetCompleted(levelId:LevelId, presetId:PresetId):Bool { + return completed.exists(levelId) && completed.get(levelId).presets.get(presetId) != null; + } + + public function completeLevel(levelId:LevelId, presetId:PresetId):Void { + if (!completed.exists(levelId)) { + completed[levelId] = { + id: levelId, + presets: new Map(), + } + } + completed[levelId].presets[presetId] = {}; } } diff --git a/src/common/haxe/ru/m/tankz/game/GameState.hx b/src/common/haxe/ru/m/tankz/game/GameState.hx index 237d806..2099a71 100644 --- a/src/common/haxe/ru/m/tankz/game/GameState.hx +++ b/src/common/haxe/ru/m/tankz/game/GameState.hx @@ -2,8 +2,8 @@ package ru.m.tankz.game; import haxework.color.Color; import ru.m.tankz.bundle.IConfigBundle; +import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.config.Config; -import ru.m.tankz.control.Control; import ru.m.tankz.Type; class State { @@ -34,16 +34,14 @@ class State { class PlayerState extends State { public var id:PlayerId; public var tank:TankType; - public var controller:Controller; public var color:Color; public var life:Int; public var total:State; - public function new(id:PlayerId, controller:Controller = null) { + public function new(id:PlayerId) { super(); this.id = id; this.tank = null; - this.controller = controller == null ? Controller.NONE : controller; this.life = 0; this.total = new State(); } @@ -70,18 +68,20 @@ class GameState { public var type:GameType; public var presetId:PresetId; - public var level:Int; + public var levelId:LevelId; public var players:Map; public var teams:Map; public var preset(get, null):GamePreset; public var config(get, null):Config; + public var level(get, null):LevelConfig; @:provide private var configBundle:IConfigBundle; + @:provide private var levelBundle:ILevelBundle; - public function new(type:GameType, presetId:PresetId = null, level:Int = 0, state:GameState = null) { + public function new(type:GameType, presetId:PresetId = 0, levelId:Int = 0, state:GameState = null) { this.type = type; - this.presetId = presetId != null ? presetId : config.presets[0].id; - this.level = level; + this.presetId = presetId; + this.levelId = levelId; if (state == null) { this.teams = new Map(); this.players = new Map(); @@ -89,8 +89,7 @@ class GameState { var teamState = new TeamState(team.id); for (player in team.players) { var playerId = new PlayerId(team.id, player.index); - var controller = player.human > 0 ? HUMAN(player.human - 1) : NONE; - var playerState = new PlayerState(playerId, controller); + var playerState = new PlayerState(playerId); players[playerId] = playerState; teamState.players[player.index] = playerState; } @@ -112,6 +111,10 @@ class GameState { return configBundle.get(type); } + private function get_level():LevelConfig { + return levelBundle.get(type, config, levelId); + } + public function getTeamLife(id:TeamId):Int { if (teams.exists(id)) { return teams[id].life + Lambda.fold(teams[id].players, function(p, c) return c + p.life, 0); diff --git a/src/common/resources/classic/config.yaml b/src/common/resources/classic/config.yaml index cb422ea..4b8cce6 100644 --- a/src/common/resources/classic/config.yaml +++ b/src/common/resources/classic/config.yaml @@ -34,39 +34,6 @@ player: - {type: bot2, rate: 0.27} - {type: bot3, rate: 0.15} -presets: - # player1 - - id: 1 Player - teams: - - id: human - players: - - {<<: *human, index: 0, color: 0xFFFF00, human: 1} - - id: bot - spawnInterval: 3000 - life: 20 - players: - - {<<: *bot, index: 0} - - {<<: *bot, index: 1} - - {<<: *bot, index: 2} - - {<<: *bot, index: 3} - # player2 - - id: 2 Players - teams: - - id: human - players: - - {<<: *human, index: 0, color: 0xFFFF00, human: 1} - - {<<: *human, index: 1, color: 0x15C040, human: 2} - - id: bot - spawnInterval: 3000 - life: 20 - players: - - {<<: *bot, index: 0} - - {<<: *bot, index: 1} - - {<<: *bot, index: 2} - - {<<: *bot, index: 3} - - {<<: *bot, index: 4} - - {<<: *bot, index: 5} - points: - {team: human, type: eagle, index: -1, direction: right, x: 12, y: 24} - {team: human, type: tank, index: 0, direction: top, x: 8, y: 24} @@ -116,7 +83,6 @@ tanks: skin: pc - type: human3 - # upgrade: human3 downgrade: human2 width: 42 height: 38 @@ -181,3 +147,49 @@ bonuses: - {score: 500, type: shovel, duration: 10} - {score: 500, type: star} - {score: 500, type: gun} + +presets: + - id: 0 + name: easy + teams: + - id: human + players: + - {<<: *human, index: 0, color: 0xFFFF00, control: human-0} + - id: bot + spawnInterval: 3000 + life: 10 + players: + - {<<: *bot, index: 0, control: bot-stupid} + - {<<: *bot, index: 1, control: bot-stupid} + + - id: 1 + name: normal + teams: + - id: human + players: + - {<<: *human, index: 0, color: 0xFFFF00, control: human-0} + - id: bot + spawnInterval: 3000 + life: 20 + players: + - {<<: *bot, index: 0, control: bot-stupid} + - {<<: *bot, index: 1, control: bot-stupid} + - {<<: *bot, index: 2, control: bot-hard} + - {<<: *bot, index: 3, control: bot-hard} + + - id: 2 + name: hard + teams: + - id: human + players: + - {<<: *human, index: 0, color: 0xFFFF00, control: human-0} + - id: bot + spawnInterval: 1000 + life: 30 + players: + - {<<: *bot, index: 0, control: bot-hard} + - {<<: *bot, index: 1, control: bot-hard} + - {<<: *bot, index: 2, control: bot-hard} + - {<<: *bot, index: 3, control: bot-hard} + - {<<: *bot, index: 4, control: bot-hard} + - {<<: *bot, index: 5, control: bot-hard} diff --git a/src/common/resources/death/config.yaml b/src/common/resources/death/config.yaml index f58aba5..5d70f99 100644 --- a/src/common/resources/death/config.yaml +++ b/src/common/resources/death/config.yaml @@ -29,15 +29,16 @@ player: team: base: &team players: - - {<<: *player, index: 0} + - {<<: *player, index: 0, control: bot-hard} presets: - - id: default + - id: 0 + name: default teams: - id: alpha color: 0xFF4422 players: - - {<<: *player, index: 0, human: 1} + - {<<: *player, index: 0, control: human-0} <<: *team - id: beta color: 0xFFD000 diff --git a/src/common/resources/dota/config.yaml b/src/common/resources/dota/config.yaml index 1a3cf47..5fd3333 100644 --- a/src/common/resources/dota/config.yaml +++ b/src/common/resources/dota/config.yaml @@ -41,24 +41,25 @@ team: id: radiant color: 0xff4422 players: - - {<<: *player-slow, index: 0, human: 1, color: 0xff8866} - - {<<: *player-fast, index: 1} - - {<<: *player-slow, index: 2} - - {<<: *player-fast, index: 3} - - {<<: *player-slow, index: 4} + - {<<: *player-slow, index: 0, control: human-0, color: 0xff8866} + - {<<: *player-fast, index: 1, control: bot-hard} + - {<<: *player-slow, index: 2, control: bot-hard} + - {<<: *player-fast, index: 3, control: bot-hard} + - {<<: *player-slow, index: 4, control: bot-hard} dire: &dire <<: *team id: dire color: 0x3284ff players: - - {<<: *player-slow, index: 0} - - {<<: *player-fast, index: 1} - - {<<: *player-slow, index: 2} - - {<<: *player-fast, index: 3} - - {<<: *player-slow, index: 4} + - {<<: *player-slow, index: 0, control: bot-hard} + - {<<: *player-fast, index: 1, control: bot-hard} + - {<<: *player-slow, index: 2, control: bot-hard} + - {<<: *player-fast, index: 3, control: bot-hard} + - {<<: *player-slow, index: 4, control: bot-hard} presets: - - id: default + - id: 0 + name: default teams: - <<: *radiant - <<: *dire diff --git a/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx b/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx index cdb60e0..353ac6f 100644 --- a/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx +++ b/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx @@ -7,13 +7,12 @@ import ru.m.tankz.util.LevelUtil; import sys.FileSystem; import sys.io.File; - class ServerLevelBundle implements ILevelBundle { public function new() {} - public function get(type:GameType, config:Config, level:Int):LevelConfig { - var path:String = FileSystem.absolutePath('./resources/${type}/levels/level${LevelUtil.formatLevel(level)}.txt'); + public function get(type:GameType, config:Config, levelId:LevelId):LevelConfig { + var path:String = FileSystem.absolutePath('./resources/${type}/levels/level${LevelUtil.formatLevel(levelId)}.txt'); var data:String = File.getContent(path); return LevelUtil.loads(config, data); }