Add more stats, crit/block/accuracy/dodge/lifesteal
This commit is contained in:
@@ -4,7 +4,8 @@ import {
|
||||
type Vec2,
|
||||
type Action,
|
||||
type RunState,
|
||||
type World
|
||||
type World,
|
||||
type CombatantActor
|
||||
} from "../core/types";
|
||||
import { TILE_SIZE } from "../core/constants";
|
||||
import { inBounds, isBlocked, isPlayerOnExit } from "../engine/world/world-logic";
|
||||
@@ -148,9 +149,11 @@ export class GameScene extends Phaser.Scene {
|
||||
if (!this.dungeonRenderer.isSeen(tx, ty)) return;
|
||||
|
||||
// Check if clicking on an enemy
|
||||
const isEnemy = [...this.world.actors.values()].some(a => a.pos.x === tx && a.pos.y === ty && !a.isPlayer);
|
||||
const isEnemy = [...this.world.actors.values()].some(a =>
|
||||
a.category === "combatant" && a.pos.x === tx && a.pos.y === ty && !a.isPlayer
|
||||
);
|
||||
|
||||
const player = this.world.actors.get(this.playerId)!;
|
||||
const player = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
const path = findPathAStar(
|
||||
this.world,
|
||||
this.dungeonRenderer.seenArray,
|
||||
@@ -170,7 +173,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
// Auto-walk one step per turn
|
||||
if (this.playerPath.length >= 2) {
|
||||
const player = this.world.actors.get(this.playerId)!;
|
||||
const player = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
const next = this.playerPath[1];
|
||||
const dx = next.x - player.pos.x;
|
||||
const dy = next.y - player.pos.y;
|
||||
@@ -183,7 +186,7 @@ export class GameScene extends Phaser.Scene {
|
||||
if (isBlocked(this.world, next.x, next.y)) {
|
||||
// Check if it's an enemy at 'next'
|
||||
const targetId = [...this.world.actors.values()].find(
|
||||
a => a.pos.x === next.x && a.pos.y === next.y && !a.isPlayer
|
||||
a => a.category === "combatant" && a.pos.x === next.x && a.pos.y === next.y && !a.isPlayer
|
||||
)?.id;
|
||||
|
||||
if (targetId !== undefined) {
|
||||
@@ -213,13 +216,13 @@ export class GameScene extends Phaser.Scene {
|
||||
else if (Phaser.Input.Keyboard.JustDown(this.cursors.down!)) dy = 1;
|
||||
|
||||
if (dx !== 0 || dy !== 0) {
|
||||
const player = this.world.actors.get(this.playerId)!;
|
||||
const player = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
const targetX = player.pos.x + dx;
|
||||
const targetY = player.pos.y + dy;
|
||||
|
||||
// Check for enemy at target position
|
||||
const targetId = [...this.world.actors.values()].find(
|
||||
a => a.pos.x === targetX && a.pos.y === targetY && !a.isPlayer
|
||||
a => a.category === "combatant" && a.pos.x === targetX && a.pos.y === targetY && !a.isPlayer
|
||||
)?.id;
|
||||
|
||||
if (targetId !== undefined) {
|
||||
@@ -254,11 +257,15 @@ export class GameScene extends Phaser.Scene {
|
||||
const allEvents = [...playerEvents, ...enemyStep.events];
|
||||
for (const ev of allEvents) {
|
||||
if (ev.type === "damaged") {
|
||||
this.dungeonRenderer.showDamage(ev.x, ev.y, ev.amount);
|
||||
this.dungeonRenderer.showDamage(ev.x, ev.y, ev.amount, ev.isCrit, ev.isBlock);
|
||||
} else if (ev.type === "dodged") {
|
||||
this.dungeonRenderer.showDodge(ev.x, ev.y);
|
||||
} else if (ev.type === "healed") {
|
||||
this.dungeonRenderer.showHeal(ev.x, ev.y, ev.amount);
|
||||
} else if (ev.type === "killed") {
|
||||
this.dungeonRenderer.spawnCorpse(ev.x, ev.y, ev.victimType || "rat");
|
||||
} else if (ev.type === "waited" && ev.actorId === this.playerId) {
|
||||
const player = this.world.actors.get(this.playerId);
|
||||
const player = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
if (player) {
|
||||
this.dungeonRenderer.showWait(player.pos.x, player.pos.y);
|
||||
}
|
||||
@@ -328,8 +335,8 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private syncRunStateFromPlayer() {
|
||||
const p = this.world.actors.get(this.playerId);
|
||||
if (!p?.stats || !p.inventory) return;
|
||||
const p = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
if (!p || p.category !== "combatant" || !p.stats || !p.inventory) return;
|
||||
|
||||
this.runState = {
|
||||
stats: { ...p.stats },
|
||||
@@ -348,7 +355,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
|
||||
private centerCameraOnPlayer() {
|
||||
const player = this.world.actors.get(this.playerId)!;
|
||||
const player = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
this.cameras.main.centerOn(
|
||||
player.pos.x * TILE_SIZE + TILE_SIZE / 2,
|
||||
player.pos.y * TILE_SIZE + TILE_SIZE / 2
|
||||
@@ -356,8 +363,8 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private allocateStat(statName: string) {
|
||||
const p = this.world.actors.get(this.playerId);
|
||||
if (!p || !p.stats || p.stats.statPoints <= 0) return;
|
||||
const p = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
if (!p || p.category !== "combatant" || !p.stats || p.stats.statPoints <= 0) return;
|
||||
|
||||
p.stats.statPoints--;
|
||||
if (statName === "strength") {
|
||||
@@ -380,8 +387,8 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private allocatePassive(nodeId: string) {
|
||||
const p = this.world.actors.get(this.playerId);
|
||||
if (!p || !p.stats || p.stats.skillPoints <= 0) return;
|
||||
const p = this.world.actors.get(this.playerId) as CombatantActor;
|
||||
if (!p || p.category !== "combatant" || !p.stats || p.stats.skillPoints <= 0) return;
|
||||
|
||||
if (p.stats.passiveNodes.includes(nodeId)) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user