Character sprite switching - directionality - added dragon head
This commit is contained in:
BIN
public/assets/sprites/items/ceramic_dragon_head.png
Normal file
BIN
public/assets/sprites/items/ceramic_dragon_head.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 408 KiB |
BIN
public/assets/sprites/priestess/PriestessEast.png
Normal file
BIN
public/assets/sprites/priestess/PriestessEast.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/assets/sprites/priestess/PriestessNorth.png
Normal file
BIN
public/assets/sprites/priestess/PriestessNorth.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
public/assets/sprites/priestess/PriestessSouth.png
Normal file
BIN
public/assets/sprites/priestess/PriestessSouth.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/assets/sprites/priestess/PriestessWest.png
Normal file
BIN
public/assets/sprites/priestess/PriestessWest.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -153,7 +153,7 @@ export const GAME_CONFIG = {
|
|||||||
gameplay: {
|
gameplay: {
|
||||||
energyThreshold: 100,
|
energyThreshold: 100,
|
||||||
actionCost: 100,
|
actionCost: 100,
|
||||||
flamethrower: {
|
ceramicDragonHead: {
|
||||||
range: 4,
|
range: 4,
|
||||||
initialDamage: 7,
|
initialDamage: 7,
|
||||||
burnDamage: 3,
|
burnDamage: 3,
|
||||||
@@ -175,8 +175,14 @@ export const GAME_CONFIG = {
|
|||||||
],
|
],
|
||||||
images: [
|
images: [
|
||||||
{ key: "splash_bg", path: "assets/ui/splash_bg.png" },
|
{ key: "splash_bg", path: "assets/ui/splash_bg.png" },
|
||||||
{ key: "character_outline", path: "assets/ui/character_outline.png" }
|
{ key: "character_outline", path: "assets/ui/character_outline.png" },
|
||||||
|
{ key: "ceramic_dragon_head", path: "assets/sprites/items/ceramic_dragon_head.png" },
|
||||||
|
{ key: "PriestessNorth", path: "assets/sprites/priestess/PriestessNorth.png" },
|
||||||
|
{ key: "PriestessSouth", path: "assets/sprites/priestess/PriestessSouth.png" },
|
||||||
|
{ key: "PriestessEast", path: "assets/sprites/priestess/PriestessEast.png" },
|
||||||
|
{ key: "PriestessWest", path: "assets/sprites/priestess/PriestessWest.png" }
|
||||||
]
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
animations: [
|
animations: [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type {
|
|||||||
RangedWeaponItem,
|
RangedWeaponItem,
|
||||||
ArmourItem,
|
ArmourItem,
|
||||||
AmmoItem,
|
AmmoItem,
|
||||||
FlamethrowerItem
|
CeramicDragonHeadItem
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import { GAME_CONFIG } from "../config/GameConfig";
|
import { GAME_CONFIG } from "../config/GameConfig";
|
||||||
|
|
||||||
@@ -246,15 +246,15 @@ export function createUpgradeScroll(quantity = 1): ConsumableItem {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createFlamethrower(): FlamethrowerItem {
|
export function createCeramicDragonHead(): CeramicDragonHeadItem {
|
||||||
const config = GAME_CONFIG.gameplay.flamethrower;
|
const config = GAME_CONFIG.gameplay.ceramicDragonHead;
|
||||||
return {
|
return {
|
||||||
id: "flamethrower",
|
id: "ceramic_dragon_head",
|
||||||
name: "Flamethrower",
|
name: "Ceramic Dragon Head",
|
||||||
type: "Weapon",
|
type: "Weapon",
|
||||||
weaponType: "flamethrower",
|
weaponType: "ceramic_dragon_head",
|
||||||
textureKey: "weapons",
|
textureKey: "ceramic_dragon_head",
|
||||||
spriteIndex: 5,
|
spriteIndex: 0,
|
||||||
charges: config.maxCharges,
|
charges: config.maxCharges,
|
||||||
maxCharges: config.maxCharges,
|
maxCharges: config.maxCharges,
|
||||||
lastRechargeTurn: 0,
|
lastRechargeTurn: 0,
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ export interface RangedWeaponItem extends BaseItem {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FlamethrowerItem extends BaseItem {
|
export interface CeramicDragonHeadItem extends BaseItem {
|
||||||
type: "Weapon";
|
type: "Weapon";
|
||||||
weaponType: "flamethrower";
|
weaponType: "ceramic_dragon_head";
|
||||||
charges: number;
|
charges: number;
|
||||||
maxCharges: number;
|
maxCharges: number;
|
||||||
lastRechargeTurn: number;
|
lastRechargeTurn: number;
|
||||||
@@ -124,7 +124,7 @@ export interface FlamethrowerItem extends BaseItem {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WeaponItem = MeleeWeaponItem | RangedWeaponItem | FlamethrowerItem;
|
export type WeaponItem = MeleeWeaponItem | RangedWeaponItem | CeramicDragonHeadItem;
|
||||||
|
|
||||||
|
|
||||||
export interface ArmourItem extends BaseItem {
|
export interface ArmourItem extends BaseItem {
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ export const Prefabs = {
|
|||||||
return EntityBuilder.create(world)
|
return EntityBuilder.create(world)
|
||||||
.withPosition(x, y)
|
.withPosition(x, y)
|
||||||
.withName("Player")
|
.withName("Player")
|
||||||
.withSprite("warrior", 0)
|
.withSprite("PriestessSouth", 0)
|
||||||
.asPlayer()
|
.asPlayer()
|
||||||
.withStats(config.initialStats)
|
.withStats(config.initialStats)
|
||||||
.withEnergy(config.speed)
|
.withEnergy(config.speed)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
createArmour,
|
createArmour,
|
||||||
createUpgradeScroll,
|
createUpgradeScroll,
|
||||||
createAmmo,
|
createAmmo,
|
||||||
createFlamethrower
|
createCeramicDragonHead
|
||||||
} from "../../core/config/Items";
|
} from "../../core/config/Items";
|
||||||
import { seededRandom } from "../../core/math";
|
import { seededRandom } from "../../core/math";
|
||||||
import * as ROT from "rot-js";
|
import * as ROT from "rot-js";
|
||||||
@@ -63,7 +63,7 @@ export function generateWorld(floor: number, runState: RunState): { world: World
|
|||||||
createConsumable("throwing_dagger", 3),
|
createConsumable("throwing_dagger", 3),
|
||||||
createRangedWeapon("pistol"),
|
createRangedWeapon("pistol"),
|
||||||
createAmmo("ammo_9mm", 10),
|
createAmmo("ammo_9mm", 10),
|
||||||
createFlamethrower(),
|
createCeramicDragonHead(),
|
||||||
createArmour("leather_armor", "heavy"),
|
createArmour("leather_armor", "heavy"),
|
||||||
createUpgradeScroll(2)
|
createUpgradeScroll(2)
|
||||||
] : [])
|
] : [])
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { TileType } from "../core/terrain";
|
|||||||
import { TILE_SIZE } from "../core/constants";
|
import { TILE_SIZE } from "../core/constants";
|
||||||
import { idx, isWall } from "../engine/world/world-logic";
|
import { idx, isWall } from "../engine/world/world-logic";
|
||||||
import { GAME_CONFIG } from "../core/config/GameConfig";
|
import { GAME_CONFIG } from "../core/config/GameConfig";
|
||||||
import { ALL_TEMPLATES } from "../core/config/Items";
|
|
||||||
import { FovManager } from "./FovManager";
|
import { FovManager } from "./FovManager";
|
||||||
import { MinimapRenderer } from "./MinimapRenderer";
|
import { MinimapRenderer } from "./MinimapRenderer";
|
||||||
import { FxRenderer } from "./FxRenderer";
|
import { FxRenderer } from "./FxRenderer";
|
||||||
@@ -88,9 +88,10 @@ export class DungeonRenderer {
|
|||||||
|
|
||||||
// Ensure player sprite exists
|
// Ensure player sprite exists
|
||||||
if (!this.playerSprite) {
|
if (!this.playerSprite) {
|
||||||
this.playerSprite = this.scene.add.sprite(0, 0, "warrior", 0);
|
this.playerSprite = this.scene.add.sprite(0, 0, "PriestessSouth");
|
||||||
this.playerSprite.setDepth(100);
|
this.playerSprite.setDepth(100);
|
||||||
this.playerSprite.play('warrior-idle');
|
this.playerSprite.setDisplaySize(TILE_SIZE, TILE_SIZE); // Ensure it fits in 1 tile
|
||||||
|
// No animation for simple sprites for now
|
||||||
}
|
}
|
||||||
|
|
||||||
this.minimapRenderer.positionMinimap();
|
this.minimapRenderer.positionMinimap();
|
||||||
@@ -288,6 +289,18 @@ export class DungeonRenderer {
|
|||||||
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
|
||||||
if (this.playerSprite.x !== tx || this.playerSprite.y !== ty) {
|
if (this.playerSprite.x !== tx || this.playerSprite.y !== ty) {
|
||||||
|
// Determine direction
|
||||||
|
const dx = tx - this.playerSprite.x;
|
||||||
|
const dy = ty - this.playerSprite.y;
|
||||||
|
|
||||||
|
if (Math.abs(dy) > Math.abs(dx)) {
|
||||||
|
if (dy < 0) this.playerSprite.setTexture("PriestessNorth");
|
||||||
|
else this.playerSprite.setTexture("PriestessSouth");
|
||||||
|
} else if (Math.abs(dx) > 0) {
|
||||||
|
if (dx > 0) this.playerSprite.setTexture("PriestessEast");
|
||||||
|
else this.playerSprite.setTexture("PriestessWest");
|
||||||
|
}
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: this.playerSprite,
|
targets: this.playerSprite,
|
||||||
x: tx,
|
x: tx,
|
||||||
@@ -465,7 +478,7 @@ export class DungeonRenderer {
|
|||||||
this.fxRenderer.showFloatingText(x, y, message, color);
|
this.fxRenderer.showFloatingText(x, y, message, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
showProjectile(from: Vec2, to: Vec2, itemId: string, onComplete: () => void) {
|
showProjectile(from: Vec2, to: Vec2, texture: string, frame: number, onComplete: () => void) {
|
||||||
// World coords
|
// World coords
|
||||||
const startX = from.x * TILE_SIZE + TILE_SIZE / 2;
|
const startX = from.x * TILE_SIZE + TILE_SIZE / 2;
|
||||||
const startY = from.y * TILE_SIZE + TILE_SIZE / 2;
|
const startY = from.y * TILE_SIZE + TILE_SIZE / 2;
|
||||||
@@ -473,15 +486,22 @@ export class DungeonRenderer {
|
|||||||
const endY = to.y * TILE_SIZE + TILE_SIZE / 2;
|
const endY = to.y * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
|
||||||
// Create sprite
|
// Create sprite
|
||||||
// Look up sprite index from config
|
const isStandalone = frame === undefined || frame === 0;
|
||||||
const itemConfig = ALL_TEMPLATES[itemId as keyof typeof ALL_TEMPLATES];
|
const sprite = isStandalone
|
||||||
const texture = itemConfig?.textureKey ?? "items";
|
? this.scene.add.sprite(startX, startY, texture)
|
||||||
const frame = itemConfig?.spriteIndex ?? 0;
|
: this.scene.add.sprite(startX, startY, texture, frame);
|
||||||
|
|
||||||
|
// Scale for standalone 24x24 image should be 1.0 (or matching world scale)
|
||||||
|
// Other sprites are 16x16.
|
||||||
|
if (isStandalone) {
|
||||||
|
sprite.setDisplaySize(16, 16);
|
||||||
|
} else {
|
||||||
|
sprite.setScale(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
// Use 'items' spritesheet
|
|
||||||
const sprite = this.scene.add.sprite(startX, startY, texture, frame);
|
|
||||||
sprite.setDepth(2000);
|
sprite.setDepth(2000);
|
||||||
|
|
||||||
|
|
||||||
// Rotate?
|
// Rotate?
|
||||||
const angle = Phaser.Math.Angle.Between(startX, startY, endX, endY);
|
const angle = Phaser.Math.Angle.Between(startX, startY, endX, endY);
|
||||||
sprite.setRotation(angle + Math.PI / 4); // Adjust for sprite orientation (diagonal usually)
|
sprite.setRotation(angle + Math.PI / 4); // Adjust for sprite orientation (diagonal usually)
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ export class FxRenderer {
|
|||||||
let fontSize = "16px";
|
let fontSize = "16px";
|
||||||
|
|
||||||
if (isCrit) {
|
if (isCrit) {
|
||||||
textStr += "!";
|
textStr += "!";
|
||||||
color = "#ffff00";
|
color = "#ffff00";
|
||||||
fontSize = "22px";
|
fontSize = "22px";
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = this.scene.add.text(screenX, screenY, textStr, {
|
const text = this.scene.add.text(screenX, screenY, textStr, {
|
||||||
@@ -63,19 +63,19 @@ export class FxRenderer {
|
|||||||
}).setOrigin(0.5, 1).setDepth(200);
|
}).setOrigin(0.5, 1).setDepth(200);
|
||||||
|
|
||||||
if (isBlock) {
|
if (isBlock) {
|
||||||
const blockText = this.scene.add.text(screenX + 10, screenY - 10, "Blocked", {
|
const blockText = this.scene.add.text(screenX + 10, screenY - 10, "Blocked", {
|
||||||
fontSize: "10px",
|
fontSize: "10px",
|
||||||
color: "#888888",
|
color: "#888888",
|
||||||
fontStyle: "bold"
|
fontStyle: "bold"
|
||||||
}).setOrigin(0, 1).setDepth(200);
|
}).setOrigin(0, 1).setDepth(200);
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: blockText,
|
targets: blockText,
|
||||||
y: screenY - 34,
|
y: screenY - 34,
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
duration: 800,
|
duration: 800,
|
||||||
onComplete: () => blockText.destroy()
|
onComplete: () => blockText.destroy()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
@@ -132,7 +132,7 @@ export class FxRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spawnCorpse(x: number, y: number, type: ActorType) {
|
spawnCorpse(x: number, y: number, type: ActorType) {
|
||||||
const textureKey = type === "player" ? "warrior" : type;
|
const textureKey = type === "player" ? "PriestessSouth" : type;
|
||||||
|
|
||||||
const corpse = this.scene.add.sprite(
|
const corpse = this.scene.add.sprite(
|
||||||
x * TILE_SIZE + TILE_SIZE / 2,
|
x * TILE_SIZE + TILE_SIZE / 2,
|
||||||
@@ -141,7 +141,23 @@ export class FxRenderer {
|
|||||||
0
|
0
|
||||||
);
|
);
|
||||||
corpse.setDepth(50);
|
corpse.setDepth(50);
|
||||||
corpse.play(`${textureKey}-die`);
|
// Use display size for Priestess sprites to match 1 tile
|
||||||
|
if (textureKey.startsWith("Priestess")) {
|
||||||
|
corpse.setDisplaySize(TILE_SIZE, TILE_SIZE);
|
||||||
|
} else {
|
||||||
|
corpse.setScale(1.0); // Reset to standard scale for spritesheet assets
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Only play animation if it's not a priestess sprite
|
||||||
|
if (!textureKey.startsWith("Priestess")) {
|
||||||
|
corpse.play(`${textureKey}-die`);
|
||||||
|
} else {
|
||||||
|
// Maybe rotate or fade for visual interest since there's no animation
|
||||||
|
corpse.setAngle(90);
|
||||||
|
}
|
||||||
|
|
||||||
this.corpseSprites.push({ sprite: corpse, x, y });
|
this.corpseSprites.push({ sprite: corpse, x, y });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,21 @@ export class ItemSpriteFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create main item sprite
|
// Create main item sprite
|
||||||
const sprite = scene.add.sprite(0, 0, item.textureKey, item.spriteIndex);
|
// Standalone images don't use frame indices
|
||||||
sprite.setScale(scale);
|
const isStandalone = item.spriteIndex === undefined || item.spriteIndex === 0;
|
||||||
|
const sprite = isStandalone
|
||||||
|
? scene.add.sprite(0, 0, item.textureKey)
|
||||||
|
: scene.add.sprite(0, 0, item.textureKey, item.spriteIndex);
|
||||||
|
|
||||||
|
if (isStandalone) {
|
||||||
|
sprite.setDisplaySize(16 * scale, 16 * scale);
|
||||||
|
} else {
|
||||||
|
sprite.setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
container.add(sprite);
|
container.add(sprite);
|
||||||
|
|
||||||
|
|
||||||
// Add upgrade level badge if item has been upgraded
|
// Add upgrade level badge if item has been upgraded
|
||||||
if (item.upgradeLevel && item.upgradeLevel > 0) {
|
if (item.upgradeLevel && item.upgradeLevel > 0) {
|
||||||
const badge = this.createUpgradeBadge(scene, item.upgradeLevel, scale);
|
const badge = this.createUpgradeBadge(scene, item.upgradeLevel, scale);
|
||||||
@@ -56,9 +67,19 @@ export class ItemSpriteFactory {
|
|||||||
y: number,
|
y: number,
|
||||||
scale: number = 1
|
scale: number = 1
|
||||||
): Phaser.GameObjects.Sprite {
|
): Phaser.GameObjects.Sprite {
|
||||||
const sprite = scene.add.sprite(x, y, item.textureKey, item.spriteIndex);
|
const isStandalone = item.spriteIndex === undefined || item.spriteIndex === 0;
|
||||||
sprite.setScale(scale);
|
const sprite = isStandalone
|
||||||
|
? scene.add.sprite(x, y, item.textureKey)
|
||||||
|
: scene.add.sprite(x, y, item.textureKey, item.spriteIndex);
|
||||||
|
|
||||||
|
if (isStandalone) {
|
||||||
|
sprite.setDisplaySize(16 * scale, 16 * scale);
|
||||||
|
} else {
|
||||||
|
sprite.setScale(scale);
|
||||||
|
}
|
||||||
return sprite;
|
return sprite;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import { generateWorld } from "../engine/world/generator";
|
|||||||
import { DungeonRenderer } from "../rendering/DungeonRenderer";
|
import { DungeonRenderer } from "../rendering/DungeonRenderer";
|
||||||
import { Prefabs } from "../engine/ecs/Prefabs";
|
import { Prefabs } from "../engine/ecs/Prefabs";
|
||||||
import { GAME_CONFIG } from "../core/config/GameConfig";
|
import { GAME_CONFIG } from "../core/config/GameConfig";
|
||||||
|
import { ALL_TEMPLATES } from "../core/config/Items";
|
||||||
|
|
||||||
import { EntityAccessor } from "../engine/EntityAccessor";
|
import { EntityAccessor } from "../engine/EntityAccessor";
|
||||||
import { ProgressionManager } from "../engine/ProgressionManager";
|
import { ProgressionManager } from "../engine/ProgressionManager";
|
||||||
import GameUI from "../ui/GameUI";
|
import GameUI from "../ui/GameUI";
|
||||||
@@ -311,13 +313,13 @@ export class GameScene extends Phaser.Scene {
|
|||||||
player.stats.mana += regenAmount;
|
player.stats.mana += regenAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flamethrower Recharge logic
|
// Ceramic Dragon Head Recharge logic
|
||||||
if (player && player.inventory) {
|
if (player && player.inventory) {
|
||||||
for (const item of player.inventory.items) {
|
for (const item of player.inventory.items) {
|
||||||
if (item.type === "Weapon" && item.weaponType === "flamethrower") {
|
if (item.type === "Weapon" && item.weaponType === "ceramic_dragon_head") {
|
||||||
if (item.charges < item.maxCharges) {
|
if (item.charges < item.maxCharges) {
|
||||||
const turnsSinceLast = this.turnCount - item.lastRechargeTurn;
|
const turnsSinceLast = this.turnCount - item.lastRechargeTurn;
|
||||||
if (turnsSinceLast >= GAME_CONFIG.gameplay.flamethrower.rechargeTurns) {
|
if (turnsSinceLast >= GAME_CONFIG.gameplay.ceramicDragonHead.rechargeTurns) {
|
||||||
item.charges++;
|
item.charges++;
|
||||||
item.lastRechargeTurn = this.turnCount;
|
item.lastRechargeTurn = this.turnCount;
|
||||||
this.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "+Charge", "#ff6600");
|
this.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "+Charge", "#ff6600");
|
||||||
@@ -470,10 +472,16 @@ export class GameScene extends Phaser.Scene {
|
|||||||
const player = this.entityAccessor.getPlayer();
|
const player = this.entityAccessor.getPlayer();
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
|
|
||||||
// Projectile Visuals
|
let projectileTexture = item.textureKey;
|
||||||
let projectileId = item.id;
|
let projectileFrame = item.spriteIndex;
|
||||||
|
|
||||||
if (item.type === "Weapon" && item.weaponType === "ranged") {
|
if (item.type === "Weapon" && item.weaponType === "ranged") {
|
||||||
projectileId = `ammo_${item.stats.ammoType}`; // Show ammo sprite
|
const ammoId = `ammo_${item.stats.ammoType}`;
|
||||||
|
const ammoTemplate = ALL_TEMPLATES[ammoId as keyof typeof ALL_TEMPLATES];
|
||||||
|
if (ammoTemplate) {
|
||||||
|
projectileTexture = ammoTemplate.textureKey;
|
||||||
|
projectileFrame = ammoTemplate.spriteIndex;
|
||||||
|
}
|
||||||
|
|
||||||
// Consume Ammo
|
// Consume Ammo
|
||||||
if (item.currentAmmo > 0) {
|
if (item.currentAmmo > 0) {
|
||||||
@@ -486,14 +494,16 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.dungeonRenderer.showProjectile(
|
this.dungeonRenderer.showProjectile(
|
||||||
player.pos,
|
player.pos,
|
||||||
blockedPos,
|
blockedPos,
|
||||||
projectileId,
|
projectileTexture,
|
||||||
|
projectileFrame ?? 0,
|
||||||
() => {
|
() => {
|
||||||
// Handle Flamethrower specific impact
|
|
||||||
if (item.type === "Weapon" && item.weaponType === "flamethrower") {
|
// Handle Ceramic Dragon Head specific impact
|
||||||
|
if (item.type === "Weapon" && item.weaponType === "ceramic_dragon_head") {
|
||||||
item.charges--;
|
item.charges--;
|
||||||
item.lastRechargeTurn = this.turnCount; // Prevent immediate recharge if turn logic is before/after
|
item.lastRechargeTurn = this.turnCount; // Prevent immediate recharge if turn logic is before/after
|
||||||
|
|
||||||
const config = GAME_CONFIG.gameplay.flamethrower;
|
const config = GAME_CONFIG.gameplay.ceramicDragonHead;
|
||||||
const targetTiles = getConeTiles(player.pos, blockedPos, config.range);
|
const targetTiles = getConeTiles(player.pos, blockedPos, config.range);
|
||||||
|
|
||||||
for (const tile of targetTiles) {
|
for (const tile of targetTiles) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export class GameEventHandler {
|
|||||||
const item = player.inventory.items[itemIdx];
|
const item = player.inventory.items[itemIdx];
|
||||||
|
|
||||||
// Ranged Weapon Logic
|
// Ranged Weapon Logic
|
||||||
if (item.type === "Weapon" && (item.weaponType === "ranged" || item.weaponType === "flamethrower")) {
|
if (item.type === "Weapon" && (item.weaponType === "ranged" || item.weaponType === "ceramic_dragon_head")) {
|
||||||
if (item.weaponType === "ranged") {
|
if (item.weaponType === "ranged") {
|
||||||
// Check Ammo
|
// Check Ammo
|
||||||
if (item.currentAmmo <= 0) {
|
if (item.currentAmmo <= 0) {
|
||||||
@@ -114,7 +114,7 @@ export class GameEventHandler {
|
|||||||
this.scene.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "Reloading...", "#aaaaaa");
|
this.scene.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "Reloading...", "#aaaaaa");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (item.weaponType === "flamethrower") {
|
} else if (item.weaponType === "ceramic_dragon_head") {
|
||||||
// Check Charges
|
// Check Charges
|
||||||
if (item.charges <= 0) {
|
if (item.charges <= 0) {
|
||||||
this.scene.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "No charges!", "#ff6600");
|
this.scene.dungeonRenderer.showFloatingText(player.pos.x, player.pos.y, "No charges!", "#ff6600");
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export class TargetingSystem {
|
|||||||
const start = player.pos;
|
const start = player.pos;
|
||||||
const end = { x: this.cursor.x, y: this.cursor.y };
|
const end = { x: this.cursor.x, y: this.cursor.y };
|
||||||
|
|
||||||
if (item.type === "Weapon" && item.weaponType === "flamethrower") {
|
if (item.type === "Weapon" && item.weaponType === "ceramic_dragon_head") {
|
||||||
if (item.charges <= 0) {
|
if (item.charges <= 0) {
|
||||||
console.log("No charges left!");
|
console.log("No charges left!");
|
||||||
return false;
|
return false;
|
||||||
@@ -206,10 +206,10 @@ export class TargetingSystem {
|
|||||||
finalEndX = bPos.x * TILE_SIZE + TILE_SIZE / 2;
|
finalEndX = bPos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||||
finalEndY = bPos.y * TILE_SIZE + TILE_SIZE / 2;
|
finalEndY = bPos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
|
||||||
// Draw Cone if it's a flamethrower
|
// Draw Cone if it's a ceramic dragon head
|
||||||
const player = this.accessor.getCombatant(this.playerId);
|
const player = this.accessor.getCombatant(this.playerId);
|
||||||
const item = player?.inventory?.items.find(it => it.id === this.targetingItemId);
|
const item = player?.inventory?.items.find(it => it.id === this.targetingItemId);
|
||||||
if (item?.type === "Weapon" && item.weaponType === "flamethrower") {
|
if (item?.type === "Weapon" && item.weaponType === "ceramic_dragon_head") {
|
||||||
const range = item.stats.range;
|
const range = item.stats.range;
|
||||||
const tiles = getConeTiles(playerPos, this.cursor, range);
|
const tiles = getConeTiles(playerPos, this.cursor, range);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export class QuickSlotComponent {
|
|||||||
private container!: Phaser.GameObjects.Container;
|
private container!: Phaser.GameObjects.Container;
|
||||||
private slots: Phaser.GameObjects.Container[] = [];
|
private slots: Phaser.GameObjects.Container[] = [];
|
||||||
private itemMap: (Item | null)[] = new Array(10).fill(null);
|
private itemMap: (Item | null)[] = new Array(10).fill(null);
|
||||||
private assignedIds: string[] = ["health_potion", "pistol", "throwing_dagger", "flamethrower", ...new Array(6).fill("")];
|
private assignedIds: string[] = ["health_potion", "pistol", "throwing_dagger", "ceramic_dragon_head", ...new Array(6).fill("")];
|
||||||
private draggedSlotIndex: number | null = null;
|
private draggedSlotIndex: number | null = null;
|
||||||
private dragIcon: Phaser.GameObjects.Sprite | null = null;
|
private dragIcon: Phaser.GameObjects.Sprite | null = null;
|
||||||
private reloadSliderContainer!: Phaser.GameObjects.Container;
|
private reloadSliderContainer!: Phaser.GameObjects.Container;
|
||||||
@@ -231,11 +231,16 @@ export class QuickSlotComponent {
|
|||||||
|
|
||||||
if (foundItem) {
|
if (foundItem) {
|
||||||
// Use ItemSpriteFactory for glow effect on variants
|
// Use ItemSpriteFactory for glow effect on variants
|
||||||
|
// Standalone images (24x24) need less scaling than 16x16 sprites
|
||||||
|
const isStandalone = foundItem.spriteIndex === undefined || foundItem.spriteIndex === 0;
|
||||||
|
const itemScale = isStandalone ? 1.5 : 2.5;
|
||||||
|
|
||||||
const itemContainer = ItemSpriteFactory.createItemSprite(
|
const itemContainer = ItemSpriteFactory.createItemSprite(
|
||||||
this.scene, foundItem, slotSize / 2, slotSize / 2, 2.5
|
this.scene, foundItem, slotSize / 2, slotSize / 2, itemScale
|
||||||
);
|
);
|
||||||
slot.add(itemContainer);
|
slot.add(itemContainer);
|
||||||
|
|
||||||
|
|
||||||
// Unified Label (Bottom-Right)
|
// Unified Label (Bottom-Right)
|
||||||
let labelText = "";
|
let labelText = "";
|
||||||
if (foundItem.stackable) {
|
if (foundItem.stackable) {
|
||||||
@@ -247,8 +252,8 @@ export class QuickSlotComponent {
|
|||||||
} else if (foundItem.type === "Weapon" && foundItem.weaponType === "ranged" && foundItem.stats) {
|
} else if (foundItem.type === "Weapon" && foundItem.weaponType === "ranged" && foundItem.stats) {
|
||||||
// Show ammo for non-stackable ranged weapons
|
// Show ammo for non-stackable ranged weapons
|
||||||
labelText = `${foundItem.currentAmmo}/${foundItem.stats.magazineSize}`;
|
labelText = `${foundItem.currentAmmo}/${foundItem.stats.magazineSize}`;
|
||||||
} else if (foundItem.type === "Weapon" && foundItem.weaponType === "flamethrower") {
|
} else if (foundItem.type === "Weapon" && foundItem.weaponType === "ceramic_dragon_head") {
|
||||||
// Show charges for flamethrower
|
// Show charges for ceramic dragon head
|
||||||
labelText = `${foundItem.charges}/${foundItem.maxCharges}`;
|
labelText = `${foundItem.charges}/${foundItem.maxCharges}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user