Added laser effect
This commit is contained in:
parent
1936cfef8d
commit
e34372891e
2
TODO.md
2
TODO.md
|
@ -77,8 +77,8 @@ Ships models and equipments
|
||||||
Artificial Intelligence
|
Artificial Intelligence
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
* Work on a simple representation of battle state, simulating effects on it, evaluating it, and only reevaluating parts that changed
|
||||||
* Use a first batch of producers, and only if no "good" move has been found, go on with some infinite producers
|
* Use a first batch of producers, and only if no "good" move has been found, go on with some infinite producers
|
||||||
* Evaluate buffs/debuffs
|
|
||||||
* Abandon fight if the AI judges there is no hope of victory
|
* Abandon fight if the AI judges there is no hope of victory
|
||||||
* Add combination of random small move and actual maneuver, as producer
|
* Add combination of random small move and actual maneuver, as producer
|
||||||
* New duel page with producers/evaluators tweaking
|
* New duel page with producers/evaluators tweaking
|
||||||
|
|
BIN
graphics/exported/battle/effects/laser.png
Normal file
BIN
graphics/exported/battle/effects/laser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
|
@ -15,7 +15,7 @@
|
||||||
viewBox="0 0 128 128"
|
viewBox="0 0 128 128"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg8"
|
id="svg8"
|
||||||
inkscape:version="0.92.0 r15299"
|
inkscape:version="0.92.1 r15371"
|
||||||
sodipodi:docname="weaponeffects.svg"
|
sodipodi:docname="weaponeffects.svg"
|
||||||
inkscape:export-filename="/tmp/image.png"
|
inkscape:export-filename="/tmp/image.png"
|
||||||
inkscape:export-xdpi="96.000008"
|
inkscape:export-xdpi="96.000008"
|
||||||
|
@ -198,6 +198,19 @@
|
||||||
r="30.446428"
|
r="30.446428"
|
||||||
gradientUnits="userSpaceOnUse"
|
gradientUnits="userSpaceOnUse"
|
||||||
gradientTransform="matrix(1.0997067,0,0,1.0997067,-4.1425418,-8.3253595)" />
|
gradientTransform="matrix(1.0997067,0,0,1.0997067,-4.1425418,-8.3253595)" />
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter5826"
|
||||||
|
x="-0.047145694"
|
||||||
|
width="1.0942914"
|
||||||
|
y="-0.98874992"
|
||||||
|
height="2.9775">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="7.6811109"
|
||||||
|
id="feGaussianBlur5828" />
|
||||||
|
</filter>
|
||||||
</defs>
|
</defs>
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
id="base"
|
id="base"
|
||||||
|
@ -206,11 +219,11 @@
|
||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="7.9195959"
|
inkscape:zoom="1.979899"
|
||||||
inkscape:cx="61.820614"
|
inkscape:cx="60.541466"
|
||||||
inkscape:cy="63.238329"
|
inkscape:cy="49.925567"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer5"
|
inkscape:current-layer="layer7"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
units="px"
|
units="px"
|
||||||
inkscape:measure-start="35.2291,59.599"
|
inkscape:measure-start="35.2291,59.599"
|
||||||
|
@ -406,7 +419,8 @@
|
||||||
<g
|
<g
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer5"
|
id="layer5"
|
||||||
inkscape:label="Stasis">
|
inkscape:label="Stasis"
|
||||||
|
style="display:none">
|
||||||
<circle
|
<circle
|
||||||
style="fill:url(#radialGradient4556);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10143852;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
style="fill:url(#radialGradient4556);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.10143852;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
id="path4548"
|
id="path4548"
|
||||||
|
@ -432,4 +446,20 @@
|
||||||
inkscape:export-xdpi="96"
|
inkscape:export-xdpi="96"
|
||||||
inkscape:export-ydpi="96" />
|
inkscape:export-ydpi="96" />
|
||||||
</g>
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer7"
|
||||||
|
inkscape:label="Laser">
|
||||||
|
<rect
|
||||||
|
transform="matrix(1.0666667,-1.4605933e-5,6.2967195e-5,0.24742509,-63.824421,36.000686)"
|
||||||
|
y="117.72057"
|
||||||
|
x="-62.353645"
|
||||||
|
height="18.644417"
|
||||||
|
width="391.01483"
|
||||||
|
id="rect5544"
|
||||||
|
style="display:inline;fill:#f1a581;fill-opacity:1;fill-rule:evenodd;stroke:#ff2300;stroke-width:7.31692886;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5826)"
|
||||||
|
inkscape:export-filename="/home/michael/workspace/perso/spacetac/graphics/exported/battle/effects/laser.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96" />
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
|
@ -36,7 +36,7 @@
|
||||||
"typescript": "^2.5.3"
|
"typescript": "^2.5.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jasmine-core": "2.8.0",
|
"jasmine-core": "2.5.2",
|
||||||
"parse": "^1.9.2",
|
"parse": "^1.9.2",
|
||||||
"phaser": "^2.6.2",
|
"phaser": "^2.6.2",
|
||||||
"phaser-plugin-scene-graph": "^1.0.4"
|
"phaser-plugin-scene-graph": "^1.0.4"
|
||||||
|
|
|
@ -11,5 +11,10 @@ module TK.SpaceTac.Specs {
|
||||||
expect(angularDistance(0.5, -0.5)).toBe(-1.0);
|
expect(angularDistance(0.5, -0.5)).toBe(-1.0);
|
||||||
expect(angularDistance(0.5, -0.3 - Math.PI * 4)).toBeCloseTo(-0.8, 0.000001);
|
expect(angularDistance(0.5, -0.3 - Math.PI * 4)).toBeCloseTo(-0.8, 0.000001);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("converts between degrees and radians", function () {
|
||||||
|
expect(degrees(Math.PI / 2)).toBeCloseTo(90, 0.000001);
|
||||||
|
expect(radians(45)).toBeCloseTo(Math.PI / 4, 0.000001);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,4 +81,18 @@ module TK.SpaceTac {
|
||||||
let dist = arenaDistance(loc1, loc2);
|
let dist = arenaDistance(loc1, loc2);
|
||||||
return border_inclusive ? (dist <= loc2.radius) : (dist < loc2.radius);
|
return border_inclusive ? (dist <= loc2.radius) : (dist < loc2.radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert radians angle to degrees
|
||||||
|
*/
|
||||||
|
export function degrees(angle: number): number {
|
||||||
|
return angle * 180 / Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert degrees angle to radians
|
||||||
|
*/
|
||||||
|
export function radians(angle: number): number {
|
||||||
|
return angle * Math.PI / 180;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ module TK.SpaceTac.UI {
|
||||||
this.loadImage("battle/actionbar/actions-background.png");
|
this.loadImage("battle/actionbar/actions-background.png");
|
||||||
this.loadSheet("battle/actionbar/button-menu.png", 79, 132);
|
this.loadSheet("battle/actionbar/button-menu.png", 79, 132);
|
||||||
this.loadImage("battle/arena/background.png");
|
this.loadImage("battle/arena/background.png");
|
||||||
this.loadImage("battle/arena/blast.png");
|
|
||||||
this.loadImage("battle/shiplist/background.png");
|
this.loadImage("battle/shiplist/background.png");
|
||||||
this.loadImage("battle/shiplist/item-background.png");
|
this.loadImage("battle/shiplist/item-background.png");
|
||||||
this.loadImage("battle/shiplist/damage.png");
|
this.loadImage("battle/shiplist/damage.png");
|
||||||
|
|
|
@ -141,17 +141,6 @@ module TK.SpaceTac.UI {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all ship sprites in a circle area
|
|
||||||
*/
|
|
||||||
getShipsInCircle(area: ArenaCircleArea, alive_only = true, border_inclusive = true): ArenaShip[] {
|
|
||||||
let base = this.ship_sprites;
|
|
||||||
if (alive_only) {
|
|
||||||
base = base.filter(ship => !ship.isDead());
|
|
||||||
}
|
|
||||||
return base.filter(ship => arenaInside(ship, area, border_inclusive));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current MainUI instance
|
* Get the current MainUI instance
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -133,6 +133,10 @@ module TK.SpaceTac.UI {
|
||||||
this.battleview.log_processor.registerForShip(ship, event => this.processShipLogEvent(event));
|
this.battleview.log_processor.registerForShip(ship, event => this.processShipLogEvent(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jasmineToString(): string {
|
||||||
|
return `ArenaShip ${this.ship.jasmineToString()}`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a battle log event
|
* Process a battle log event
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -161,8 +161,8 @@ module TK.SpaceTac.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radius) {
|
if (radius) {
|
||||||
area.lineStyle(2, 0x90481e, 0.6);
|
area.lineStyle(2, color, 0.6);
|
||||||
area.beginFill(0x90481e, 0.2);
|
area.beginFill(color, 0.2);
|
||||||
if (angle) {
|
if (angle) {
|
||||||
area.arc(0, 0, radius, angle, -angle, true);
|
area.arc(0, 0, radius, angle, -angle, true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,31 +33,45 @@ module TK.SpaceTac.UI.Specs {
|
||||||
let battleview = testgame.battleview;
|
let battleview = testgame.battleview;
|
||||||
battleview.timer = new Timer();
|
battleview.timer = new Timer();
|
||||||
|
|
||||||
|
let ship = nn(battleview.battle.playing_ship);
|
||||||
|
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromShip(ship), new Equipment());
|
||||||
|
effect.gunEffect();
|
||||||
|
|
||||||
|
let layer = battleview.arena.layer_weapon_effects;
|
||||||
|
expect(layer.children.length).toBe(1);
|
||||||
|
expect(layer.children[0] instanceof Phaser.Particles.Arcade.Emitter).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("displays shield and hull effect on impacted ships", function () {
|
||||||
|
let battleview = testgame.battleview;
|
||||||
|
battleview.timer = new Timer();
|
||||||
|
|
||||||
let ship = nn(battleview.battle.playing_ship);
|
let ship = nn(battleview.battle.playing_ship);
|
||||||
let sprite = nn(battleview.arena.findShipSprite(ship));
|
let sprite = nn(battleview.arena.findShipSprite(ship));
|
||||||
ship.setArenaPosition(50, 30);
|
ship.setArenaPosition(50, 30);
|
||||||
sprite.position.set(50, 30);
|
sprite.position.set(50, 30);
|
||||||
sprite.hull_bar.setValue(10, 10);
|
sprite.hull_bar.setValue(10, 10);
|
||||||
sprite.shield_bar.setValue(0, 10);
|
sprite.shield_bar.setValue(0, 10);
|
||||||
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromShip(ship), new Equipment());
|
|
||||||
|
let weapon = new Equipment();
|
||||||
|
weapon.action = new TriggerAction(weapon, [new DamageEffect()], 1, 500);
|
||||||
|
spyOn(weapon.action, "getImpactedShips").and.returnValue([ship]);
|
||||||
|
|
||||||
|
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromShip(ship), weapon);
|
||||||
|
spyOn(effect, "getEffectForWeapon").and.returnValue(() => 100);
|
||||||
|
|
||||||
let mock_shield_impact = spyOn(effect, "shieldImpactEffect").and.stub();
|
let mock_shield_impact = spyOn(effect, "shieldImpactEffect").and.stub();
|
||||||
let mock_hull_impact = spyOn(effect, "hullImpactEffect").and.stub();
|
let mock_hull_impact = spyOn(effect, "hullImpactEffect").and.stub();
|
||||||
|
|
||||||
effect.gunEffect();
|
effect.start();
|
||||||
|
|
||||||
let layer = battleview.arena.layer_weapon_effects;
|
|
||||||
expect(layer.children.length).toBe(1);
|
|
||||||
|
|
||||||
expect(layer.children[0] instanceof Phaser.Particles.Arcade.Emitter).toBe(true);
|
|
||||||
expect(mock_shield_impact).toHaveBeenCalledTimes(0);
|
expect(mock_shield_impact).toHaveBeenCalledTimes(0);
|
||||||
expect(mock_hull_impact).toHaveBeenCalledTimes(1);
|
expect(mock_hull_impact).toHaveBeenCalledTimes(1);
|
||||||
expect(mock_hull_impact).toHaveBeenCalledWith(jasmine.objectContaining({ x: 0, y: 0 }), jasmine.objectContaining({ x: 50, y: 30 }), 100, 800);
|
expect(mock_hull_impact).toHaveBeenCalledWith(jasmine.objectContaining({ x: 0, y: 0 }), jasmine.objectContaining({ x: 50, y: 30 }), 40, 400);
|
||||||
|
|
||||||
sprite.shield_bar.setValue(10, 10);
|
sprite.shield_bar.setValue(10, 10);
|
||||||
effect.gunEffect();
|
effect.start();
|
||||||
expect(mock_shield_impact).toHaveBeenCalledTimes(1);
|
expect(mock_shield_impact).toHaveBeenCalledTimes(1);
|
||||||
expect(mock_shield_impact).toHaveBeenCalledWith(jasmine.objectContaining({ x: 0, y: 0 }), jasmine.objectContaining({ x: 50, y: 30 }), 100, 800, true);
|
expect(mock_shield_impact).toHaveBeenCalledWith(jasmine.objectContaining({ x: 0, y: 0 }), jasmine.objectContaining({ x: 50, y: 30 }), 40, 800, false);
|
||||||
expect(mock_hull_impact).toHaveBeenCalledTimes(1);
|
expect(mock_hull_impact).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,7 +82,7 @@ module TK.SpaceTac.UI.Specs {
|
||||||
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromLocation(50, 50), new Equipment());
|
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromLocation(50, 50), new Equipment());
|
||||||
|
|
||||||
effect.gunEffect();
|
effect.gunEffect();
|
||||||
checkEmitters("gun effect started", 2);
|
checkEmitters("gun effect started", 1);
|
||||||
fastForward(6000);
|
fastForward(6000);
|
||||||
checkEmitters("gun effect ended", 0);
|
checkEmitters("gun effect ended", 0);
|
||||||
|
|
||||||
|
@ -77,5 +91,31 @@ module TK.SpaceTac.UI.Specs {
|
||||||
fastForward(8500);
|
fastForward(8500);
|
||||||
checkEmitters("hull effect ended", 0);
|
checkEmitters("hull effect ended", 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("adds a laser effect", function () {
|
||||||
|
let battleview = testgame.battleview;
|
||||||
|
battleview.timer = new Timer();
|
||||||
|
|
||||||
|
let effect = new WeaponEffect(battleview.arena, new Ship(), Target.newFromLocation(31, 49), new Equipment());
|
||||||
|
|
||||||
|
let result = effect.angularLaser({ x: 20, y: 30 }, 300, Math.PI / 4, -Math.PI / 2, 5);
|
||||||
|
expect(result).toBe(200);
|
||||||
|
|
||||||
|
let layer = battleview.arena.layer_weapon_effects;
|
||||||
|
expect(layer.children.length).toBe(1);
|
||||||
|
expect(layer.children[0] instanceof Phaser.Image).toBe(true, "is image");
|
||||||
|
let image = <Phaser.Image>layer.children[0];
|
||||||
|
expect(image.name).toEqual("battle-effects-laser");
|
||||||
|
expect(image.width).toBe(300);
|
||||||
|
expect(image.x).toEqual(20);
|
||||||
|
expect(image.y).toEqual(30);
|
||||||
|
expect(image.rotation).toBeCloseTo(Math.PI / 4, 0.000001);
|
||||||
|
|
||||||
|
let values = battleview.animations.simulate(image, "rotation", 4, result);
|
||||||
|
expect(values[0]).toBeCloseTo(Math.PI / 4, 0.000001);
|
||||||
|
expect(values[1]).toBeCloseTo(0, 0.000001);
|
||||||
|
expect(values[2]).toBeCloseTo(-Math.PI / 4, 0.000001);
|
||||||
|
expect(values[3]).toBeCloseTo(-Math.PI / 2, 0.000001);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,6 @@ module TK.SpaceTac.UI {
|
||||||
// Weapon used
|
// Weapon used
|
||||||
private weapon: Equipment
|
private weapon: Equipment
|
||||||
|
|
||||||
// Effect in use
|
|
||||||
private effect: Function
|
|
||||||
|
|
||||||
constructor(arena: Arena, ship: Ship, target: Target, weapon: Equipment) {
|
constructor(arena: Arena, ship: Ship, target: Target, weapon: Equipment) {
|
||||||
this.ui = arena.game;
|
this.ui = arena.game;
|
||||||
this.arena = arena;
|
this.arena = arena;
|
||||||
|
@ -47,7 +44,6 @@ module TK.SpaceTac.UI {
|
||||||
this.ship = ship;
|
this.ship = ship;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.weapon = weapon;
|
this.weapon = weapon;
|
||||||
this.effect = this.getEffectForWeapon(weapon.code);
|
|
||||||
|
|
||||||
this.source = this.getCoords(Target.newFromShip(this.ship));
|
this.source = this.getCoords(Target.newFromShip(this.ship));
|
||||||
this.destination = this.getCoords(this.target);
|
this.destination = this.getCoords(this.target);
|
||||||
|
@ -59,11 +55,45 @@ module TK.SpaceTac.UI {
|
||||||
* Returns the duration of the effect.
|
* Returns the duration of the effect.
|
||||||
*/
|
*/
|
||||||
start(): number {
|
start(): number {
|
||||||
if (this.effect) {
|
// Fire effect
|
||||||
return this.effect();
|
let effect = this.getEffectForWeapon(this.weapon.code, this.weapon.action);
|
||||||
} else {
|
let duration = effect();
|
||||||
return 0;
|
|
||||||
|
// Damage effect
|
||||||
|
let action = this.weapon.action;
|
||||||
|
if (action instanceof TriggerAction && any(action.effects, effect => effect instanceof DamageEffect)) {
|
||||||
|
let ships = action.getImpactedShips(this.ship, this.target, this.source);
|
||||||
|
let source = action.blast ? this.target : this.source;
|
||||||
|
let damage_duration = this.damageEffect(source, ships, duration * 0.4, this.weapon.code == "gatlinggun");
|
||||||
|
duration = Math.max(duration, damage_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a damage effect on ships impacted by a weapon
|
||||||
|
*/
|
||||||
|
damageEffect(source: IArenaLocation, ships: Ship[], base_delay = 0, shield_flares = false): number {
|
||||||
|
let duration = 0;
|
||||||
|
|
||||||
|
// TODO For each ship, delay should depend on fire effect animation
|
||||||
|
let delay = base_delay;
|
||||||
|
|
||||||
|
ships.forEach(ship => {
|
||||||
|
let sprite = this.arena.findShipSprite(ship);
|
||||||
|
if (sprite) {
|
||||||
|
if (sprite.getValue("shield") > 0) {
|
||||||
|
this.shieldImpactEffect(source, sprite, delay, 800, shield_flares);
|
||||||
|
duration = Math.max(duration, delay + 800);
|
||||||
|
} else {
|
||||||
|
this.hullImpactEffect(source, sprite, delay, 400);
|
||||||
|
duration = Math.max(duration, delay + 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,12 +115,17 @@ module TK.SpaceTac.UI {
|
||||||
/**
|
/**
|
||||||
* Get the function that will be called to start the visual effect
|
* Get the function that will be called to start the visual effect
|
||||||
*/
|
*/
|
||||||
getEffectForWeapon(weapon: string): Function {
|
getEffectForWeapon(weapon: string, action: BaseAction | null): () => number {
|
||||||
switch (weapon) {
|
switch (weapon) {
|
||||||
case "gatlinggun":
|
case "gatlinggun":
|
||||||
return this.gunEffect.bind(this);
|
return () => this.gunEffect();
|
||||||
|
case "prokhorovlaser":
|
||||||
|
let trigger = <TriggerAction>nn(action);
|
||||||
|
let angle = arenaAngle(this.source, this.target);
|
||||||
|
let dangle = radians(trigger.angle) * 0.5;
|
||||||
|
return () => this.angularLaser(this.source, trigger.range, angle - dangle, angle + dangle);
|
||||||
default:
|
default:
|
||||||
return this.defaultEffect.bind(this);
|
return () => this.defaultEffect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,22 +220,28 @@ module TK.SpaceTac.UI {
|
||||||
});
|
});
|
||||||
tween.start();
|
tween.start();
|
||||||
|
|
||||||
if (blast_radius > 0 && this.weapon.action instanceof TriggerAction) {
|
|
||||||
if (any(this.weapon.action.effects, effect => effect instanceof DamageEffect)) {
|
|
||||||
let ships = this.arena.getShipsInCircle(new ArenaCircleArea(this.destination.x, this.destination.y, blast_radius));
|
|
||||||
ships.forEach(sprite => {
|
|
||||||
if (sprite.getValue("shield") > 0) {
|
|
||||||
this.shieldImpactEffect(this.target, sprite, 1200, 800);
|
|
||||||
} else {
|
|
||||||
this.hullImpactEffect(this.target, sprite, 1200, 400);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectile_duration + (blast_radius ? 1500 : 0);
|
return projectile_duration + (blast_radius ? 1500 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Laser effect, scanning from one angle to the other
|
||||||
|
*/
|
||||||
|
angularLaser(source: IArenaLocation, radius: number, start_angle: number, end_angle: number, speed = 1): number {
|
||||||
|
let duration = 1000 / speed;
|
||||||
|
|
||||||
|
let laser = this.view.newImage("battle-effects-laser", source.x, source.y);
|
||||||
|
laser.anchor.set(0, 0.5);
|
||||||
|
laser.rotation = start_angle;
|
||||||
|
laser.scale.set(radius / laser.width);
|
||||||
|
this.layer.add(laser);
|
||||||
|
|
||||||
|
let tween = this.view.tweens.create(laser).to({ rotation: end_angle }, duration);
|
||||||
|
tween.onComplete.addOnce(() => laser.destroy());
|
||||||
|
tween.start();
|
||||||
|
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submachine gun effect (quick chain of small bullets)
|
* Submachine gun effect (quick chain of small bullets)
|
||||||
*/
|
*/
|
||||||
|
@ -230,12 +271,6 @@ module TK.SpaceTac.UI {
|
||||||
this.layer.add(emitter);
|
this.layer.add(emitter);
|
||||||
this.timer.schedule(5000, () => emitter.destroy());
|
this.timer.schedule(5000, () => emitter.destroy());
|
||||||
|
|
||||||
if (has_shield) {
|
|
||||||
this.shieldImpactEffect(this.source, this.target, 100, 800, true);
|
|
||||||
} else {
|
|
||||||
this.hullImpactEffect(this.source, this.target, 100, 800);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ module TK.SpaceTac.UI {
|
||||||
simulate(obj: any, property: string, points = 5, duration = 1000): number[] {
|
simulate(obj: any, property: string, points = 5, duration = 1000): number[] {
|
||||||
let tween = first(this.tweens.getAll().concat((<any>this.tweens)._add), tween => tween.target === obj && !tween.pendingDelete);
|
let tween = first(this.tweens.getAll().concat((<any>this.tweens)._add), tween => tween.target === obj && !tween.pendingDelete);
|
||||||
if (tween) {
|
if (tween) {
|
||||||
return [obj[property]].concat(tween.generateData(points - 1).map(data => data[property]));
|
return [obj[property]].concat(tween.generateData(1000 * (points - 1) / duration).map(data => data[property]));
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1315,7 +1315,11 @@ istanbul@0.4.5, istanbul@^0.4.0:
|
||||||
which "^1.1.1"
|
which "^1.1.1"
|
||||||
wordwrap "^1.0.0"
|
wordwrap "^1.0.0"
|
||||||
|
|
||||||
jasmine-core@2.8.0, jasmine-core@~2.8.0:
|
jasmine-core@2.5.2:
|
||||||
|
version "2.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.5.2.tgz#6f61bd79061e27f43e6f9355e44b3c6cab6ff297"
|
||||||
|
|
||||||
|
jasmine-core@~2.8.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
|
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue