1
0
Fork 0
spacetac/src/ui/battle/LogProcessor.ts

227 lines
7.5 KiB
TypeScript
Raw Normal View History

2017-02-09 00:00:35 +00:00
module TS.SpaceTac.UI {
2014-12-31 00:00:00 +00:00
// Processor of battle log events
// This will process incoming battle events, and update the battleview accordingly
export class LogProcessor {
// Link to the battle view
private view: BattleView;
// Link to the battle
2017-02-09 00:00:35 +00:00
private battle: Battle;
2014-12-31 00:00:00 +00:00
// Link to the battle log
2017-02-09 00:00:35 +00:00
private log: BattleLog;
2014-12-31 00:00:00 +00:00
// Subscription identifier
2017-02-21 22:38:31 +00:00
private subscription: any = null;
2014-12-31 00:00:00 +00:00
// Delay before processing next events
private delayed = false;
// Processing queue, when delay is active
private queue: BaseLogEvent[] = [];
// Forward events to other subscribers
private forwarding: LogSubscriber[] = [];
2014-12-31 00:00:00 +00:00
constructor(view: BattleView) {
this.view = view;
this.battle = view.battle;
this.log = view.battle.log;
2017-02-21 22:38:31 +00:00
}
2014-12-31 00:00:00 +00:00
2017-02-21 22:38:31 +00:00
/**
* Start log processing
*/
start() {
this.subscription = this.log.subscribe(event => this.processBattleEvent(event));
2017-02-21 22:38:31 +00:00
this.battle.injectInitialEvents();
}
/**
* Register a sub-subscriber.
*
* The difference with registering directly to the BattleLog is that events may be delayed
* for animations.
*/
register(callback: LogSubscriber) {
this.forwarding.push(callback);
2014-12-31 00:00:00 +00:00
}
/**
* Introduce a delay in event processing
*/
delayNextEvents(duration: number) {
if (duration > 0 && !this.view.gameui.headless) {
this.delayed = true;
2017-02-16 22:59:41 +00:00
this.view.timer.schedule(duration, () => this.processQueued());
}
}
/**
* Process the events queued due to a delay
*/
processQueued() {
let events = acopy(this.queue);
this.queue = [];
this.delayed = false;
events.forEach(event => this.processBattleEvent(event));
}
/**
* Process a single event
*/
2017-02-09 00:00:35 +00:00
processBattleEvent(event: BaseLogEvent) {
if (!this.subscription) {
return;
}
if (this.delayed) {
this.queue.push(event);
return;
}
2014-12-31 00:00:00 +00:00
console.log("Battle event", event);
this.forwarding.forEach(subscriber => subscriber(event));
2017-02-09 00:00:35 +00:00
if (event instanceof ShipChangeEvent) {
2017-02-08 18:54:02 +00:00
this.processShipChangeEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof MoveEvent) {
2017-02-08 18:54:02 +00:00
this.processMoveEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof ValueChangeEvent) {
2017-02-08 18:54:02 +00:00
this.processValueChangedEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof DeathEvent) {
2017-02-08 18:54:02 +00:00
this.processDeathEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof FireEvent) {
2017-02-08 18:54:02 +00:00
this.processFireEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof DamageEvent) {
2017-02-08 18:54:02 +00:00
this.processDamageEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof EndBattleEvent) {
2017-02-08 18:54:02 +00:00
this.processEndBattleEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof DroneDeployedEvent) {
2017-02-08 18:54:02 +00:00
this.processDroneDeployedEvent(event);
2017-02-09 00:00:35 +00:00
} else if (event instanceof DroneDestroyedEvent) {
2017-02-08 18:54:02 +00:00
this.processDroneDestroyedEvent(event);
} else if (event instanceof DroneAppliedEvent) {
this.processDroneAppliedEvent(event);
2017-03-12 23:32:41 +00:00
} else if (event instanceof EffectAddedEvent || event instanceof EffectRemovedEvent || event instanceof EffectDurationChangedEvent) {
2017-02-08 18:54:02 +00:00
this.processEffectEvent(event);
2014-12-31 00:00:00 +00:00
}
}
// Destroy the log processor
destroy() {
if (this.subscription) {
this.log.unsubscribe(this.subscription);
this.subscription = null;
this.queue = [];
2014-12-31 00:00:00 +00:00
}
}
2015-02-03 00:00:00 +00:00
// Playing ship changed
2017-02-09 00:00:35 +00:00
private processShipChangeEvent(event: ShipChangeEvent): void {
2017-03-15 00:24:56 +00:00
this.view.arena.setShipPlaying(event.new_ship);
this.view.ship_list.setPlaying(event.new_ship);
2017-02-16 22:59:41 +00:00
if (this.battle.canPlay(this.view.player)) {
// Player turn
this.view.setInteractionEnabled(true);
} else {
this.view.setInteractionEnabled(false);
2017-03-15 00:24:56 +00:00
if (event.new_ship.isAbleToPlay()) {
2017-02-16 22:59:41 +00:00
// AI turn
this.battle.playAI();
} else {
// Ship unable to play, skip turn
2017-03-15 00:24:56 +00:00
this.view.timer.schedule(event.new_ship.alive ? 2000 : 500, () => {
2017-02-16 22:59:41 +00:00
this.battle.advanceToNextShip();
});
}
}
2015-02-03 00:00:00 +00:00
}
// Damage to ship
2017-02-09 00:00:35 +00:00
private processDamageEvent(event: DamageEvent): void {
var item = this.view.ship_list.findItem(event.ship);
if (item) {
item.setDamageHit();
}
2015-02-03 00:00:00 +00:00
}
// Ship moved
2017-02-09 00:00:35 +00:00
private processMoveEvent(event: MoveEvent): void {
2015-02-03 00:00:00 +00:00
var sprite = this.view.arena.findShipSprite(event.ship);
if (sprite) {
let duration = sprite.moveTo(event.target.x, event.target.y, event.facing_angle, !event.initial);
this.delayNextEvents(duration);
2015-02-03 00:00:00 +00:00
}
}
// Ship value changed
2017-02-09 00:00:35 +00:00
private processValueChangedEvent(event: ValueChangeEvent): void {
var sprite = this.view.arena.findShipSprite(event.ship);
if (sprite) {
sprite.displayValueChanged(event);
}
// TODO Update tooltip
2015-02-03 00:00:00 +00:00
}
2015-02-18 00:00:00 +00:00
// A ship died
2017-02-09 00:00:35 +00:00
private processDeathEvent(event: DeathEvent): void {
2015-02-23 00:00:00 +00:00
if (this.view.ship_hovered === event.ship) {
this.view.setShipHovered(null);
}
this.view.arena.markAsDead(event.ship);
this.view.ship_list.markAsDead(event.ship);
2017-02-15 22:34:27 +00:00
if (!event.initial) {
this.delayNextEvents(1000);
}
2015-02-18 00:00:00 +00:00
}
2015-02-20 00:00:00 +00:00
// Weapon used
2017-02-09 00:00:35 +00:00
private processFireEvent(event: FireEvent): void {
var source = Target.newFromShip(event.ship);
var destination = event.target;
2015-02-20 00:00:00 +00:00
2017-02-15 16:41:24 +00:00
var effect = new WeaponEffect(this.view.arena, source, destination, event.weapon);
let duration = effect.start();
this.delayNextEvents(duration);
2015-02-20 00:00:00 +00:00
}
// Battle ended (victory or defeat)
2017-02-09 00:00:35 +00:00
private processEndBattleEvent(event: EndBattleEvent): void {
2017-03-12 23:32:41 +00:00
this.view.endBattle();
this.destroy();
}
2017-01-23 23:07:54 +00:00
// Sticky effect on ship added, changed or removed
2017-03-09 17:11:00 +00:00
private processEffectEvent(event: EffectAddedEvent | EffectRemovedEvent | EffectDurationChangedEvent): void {
2017-05-14 21:03:03 +00:00
// TODO
}
2017-02-08 18:54:02 +00:00
// New drone deployed
2017-02-09 00:00:35 +00:00
private processDroneDeployedEvent(event: DroneDeployedEvent): void {
2017-02-15 22:34:27 +00:00
let duration = this.view.arena.addDrone(event.drone, !event.initial);
this.delayNextEvents(duration);
2017-02-08 18:54:02 +00:00
}
// Drone destroyed
2017-02-09 00:00:35 +00:00
private processDroneDestroyedEvent(event: DroneDestroyedEvent): void {
2017-02-08 18:54:02 +00:00
this.view.arena.removeDrone(event.drone);
}
// Drone applied
private processDroneAppliedEvent(event: DroneAppliedEvent): void {
let drone = this.view.arena.findDrone(event.drone);
if (drone) {
let duration = drone.setApplied();
this.delayNextEvents(duration);
}
}
2014-12-31 00:00:00 +00:00
}
2015-01-07 00:00:00 +00:00
}