[common] added GameSave
This commit is contained in:
9
src/common/haxe/ru/m/tankz/bundle/IConfigBundle.hx
Normal file
9
src/common/haxe/ru/m/tankz/bundle/IConfigBundle.hx
Normal file
@@ -0,0 +1,9 @@
|
||||
package ru.m.tankz.bundle;
|
||||
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
interface IConfigBundle {
|
||||
public function get(type:GameType):Config;
|
||||
}
|
||||
9
src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx
Normal file
9
src/common/haxe/ru/m/tankz/bundle/ILevelBundle.hx
Normal file
@@ -0,0 +1,9 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package ru.m.tankz.config;
|
||||
|
||||
import yaml.Parser;
|
||||
import openfl.Assets;
|
||||
import yaml.Yaml;
|
||||
import ru.m.tankz.config.Config;
|
||||
|
||||
|
||||
typedef ConfigSource = {
|
||||
var game:GameConfig;
|
||||
var map: MapConfig;
|
||||
var bricks: Array<BrickConfig>;
|
||||
var presets: Array<GamePreset>;
|
||||
var points: Array<SpawnPoint>;
|
||||
var tanks: Array<TankConfig>;
|
||||
var bonuses: Array<BonusConfig>;
|
||||
}
|
||||
|
||||
class ConfigBundle {
|
||||
|
||||
private static function convert(raw:Dynamic):ConfigSource {
|
||||
return raw;
|
||||
}
|
||||
|
||||
public static function get(type:String):Config {
|
||||
var source = convert(Yaml.parse(Assets.getText('resources/${type}/config.yaml'), Parser.options().useObjects()));
|
||||
return new Config(type, source.game, source.map, source.bricks, source.presets, source.points, source.tanks, source.bonuses);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.game.GameSave.PlayerSave;
|
||||
import haxe.ds.Option;
|
||||
import haxe.Timer;
|
||||
import haxework.provider.Provider;
|
||||
import promhx.Deferred;
|
||||
import promhx.Stream;
|
||||
import ru.m.geom.Direction;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.tankz.bot.BotControl;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.bundle.ILevelBundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.config.ConfigBundle;
|
||||
import ru.m.tankz.config.LevelBundle;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.control.HumanControl;
|
||||
import ru.m.tankz.core.Bonus;
|
||||
@@ -40,7 +42,7 @@ class Game implements EngineListener {
|
||||
|
||||
public function new(type:GameType) {
|
||||
this.type = type;
|
||||
this.config = ConfigBundle.get(type);
|
||||
this.config = Provider.get(IConfigBundle).get(type);
|
||||
this.engine = new Engine(config);
|
||||
engine.listeners.push(this);
|
||||
}
|
||||
@@ -73,11 +75,11 @@ class Game implements EngineListener {
|
||||
entity.rect.direction = Direction.fromString(point.direction);
|
||||
}
|
||||
|
||||
public function start(state:GameState):Stream<GameState> {
|
||||
this.state = state;
|
||||
public function start(save:GameSave):Stream<GameState> {
|
||||
this.state = save.state;
|
||||
this.preset = config.getPreset(state.presetId);
|
||||
this.deferred = new Deferred();
|
||||
var level = LevelBundle.get(type, config, state.level);
|
||||
var level:LevelConfig = Provider.get(ILevelBundle).get(type, config, state.level);
|
||||
points = level.points != null ? level.points : config.points;
|
||||
engine.map.setData(level.data);
|
||||
teams = new Map<TeamId, Team>();
|
||||
@@ -87,6 +89,16 @@ class Game implements EngineListener {
|
||||
var team:Team = new Team(teamConfig, teamPoints);
|
||||
teams[team.id] = team;
|
||||
for (player in team.players.iterator()) {
|
||||
var playerSave:PlayerSave = save.getPlayer(player.id);
|
||||
if (playerSave != null) {
|
||||
player.life = playerSave.life;
|
||||
if (playerSave.tank != null) {
|
||||
player.config.tanks = [{
|
||||
type: playerSave.tank,
|
||||
rate: 1,
|
||||
}];
|
||||
}
|
||||
}
|
||||
if (player.config.control != null) {
|
||||
var control = switch (player.config.control) {
|
||||
case Control.HUMAN: new HumanControl(player.id, humanControlIndex++);
|
||||
@@ -223,7 +235,7 @@ class Game implements EngineListener {
|
||||
var level = state.level + 1;
|
||||
state.level++;
|
||||
if (level >= config.game.levels) level = 0;
|
||||
return Option.Some(new GameState(state.type, preset.id, level));
|
||||
return Option.Some({type: state.type, presetId: preset.id, level: level});
|
||||
}
|
||||
|
||||
public function dispose():Void {
|
||||
@@ -277,4 +289,25 @@ class Game implements EngineListener {
|
||||
engine.destroy(tank); // :-D
|
||||
}
|
||||
}
|
||||
|
||||
public function save():GameSave {
|
||||
var players:Array<PlayerSave> = [];
|
||||
for (team in teams) {
|
||||
for (player in team.players) {
|
||||
if (player.config.control == Control.HUMAN) {
|
||||
var tank:Tank = EntityTypeResolver.as(engine.entities[player.tankId], Tank);
|
||||
players.push({
|
||||
id: player.id,
|
||||
life: player.life + (player.tankId > 0 ? 1 : 0),
|
||||
tank: tank != null ? tank.config.type : null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return new GameSave({
|
||||
type: state.type,
|
||||
presetId: state.presetId,
|
||||
level: state.level
|
||||
}, players);
|
||||
}
|
||||
}
|
||||
|
||||
46
src/common/haxe/ru/m/tankz/game/GameSave.hx
Normal file
46
src/common/haxe/ru/m/tankz/game/GameSave.hx
Normal file
@@ -0,0 +1,46 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import yaml.Parser;
|
||||
import yaml.Renderer;
|
||||
import yaml.Yaml;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
typedef PlayerSave = {
|
||||
var id:PlayerId;
|
||||
var tank:TankType;
|
||||
var life:Int;
|
||||
}
|
||||
|
||||
|
||||
class GameSave {
|
||||
|
||||
public var state:GameState;
|
||||
public var players:Array<PlayerSave>;
|
||||
|
||||
public function new(state:GameState, ?players:Array<PlayerSave>) {
|
||||
this.state = state;
|
||||
this.players = players != null ? players : [];
|
||||
}
|
||||
|
||||
public function getPlayer(id:PlayerId):PlayerSave {
|
||||
for (player in players) {
|
||||
if (player.id.team == id.team && player.id.index == id.index) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toYaml():String {
|
||||
return Yaml.render({
|
||||
state: state,
|
||||
players: players,
|
||||
}, Renderer.options().setFlowLevel(0));
|
||||
}
|
||||
|
||||
public static function fromYaml(value:String):GameSave {
|
||||
var data:Dynamic = Yaml.parse(value, Parser.options().useObjects());
|
||||
return new GameSave(data.state, data.players);
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,9 @@ package ru.m.tankz.game;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
class GameState {
|
||||
public var type:GameType;
|
||||
public var level:Int;
|
||||
public var presetId:PresetId;
|
||||
public var loser:TeamId;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId, level:Int = 0) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.level = level;
|
||||
this.loser = null;
|
||||
}
|
||||
typedef GameState = {
|
||||
var type:GameType;
|
||||
var presetId:PresetId;
|
||||
@:optional var level:Int;
|
||||
@:optional var loser:TeamId;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package ru.m.tankz.config;
|
||||
package ru.m.tankz.util;
|
||||
|
||||
import openfl.Assets;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.Type;
|
||||
import yaml.Parser;
|
||||
import yaml.Renderer;
|
||||
import yaml.Yaml;
|
||||
@@ -13,9 +11,9 @@ typedef LevelSource = {
|
||||
@:optional var points:Array<SpawnPoint>;
|
||||
}
|
||||
|
||||
class LevelBundle {
|
||||
class LevelUtil {
|
||||
|
||||
private static function formatLevel(level:Int):String {
|
||||
public static function formatLevel(level:Int):String {
|
||||
var result = Std.string(level);
|
||||
while (result.length < 3) result = '0${result}';
|
||||
return result;
|
||||
@@ -60,9 +58,4 @@ class LevelBundle {
|
||||
data: [for (i in 0...config.map.gridWidth * config.map.gridHeight) config.bricks[1]]
|
||||
}
|
||||
}
|
||||
|
||||
public static function get(type:GameType, config:Config, level:Int):LevelConfig {
|
||||
var data:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
|
||||
return loads(config, data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user