Fixed move exclusion radius
This commit is contained in:
parent
4105319fff
commit
6d01734238
1
TODO
1
TODO
|
@ -22,6 +22,7 @@
|
|||
* Arena: add auto-move to attack
|
||||
* Arena: fix effects originating from real ship location instead of current sprite (when AI fires then moves)
|
||||
* Arena: add engine trail
|
||||
* Arena: draw move exclusion circles (only on clonflict or in tactical mode ?)
|
||||
* Fix capacity limit effect not refreshing associated value (for example, on "limit power capacity to 3", potential "power" value change is not broadcast)
|
||||
* Actions: show power usage/recovery in power bar, on action hover
|
||||
* Actions: fix targetting not resetting when using keyboard shortcuts
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9957f153b1da5f1d30beebd670cc0a952d541304
|
||||
Subproject commit df24442f844494bf0f799fcf5bdcf5bcad36501e
|
|
@ -411,6 +411,13 @@ module TS.SpaceTac {
|
|||
return distance <= radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance to another ship
|
||||
*/
|
||||
getDistanceTo(other: Ship): number {
|
||||
return Target.newFromShip(this).getDistanceTo(Target.newFromShip(other));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the ship in place to face a direction
|
||||
*/
|
||||
|
|
|
@ -2,17 +2,31 @@ module TS.SpaceTac {
|
|||
// Find the nearest intersection between a line and a circle
|
||||
// Circle is supposed to be centered at (0,0)
|
||||
// Nearest intersection to (x1,y1) is returned
|
||||
function intersectLineCircle(x1: number, y1: number, x2: number, y2: number, r: number): [number, number] {
|
||||
// See http://mathworld.wolfram.com/Circle-LineIntersection.html
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
var dr = Math.sqrt(dx * dx + dy * dy);
|
||||
var d = x1 * y2 - x2 * y1;
|
||||
var delta = r * r * dr * dr - d * d;
|
||||
function intersectLineCircle(x1: number, y1: number, x2: number, y2: number, r: number): [number, number] | null {
|
||||
let a = y2 - y1;
|
||||
let b = -(x2 - x1);
|
||||
let c = -(a * x1 + b * y1);
|
||||
let x0 = -a * c / (a * a + b * b), y0 = -b * c / (a * a + b * b);
|
||||
let EPS = 10e-8;
|
||||
if (c * c > r * r * (a * a + b * b) + EPS) {
|
||||
return null;
|
||||
} else if (Math.abs(c * c - r * r * (a * a + b * b)) < EPS) {
|
||||
return [x0, y0];
|
||||
} else {
|
||||
let d = r * r - c * c / (a * a + b * b);
|
||||
let mult = Math.sqrt(d / (a * a + b * b));
|
||||
let ax, ay, bx, by;
|
||||
ax = x0 + b * mult;
|
||||
bx = x0 - b * mult;
|
||||
ay = y0 - a * mult;
|
||||
by = y0 + a * mult;
|
||||
|
||||
var rx = (d * dy - dx * Math.sqrt(delta)) / (dr * dr);
|
||||
var ry = (-d * dx - dy * Math.sqrt(delta)) / (dr * dr);
|
||||
return [rx, ry];
|
||||
let candidates: [number, number][] = [
|
||||
[x0 + b * mult, y0 - a * mult],
|
||||
[x0 - b * mult, y0 + a * mult]
|
||||
]
|
||||
return minBy(candidates, ([x, y]) => Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)));
|
||||
}
|
||||
}
|
||||
|
||||
// Target for a capability
|
||||
|
@ -99,9 +113,12 @@ module TS.SpaceTac {
|
|||
return this;
|
||||
} else {
|
||||
// Find nearest intersection with circle
|
||||
var res = intersectLineCircle(sourcex - circlex, sourcey - circley,
|
||||
this.x - circlex, this.y - circley, radius);
|
||||
return Target.newFromLocation(res[0] + circlex, res[1] + circley);
|
||||
var res = intersectLineCircle(sourcex - circlex, sourcey - circley, dx, dy, radius);
|
||||
if (res) {
|
||||
return Target.newFromLocation(res[0] + circlex, res[1] + circley);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,5 +103,22 @@ module TS.SpaceTac {
|
|||
result = action.checkLocationTarget(ship, Target.newFromLocation(12, 5));
|
||||
expect(result).toEqual(Target.newFromLocation(12, 5));
|
||||
});
|
||||
|
||||
it("move exclusion radius is applied correctly over two ships", function () {
|
||||
var battle = TestTools.createBattle(1, 2);
|
||||
var ship = battle.fleets[0].ships[0];
|
||||
var enemy1 = battle.fleets[1].ships[0];
|
||||
var enemy2 = battle.fleets[1].ships[1];
|
||||
TestTools.setShipAP(ship, 100);
|
||||
enemy1.setArenaPosition(0, 80);
|
||||
enemy2.setArenaPosition(0, 100);
|
||||
|
||||
var action = new MoveAction(new Equipment());
|
||||
action.distance_per_power = 1000;
|
||||
action.safety_distance = 15;
|
||||
|
||||
var result = action.checkLocationTarget(ship, Target.newFromLocation(0, 110));
|
||||
expect(result).toEqual(Target.newFromLocation(0, 65));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,19 +2,19 @@ module TS.SpaceTac {
|
|||
// Action to move to a given location
|
||||
export class MoveAction extends BaseAction {
|
||||
// Distance allowed for each power point
|
||||
distance_per_power: number;
|
||||
distance_per_power: number
|
||||
|
||||
// Safety distance from other ships
|
||||
safety_distance: number;
|
||||
// Safety distance from other ships and arena borders
|
||||
safety_distance: number
|
||||
|
||||
// Equipment cannot be null (engine)
|
||||
equipment: Equipment;
|
||||
equipment: Equipment
|
||||
|
||||
constructor(equipment: Equipment, distance_per_power = 0) {
|
||||
super("move", "Move", true, equipment);
|
||||
|
||||
this.distance_per_power = distance_per_power;
|
||||
this.safety_distance = 50;
|
||||
this.safety_distance = 120;
|
||||
}
|
||||
|
||||
checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): string | null {
|
||||
|
@ -62,11 +62,10 @@ module TS.SpaceTac {
|
|||
// Apply collision prevention
|
||||
let battle = ship.getBattle();
|
||||
if (battle) {
|
||||
battle.play_order.forEach((iship: Ship) => {
|
||||
if (iship !== ship) {
|
||||
target = target.moveOutOfCircle(iship.arena_x, iship.arena_y, this.safety_distance,
|
||||
ship.arena_x, ship.arena_y);
|
||||
}
|
||||
let ships = imaterialize(ifilter(battle.iships(true), s => s !== ship));
|
||||
ships = ships.sort((a, b) => cmp(a.getDistanceTo(ship), b.getDistanceTo(ship), true));
|
||||
ships.forEach(s => {
|
||||
target = target.moveOutOfCircle(s.arena_x, s.arena_y, this.safety_distance, ship.arena_x, ship.arena_y);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,26 +5,26 @@ module TS.SpaceTac.Equipments {
|
|||
|
||||
let equipment = template.generate(1);
|
||||
expect(equipment.requirements).toEqual({ "skill_human": 1 });
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 300, 10, 100, [new ValueEffect("hull", 5)]));
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 300, 10, 150, [new ValueEffect("hull", 5)]));
|
||||
|
||||
equipment = template.generate(2);
|
||||
expect(equipment.requirements).toEqual({ "skill_human": 2 });
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 310, 11, 110, [new ValueEffect("hull", 6)]));
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 310, 11, 155, [new ValueEffect("hull", 6)]));
|
||||
|
||||
equipment = template.generate(3);
|
||||
expect(equipment.requirements).toEqual({ "skill_human": 3 });
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 320, 12, 120, [new ValueEffect("hull", 7)]));
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 320, 12, 160, [new ValueEffect("hull", 7)]));
|
||||
|
||||
equipment = template.generate(10);
|
||||
expect(equipment.requirements).toEqual({ "skill_human": 10 });
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 390, 19, 190, [new ValueEffect("hull", 14)]));
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 390, 19, 195, [new ValueEffect("hull", 14)]));
|
||||
});
|
||||
|
||||
it("generates a drone that may repair ships hull", function () {
|
||||
let template = new RepairDrone();
|
||||
|
||||
let equipment = template.generate(1);
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 300, 10, 100, [new ValueEffect("hull", 5)]));
|
||||
expect(equipment.action).toEqual(new DeployDroneAction(equipment, 4, 300, 10, 150, [new ValueEffect("hull", 5)]));
|
||||
|
||||
let battle = new Battle();
|
||||
let ship = battle.fleets[0].addShip();
|
||||
|
|
|
@ -10,7 +10,7 @@ module TS.SpaceTac.Equipments {
|
|||
|
||||
this.setSkillsRequirements({ "skill_human": 1 });
|
||||
this.setCooldown(irepeat(1), istep(3, irepeat(0.2)));
|
||||
this.addDroneAction(irepeat(4), istep(300, irepeat(10)), istep(10, irepeat(1)), istep(100, irepeat(10)), [
|
||||
this.addDroneAction(irepeat(4), istep(300, irepeat(10)), istep(10, irepeat(1)), istep(150, irepeat(5)), [
|
||||
new EffectTemplate(new ValueEffect("hull"), { "value": istep(5) })
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -6,22 +6,22 @@ module TS.SpaceTac.Equipments {
|
|||
let equipment = template.generate(1);
|
||||
expect(equipment.requirements).toEqual({ "skill_gravity": 1 });
|
||||
expect(equipment.cooldown).toEqual(new Cooldown(3, 3));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 100, 0, [new ValueTransferEffect("shield", -20)]));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 150, 0, [new ValueTransferEffect("shield", -20)]));
|
||||
|
||||
equipment = template.generate(2);
|
||||
expect(equipment.requirements).toEqual({ "skill_gravity": 2 });
|
||||
expect(equipment.cooldown).toEqual(new Cooldown(3, 3));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 110, 0, [new ValueTransferEffect("shield", -22)]));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 160, 0, [new ValueTransferEffect("shield", -22)]));
|
||||
|
||||
equipment = template.generate(3);
|
||||
expect(equipment.requirements).toEqual({ "skill_gravity": 3 });
|
||||
expect(equipment.cooldown).toEqual(new Cooldown(3, 3));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 120, 0, [new ValueTransferEffect("shield", -24)]));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 170, 0, [new ValueTransferEffect("shield", -24)]));
|
||||
|
||||
equipment = template.generate(10);
|
||||
expect(equipment.requirements).toEqual({ "skill_gravity": 10 });
|
||||
expect(equipment.cooldown).toEqual(new Cooldown(3, 3));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 190, 0, [new ValueTransferEffect("shield", -38)]));
|
||||
expect(equipment.action).toEqual(new FireWeaponAction(equipment, 3, 240, 0, [new ValueTransferEffect("shield", -38)]));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ module TS.SpaceTac.Equipments {
|
|||
|
||||
this.setSkillsRequirements({ "skill_gravity": 1 });
|
||||
this.setCooldown(irepeat(3), irepeat(3));
|
||||
this.addFireAction(irepeat(3), istep(100, irepeat(10)), 0, [
|
||||
this.addFireAction(irepeat(3), istep(150, irepeat(10)), 0, [
|
||||
new EffectTemplate(new ValueTransferEffect("shield"), { "amount": istep(-20, irepeat(-2)) })
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue