[common] add PlayerControl presets
This commit is contained in:
@@ -16,7 +16,7 @@ class ConfigBundle implements IConfigBundle {
|
||||
public function get(type:GameType):Config {
|
||||
if (!_cache.exists(type)) {
|
||||
var source:ConfigSource = Yaml.parse(Assets.getText('resources/${type}/config.yaml'), Parser.options().useObjects());
|
||||
_cache.set(type, new Config(type, source.game, source.map, source.bricks, source.presets, source.points, source.tanks, source.bonuses));
|
||||
_cache.set(type, Config.fromSource(type, source));
|
||||
}
|
||||
return _cache.get(type);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ class NetworkControl extends HumanControl {
|
||||
@:provide private var network:NetworkManager;
|
||||
|
||||
override public function action(action:TankAction):Void {
|
||||
if (tankId > -1) {
|
||||
network.action(tankId, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,14 @@ class NetworkGame extends Game {
|
||||
gameEventSignal.emit(event);
|
||||
}
|
||||
|
||||
override public function start():Void {
|
||||
var player = Lambda.find(network.game.players, function(player) return player.user.uuid == network.user.uuid);
|
||||
if (player != null) {
|
||||
state.controls.push({playerId: [player.team, player.index], control: "human-0"});
|
||||
}
|
||||
super.start();
|
||||
}
|
||||
|
||||
override public function dispose():Void {
|
||||
super.dispose();
|
||||
network.gameEventSignal.disconnect(onGameEventProto);
|
||||
|
||||
@@ -117,7 +117,7 @@ class Render extends SpriteView implements IRender {
|
||||
case SPAWN(TANK(id, rect, playerId, info)):
|
||||
var item = new TankRenderItem(rect);
|
||||
var tankConfig = config.getTank(info.type);
|
||||
item.color = config.getColor(playerId);
|
||||
item.color = info.color;
|
||||
item.skin = tankConfig.skin;
|
||||
item.hits = info.hits;
|
||||
item.bonus = info.bonus;
|
||||
|
||||
@@ -33,9 +33,10 @@ import ru.m.tankz.view.popup.LevelPopup;
|
||||
levels.data = [for (i in 0...state.config.game.levels) i];
|
||||
}
|
||||
|
||||
private function start(level:LevelConfig, preset:GamePreset):Void {
|
||||
private function start(level:LevelConfig, preset:GamePreset, control:ControlPreset):Void {
|
||||
state.levelId = level.id;
|
||||
state.presetId = preset.id;
|
||||
state.controls = control.values;
|
||||
game = new LocalGame(state);
|
||||
switcher.change(GameFrame.ID);
|
||||
}
|
||||
@@ -61,8 +62,9 @@ import ru.m.tankz.view.popup.LevelPopup;
|
||||
levelPopup.setData(
|
||||
level,
|
||||
state.config.presets,
|
||||
state.config.controls,
|
||||
storage.get(state.type)
|
||||
);
|
||||
levelPopup.show().then(function(preset) preset != null ? start(level, preset) : {});
|
||||
levelPopup.show().then(function(result) result != null ? start(level, result.preset, result.control) : {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import ru.m.tankz.game.NetworkGame;
|
||||
import ru.m.tankz.network.NetworkManager;
|
||||
import ru.m.tankz.proto.core.GameProto;
|
||||
import ru.m.tankz.proto.core.GameStateProto;
|
||||
import ru.m.tankz.proto.core.UserProto;
|
||||
import ru.m.tankz.proto.core.PlayerProto;
|
||||
|
||||
@:template class GameRoomFrame extends VGroupView {
|
||||
|
||||
@@ -18,7 +18,7 @@ import ru.m.tankz.proto.core.UserProto;
|
||||
|
||||
@:view var start:ButtonView;
|
||||
@:view var info:TextView;
|
||||
@:view var players:VListView<UserProto>;
|
||||
@:view var players:VListView<PlayerProto>;
|
||||
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
@:provide var network:NetworkManager;
|
||||
|
||||
@@ -3,18 +3,18 @@ package ru.m.tankz.view.network;
|
||||
import haxework.view.HGroupView;
|
||||
import haxework.view.LabelView;
|
||||
import haxework.view.list.ListView;
|
||||
import ru.m.tankz.proto.core.UserProto;
|
||||
import ru.m.tankz.proto.core.PlayerProto;
|
||||
|
||||
@:template class PlayerItemView extends HGroupView implements IListItemView<UserProto> {
|
||||
@:template class PlayerItemView extends HGroupView implements IListItemView<PlayerProto> {
|
||||
|
||||
public var item_index(default, default):Int;
|
||||
public var data(default, set):UserProto;
|
||||
public var data(default, set):PlayerProto;
|
||||
|
||||
@:view var label:LabelView;
|
||||
|
||||
private function set_data(value:UserProto):UserProto {
|
||||
private function set_data(value:PlayerProto):PlayerProto {
|
||||
data = value;
|
||||
label.text = '${value.name}';
|
||||
label.text = '${value.user.name}';
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.view.popup;
|
||||
|
||||
import haxework.view.ToggleButtonView;
|
||||
import haxework.view.ButtonView;
|
||||
import haxework.view.DataView;
|
||||
import haxework.view.LabelView;
|
||||
@@ -7,19 +8,28 @@ import haxework.view.popup.PopupView;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.game.GameProgress;
|
||||
|
||||
@:template class LevelPopup extends PopupView<GamePreset> {
|
||||
typedef Result = {
|
||||
var control:ControlPreset;
|
||||
var preset:GamePreset;
|
||||
}
|
||||
|
||||
@:template class LevelPopup extends PopupView<Result> {
|
||||
|
||||
private var level:LevelConfig;
|
||||
private var progress:GameProgress;
|
||||
|
||||
@:view var name:LabelView;
|
||||
@:view("presets") var presetsView:DataView<GamePreset, ButtonView>;
|
||||
@:view("controls") var controlsView:DataView<ControlPreset, ToggleButtonView>;
|
||||
private var control:ControlPreset;
|
||||
|
||||
public function setData(level:LevelConfig, presets:Array<GamePreset>, progress:GameProgress):Void {
|
||||
public function setData(level:LevelConfig, presets:Array<GamePreset>, controls:Array<ControlPreset>, progress:GameProgress):Void {
|
||||
this.level = level;
|
||||
this.progress = progress;
|
||||
name.text = '${level.id}. ${level.name != null ? level.name : "#"}';
|
||||
presetsView.data = presets;
|
||||
control = controls[0];
|
||||
controlsView.data = controls;
|
||||
}
|
||||
|
||||
private function presetViewFactory(index:Int, value:GamePreset):ButtonView {
|
||||
@@ -32,7 +42,22 @@ import ru.m.tankz.game.GameProgress;
|
||||
|
||||
private function onPresetSelect(value:GamePreset):Void {
|
||||
if (progress.isPresetAvailable(level.id, value.id)) {
|
||||
close(value);
|
||||
close({control: control, preset: value});
|
||||
}
|
||||
}
|
||||
|
||||
private function controlViewFactory(index:Int, value:ControlPreset):ToggleButtonView {
|
||||
var result = new ToggleButtonView();
|
||||
result.skinId = 'button.simple.active';
|
||||
result.on = control == value;
|
||||
result.text = value.name;
|
||||
return result;
|
||||
}
|
||||
|
||||
private function onControlSelect(index:Int, value:ControlPreset, view:ToggleButtonView):Void {
|
||||
control = value;
|
||||
for (v in controlsView.dataViews) {
|
||||
v.on = v == view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,15 @@ view:
|
||||
+onPress: $code:reject('close')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.height: 100%
|
||||
- id: controls
|
||||
$type: haxework.view.DataView
|
||||
factory: $this:controlViewFactory
|
||||
+onItemSelect: $this:onControlSelect
|
||||
layout:
|
||||
$type: haxework.view.layout.HorizontalLayout
|
||||
hAlign: center
|
||||
margin: 5
|
||||
skinId: panel
|
||||
- id: presets
|
||||
$type: haxework.view.DataView
|
||||
factory: $this:presetViewFactory
|
||||
|
||||
@@ -3,17 +3,6 @@ package ru.m.tankz.bundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
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>;
|
||||
}
|
||||
|
||||
interface IConfigBundle {
|
||||
public function get(type:GameType):Config;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,29 @@ typedef LevelConfig = {
|
||||
@:optional var points:Array<SpawnPoint>;
|
||||
}
|
||||
|
||||
typedef PlayerControl = {
|
||||
var playerId:PlayerId;
|
||||
var control:String;
|
||||
@:optional var color:Color;
|
||||
}
|
||||
|
||||
typedef ControlPreset = {
|
||||
var id:Int;
|
||||
var name:String;
|
||||
var values:Array<PlayerControl>;
|
||||
};
|
||||
|
||||
typedef ConfigSource = {
|
||||
var game:GameConfig;
|
||||
var map: MapConfig;
|
||||
var bricks: Array<BrickConfig>;
|
||||
var presets: Array<GamePreset>;
|
||||
var controls: Array<ControlPreset>;
|
||||
var points: Array<SpawnPoint>;
|
||||
var tanks: Array<TankConfig>;
|
||||
var bonuses: Array<BonusConfig>;
|
||||
}
|
||||
|
||||
class Config {
|
||||
public var type(default, null):String;
|
||||
public var game(default, null):GameConfig;
|
||||
@@ -112,6 +135,7 @@ class Config {
|
||||
public var bricks(default, null):Array<BrickConfig>;
|
||||
public var tanks(default, null):Array<TankConfig>;
|
||||
public var presets(default, null):Array<GamePreset>;
|
||||
public var controls(default, null):Array<ControlPreset>;
|
||||
public var points(default, null):Array<SpawnPoint>;
|
||||
public var bonuses(default, null):Array<BonusConfig>;
|
||||
|
||||
@@ -123,12 +147,17 @@ class Config {
|
||||
private var teamsMap:Map<TeamId, TeamConfig>;
|
||||
private var playersMap:Map<String, PlayerConfig>;
|
||||
|
||||
public static function fromSource(type:GameType, source:ConfigSource):Config {
|
||||
return new Config(type, source.game, source.map, source.bricks, source.presets, source.controls, source.points, source.tanks, source.bonuses);
|
||||
}
|
||||
|
||||
public function new(
|
||||
type:String,
|
||||
game:GameConfig,
|
||||
map:MapConfig,
|
||||
bricks:Array<BrickConfig>,
|
||||
presets:Array<GamePreset>,
|
||||
controls:Array<ControlPreset>,
|
||||
points:Array<SpawnPoint>,
|
||||
tanks:Array<TankConfig>,
|
||||
bonuses:Array<BonusConfig>
|
||||
@@ -138,6 +167,7 @@ class Config {
|
||||
this.map = map;
|
||||
this.bricks = bricks;
|
||||
this.presets = presets;
|
||||
this.controls = controls;
|
||||
this.points = points;
|
||||
this.tanks = tanks;
|
||||
this.bonuses = bonuses;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import haxework.color.Color;
|
||||
import ru.m.geom.Direction;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.geom.Rectangle;
|
||||
@@ -43,11 +44,11 @@ class EntityBuilder {
|
||||
return eagle;
|
||||
}
|
||||
|
||||
public function buildTank(point:EntityPoint, playerId:PlayerId, type:TankType, bonusOff:Bool = false):Tank {
|
||||
public function buildTank(point:EntityPoint, playerId:PlayerId, type:TankType, color:Color, bonusOff:Bool = false):Tank {
|
||||
var playerConfig = config.getPlayer(playerId);
|
||||
var tankConfig = config.getTank(type);
|
||||
var tank = new Tank(++entityId, buildRect(point, tankConfig.width, tankConfig.height), playerId, tankConfig);
|
||||
tank.color = config.getColor(playerId);
|
||||
tank.color = color.zero ? config.getColor(playerId) : color;
|
||||
if (!bonusOff) {
|
||||
tank.bonus = Math.random() < playerConfig.bonus;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ class EventUtil {
|
||||
return GameEvent.SPAWN(TANK(tank.id, tank.rect.clone(), tank.playerId, {
|
||||
type:tank.config.type,
|
||||
hits:tank.hits,
|
||||
bonus:tank.bonus
|
||||
bonus:tank.bonus,
|
||||
color:tank.color,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -55,15 +55,15 @@ import ru.m.tankz.Type;
|
||||
|
||||
public function onGameEvent(event:GameEvent):Void {
|
||||
switch event {
|
||||
case GameEvent.START(state):
|
||||
case START(state):
|
||||
this.state = state;
|
||||
case GameEvent.COMPLETE(state, winnerId):
|
||||
case COMPLETE(state, winnerId):
|
||||
this.state = state;
|
||||
this.winner = winnerId;
|
||||
case GameEvent.SPAWN(EAGLE(id, rect, teamId)):
|
||||
case SPAWN(EAGLE(id, rect, teamId)):
|
||||
var team = getTeam(teamId);
|
||||
team.eagleId = id;
|
||||
case GameEvent.SPAWN(TANK(id, rect, playerId, info)):
|
||||
case SPAWN(TANK(id, rect, playerId, info)):
|
||||
var player = getPlayer(playerId);
|
||||
player.tankId = id;
|
||||
player.state.tank = info.type;
|
||||
@@ -79,12 +79,24 @@ import ru.m.tankz.Type;
|
||||
var team:Team = new Team(teamConfig, teamPoints, state.teams[teamConfig.id]);
|
||||
teams[team.id] = team;
|
||||
}
|
||||
var controlsById:Map<String, PlayerControl> = new Map();
|
||||
for (control in state.controls) {
|
||||
controlsById[control.playerId] = control;
|
||||
}
|
||||
for (team in teams.iterator()) {
|
||||
for (player in team.players.iterator()) {
|
||||
var control = controlFactory.build(player.id, AController.fromString(player.config.control));
|
||||
var playerControl = controlsById.get(player.id);
|
||||
if (playerControl != null && !playerControl.color.zero) {
|
||||
player.state.color = playerControl.color;
|
||||
}
|
||||
var controlType:Controller = AController.fromString(playerControl != null ? playerControl.control : player.config.control);
|
||||
var control = controlFactory.build(player.id, controlType);
|
||||
if (control != null) {
|
||||
player.control = control;
|
||||
player.control.bind(this, engine);
|
||||
} else {
|
||||
// ToDo: remove player
|
||||
player.state.life = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import haxework.color.Color;
|
||||
import ru.m.geom.Position;
|
||||
import ru.m.geom.Rectangle;
|
||||
import ru.m.tankz.control.Control;
|
||||
@@ -9,6 +10,7 @@ typedef TankInfo = {
|
||||
var type:TankType;
|
||||
var hits:Int;
|
||||
var bonus:Bool;
|
||||
var color:Color;
|
||||
}
|
||||
|
||||
typedef BrickInfo = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import haxework.color.Color;
|
||||
import ru.m.geom.Line;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.tankz.control.Control;
|
||||
@@ -58,12 +59,13 @@ class GameRunner extends Game implements EngineListener {
|
||||
}
|
||||
}
|
||||
gameEventSignal.emit(EventUtil.buildBricksSpawn(engine.map));
|
||||
gameEventSignal.emit(GameEvent.START(state));
|
||||
gameEventSignal.emit(START(state));
|
||||
//for (i in 0...10) spawnBonus();
|
||||
}
|
||||
|
||||
private function spawn(task:SpawnTask):Void {
|
||||
var tank = builder.buildTank(task.point, task.playerId, task.tankType);
|
||||
var player = getPlayer(task.playerId);
|
||||
var tank = builder.buildTank(task.point, task.playerId, task.tankType, player.state.color);
|
||||
engine.spawn(tank);
|
||||
gameEventSignal.emit(EventUtil.buildTankSpawn(tank));
|
||||
tank.protect.connect(onTankProtectChange);
|
||||
@@ -71,15 +73,15 @@ class GameRunner extends Game implements EngineListener {
|
||||
}
|
||||
|
||||
private function onEagleProtectChange(id:Int, state:Bool):Void {
|
||||
gameEventSignal.emit(GameEvent.CHANGE(EAGLE_PROTECT(id, state)));
|
||||
gameEventSignal.emit(CHANGE(EAGLE_PROTECT(id, state)));
|
||||
}
|
||||
|
||||
private function onTankProtectChange(id:Int, state:Bool):Void {
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TANK_PROTECT(id, state)));
|
||||
gameEventSignal.emit(CHANGE(TANK_PROTECT(id, state)));
|
||||
}
|
||||
|
||||
private function onTankFreezingChange(id:Int, state:Bool):Void {
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TANK_FREEZE(id, state)));
|
||||
gameEventSignal.emit(CHANGE(TANK_FREEZE(id, state)));
|
||||
}
|
||||
|
||||
private function checkComplete():Void {
|
||||
@@ -107,13 +109,13 @@ class GameRunner extends Game implements EngineListener {
|
||||
for (team in teams.iterator()) {
|
||||
for (player in team.players) {
|
||||
if (player.control != null) {
|
||||
player.control.action(TankAction.STOP);
|
||||
player.control.action(STOP);
|
||||
player.control.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer.delay(function() {
|
||||
gameEventSignal.emit(GameEvent.COMPLETE(state, winner));
|
||||
gameEventSignal.emit(COMPLETE(state, winner));
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
@@ -129,11 +131,11 @@ class GameRunner extends Game implements EngineListener {
|
||||
}
|
||||
|
||||
private inline function emitTankMove(tank:Tank):Void {
|
||||
gameEventSignal.emit(GameEvent.MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
|
||||
gameEventSignal.emit(MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
|
||||
}
|
||||
|
||||
private inline function emitTankChange(tank:Tank):Void {
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus)));
|
||||
gameEventSignal.emit(CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus)));
|
||||
}
|
||||
|
||||
public function onCollision(entity:EntityType, with:EntityType):Void {
|
||||
@@ -154,14 +156,14 @@ class GameRunner extends Game implements EngineListener {
|
||||
tank.rect.lean(cell.rect);
|
||||
emitTankMove(tank);
|
||||
case [BULLET(bullet), BULLET(other_bullet)]:
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet.id)));
|
||||
gameEventSignal.emit(DESTROY(BULLET(bullet.id)));
|
||||
gameEventSignal.emit(DESTROY(BULLET(other_bullet.id)));
|
||||
case [BULLET(bullet), CELL(cell)]:
|
||||
bullet.rect.lean(cell.rect);
|
||||
gameEventSignal.emit(GameEvent.HIT(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||
gameEventSignal.emit(HIT(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||
gameEventSignal.emit(DESTROY(BULLET(bullet.id)));
|
||||
case [TANK(tank), BONUS(bonus)]:
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BONUS(bonus.id, {tankId: tank.id, score: bonus.config.score})));
|
||||
gameEventSignal.emit(DESTROY(BONUS(bonus.id, {tankId: tank.id, score: bonus.config.score})));
|
||||
case [BULLET(bullet), TANK(tank)]/* | [TANK(tank), BULLET(bullet)]*/:
|
||||
if (bullet.tankId == tank.id || (!config.game.friendlyFire && tank.playerId.team == bullet.playerId.team)) {
|
||||
// Nothing
|
||||
@@ -173,27 +175,27 @@ class GameRunner extends Game implements EngineListener {
|
||||
tank.bonus = false;
|
||||
spawnBonus();
|
||||
}
|
||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||
gameEventSignal.emit(HIT(TANK(tank.id, buildShot(bullet))));
|
||||
emitTankChange(tank);
|
||||
} else if (tank.config.downgrade != null) {
|
||||
tank.config = config.getTank(tank.config.downgrade);
|
||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||
gameEventSignal.emit(HIT(TANK(tank.id, buildShot(bullet))));
|
||||
emitTankChange(tank);
|
||||
} else {
|
||||
var score = tank.config.score;
|
||||
if (tank.playerId.team == bullet.playerId.team) {
|
||||
score = Math.round(score * -0.5);
|
||||
}
|
||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank.id, buildShot(bullet, score))));
|
||||
gameEventSignal.emit(DESTROY(TANK(tank.id, buildShot(bullet, score))));
|
||||
}
|
||||
}
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||
gameEventSignal.emit(DESTROY(BULLET(bullet.id)));
|
||||
}
|
||||
case [BULLET(bullet), EAGLE(eagle)]:
|
||||
if (!eagle.protect.active) {
|
||||
gameEventSignal.emit(GameEvent.DESTROY(EAGLE(eagle.id, buildShot(bullet, eagle.score))));
|
||||
gameEventSignal.emit(DESTROY(EAGLE(eagle.id, buildShot(bullet, eagle.score))));
|
||||
}
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||
gameEventSignal.emit(DESTROY(BULLET(bullet.id)));
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -203,7 +205,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
case TANK(tank):
|
||||
emitTankMove(tank);
|
||||
case BULLET(bullet):
|
||||
gameEventSignal.emit(GameEvent.MOVE(BULLET(bullet.id, {x:bullet.rect.x, y:bullet.rect.y, direction:bullet.rect.direction})));
|
||||
gameEventSignal.emit(MOVE(BULLET(bullet.id, {x:bullet.rect.x, y:bullet.rect.y, direction:bullet.rect.direction})));
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -220,7 +222,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
}
|
||||
var bonus = builder.buildBonus(point, type);
|
||||
engine.spawn(bonus);
|
||||
gameEventSignal.emit(GameEvent.SPAWN(BONUS(bonus.id, bonus.rect.clone(), bonus.config.type)));
|
||||
gameEventSignal.emit(SPAWN(BONUS(bonus.id, bonus.rect.clone(), bonus.config.type)));
|
||||
}
|
||||
|
||||
private inline function alienTank(team:TeamId):Tank->Bool {
|
||||
@@ -235,7 +237,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
upgradeTank(tank);
|
||||
case "grenade":
|
||||
for (t in engine.iterTanks(alienTank(tank.playerId.team))) {
|
||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(t.id, {tankId: tank.id})));
|
||||
gameEventSignal.emit(DESTROY(TANK(t.id, {tankId: tank.id})));
|
||||
}
|
||||
case "helmet":
|
||||
tank.protect.on(bonus.config.duration);
|
||||
@@ -243,7 +245,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
for (t in engine.iterTanks(alienTank(tank.playerId.team))) {
|
||||
t.freezing.on(bonus.config.duration);
|
||||
t.stop();
|
||||
gameEventSignal.emit(GameEvent.STOP(TANK(t.id)));
|
||||
gameEventSignal.emit(STOP(TANK(t.id)));
|
||||
}
|
||||
case "shovel":
|
||||
// ToDo: protect eagle/area
|
||||
@@ -255,7 +257,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
case "gun":
|
||||
upgradeTank(tank, 5);
|
||||
case _:
|
||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank.id, {tankId: tank.id}))); // :-D
|
||||
gameEventSignal.emit(DESTROY(TANK(tank.id, {tankId: tank.id}))); // :-D
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,34 +276,34 @@ class GameRunner extends Game implements EngineListener {
|
||||
var player = getPlayer(playerId);
|
||||
var team = getTeam(playerId.team);
|
||||
player.state.score += score;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_SCORE(playerId, player.state.score)));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_SCORE(playerId.team, state.getTeamScore(team.id))));
|
||||
gameEventSignal.emit(CHANGE(PLAYER_SCORE(playerId, player.state.score)));
|
||||
gameEventSignal.emit(CHANGE(TEAM_SCORE(playerId.team, state.getTeamScore(team.id))));
|
||||
}
|
||||
|
||||
private function changeLife(playerId:PlayerId, life:Int):Void {
|
||||
var player = getPlayer(playerId);
|
||||
player.state.life += life;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_LIFE(playerId, player.state.life)));
|
||||
gameEventSignal.emit(CHANGE(PLAYER_LIFE(playerId, player.state.life)));
|
||||
}
|
||||
|
||||
private function changeTeamLife(teamId:TeamId, life:Int):Void {
|
||||
var team = getTeam(teamId);
|
||||
team.state.life += life;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_LIFE(teamId, team.state.life)));
|
||||
gameEventSignal.emit(CHANGE(TEAM_LIFE(teamId, team.state.life)));
|
||||
}
|
||||
|
||||
override public function onGameEvent(event:GameEvent):Void {
|
||||
super.onGameEvent(event);
|
||||
switch event {
|
||||
case GameEvent.START(_):
|
||||
case START(_):
|
||||
timer = new Timer(30);
|
||||
timer.run = update;
|
||||
case GameEvent.COMPLETE(_, _):
|
||||
case COMPLETE(_, _):
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
timer = null;
|
||||
}
|
||||
case GameEvent.ACTION(tankId, SHOT):
|
||||
case ACTION(tankId, SHOT):
|
||||
var tank:Tank = cast engine.entities.get(tankId);
|
||||
var player = getPlayer(tank.playerId);
|
||||
if (!tank.freezing.active && player.bullets < tank.config.bullets) {
|
||||
@@ -311,21 +313,21 @@ class GameRunner extends Game implements EngineListener {
|
||||
bullet.tank = tank;
|
||||
bullet.move(bullet.rect.direction);
|
||||
engine.spawn(bullet);
|
||||
gameEventSignal.emit(GameEvent.SPAWN(BULLET(bullet.id, bullet.rect.clone(), bullet.playerId, bullet.config.piercing)));
|
||||
gameEventSignal.emit(SPAWN(BULLET(bullet.id, bullet.rect.clone(), bullet.playerId, bullet.config.piercing)));
|
||||
}
|
||||
case GameEvent.ACTION(tankId, MOVE(direction)):
|
||||
case ACTION(tankId, MOVE(direction)):
|
||||
engine.move(tankId, direction);
|
||||
case GameEvent.ACTION(tankId, STOP):
|
||||
gameEventSignal.emit(GameEvent.STOP(TANK(tankId)));
|
||||
case ACTION(tankId, STOP):
|
||||
gameEventSignal.emit(STOP(TANK(tankId)));
|
||||
engine.stop(tankId);
|
||||
case GameEvent.SPAWN(TANK(_, _, playerId, _)):
|
||||
case SPAWN(TANK(_, _, playerId, _)):
|
||||
var control = getPlayer(playerId).control;
|
||||
if (control != null) {
|
||||
control.start();
|
||||
}
|
||||
case GameEvent.SPAWN(BULLET(_, _, playerId, _)):
|
||||
case SPAWN(BULLET(_, _, playerId, _)):
|
||||
getPlayer(playerId).bullets++;
|
||||
case GameEvent.DESTROY(EAGLE(id, shot)):
|
||||
case DESTROY(EAGLE(id, shot)):
|
||||
var eagle:Eagle = engine.getEntity(id);
|
||||
eagle.death = true;
|
||||
if (shot.score != 0) {
|
||||
@@ -333,7 +335,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
changeScore(tank.playerId, shot.score);
|
||||
}
|
||||
checkComplete();
|
||||
case GameEvent.DESTROY(TANK(id, shot)):
|
||||
case DESTROY(TANK(id, shot)):
|
||||
var tank:Tank = engine.getEntity(id);
|
||||
var team = getTeam(tank.playerId.team);
|
||||
var player = getPlayer(tank.playerId);
|
||||
@@ -362,7 +364,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
changeScore(shooterTank.playerId, shot.score);
|
||||
}
|
||||
engine.destroy(id);
|
||||
case GameEvent.DESTROY(BONUS(id, shot)):
|
||||
case DESTROY(BONUS(id, shot)):
|
||||
var bonus:Bonus = engine.getEntity(id);
|
||||
var tank:Tank = engine.getEntity(shot.tankId);
|
||||
applyBonus(tank, bonus);
|
||||
@@ -370,7 +372,7 @@ class GameRunner extends Game implements EngineListener {
|
||||
changeScore(tank.playerId, shot.score);
|
||||
}
|
||||
engine.destroy(id);
|
||||
case GameEvent.DESTROY(BULLET(id)):
|
||||
case DESTROY(BULLET(id)):
|
||||
var bullet:Bullet = engine.getEntity(id);
|
||||
var player = getPlayer(bullet.playerId);
|
||||
player.bullets--;
|
||||
@@ -385,13 +387,13 @@ class GameRunner extends Game implements EngineListener {
|
||||
if (cell.armor == bullet.config.piercing) {
|
||||
engine.destroyCell(cell.cellX, cell.cellY);
|
||||
var brick = engine.map.getBrick(cell.position);
|
||||
gameEventSignal.emit(GameEvent.DESTROY(CELL(brick.id, cell.cellX - brick.cellX * 2, cell.cellY - brick.cellY * 2, shot)));
|
||||
gameEventSignal.emit(DESTROY(CELL(brick.id, cell.cellX - brick.cellX * 2, cell.cellY - brick.cellY * 2, shot)));
|
||||
} else if (cell.armor < bullet.config.piercing) {
|
||||
var brick = engine.map.getBrick(cell.position);
|
||||
for (cell in brick.cells) {
|
||||
engine.destroyCell(cell.cellX, cell.cellY);
|
||||
}
|
||||
gameEventSignal.emit(GameEvent.DESTROY(BRICK(brick.id, shot)));
|
||||
gameEventSignal.emit(DESTROY(BRICK(brick.id, shot)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ class GameState {
|
||||
public var type:GameType;
|
||||
public var presetId:PresetId;
|
||||
public var levelId:LevelId;
|
||||
public var controls:Array<PlayerControl>;
|
||||
public var players:Map<String, PlayerState>;
|
||||
public var teams:Map<TeamId, TeamState>;
|
||||
public var preset(get, null):GamePreset;
|
||||
@@ -81,10 +82,12 @@ class GameState {
|
||||
@:provide static private var configBundle:IConfigBundle;
|
||||
@:provide static private var levelBundle:ILevelBundle;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId = 0, levelId:Int = 0, state:GameState = null) {
|
||||
public function new(type:GameType, presetId:PresetId = 0, levelId:Int = 0, state:GameState = null, controls:Array<PlayerControl> = null) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.levelId = levelId;
|
||||
//this.controls = controls == null ? config.controls[0].values : controls;
|
||||
this.controls = controls == null ? [] : controls;
|
||||
if (state == null) {
|
||||
this.teams = new Map();
|
||||
this.players = new Map();
|
||||
|
||||
@@ -2,7 +2,6 @@ syntax = "proto3";
|
||||
|
||||
package ru.m.tankz.proto.core;
|
||||
|
||||
|
||||
message UserProto {
|
||||
string uuid = 1;
|
||||
string name = 2;
|
||||
@@ -14,11 +13,17 @@ enum GameStateProto {
|
||||
ENDED = 2;
|
||||
}
|
||||
|
||||
message PlayerProto {
|
||||
UserProto user = 1;
|
||||
string team = 2;
|
||||
int32 index = 3;
|
||||
}
|
||||
|
||||
message GameProto {
|
||||
int32 id = 1;
|
||||
string type = 2;
|
||||
int32 level = 3;
|
||||
UserProto creator = 4;
|
||||
repeated UserProto players = 5;
|
||||
repeated PlayerProto players = 5;
|
||||
GameStateProto state = 6;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,15 @@ team:
|
||||
human: &team_human
|
||||
id: human
|
||||
players:
|
||||
- {<<: *human, index: 0, color: 0xFFFF00, control: human-0}
|
||||
- {<<: *human, index: 0, color: 0xFFFF00, control: 'null'}
|
||||
- {<<: *human, index: 1, color: 0x15C040, control: 'null'}
|
||||
eagle:
|
||||
score: 0
|
||||
|
||||
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}
|
||||
#- {team: human, type: tank, index: 1, direction: top, x: 16, y: 24}
|
||||
- {team: human, type: tank, index: 1, direction: top, x: 16, y: 24}
|
||||
- {team: bot, type: tank, index: -1, direction: bottom, x: 0, y: 0}
|
||||
- {team: bot, type: tank, index: -2, direction: bottom, x: 12, y: 0}
|
||||
- {team: bot, type: tank, index: -3, direction: bottom, x: 24, y: 0}
|
||||
@@ -195,3 +196,17 @@ presets:
|
||||
- {<<: *bot, index: 3, control: bot-hard}
|
||||
- {<<: *bot, index: 4, control: bot-hard}
|
||||
- {<<: *bot, index: 5, control: bot-hard}
|
||||
|
||||
controls:
|
||||
- id: 0
|
||||
name: 1 Player
|
||||
values:
|
||||
- playerId: [human, 0]
|
||||
control: human-0
|
||||
- id: 1
|
||||
name: 2 Player
|
||||
values:
|
||||
- playerId: [human, 0]
|
||||
control: human-0
|
||||
- playerId: [human, 1]
|
||||
control: human-1
|
||||
|
||||
@@ -37,8 +37,6 @@ presets:
|
||||
teams:
|
||||
- id: alpha
|
||||
color: 0xFF4422
|
||||
players:
|
||||
- {<<: *player, index: 0, control: human-0}
|
||||
<<: *team
|
||||
- id: beta
|
||||
color: 0xFFD000
|
||||
@@ -91,3 +89,17 @@ tanks:
|
||||
skin: pc
|
||||
|
||||
bonuses: []
|
||||
|
||||
controls:
|
||||
- id: 0
|
||||
name: 1 Player
|
||||
values:
|
||||
- playerId: [alpha, 0]
|
||||
control: human-0
|
||||
- id: 1
|
||||
name: 2 Player
|
||||
values:
|
||||
- playerId: [alpha, 0]
|
||||
control: human-0
|
||||
- playerId: [beta, 0]
|
||||
control: human-1
|
||||
|
||||
@@ -41,7 +41,7 @@ team:
|
||||
id: radiant
|
||||
color: 0xff4422
|
||||
players:
|
||||
- {<<: *player-slow, index: 0, control: human-0, color: 0xff8866}
|
||||
- {<<: *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}
|
||||
@@ -114,3 +114,29 @@ bonuses:
|
||||
- {type: life}
|
||||
- {type: shovel, duration: 10}
|
||||
- {type: star}
|
||||
|
||||
controls:
|
||||
- id: 0
|
||||
name: 1 Player
|
||||
values:
|
||||
- playerId: [radiant, 0]
|
||||
control: human-0
|
||||
color: 0xff8866
|
||||
- id: 1
|
||||
name: 2 Player Coop
|
||||
values:
|
||||
- playerId: [radiant, 0]
|
||||
control: human-0
|
||||
color: 0xff8866
|
||||
- playerId: [radiant, 1]
|
||||
control: human-1
|
||||
color: 0xff8866
|
||||
- id: 2
|
||||
name: 2 Player VS
|
||||
values:
|
||||
- playerId: [radiant, 0]
|
||||
control: human-0
|
||||
color: 0xff8866
|
||||
- playerId: [dire, 0]
|
||||
control: human-1
|
||||
color: 0x4294ff
|
||||
|
||||
@@ -117,7 +117,7 @@ enum Brush {
|
||||
var playerId = new PlayerId(point.team, point.index < 0 ? 0 : point.index);
|
||||
var player = config.getPlayer(playerId);
|
||||
var tankSpawn = player.tanks[0];
|
||||
var tank = builder.buildTank(point, playerId, tankSpawn.type, true);
|
||||
var tank = builder.buildTank(point, playerId, tankSpawn.type, 0, true);
|
||||
pointEntities[pointKey(point)] = tank;
|
||||
gameEventSignal.emit(EventUtil.buildTankSpawn(tank));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ class ServerConfigBundle implements IConfigBundle {
|
||||
var path:String = FileSystem.absolutePath('./resources/${type}/config.yaml');
|
||||
var data:String = File.getContent(path);
|
||||
var source:ConfigSource = Yaml.parse(data, Parser.options().useObjects());
|
||||
return new Config(type, source.game, source.map, source.bricks, source.presets, source.points, source.tanks, source.bonuses);
|
||||
return Config.fromSource(type, source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package ru.m.tankz.server.control;
|
||||
|
||||
import ru.m.tankz.Type;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.control.BaseControlFactory;
|
||||
|
||||
class ClientControl extends Control {}
|
||||
|
||||
class ServerControlFactory extends BaseControlFactory {
|
||||
|
||||
override private function buildHuman(id:PlayerId, index:Int):Control {
|
||||
return new ClientControl(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ class _GameListener implements GameListener {
|
||||
.setId(++counter)
|
||||
.setCreator(user)
|
||||
.setType(type)
|
||||
.setLevel(level)
|
||||
.setPlayers([user]);
|
||||
.setLevel(level);
|
||||
var game = new ServerGame(proto);
|
||||
game.joinUser(user);
|
||||
games.push(game);
|
||||
gamesById[game.proto.id] = game;
|
||||
gamesByCreator[game.proto.creator.uuid] = game;
|
||||
@@ -71,7 +71,7 @@ class _GameListener implements GameListener {
|
||||
public function join(gameId:Int, user:UserProto):Void {
|
||||
if (gamesById.exists(gameId)) {
|
||||
var game = gamesById[gameId];
|
||||
game.proto.players.push(user);
|
||||
game.joinUser(user);
|
||||
gamesByUser[user.uuid] = game;
|
||||
changeSignal.emit(game, JOIN(user));
|
||||
}
|
||||
@@ -92,7 +92,7 @@ class _GameListener implements GameListener {
|
||||
delete(gamesByCreator[user.uuid].proto.id);
|
||||
} else if (gamesByUser.exists(user.uuid)) {
|
||||
var game = gamesByUser[user.uuid];
|
||||
game.proto.setPlayers(game.proto.players.filter(function(player) return player.uuid != user.uuid));
|
||||
game.leaveUser(user);
|
||||
changeSignal.emit(game, LEAVE(user));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package ru.m.tankz.server.game;
|
||||
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.game.GameRunner;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.proto.core.GameProto;
|
||||
import ru.m.tankz.proto.core.PlayerProto;
|
||||
import ru.m.tankz.proto.core.UserProto;
|
||||
import ru.m.tankz.server.control.ServerControlFactory;
|
||||
|
||||
class ServerGame extends GameRunner {
|
||||
@@ -15,4 +18,22 @@ class ServerGame extends GameRunner {
|
||||
this.controlFactory = new ServerControlFactory();
|
||||
this.proto = proto;
|
||||
}
|
||||
|
||||
public function joinUser(user:UserProto):Void {
|
||||
var index = proto.players.length;
|
||||
var teamId = "human"; // ToDo:
|
||||
proto.players.push(new PlayerProto().setUser(user).setTeam(teamId).setIndex(index));
|
||||
}
|
||||
|
||||
public function leaveUser(user:UserProto):Void {
|
||||
proto.setPlayers(proto.players.filter(function(player) return player.user.uuid != user.uuid));
|
||||
}
|
||||
|
||||
override public function start():Void {
|
||||
state.controls = proto.players.map(function(player):PlayerControl return {
|
||||
playerId: [player.team, player.index],
|
||||
control: 'human-0'
|
||||
});
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user