Apply player damage once per pirate broadside
This commit is contained in:
parent
5ea729a3a8
commit
f5b35fd87f
@ -46,6 +46,8 @@ class GameScene extends Phaser.Scene {
|
|||||||
this.lastPlayerShot = 0;
|
this.lastPlayerShot = 0;
|
||||||
this.lastPlayerHitAt = -Infinity;
|
this.lastPlayerHitAt = -Infinity;
|
||||||
this.pendingPlayerHits = [];
|
this.pendingPlayerHits = [];
|
||||||
|
this.nextPirateVolleyId = 1;
|
||||||
|
this.damagedPlayerVolleys = new Set();
|
||||||
this.lastDiagnosticsAt = -Infinity;
|
this.lastDiagnosticsAt = -Infinity;
|
||||||
this.wave = 1;
|
this.wave = 1;
|
||||||
this.defeated = 0;
|
this.defeated = 0;
|
||||||
@ -459,6 +461,7 @@ class GameScene extends Phaser.Scene {
|
|||||||
fireBroadside(ship, side, group, texture, damage, velocityScale) {
|
fireBroadside(ship, side, group, texture, damage, velocityScale) {
|
||||||
if (!ship?.body) return;
|
if (!ship?.body) return;
|
||||||
const actor = group === this.pirateShots ? 'pirate' : 'player';
|
const actor = group === this.pirateShots ? 'pirate' : 'player';
|
||||||
|
const volleyId = actor === 'pirate' ? this.nextPirateVolleyId++ : null;
|
||||||
const base = headingRad(ship) + side * Math.PI / 2;
|
const base = headingRad(ship) + side * Math.PI / 2;
|
||||||
|
|
||||||
airshipLog('combat:broadside-fired', {
|
airshipLog('combat:broadside-fired', {
|
||||||
@ -468,6 +471,7 @@ class GameScene extends Phaser.Scene {
|
|||||||
x: Math.round(ship.x),
|
x: Math.round(ship.x),
|
||||||
y: Math.round(ship.y),
|
y: Math.round(ship.y),
|
||||||
angle: Math.round(ship.angle),
|
angle: Math.round(ship.angle),
|
||||||
|
volleyId,
|
||||||
}, 'debug');
|
}, 'debug');
|
||||||
const offsets = [-7, 0, 7];
|
const offsets = [-7, 0, 7];
|
||||||
|
|
||||||
@ -480,6 +484,7 @@ class GameScene extends Phaser.Scene {
|
|||||||
shot.body.setAllowGravity(false);
|
shot.body.setAllowGravity(false);
|
||||||
shot.setData('bornAt', this.time.now);
|
shot.setData('bornAt', this.time.now);
|
||||||
shot.setData('damage', damage);
|
shot.setData('damage', damage);
|
||||||
|
if (volleyId !== null) shot.setData('volleyId', volleyId);
|
||||||
shot.setVelocity(
|
shot.setVelocity(
|
||||||
Math.cos(angle) * SHOT_SPEED * velocityScale + ship.body.velocity.x * 0.25,
|
Math.cos(angle) * SHOT_SPEED * velocityScale + ship.body.velocity.x * 0.25,
|
||||||
Math.sin(angle) * SHOT_SPEED * velocityScale + ship.body.velocity.y * 0.25,
|
Math.sin(angle) * SHOT_SPEED * velocityScale + ship.body.velocity.y * 0.25,
|
||||||
@ -536,12 +541,14 @@ class GameScene extends Phaser.Scene {
|
|||||||
this.pendingPlayerHits.push({
|
this.pendingPlayerHits.push({
|
||||||
shot,
|
shot,
|
||||||
damage,
|
damage,
|
||||||
|
volleyId: shot.getData('volleyId'),
|
||||||
x: shot.x,
|
x: shot.x,
|
||||||
y: shot.y,
|
y: shot.y,
|
||||||
});
|
});
|
||||||
|
|
||||||
airshipLog('combat:player-hit-queued', {
|
airshipLog('combat:player-hit-queued', {
|
||||||
damage,
|
damage,
|
||||||
|
volleyId: shot.getData('volleyId'),
|
||||||
pendingHits: this.pendingPlayerHits.length,
|
pendingHits: this.pendingPlayerHits.length,
|
||||||
shotAgeMs: this.time.now - (shot.getData('bornAt') || this.time.now),
|
shotAgeMs: this.time.now - (shot.getData('bornAt') || this.time.now),
|
||||||
hull: this.playerHull,
|
hull: this.playerHull,
|
||||||
@ -564,20 +571,33 @@ class GameScene extends Phaser.Scene {
|
|||||||
gameState: this.gameState,
|
gameState: this.gameState,
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = processQueuedPlayerHits({
|
const acceptedHits = [];
|
||||||
hull: this.playerHull,
|
const ignoredHits = [];
|
||||||
lastHitAt: this.lastPlayerHitAt,
|
|
||||||
now: this.time.now,
|
|
||||||
hits,
|
|
||||||
cooldownMs: PLAYER_HIT_COOLDOWN_MS,
|
|
||||||
maxHull: PLAYER_MAX_HULL,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.playerHull = result.hull;
|
for (const hit of hits) {
|
||||||
this.lastPlayerHitAt = result.lastHitAt;
|
const volleyId = hit.volleyId;
|
||||||
|
if (volleyId != null && this.damagedPlayerVolleys.has(volleyId)) {
|
||||||
|
ignoredHits.push(hit);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.appliedHits > 0) {
|
if (volleyId != null) {
|
||||||
const impact = hits[0];
|
this.damagedPlayerVolleys.add(volleyId);
|
||||||
|
if (this.damagedPlayerVolleys.size > 128) {
|
||||||
|
const oldestVolleyId = this.damagedPlayerVolleys.values().next().value;
|
||||||
|
this.damagedPlayerVolleys.delete(oldestVolleyId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acceptedHits.push(hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalDamage = acceptedHits.reduce((sum, hit) => sum + normalizePlayerDamage(hit.damage, PIRATE_SHOT_DAMAGE), 0);
|
||||||
|
this.playerHull = Math.max(0, this.playerHull - totalDamage);
|
||||||
|
const gameOver = this.playerHull <= 0;
|
||||||
|
|
||||||
|
if (acceptedHits.length > 0) {
|
||||||
|
const impact = acceptedHits[0];
|
||||||
try {
|
try {
|
||||||
this.spawnExplosion(impact.x, impact.y, 0.32);
|
this.spawnExplosion(impact.x, impact.y, 0.32);
|
||||||
this.flashShip(this.player, 0xffcccc);
|
this.flashShip(this.player, 0xffcccc);
|
||||||
@ -585,6 +605,7 @@ class GameScene extends Phaser.Scene {
|
|||||||
x: Math.round(impact.x),
|
x: Math.round(impact.x),
|
||||||
y: Math.round(impact.y),
|
y: Math.round(impact.y),
|
||||||
scale: 0.32,
|
scale: 0.32,
|
||||||
|
volleyId: impact.volleyId ?? null,
|
||||||
}, 'debug');
|
}, 'debug');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
airshipLog('combat:player-hit-fx-error', {
|
airshipLog('combat:player-hit-fx-error', {
|
||||||
@ -595,12 +616,14 @@ class GameScene extends Phaser.Scene {
|
|||||||
|
|
||||||
airshipLog('combat:player-hit-processed', {
|
airshipLog('combat:player-hit-processed', {
|
||||||
queuedHits: hits.length,
|
queuedHits: hits.length,
|
||||||
appliedHits: result.appliedHits,
|
appliedHits: acceptedHits.length,
|
||||||
ignoredHits: result.ignoredHits,
|
ignoredHits: ignoredHits.length,
|
||||||
damage: result.totalDamage,
|
acceptedVolleyIds: acceptedHits.map((hit) => hit.volleyId ?? null),
|
||||||
|
ignoredVolleyIds: ignoredHits.map((hit) => hit.volleyId ?? null),
|
||||||
|
damage: totalDamage,
|
||||||
hullBefore: beforeHull,
|
hullBefore: beforeHull,
|
||||||
hullAfter: this.playerHull,
|
hullAfter: this.playerHull,
|
||||||
gameOver: result.gameOver,
|
gameOver,
|
||||||
now: this.time.now,
|
now: this.time.now,
|
||||||
playerStateBefore,
|
playerStateBefore,
|
||||||
playerStateAfter: {
|
playerStateAfter: {
|
||||||
@ -611,9 +634,9 @@ class GameScene extends Phaser.Scene {
|
|||||||
velocityY: this.player?.body?.velocity?.y ?? null,
|
velocityY: this.player?.body?.velocity?.y ?? null,
|
||||||
gameState: this.gameState,
|
gameState: this.gameState,
|
||||||
},
|
},
|
||||||
}, result.gameOver ? 'warn' : 'info');
|
}, gameOver ? 'warn' : 'info');
|
||||||
|
|
||||||
if (result.gameOver) this.finishGame();
|
if (gameOver) this.finishGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnExplosion(x, y, scale = 1) {
|
spawnExplosion(x, y, scale = 1) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user