diff --git a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx index dff3100..8a3162f 100755 --- a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx @@ -51,7 +51,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand render.draw(game.engine); timer = new Timer(10); timer.run = updateEngine; - state.text = stateString(s); + state.text = stateString(game); } private function stop():Void { @@ -68,20 +68,18 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand render.reset(); } - private function stateString(state:GameState):String { + private function stateString(game:Game):String { var result:Array = []; - result.push('Level: ${state.level}'); - for (teamId in state.teams.keys()) { - var ts:TeamState = state.teams[teamId]; - if (ts.lose) { - result.push('${teamId}: LOSE'); - } else if (ts.life > -1) { - result.push('${teamId}: ${ts.life}'); + result.push('Level: ${game.state.level}'); + for (team in game.teams) { + if (game.state.loser == team.id) { + result.push('${team.id}: LOSE'); + } else if (team.life > -1) { + result.push('${team.id}: ${team.life}'); } else { - for (index in ts.players.keys()) { - var ps:PlayerState = ts.players[index]; - if (ps.life > -1) { - result.push('${teamId}${index}: ${ps.life}'); + for (player in team.players) { + if (player.life > -1) { + result.push('${player.id.team}${player.id.index}: ${player.life}'); } } } @@ -90,14 +88,14 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand } private function onGameStateChange(s:GameState):GameState { - state.text = stateString(s); + state.text = stateString(game); return s; } private function onGameComplete(result:Option):Void { switch (result) { case Option.Some(s): - state.text = stateString(s); + state.text = stateString(game); case Option.None: } switch (game.next()) { diff --git a/src/client/haxe/ru/m/tankz/view/frames/StartFrame.hx b/src/client/haxe/ru/m/tankz/view/frames/StartFrame.hx index 38ce4f6..8d47409 100644 --- a/src/client/haxe/ru/m/tankz/view/frames/StartFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/frames/StartFrame.hx @@ -47,14 +47,8 @@ class StartFrame extends VGroupView implements ViewBuilder implements StartFrame } } - private function startGame(type:GameType, mode:GameMode):Void { - switch (type) { - case ClassicGame.TYPE: - Provider.set(GameState, ClassicGame.buildState(0, mode)); - Provider.get(IFrameSwitcher).change(LevelFrame.ID); - case DotaGame.TYPE: - Provider.set(GameState, DotaGame.buildState(0, mode)); - Provider.get(IFrameSwitcher).change(LevelFrame.ID); - } + private function startGame(type:GameType, presetId:PresetId):Void { + Provider.set(GameState, new GameState(type, presetId)); + Provider.get(IFrameSwitcher).change(LevelFrame.ID); } } diff --git a/src/client/resources/classic/config.yaml b/src/client/resources/classic/config.yaml index 5b61783..18845f2 100644 --- a/src/client/resources/classic/config.yaml +++ b/src/client/resources/classic/config.yaml @@ -17,18 +17,55 @@ bricks: - {type: 4, layer: 2, armor: 2} # armor - {type: 5, layer: 2, armor: 1} # brick -teams: - - id: human +player: + human: &human + control: human + life: 3 tanks: - {type: human0, rate: 1} - - id: bot - spawnInterval: 3000 + bot: &bot + control: bot + life: -1 tanks: - {type: bot0, rate: 0.25, bonus: 0.25} - {type: bot1, rate: 0.25, bonus: 0.25} - {type: bot2, rate: 0.25, bonus: 0.25} - {type: bot3, rate: 0.25, bonus: 0.25} +presets: + - id: player1 + teams: + - id: human + life: -1 + players: + - {<<: *human, index: 0, color: 0xFC9838, life: 3} + - id: bot + spawnInterval: 3000 + life: 20 + players: + - {<<: *bot, index: 0} + - {<<: *bot, index: 1} + - {<<: *bot, index: 2} + - {<<: *bot, index: 3} + + - id: player2 + teams: + - id: human + life: -1 + players: + - {<<: *human, index: 0, color: 0xFC9838, life: 3} + - {<<: *human, index: 1, color: 0x159D49, life: 3} + - 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} diff --git a/src/client/resources/dota/config.yaml b/src/client/resources/dota/config.yaml index 8be74c7..b3ba38c 100644 --- a/src/client/resources/dota/config.yaml +++ b/src/client/resources/dota/config.yaml @@ -17,18 +17,72 @@ bricks: - {type: 4, layer: 2, armor: 2} # armor - {type: 5, layer: 2, armor: 1} # brick -team_tanks: &team_tanks +team: + radiant: &radiant + id: radiant + color: 0xff5555 + life: 20 + dire: &dire + id: dire + color: 0x5555ff + life: 20 + +player: &player + life: -1 + control: bot tanks: - {type: slow, rate: 0.5} - {type: fast, rate: 0.5} -teams: - - <<: *team_tanks - id: radiant - color: 0xff5555 - - <<: *team_tanks - id: dire - color: 0x5555ff +presets: + - id: player1 + teams: + - <<: *radiant + players: + - {<<: *player, index: 0, control: human, color: 0xff7777} + - {<<: *player, index: 1} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} + - <<: *dire + players: + - {<<: *player, index: 0} + - {<<: *player, index: 1} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} + - id: player2_coop + teams: + - <<: *radiant + players: + - {<<: *player, index: 0, control: human, color: 0xff7777} + - {<<: *player, index: 1, control: human, color: 0xff7777} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} + - <<: *dire + players: + - {<<: *player, index: 0} + - {<<: *player, index: 1} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} + - id: player2_vs + teams: + - <<: *radiant + players: + - {<<: *player, index: 0, control: human, color: 0xff7777} + - {<<: *player, index: 1} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} + - <<: *dire + players: + - {<<: *player, index: 0, control: human, color: 0x7777ff} + - {<<: *player, index: 1} + - {<<: *player, index: 2} + - {<<: *player, index: 3} + - {<<: *player, index: 4} points: - {team: radiant, type: eagle, index: -1, direction: right, x: 0, y: 28} diff --git a/src/common/haxe/ru/m/tankz/Type.hx b/src/common/haxe/ru/m/tankz/Type.hx index 96c76cb..c598298 100644 --- a/src/common/haxe/ru/m/tankz/Type.hx +++ b/src/common/haxe/ru/m/tankz/Type.hx @@ -1,6 +1,5 @@ package ru.m.tankz; -import ru.m.draw.Color; typedef Type = Dynamic; @@ -18,9 +17,7 @@ typedef BonusType = String; typedef PlayerId = { var team:TeamId; - var type:ControlType; var index:Int; - @:optional var color:Color; } -typedef GameMode = Array; +typedef PresetId = String; diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 37c33eb..9c0a630 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -60,15 +60,26 @@ typedef TankSpawn = { @:optional var bonus:Float; } +typedef PlayerConfig = { + var index:Int; + var control:ControlType; + var tanks:Array; + @:optional var life:Int; + @:optional var color:Color; +} typedef TeamConfig = { var id:TeamId; - var size:Int; - var tanks:Array; + var players:Array; + @:optional var life:Int; @:optional var spawnInterval:Int; @:optional var color:Color; } +typedef GamePreset = { + var id:PresetId; + var teams:Array; +} typedef LevelConfig = { var data:Array; @@ -82,13 +93,13 @@ class Config { public var map(default, null):MapConfig; public var bricks(default, null):Array; public var tanks(default, null):Array; - public var teams(default, null):Array; + public var presets(default, null):Array; public var points(default, null):Array; public var bonuses(default, null):Array; private var brickMap:Map; private var tankMap:Map; - private var teamMap:Map; + private var presetsMap:Map; private var bonusMap:Map; public function new( @@ -96,7 +107,7 @@ class Config { game:GameConfig, map:MapConfig, bricks:Array, - teams:Array, + presets:Array, points:Array, tanks:Array, bonuses:Array @@ -105,7 +116,7 @@ class Config { this.game = game; this.map = map; this.bricks = bricks; - this.teams = teams; + this.presets = presets; this.points = points; this.tanks = tanks; this.bonuses = bonuses; @@ -117,9 +128,9 @@ class Config { for (item in bricks) { brickMap.set(item.type, item); } - teamMap = new Map(); - for (team in teams) { - teamMap.set(team.id, team); + presetsMap = new Map(); + for (preset in presets) { + presetsMap.set(preset.id, preset); } tankMap = new Map(); for (item in tanks) { @@ -135,8 +146,8 @@ class Config { return brickMap.get(type); } - public function getTeam(id:String):TeamConfig { - return teamMap.get(id); + public function getPreset(id:PresetId):GamePreset { + return presetsMap.get(id); } public function getTank(type:TankType):TankConfig { diff --git a/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx b/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx index bcca43a..e015b3d 100644 --- a/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx +++ b/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx @@ -10,7 +10,7 @@ typedef ConfigSource = { var game:GameConfig; var map: MapConfig; var bricks: Array; - var teams: Array; + var presets: Array; var points: Array; var tanks: Array; var bonuses: Array; @@ -24,6 +24,6 @@ class ConfigBundle { 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.teams, source.points, source.tanks, source.bonuses); + return new Config(type, source.game, source.map, source.bricks, source.presets, source.points, source.tanks, source.bonuses); } } diff --git a/src/common/haxe/ru/m/tankz/game/ClassicGame.hx b/src/common/haxe/ru/m/tankz/game/ClassicGame.hx index eb5f43c..2e30c13 100644 --- a/src/common/haxe/ru/m/tankz/game/ClassicGame.hx +++ b/src/common/haxe/ru/m/tankz/game/ClassicGame.hx @@ -1,10 +1,8 @@ package ru.m.tankz.game; import haxe.ds.Option; -import ru.m.draw.Color; -import ru.m.tankz.control.Control; import ru.m.tankz.game.Game; -import ru.m.tankz.game.GameState.PlayerState; +import ru.m.tankz.game.GameState; import ru.m.tankz.Type; @@ -15,57 +13,17 @@ class ClassicGame extends Game { public static var HUMAN(default, never):TeamId = 'human'; public static var BOT(default, never):TeamId = 'bot'; - private static var PLAYER1_COLOR:Color = 0xFC9838; - private static var PLAYER2_COLOR:Color = 0x159D49; - - public static var PLAYER1(default, never):GameMode = [ - {team:HUMAN, type:Control.HUMAN, color: PLAYER1_COLOR, index:0} - ]; - public static var PLAYER2(default, never):GameMode = [ - {team:HUMAN, type:Control.HUMAN, color: PLAYER1_COLOR, index:0}, - {team:HUMAN, type:Control.HUMAN, color: PLAYER2_COLOR, index:1} - ]; - - private static var HUMAN_LIFE(default, never):Int = 3; - private static var BOT_LIFE(default, never):Int = 20; + public static var PLAYER1(default, never):PresetId = 'player1'; + public static var PLAYER2(default, never):PresetId = 'player2'; public function new() { super(TYPE); } - public static function buildState(level:Int, mode:GameMode):GameState { - var state = new GameState(); - state.type = TYPE; - state.mode = mode; - state.level = level; - state.teams[HUMAN] = {life: -1, players: new Map(), lose: false}; - state.teams[BOT] = {life: BOT_LIFE, players: new Map(), lose: false}; - for (human in mode) { - state.teams[HUMAN].players[human.index] = { - id:human, - life:HUMAN_LIFE, - }; - } - for (i in 0...mode.length * 2 + 2) { - state.teams[BOT].players[i] = { - id:{team:BOT, index:i, type:Control.BOT}, - life:-1, - }; - } - return state; - } - override public function next():Option { - if (!state.teams[HUMAN].lose) { - state.level++; - if (state.level >= config.game.levels) state.level = 0; - state.teams[BOT].lose = false; - state.teams[BOT].life = BOT_LIFE; - for (ps in state.teams[HUMAN].players) { - if (ps.life > 0) ps.life++; - } - return Option.Some(state); + if (state.loser == HUMAN) { + return Option.None; } - return Option.None; + return super.next(); } } diff --git a/src/common/haxe/ru/m/tankz/game/DotaGame.hx b/src/common/haxe/ru/m/tankz/game/DotaGame.hx index 934cb7e..6789b43 100644 --- a/src/common/haxe/ru/m/tankz/game/DotaGame.hx +++ b/src/common/haxe/ru/m/tankz/game/DotaGame.hx @@ -1,10 +1,6 @@ package ru.m.tankz.game; -import haxe.ds.Option; -import ru.m.draw.Color; -import ru.m.tankz.control.Control; import ru.m.tankz.game.Game; -import ru.m.tankz.game.GameState; import ru.m.tankz.Type; @@ -15,57 +11,11 @@ class DotaGame extends Game { public static var RADIANT(default, never):TeamId = 'radiant'; public static var DIRE(default, never):TeamId = 'dire'; - public static var PLAYER1(default, never):GameMode = [ - {team:RADIANT, type:Control.HUMAN, index:0} - ]; - - private static var PLAYER1_COLOR:Color = 0xff7777; - private static var PLAYER2_COLOR:Color = 0x7777ff; - - public static var PLAYER2_COOP(default, never):GameMode = [ - {team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:0}, - {team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:1} - ]; - - public static var PLAYER2_VS(default, never):GameMode = [ - {team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:0}, - {team:DIRE, type:Control.HUMAN, color: PLAYER2_COLOR, index:0} - ]; - - private static var TEAM_SIZE(default, never):Int = 5; + public static var PLAYER1(default, never):PresetId = 'player1'; + public static var PLAYER2_COOP(default, never):PresetId = 'player2_coop'; + public static var PLAYER2_VS(default, never):PresetId = 'player2_vs'; public function new() { super(TYPE); } - - public static function buildState(level:Int, mode:GameMode):GameState { - var state = new GameState(); - state.type = TYPE; - state.mode = mode; - state.level = level; - state.teams[RADIANT] = {life: 20, players: new Map(), lose: false}; - state.teams[DIRE] = {life: 20, players: new Map(), lose: false}; - for (i in 0...TEAM_SIZE) { - state.teams[RADIANT].players[i] = { - id: {team:RADIANT, index:i, type:Control.BOT}, - life: -1, - }; - } - for (i in 0...TEAM_SIZE) { - state.teams[DIRE].players[i] = { - id: {team:DIRE, index:i, type:Control.BOT}, - life: -1, - }; - } - for (human in mode) { - state.teams[human.team].players[human.index].id = human; - } - return state; - } - - override public function next():Option { - state.level++; - if (state.level >= config.game.levels) state.level = 0; - return Option.Some(buildState(state.level, state.mode)); - } } diff --git a/src/common/haxe/ru/m/tankz/game/Game.hx b/src/common/haxe/ru/m/tankz/game/Game.hx index 61659bb..c52a32d 100644 --- a/src/common/haxe/ru/m/tankz/game/Game.hx +++ b/src/common/haxe/ru/m/tankz/game/Game.hx @@ -1,6 +1,5 @@ package ru.m.tankz.game; -import ru.m.tankz.core.Bonus; import haxe.ds.Option; import haxe.Timer; import promhx.Deferred; @@ -13,6 +12,7 @@ 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; import ru.m.tankz.core.Eagle; import ru.m.tankz.core.Entity; import ru.m.tankz.core.EntityType; @@ -29,12 +29,12 @@ class Game implements EngineListener { public var type(default, null):GameType; public var state(default, null):GameState; + public var preset(default, null):GamePreset; public var teams(default, null):Map; public var config(default, null):Config; public var engine(default, null):Engine; private var points:Array; - private var spawners:Map; private var deferred:Deferred; private var stream:Stream; @@ -45,16 +45,21 @@ class Game implements EngineListener { engine.listeners.push(this); } + public function getTeam(teamId:TeamId):Team { + return teams[teamId]; + } + public function getPlayer(playerId:PlayerId):Player { return teams[playerId.team].players[playerId.index]; } private function buildTank(playerId:PlayerId, point:SpawnPoint):Tank { - var spawns:Array = teams[playerId.team].config.tanks; + var player = getPlayer(playerId); + var spawns:Array = player.config.tanks; var spawn:TankSpawn = spawns[Math.floor(Math.random() * spawns.length)]; var tankConfig:TankConfig = config.getTank(spawn.type); var tank = new Tank(playerId, tankConfig); - tank.color = playerId.color.zero ? teams[playerId.team].config.color : playerId.color; + tank.color = player.config.color.zero ? teams[playerId.team].config.color : player.config.color; tank.bonus = Math.random() < spawn.bonus; applyPoint(tank, point); return tank; @@ -66,26 +71,25 @@ class Game implements EngineListener { } public function start(state:GameState):Stream { - this.deferred = new Deferred(); this.state = state; + this.preset = config.getPreset(state.presetId); + this.deferred = new Deferred(); var level = LevelBundle.get(type, config, state.level); points = level.points != null ? level.points : config.points; engine.map.setData(level.data); teams = new Map(); - spawners = new Map(); var humanControlIndex = 0; - for (teamConfig in config.teams) { - var team = new Team(teamConfig); - for (playerState in state.teams[team.id].players) { - var player = new Player(playerState.id); - team.players[player.id.index] = player; - teams[team.id] = team; - if (player.id.type != null) { - var control = switch (player.id.type) { + for (teamConfig in preset.teams) { + var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id); + var team:Team = new Team(teamConfig, teamPoints); + teams[team.id] = team; + for (player in team.players.iterator()) { + if (player.config.control != null) { + var control = switch (player.config.control) { case Control.HUMAN: new HumanControl(player.id, humanControlIndex++); case Control.BOT: new BotControl(player.id); case Control.NONE: null; - case _: throw 'Unsupported control type: "${player.id.type}"'; + case _: throw 'Unsupported control type: "${player.config.control}"'; } L.d(TAG, 'control(${player.id} - ${control})'); if (control != null) { @@ -94,17 +98,16 @@ class Game implements EngineListener { } } } - var teamPoints = points.filter(function(p:SpawnPoint) return p.team == team.id); - spawners[team.id] = new Spawner(team.config, teamPoints, spawn); + team.spawner.runner = spawn; } - for (team in teams) { - for (player in team.players) { - if (trySpawn(player.id)) { - spawners[team.id].push(player.id); + for (team in teams.iterator()) { + for (player in team.players.iterator()) { + if (team.trySpawn(player.id)) { + team.spawner.push(player.id); } } - var eaglePoint = spawners[team.id].getPoint('eagle'); + var eaglePoint = team.spawner.getPoint('eagle'); if (eaglePoint != null) { var eagle = new Eagle(team.id); applyPoint(eagle, eaglePoint); @@ -117,15 +120,15 @@ class Game implements EngineListener { private function spawn(task:SpawnTask):Void { L.d(TAG, 'spawn(${task}'); - getPlayer(task.playerId).tankId = 0; - if (trySpawn(task.playerId, true)) { + var team = getTeam(task.playerId.team); + var player = getPlayer(task.playerId); + player.tankId = 0; + if (getTeam(task.playerId.team).trySpawn(task.playerId, true)) { var tank = buildTank(task.playerId, task.point); - var player:Player = getPlayer(task.playerId); player.tankId = tank.id; Timer.delay(function() engine.spawn(tank), 1500); - } else if (!isTeamAlive(task.playerId.team)) { - state.teams[task.playerId.team].lose = true; - complete(); + } else if (!team.isAlive) { + lose(team.id); } deferred.resolve(state); } @@ -165,71 +168,43 @@ class Game implements EngineListener { } } - private function isTeamAlive(team:TeamId):Bool { - var ts:TeamState = state.teams[team]; - var life:Int = Lambda.fold(ts.players, function(ps, t) return t + ps.life, ts.life); - if (life > 0) { - return true; - } else { - for (player in teams[team].players) { - if (player.tankId > 0) { - return true; - } - } - if (spawners[team].active) { - return true; - } - } - return false; - } - - private function trySpawn(player:PlayerId, spawn:Bool = false):Bool { - var ts:TeamState = state.teams[player.team]; - var ps:PlayerState = ts.players[player.index]; - var result = false; - if (ps.life > -1) { - if (ps.life > 0) { - if (spawn) ps.life--; - result = true; - } - } else if (ts.life > -1) { - if (ts.life > 0) { - if (spawn) ts.life--; - result = true; - } - } - return result; - } - public function onDestroy(entity:EntityType):Void { switch (entity) { case EntityType.TANK(tank): - getPlayer(tank.playerId).control.stop(); - getPlayer(tank.playerId).tankId = 0; //ToDo: ? - var respawn:Bool = trySpawn(tank.playerId); + var team = getTeam(tank.playerId.team); + var player = getPlayer(tank.playerId); + player.control.stop(); + player.tankId = 0; //ToDo: ? + var respawn:Bool = team.trySpawn(player.id); if (respawn) { - spawners[tank.playerId.team].push(tank.playerId); + team.spawner.push(player.id); } - if (!isTeamAlive(tank.playerId.team)) { - state.teams[tank.playerId.team].lose = true; - complete(); + if (!team.isAlive) { + lose(team.id); } if (tank.bonus) spawnBonus(); deferred.resolve(state); case EntityType.EAGLE(eagle): - state.teams[eagle.team].lose = true; - complete(); + lose(eagle.team); deferred.resolve(state); case x: } } + private function lose(teamId:TeamId):Void { + state.loser = teamId; + complete(); + } + public function onAction(tankId:Int, action:TankAction):Void { engine.action(tankId, action); } public function next():Option { - return Option.None; + var level = state.level + 1; + state.level++; + if (level >= config.game.levels) level = 0; + return Option.Some(new GameState(state.type, preset.id, level)); } public function dispose():Void { @@ -249,7 +224,7 @@ class Game implements EngineListener { private function applyBonus(tank:Tank, bonus:Bonus):Void { switch (bonus.bonusType) { case 'life': - state.teams[tank.playerId.team].players[tank.playerId.index].life++; + getPlayer(tank.playerId).life++; case 'star': if (tank.config.upgrade != null) { tank.config = config.getTank(tank.config.upgrade); diff --git a/src/common/haxe/ru/m/tankz/game/GameState.hx b/src/common/haxe/ru/m/tankz/game/GameState.hx index 2555f06..c85cb29 100644 --- a/src/common/haxe/ru/m/tankz/game/GameState.hx +++ b/src/common/haxe/ru/m/tankz/game/GameState.hx @@ -3,26 +3,16 @@ package ru.m.tankz.game; import ru.m.tankz.Type; -typedef PlayerState = { - var id:PlayerId; - var life:Int; -} - -typedef TeamState = { - var players:Map; - var life:Int; - var lose:Bool; -} - class GameState { public var type:GameType; - public var mode:GameMode; public var level:Int; - public var teams:Map; + public var presetId:PresetId; + public var loser:TeamId; - public function new() { - type = null; - level = -1; - teams = new Map(); + public function new(type:GameType, presetId:PresetId, level:Int = 0) { + this.type = type; + this.presetId = presetId; + this.level = level; + this.loser = null; } } diff --git a/src/common/haxe/ru/m/tankz/game/Player.hx b/src/common/haxe/ru/m/tankz/game/Player.hx index 20d5c28..a1d8a8c 100644 --- a/src/common/haxe/ru/m/tankz/game/Player.hx +++ b/src/common/haxe/ru/m/tankz/game/Player.hx @@ -1,18 +1,23 @@ package ru.m.tankz.game; +import ru.m.tankz.config.Config; import ru.m.tankz.control.Control; import ru.m.tankz.Type; class Player { + public var config(default, null):PlayerConfig; public var id(default, null):PlayerId; public var tankId(default, set):Int; public var control(default, set):Control; + public var life(default, default):Int; - public function new(id:PlayerId, control:Control=null) { - this.id = id; - this.control = control; + public function new(teamId:TeamId, config:PlayerConfig) { + this.config = config; + this.id = {team:teamId, index:config.index}; + this.control = null; + this.life = config.life; } public function set_tankId(value:Int):Int { diff --git a/src/common/haxe/ru/m/tankz/game/Spawner.hx b/src/common/haxe/ru/m/tankz/game/Spawner.hx index 74d6b76..070286c 100644 --- a/src/common/haxe/ru/m/tankz/game/Spawner.hx +++ b/src/common/haxe/ru/m/tankz/game/Spawner.hx @@ -13,10 +13,10 @@ typedef SpawnTask = { class Spawner { public var active(get, never):Bool; + public var runner(default, default):SpawnTask -> Void; private var config:TeamConfig; private var points:Array; - private var runner:SpawnTask -> Void; private var queue:Array; private var timer:Timer; @@ -24,10 +24,10 @@ class Spawner { private var anyPoints:Array; private var index:Int; - public function new(config:TeamConfig, points:Array, runner:SpawnTask -> Void) { + public function new(config:TeamConfig, points:Array) { this.config = config; this.points = points; - this.runner = runner; + this.runner = null; queue = []; indexedPoints = new Map(); anyPoints = []; diff --git a/src/common/haxe/ru/m/tankz/game/Team.hx b/src/common/haxe/ru/m/tankz/game/Team.hx index 5b1a804..bd2a2b3 100644 --- a/src/common/haxe/ru/m/tankz/game/Team.hx +++ b/src/common/haxe/ru/m/tankz/game/Team.hx @@ -1,21 +1,61 @@ package ru.m.tankz.game; -import ru.m.tankz.config.Config; -import ru.m.tankz.game.Player; import ru.m.tankz.Type; +import ru.m.tankz.config.Config; class Team { public var id(default, null):TeamId; public var config(default, null):TeamConfig; + public var spawner(default, null):Spawner; public var players(default, null):Map; + public var life(default, default):Int; + public var isAlive(get, null):Bool; - private static var i:Int = 0; - - public function new(config:TeamConfig) { + public function new(config:TeamConfig, points:Array) { this.id = config.id; this.config = config; this.players = new Map(); + for (playerConfig in config.players) { + this.players[playerConfig.index] = new Player(id, playerConfig); + } + this.life = config.life; + this.spawner = new Spawner(config, points); + } + + public function trySpawn(player:PlayerId, spawn:Bool = false):Bool { + var player:Player = players[player.index]; + var result = false; + if (player.life > -1) { + if (player.life > 0) { + if (spawn) player.life--; + result = true; + } + } else if (life > -1) { + if (life > 0) { + if (spawn) life--; + result = true; + } + } + return result; + } + + // ToDo: eagle state? + private function get_isAlive():Bool { + var life:Int = Lambda.fold(players, function(p:Player, t:Int) return t + p.life, life); + if (life > 0) { + return true; + } else { + for (player in players) { + if (player.tankId > 0) { + return true; + } + } + if (spawner.active) { + return true; + } + } + return false; } }