first commit
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* BuffManager.js
|
||||
* Manages pre-game buff purchases and activation.
|
||||
* Buffs are one-time per round: Shield (100g) and Double Fire (150g).
|
||||
*/
|
||||
|
||||
/** Buff type definitions. */
|
||||
const BUFF_TYPE = {
|
||||
SHIELD: 'SHIELD',
|
||||
DOUBLE_FIRE: 'DOUBLE_FIRE',
|
||||
};
|
||||
|
||||
/** Buff cost in gold. */
|
||||
const BUFF_COST = {
|
||||
[BUFF_TYPE.SHIELD]: 100,
|
||||
[BUFF_TYPE.DOUBLE_FIRE]: 150,
|
||||
};
|
||||
|
||||
/** Double fire duration in seconds. */
|
||||
const DOUBLE_FIRE_DURATION = 10;
|
||||
|
||||
class BuffManager {
|
||||
constructor() {
|
||||
/** @type {Set<string>} Active buffs for the current round. */
|
||||
this._activeBuffs = new Set();
|
||||
|
||||
/** @type {number} Remaining double fire time in seconds. */
|
||||
this._doubleFireTimer = 0;
|
||||
|
||||
/** @type {boolean} Whether shield is currently active. */
|
||||
this._shieldActive = false;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Purchase
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Purchase a buff for the upcoming round.
|
||||
* Deducts gold via CurrencyManager.
|
||||
* @param {string} buffType - One of BUFF_TYPE values.
|
||||
* @returns {{ success: boolean, error?: string }}
|
||||
*/
|
||||
purchaseBuff(buffType) {
|
||||
const cost = BUFF_COST[buffType];
|
||||
if (cost === undefined) {
|
||||
return { success: false, error: 'Invalid buff type' };
|
||||
}
|
||||
|
||||
if (this._activeBuffs.has(buffType)) {
|
||||
return { success: false, error: 'Already purchased' };
|
||||
}
|
||||
|
||||
const cm = GameGlobal.currencyManager;
|
||||
if (!cm || !cm.hasGold(cost)) {
|
||||
return { success: false, error: 'Insufficient gold' };
|
||||
}
|
||||
|
||||
const spent = cm.spendGold(cost);
|
||||
if (!spent) {
|
||||
return { success: false, error: 'Insufficient gold' };
|
||||
}
|
||||
|
||||
this._activeBuffs.add(buffType);
|
||||
console.log(`[BuffManager] Purchased buff: ${buffType} for ${cost} gold`);
|
||||
|
||||
// Emit event
|
||||
try {
|
||||
if (GameGlobal.eventBus) {
|
||||
GameGlobal.eventBus.emit('buff:purchased', { type: buffType, cost });
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Activation & Game Logic
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Check if a buff was purchased for this round.
|
||||
* @param {string} buffType
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasBuff(buffType) {
|
||||
return this._activeBuffs.has(buffType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active buffs for this round.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getActiveBuffs() {
|
||||
return Array.from(this._activeBuffs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate buffs at the start of a round.
|
||||
* Should be called when the game scene initializes.
|
||||
* @param {object} playerTank - The player tank instance.
|
||||
*/
|
||||
activateBuffs(playerTank) {
|
||||
if (!playerTank) return;
|
||||
|
||||
// Shield buff: add a shield layer to the player tank
|
||||
if (this._activeBuffs.has(BUFF_TYPE.SHIELD)) {
|
||||
this._shieldActive = true;
|
||||
playerTank._buffShield = true;
|
||||
console.log('[BuffManager] Shield buff activated');
|
||||
}
|
||||
|
||||
// Double fire buff: start the timer
|
||||
if (this._activeBuffs.has(BUFF_TYPE.DOUBLE_FIRE)) {
|
||||
this._doubleFireTimer = DOUBLE_FIRE_DURATION;
|
||||
playerTank._buffDoubleFire = true;
|
||||
console.log('[BuffManager] Double fire buff activated');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update buff timers. Called every frame from GameScene.
|
||||
* @param {number} dt - Delta time in seconds.
|
||||
* @param {object} playerTank - The player tank instance.
|
||||
*/
|
||||
update(dt, playerTank) {
|
||||
if (!playerTank) return;
|
||||
|
||||
// Double fire timer countdown
|
||||
if (this._doubleFireTimer > 0) {
|
||||
this._doubleFireTimer -= dt;
|
||||
if (this._doubleFireTimer <= 0) {
|
||||
this._doubleFireTimer = 0;
|
||||
playerTank._buffDoubleFire = false;
|
||||
console.log('[BuffManager] Double fire buff expired');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the shield buff (called when player takes damage).
|
||||
* @param {object} playerTank - The player tank instance.
|
||||
* @returns {boolean} True if shield was consumed (damage absorbed).
|
||||
*/
|
||||
consumeShield(playerTank) {
|
||||
if (this._shieldActive && playerTank && playerTank._buffShield) {
|
||||
this._shieldActive = false;
|
||||
playerTank._buffShield = false;
|
||||
console.log('[BuffManager] Shield buff consumed');
|
||||
|
||||
// Emit event for visual feedback
|
||||
try {
|
||||
if (GameGlobal.eventBus) {
|
||||
GameGlobal.eventBus.emit('buff:shield:consumed');
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if double fire is currently active.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isDoubleFireActive() {
|
||||
return this._doubleFireTimer > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remaining double fire time in seconds.
|
||||
* @returns {number}
|
||||
*/
|
||||
getDoubleFireRemaining() {
|
||||
return Math.max(0, this._doubleFireTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if shield buff is still active (not yet consumed).
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isShieldActive() {
|
||||
return this._shieldActive;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Round Lifecycle
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Clear all buffs at the end of a round.
|
||||
* Must be called when the game ends (win or lose).
|
||||
*/
|
||||
clearBuffs() {
|
||||
this._activeBuffs.clear();
|
||||
this._doubleFireTimer = 0;
|
||||
this._shieldActive = false;
|
||||
console.log('[BuffManager] All buffs cleared');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get buff cost.
|
||||
* @param {string} buffType
|
||||
* @returns {number}
|
||||
*/
|
||||
getBuffCost(buffType) {
|
||||
return BUFF_COST[buffType] || 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Export constants
|
||||
BuffManager.BUFF_TYPE = BUFF_TYPE;
|
||||
BuffManager.BUFF_COST = BUFF_COST;
|
||||
BuffManager.DOUBLE_FIRE_DURATION = DOUBLE_FIRE_DURATION;
|
||||
|
||||
module.exports = BuffManager;
|
||||
Reference in New Issue
Block a user