diff --git a/gulpfile.js b/gulpfile.js index a294a0a..609df07 100755 --- a/gulpfile.js +++ b/gulpfile.js @@ -160,6 +160,7 @@ const server = new Project( */ module.exports.default = gulp.series( exports.clean, + exports.levels, module.exports['client:flash:build'], module.exports['client:flash:html'], module.exports['client:html5:build'], diff --git a/package.json b/package.json index 3392a45..a7032a4 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.14.4", + "version": "0.15.0", "private": true, "devDependencies": { "dateformat": "^3.0.3", diff --git a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx index 9a6f564..5498294 100644 --- a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx +++ b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx @@ -9,11 +9,10 @@ class LevelBundle implements ILevelBundle { public function new() {} - public function get(type:GameType, name:String):LevelPack { - var bytes = Assets.getBytes('levels/${type}_${name}.zip'); + public function get(id:PackId):LevelPack { + var bytes = Assets.getBytes('levels/${id}.zip'); return { - type: type, - name: name, + id: id, data: LevelUtil.unpack(bytes), }; } diff --git a/src/client/haxe/ru/m/tankz/storage/GameStorage.hx b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx index ff0fbdb..1a6cc9d 100644 --- a/src/client/haxe/ru/m/tankz/storage/GameStorage.hx +++ b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx @@ -1,8 +1,8 @@ package ru.m.tankz.storage; import haxework.storage.SharedObjectStorage; -import ru.m.tankz.game.GameProgress; -import ru.m.tankz.Type.GameType; +import ru.m.tankz.game.PackProgress; +import ru.m.tankz.Type; class GameStorage extends SharedObjectStorage { @@ -12,11 +12,11 @@ class GameStorage extends SharedObjectStorage { super('game_${VERSION}'); } - public function get(type:GameType):GameProgress { - return exists(type) ? read(type) : new GameProgress(type); + public function get(id:PackId):PackProgress { + return exists(id) ? read(id) : new PackProgress(id); } - public function set(progress:GameProgress):Void { - write(progress.type, progress); + public function set(progress:PackProgress):Void { + write(progress.id, progress); } } diff --git a/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx b/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx index a22ba3d..03b698c 100644 --- a/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx +++ b/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx @@ -11,8 +11,10 @@ import ru.m.tankz.control.Control; class SettingsStorage extends SharedObjectStorage { + private static inline var VERSION = 3; + public function new() { - super("settings-3"); + super('settings_${VERSION}'); } public function getBinding(index:Int):Binding { diff --git a/src/client/haxe/ru/m/tankz/view/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/GameFrame.hx index 97d00df..44aedea 100644 --- a/src/client/haxe/ru/m/tankz/view/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/GameFrame.hx @@ -12,6 +12,7 @@ import ru.m.tankz.network.NetworkManager; import ru.m.tankz.sound.SoundManager; import ru.m.tankz.storage.GameStorage; import ru.m.tankz.storage.SettingsStorage; +import ru.m.tankz.Type; import ru.m.tankz.view.game.GameView; import ru.m.tankz.view.GamepadView; @@ -28,7 +29,7 @@ import ru.m.tankz.view.GamepadView; @:provide var state:GameState; @:provide var record:GameRecord; @:provide var switcher:FrameSwitcher; - @:provide var gameStorage:GameStorage; + @:provide static var gameStorage:GameStorage; @:provide static var settings:SettingsStorage; @:provide var game:IGame; @@ -75,12 +76,28 @@ import ru.m.tankz.view.GamepadView; switch event { case COMPLETE(state, winner): this.state = state; + updateProgress(game, winner); stop(); switcher.change(ResultFrame.ID); case _: } } + // ToDo: + private static function updateProgress(game:IGame, winner:TeamId):Void { + var complete = true; + for (rule in game.config.game.complete) { + if (rule.team != null && rule.team != winner) { + complete = false; + } + } + if (complete) { + var progress = gameStorage.get(new PackId(game.state.type)); + progress.completeLevel(game.level.id, game.state.presetId); + gameStorage.set(progress); + } + } + public function onHide():Void { stop(); soundManager.stopAll(); diff --git a/src/client/haxe/ru/m/tankz/view/LevelFrame.hx b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx index ee05fc4..b6bb3c8 100644 --- a/src/client/haxe/ru/m/tankz/view/LevelFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx @@ -11,6 +11,7 @@ import ru.m.tankz.game.GameState; import ru.m.tankz.game.IGame; import ru.m.tankz.local.LocalGame; import ru.m.tankz.storage.GameStorage; +import ru.m.tankz.Type; import ru.m.tankz.view.popup.LevelPopup; @:template class LevelFrame extends VGroupView { @@ -25,11 +26,12 @@ import ru.m.tankz.view.popup.LevelPopup; @:provide var levelBundle:ILevelBundle; @:provide var storage:GameStorage; + private var pack:LevelPack; private var levelPopup:LevelPopup; public function onShow():Void { header.text = state.type; - var pack = levelBundle.get(state.type, "standard"); + pack = levelBundle.get(new PackId(state.type)); levels.data = pack.data; } @@ -41,7 +43,7 @@ import ru.m.tankz.view.popup.LevelPopup; } private function levelViewFactory(index:Int, level:LevelConfig):ButtonView { - var progress = storage.get(state.type); + var progress = storage.get(pack.id); var result = new ButtonView(); result.skinId = "button.level"; var presetsLine = [for (p in state.config.presets) progress.isPresetCompleted(level.id, p.id) ? '*' : '_'].join(''); @@ -51,7 +53,7 @@ import ru.m.tankz.view.popup.LevelPopup; } private function onLevelSelect(index:Int, level:LevelConfig, view:ButtonView):Void { - if (!storage.get(state.type).isLevelAvailable(level.id)) { + if (!storage.get(pack.id).isLevelAvailable(level.id)) { return; } if (levelPopup == null) { @@ -61,7 +63,7 @@ import ru.m.tankz.view.popup.LevelPopup; level, state.config.presets, state.config.controls, - storage.get(state.type) + storage.get(pack.id) ); levelPopup.show().then(function(result) result != null ? start(level, result.preset, result.control) : {}); } diff --git a/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx index 5979ec1..b09d821 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx +++ b/src/client/haxe/ru/m/tankz/view/popup/CreateGamePopup.hx @@ -46,7 +46,7 @@ private typedef Result = { for (v in typeView.dataViews) { v.on = v == view; } - levelView.data = levelBundle.get(value, "standard").data; + levelView.data = levelBundle.get(new PackId(value)).data; onLevelSelect(0, levelView.data[0], levelView.dataViews[0]); } 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 a42f600..7f1f53c 100644 --- a/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx +++ b/src/client/haxe/ru/m/tankz/view/popup/LevelPopup.hx @@ -1,12 +1,12 @@ package ru.m.tankz.view.popup; -import haxework.view.ToggleButtonView; import haxework.view.ButtonView; import haxework.view.DataView; import haxework.view.LabelView; import haxework.view.popup.PopupView; +import haxework.view.ToggleButtonView; import ru.m.tankz.config.Config; -import ru.m.tankz.game.GameProgress; +import ru.m.tankz.game.PackProgress; private typedef Result = { var control:ControlPreset; @@ -16,14 +16,14 @@ private typedef Result = { @:template class LevelPopup extends PopupView { private var level:LevelConfig; - private var progress:GameProgress; + private var progress:PackProgress; @:view var name:LabelView; @:view("presets") var presetsView:DataView; @:view("controls") var controlsView:DataView; private var control:ControlPreset; - public function setData(level:LevelConfig, presets:Array, controls:Array, progress:GameProgress):Void { + public function setData(level:LevelConfig, presets:Array, controls:Array, progress:PackProgress):Void { this.level = level; this.progress = progress; name.text = '${level.id}. ${level.name != null ? level.name : "#"}'; diff --git a/src/common/haxe/ru/m/tankz/Type.hx b/src/common/haxe/ru/m/tankz/Type.hx index e40316b..c9fe7f2 100644 --- a/src/common/haxe/ru/m/tankz/Type.hx +++ b/src/common/haxe/ru/m/tankz/Type.hx @@ -39,5 +39,33 @@ abstract PlayerId(Array) { } } +abstract PackId(Array) { + public static inline var DEFAULT = "standard"; + + public var type(get, never):GameType; + public var name(get, never):String; + + public function new(type:GameType, name:String = DEFAULT) { + this = [type, name]; + } + + private inline function get_type():GameType return this[0]; + + private inline function get_name():String return this[1]; + + @:from static public inline function fromArray(value:Array):PackId { + return new PackId(value[0], value[1]); + } + + @:to public inline function toString():String { + return '${type}_${name}'; + } + + @:op(X == Y) static public inline function equals(x:PackId, y:PackId):Bool { + return x.type == y.type && x.name == y.name; + } +} + 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 97ee63d..90b44a6 100644 --- a/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx +++ b/src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx @@ -4,5 +4,5 @@ import ru.m.tankz.config.Config; import ru.m.tankz.Type; interface ILevelBundle { - public function get(type:GameType, name:String):LevelPack; + public function get(id:PackId):LevelPack; } diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 2f1ef76..252d8f1 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -115,8 +115,7 @@ typedef LevelConfig = { } typedef LevelPack = { - var type:GameType; - var name:String; + var id:PackId; var data:Array; } diff --git a/src/common/haxe/ru/m/tankz/game/IGame.hx b/src/common/haxe/ru/m/tankz/game/IGame.hx index f5ad075..6d5ee0b 100644 --- a/src/common/haxe/ru/m/tankz/game/IGame.hx +++ b/src/common/haxe/ru/m/tankz/game/IGame.hx @@ -12,6 +12,7 @@ interface IGame extends GameListener { public var config(default, null):Config; public var winner(default, null):Null; public var state(default, null):GameState; + public var level(default, null):LevelConfig; public var controlFactory(default, null):IControlFactory; public var pause(default, set):Bool; public var controls(default, null):Map; diff --git a/src/common/haxe/ru/m/tankz/game/GameProgress.hx b/src/common/haxe/ru/m/tankz/game/PackProgress.hx similarity index 89% rename from src/common/haxe/ru/m/tankz/game/GameProgress.hx rename to src/common/haxe/ru/m/tankz/game/PackProgress.hx index 0291a73..7b80484 100644 --- a/src/common/haxe/ru/m/tankz/game/GameProgress.hx +++ b/src/common/haxe/ru/m/tankz/game/PackProgress.hx @@ -11,13 +11,14 @@ typedef LevelProgress = { var presets:Map; } -class GameProgress { +class PackProgress { + + public var id(default, null):PackId; - public var type(default, null):GameType; private var completed(default, null):Map; - public function new(type:GameType) { - this.type = type; + public function new(id:PackId) { + this.id = id; this.completed = new Map(); } 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 dd9fd95..ef00451 100644 --- a/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx +++ b/src/server/haxe/ru/m/tankz/server/bundle/ServerLevelBundle.hx @@ -11,12 +11,11 @@ class ServerLevelBundle implements ILevelBundle { public function new() {} - public function get(type:GameType, name:String):LevelPack { - var path = FileSystem.absolutePath('./levels/${type}_${name}.zip'); + public function get(id:PackId):LevelPack { + var path = FileSystem.absolutePath('./levels/${id}.zip'); var bytes = File.getBytes(path); return { - type: type, - name: name, + id: id, data: LevelUtil.unpack(bytes), }; } diff --git a/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx b/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx index 255ff7a..2118854 100644 --- a/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx +++ b/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx @@ -1,7 +1,6 @@ package ru.m.tankz.server.game; import ru.m.tankz.bundle.ILevelBundle; -import ru.m.tankz.proto.room.RoomSlotProto; import ru.m.tankz.config.Config; import ru.m.tankz.core.EntityType; import ru.m.tankz.game.EventUtil; @@ -10,8 +9,10 @@ import ru.m.tankz.game.GameRunner; import ru.m.tankz.game.GameState; import ru.m.tankz.proto.core.UserProto; import ru.m.tankz.proto.room.RoomProto; +import ru.m.tankz.proto.room.RoomSlotProto; import ru.m.tankz.proto.room.SlotProto; import ru.m.tankz.server.control.ServerControlFactory; +import ru.m.tankz.Type; class ServerGame extends GameRunner { @@ -22,7 +23,7 @@ class ServerGame extends GameRunner { @:provide static var levelBundle:ILevelBundle; public function new(room:RoomProto) { - super(new GameState(room.game.type, 0), levelBundle.get(room.game.type, "standard").data[room.game.level]); + super(new GameState(room.game.type, 0), levelBundle.get(new PackId(room.game.type)).data[room.game.level]); this.controlFactory = new ServerControlFactory(); this.room = room; }