feat: 메이플 전사 전직 카드와 연계 기믹 추가
This commit is contained in:
@@ -246,6 +246,9 @@ export function simulateCombat(data, rng, stats) {
|
||||
let cardsDrawnThisCombat = 0;
|
||||
let bonusRewardScreens = 0;
|
||||
let activeKillReward = 0;
|
||||
let comboCount = 0;
|
||||
let holyChargeCount = 0;
|
||||
let damagePowerStrengthUsed = false;
|
||||
let energy = 0;
|
||||
const powers = [];
|
||||
const mob = monsters.map((m) => ({
|
||||
@@ -467,6 +470,9 @@ export function simulateCombat(data, rng, stats) {
|
||||
base += countOwnedNameMatches(c.damageNameMatch) * c.damagePerOwnedNameMatch;
|
||||
}
|
||||
if (c.damageFromCurrentBlock) base += pBlock * c.damageFromCurrentBlock;
|
||||
const comboScale = (c.damagePerCombo || 0) + powerFieldTotal('attackDamagePerCombo');
|
||||
if (comboScale) base += comboCount * comboScale;
|
||||
if (c.damagePerHolyCharge) base += holyChargeCount * c.damagePerHolyCharge;
|
||||
const otherHand = Math.max(0, hand.length - 1);
|
||||
if (c.damagePerOtherHandCard) base += otherHand * c.damagePerOtherHandCard;
|
||||
if (c.damagePerAttackPlayedThisTurn) base += turnAttackCardsPlayed * c.damagePerAttackPlayedThisTurn;
|
||||
@@ -518,6 +524,23 @@ export function simulateCombat(data, rng, stats) {
|
||||
}
|
||||
return total;
|
||||
}
|
||||
function powerFieldMax(field) {
|
||||
let best = 0;
|
||||
for (const pid of powers) best = Math.max(best, cards[pid]?.[field] || 0);
|
||||
return best;
|
||||
}
|
||||
function comboMax() {
|
||||
return Math.max(5, powerFieldMax('comboMax'));
|
||||
}
|
||||
function gainCombo(amount) {
|
||||
if (amount > 0) comboCount = Math.min(comboMax(), comboCount + amount);
|
||||
}
|
||||
function holyChargeMax() {
|
||||
return Math.max(3, powerFieldMax('holyChargeMax'));
|
||||
}
|
||||
function gainHolyCharge(amount) {
|
||||
if (amount > 0) holyChargeCount = Math.min(holyChargeMax(), holyChargeCount + amount);
|
||||
}
|
||||
function triggerExhaust(count = 1) {
|
||||
const drawOnExhaust = powerFieldTotal('drawOnExhaust');
|
||||
if (drawOnExhaust > 0 && count > 0) draw(drawOnExhaust * count);
|
||||
@@ -607,8 +630,9 @@ export function simulateCombat(data, rng, stats) {
|
||||
if (!target || !target.alive) return { killed: false, dealt: 0 };
|
||||
let dealt = amount;
|
||||
if (target.vuln > 0) dealt = Math.floor(dealt * 1.5);
|
||||
if (target.weak > 0 && c.attackDamageVsWeakMultiplier && c.attackDamageVsWeakMultiplier > 1) {
|
||||
dealt = Math.floor(dealt * c.attackDamageVsWeakMultiplier);
|
||||
const weakMultiplier = Math.max(c.attackDamageVsWeakMultiplier || 1, powerFieldMax('attackDamageVsWeakMultiplier'));
|
||||
if (target.weak > 0 && weakMultiplier > 1) {
|
||||
dealt = Math.floor(dealt * weakMultiplier);
|
||||
}
|
||||
if (c.pierce === true) {
|
||||
target.hp -= dealt;
|
||||
@@ -669,11 +693,11 @@ export function simulateCombat(data, rng, stats) {
|
||||
roundKilled = resolveAttackRound();
|
||||
} while (c.repeatOnKill === true && roundKilled === true && countAliveMonsters() > 0);
|
||||
}
|
||||
if (c.block) blockGained = addBlock(c.block);
|
||||
if (c.block) blockGained = addBlock(c.block + holyChargeCount * (c.blockPerHolyCharge || 0));
|
||||
} else if (c.kind === 'Power') {
|
||||
powers.push(id);
|
||||
} else {
|
||||
if (c.block) blockGained = addBlock(c.block);
|
||||
if (c.block) blockGained = addBlock(c.block + holyChargeCount * (c.blockPerHolyCharge || 0));
|
||||
const weakAmount = (c.weak || 0) + (c.xWeakPerEnergy || 0) * xEnergy;
|
||||
const vulnAmount = c.vuln || 0;
|
||||
if ((weakAmount || vulnAmount || c.poison || c.removeEnemyBlock || c.removeEnemyArtifact || c.enemyStrengthLossThisTurn) && alive.length) {
|
||||
@@ -705,8 +729,10 @@ export function simulateCombat(data, rng, stats) {
|
||||
if (c.dex) pDex += c.dex;
|
||||
if (c.thorns) pThorns += c.thorns;
|
||||
if (c.selfVuln) pVuln += c.selfVuln;
|
||||
if (c.heal) pHp = Math.min(pHp + c.heal, playerMaxHp);
|
||||
if (c.heal) pHp = Math.min(pHp + c.heal + holyChargeCount * (c.healPerHolyCharge || 0), playerMaxHp);
|
||||
if (c.gainEnergy) energy += c.gainEnergy;
|
||||
if (c.kind !== 'Attack' && c.comboGain) gainCombo(c.comboGain);
|
||||
if (c.removePlayerDebuffs === true) { pWeak = 0; pVuln = 0; }
|
||||
activeKillReward = c.rewardOnKill || 0;
|
||||
if (c.intangible) pIntangible += c.intangible;
|
||||
queueNextTurnEffects(c);
|
||||
@@ -766,6 +792,28 @@ export function simulateCombat(data, rng, stats) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.kind === 'Attack') {
|
||||
gainCombo((c.comboGain || 0) + powerFieldTotal('comboOnAttack'));
|
||||
const extraDamage = powerFieldTotal('attackPlayedDamage');
|
||||
if (extraDamage > 0) {
|
||||
const target = chooseTarget(aliveList(), extraDamage);
|
||||
if (target) {
|
||||
const r = applyDamage(target.hp, target.block, extraDamage);
|
||||
target.hp = r.hp; target.block = r.block;
|
||||
damageDealtThisTurn += extraDamage;
|
||||
if (target.hp <= 0) target.alive = false;
|
||||
}
|
||||
}
|
||||
const attackWeak = powerFieldTotal('attackWeak');
|
||||
if (attackWeak > 0) {
|
||||
const target = chooseTarget(aliveList(), 0);
|
||||
if (target) applyMonsterWeak(target, attackWeak);
|
||||
}
|
||||
}
|
||||
let holyGain = c.holyChargeGain || 0;
|
||||
if (c.holyForce === true) holyGain += powerFieldTotal('holyChargeOnHolyForce');
|
||||
gainHolyCharge(holyGain);
|
||||
if (c.holyChargeSpendAll === true) holyChargeCount = 0;
|
||||
if (c.blockPerDamageDealtThisTurn && c.blockPerDamageDealtThisTurn > 0 && c.kind !== 'Power') {
|
||||
blockGained += addBlock(Math.max(0, damageDealtThisTurn * c.blockPerDamageDealtThisTurn));
|
||||
}
|
||||
@@ -878,6 +926,8 @@ export function simulateCombat(data, rng, stats) {
|
||||
m.hp = r.hp; m.block = r.block;
|
||||
if (m.hp <= 0) m.alive = false;
|
||||
}
|
||||
} else if (pc.powerEffect === 'healPerTurn') {
|
||||
pHp = Math.min(playerMaxHp, pHp + (pc.value || 0));
|
||||
}
|
||||
if (pc.turnStartShiv) addCardsToHand('Shiv', pc.turnStartShiv);
|
||||
if (pc.turnStartDraw) powerTurnDraw += pc.turnStartDraw;
|
||||
@@ -991,8 +1041,18 @@ export function simulateCombat(data, rng, stats) {
|
||||
const atk = calcEnemyAttack(it.value, m.str, m.weak, pVuln, enemyStrengthLossThisTurn);
|
||||
const beforeHp = pHp;
|
||||
let incoming = atk;
|
||||
const reduction = Math.min(0.75, powerFieldTotal('damageTakenReduction'));
|
||||
if (reduction > 0) incoming = Math.floor(incoming * (1 - reduction));
|
||||
if (pIntangible > 0 && incoming > 1) incoming = 1;
|
||||
const r = applyDamage(pHp, pBlock, incoming); pHp = r.hp; pBlock = r.block;
|
||||
if (beforeHp > pHp) {
|
||||
const reactiveBlock = powerFieldTotal('blockOnDamaged');
|
||||
if (reactiveBlock > 0) addBlock(reactiveBlock);
|
||||
if (!damagePowerStrengthUsed) {
|
||||
const reactiveStrength = powerFieldTotal('strengthOnDamagedOnce');
|
||||
if (reactiveStrength > 0) { pStr += reactiveStrength; damagePowerStrengthUsed = true; }
|
||||
}
|
||||
}
|
||||
if (beforeHp > pHp && pThorns > 0) {
|
||||
m.hp -= pThorns;
|
||||
if (m.hp <= 0) m.alive = false;
|
||||
|
||||
Reference in New Issue
Block a user