mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-04 11:00:01 +08:00
fixed # 更新刘备配置和奖励
This commit is contained in:
@@ -18,6 +18,7 @@ EXCLUDE_DIRS = {
|
||||
"__pycache__",
|
||||
}
|
||||
EXCLUDE_FILES = {".gitignore", "log.txt"}
|
||||
EXCLUDE_EXTENSIONS = {".md", ".mjs"}
|
||||
|
||||
|
||||
def sha256_file(path: Path) -> str:
|
||||
@@ -33,6 +34,7 @@ def should_include(path: Path, root: Path) -> bool:
|
||||
return (
|
||||
path.is_file()
|
||||
and relative.name not in EXCLUDE_FILES
|
||||
and path.suffix.lower() not in EXCLUDE_EXTENSIONS
|
||||
and not any(part in EXCLUDE_DIRS for part in relative.parts)
|
||||
)
|
||||
|
||||
|
||||
+95
-1
@@ -1,7 +1,10 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { grantRelic, canAcquireRelic, getRelic, heldRelics,
|
||||
relicRewardIds } from "../mengsan/relics/definitions.js";
|
||||
relicRewardIds, initializeRelicMaxHp } from "../mengsan/relics/definitions.js";
|
||||
import { applyRoomRelics, restRecovery } from "../mengsan/relics/rooms.js";
|
||||
import { createOpeningEffects, createRelicCombatSkills }
|
||||
from "../mengsan/relics/combat.js";
|
||||
import { createRelicBattle, createRelicSkills,
|
||||
applyBattleEndRelics } from "../mengsan/relics/battle.js";
|
||||
import { canAcquireReward, getRandomRewardChoices }
|
||||
@@ -32,6 +35,97 @@ const runtime = run => {
|
||||
return { battle, draws, logs, stop: () => { running = false; } };
|
||||
};
|
||||
|
||||
test("strawberry raises max HP once without healing, including early grants", () => {
|
||||
const run = newRun();
|
||||
grant(run, "strawberry", "strawberry");
|
||||
assert.equal(run.player.maxHp, 57);
|
||||
assert.equal(run.player.hp, 20);
|
||||
run.player.maxHp = null;
|
||||
run.player.items = [];
|
||||
grant(run, "strawberry");
|
||||
run.player.maxHp = 50;
|
||||
initializeRelicMaxHp(run);
|
||||
initializeRelicMaxHp(run);
|
||||
assert.equal(run.player.maxHp, 57);
|
||||
});
|
||||
|
||||
test("shop entrance and rest healing cap HP and survive reload without repeats", () => {
|
||||
const run = newRun();
|
||||
grant(run, "meal_ticket", "regal_pillow");
|
||||
const shop = { id: "shop1", type: "shop" };
|
||||
assert.equal(applyRoomRelics(run, shop, "enter").recovered, 15);
|
||||
const restored = structuredClone(run);
|
||||
assert.equal(applyRoomRelics(restored, shop, "enter"), null);
|
||||
const rest = { id: "rest1", type: "rest" };
|
||||
assert.equal(restRecovery(run), 23);
|
||||
assert.equal(applyRoomRelics(run, rest, "upgrade"), null);
|
||||
assert.equal(applyRoomRelics(run, rest, "heal").recovered, 15);
|
||||
assert.equal(run.player.hp, 50);
|
||||
assert.equal(applyRoomRelics(run, rest, "heal"), null);
|
||||
assert.equal(restRecovery(newRun()), 8);
|
||||
});
|
||||
|
||||
test("opening effects target enemies, apply buffs before damage, and lantern is temporary", async () => {
|
||||
const run = newRun();
|
||||
grant(run, "festive_poppers", "bag_of_marbles", "red_mask", "vajra", "lantern");
|
||||
const hits = [];
|
||||
const actor = camp => ({ storage: { mengsanCamp_shuying: camp },
|
||||
isAlive: () => true, addSkill() {}, markSkill() {},
|
||||
damage(amount, source, nature) {
|
||||
hits.push({ amount, source, nature,
|
||||
vulnerable: this.storage.mengsanVulnerable_shuying,
|
||||
weak: this.storage.mengsanWeak_shuying });
|
||||
return Promise.resolve();
|
||||
} });
|
||||
const owner = actor("player"), enemy = actor("enemy"), ally = actor("ally");
|
||||
owner.storage.mengsanEnergy_shuying = 3;
|
||||
owner.storage.mengsanMaxEnergy_shuying = 3;
|
||||
let refreshes = 0;
|
||||
const battle = createRelicBattle(run, { active: () => true,
|
||||
draw: async () => {}, log: () => {},
|
||||
effect: createOpeningEffects({ players: [owner, enemy, ally] },
|
||||
owner, () => { refreshes++; }) });
|
||||
await battle.start();
|
||||
await battle.start();
|
||||
assert.equal(hits.length, 1);
|
||||
assert.equal(hits[0].amount, 9);
|
||||
assert.equal(hits[0].vulnerable, 1);
|
||||
assert.equal(hits[0].weak, 1);
|
||||
assert.equal(hits[0].nature, "nocard");
|
||||
assert.equal(owner.storage.mengsanStrength_shuying, 1);
|
||||
assert.equal(ally.storage.mengsanWeak_shuying, undefined);
|
||||
const first = {};
|
||||
await battle.turnStart(first);
|
||||
await battle.turnStart(first);
|
||||
assert.equal(owner.storage.mengsanEnergy_shuying, 4);
|
||||
assert.equal(owner.storage.mengsanMaxEnergy_shuying, 3);
|
||||
owner.storage.mengsanEnergy_shuying = owner.storage.mengsanMaxEnergy_shuying;
|
||||
await battle.turnStart({});
|
||||
assert.equal(owner.storage.mengsanEnergy_shuying, 3);
|
||||
assert.equal(refreshes, 1);
|
||||
});
|
||||
|
||||
test("card attacks add owner strength before weakness and skip scripted damage", async () => {
|
||||
const owner = { storage: { mengsanStrength_shuying: 1,
|
||||
mengsanWeak_shuying: 1 } };
|
||||
const skills = createRelicCombatSkills(() => ({ session: { active: true } }),
|
||||
() => owner);
|
||||
const attack = skills.mengsan_relic_attack_shuying;
|
||||
const event = { source: owner, card: {}, num: 6 };
|
||||
assert.equal(attack.filter(event), true);
|
||||
await attack.content({}, event);
|
||||
assert.equal(event.num, 5);
|
||||
assert.equal(attack.filter({ ...event, card: null }), false);
|
||||
assert.equal(attack.filter({ ...event, mengsanScriptedSkill_shuying: true }), false);
|
||||
const enemy = { storage: { mengsanWeak_shuying: 1 },
|
||||
removeSkill(skill) { assert.equal(skill, "mengsan_weak_shuying"); } };
|
||||
const hit = { source: enemy, card: {}, num: 9 };
|
||||
await attack.content({}, hit);
|
||||
assert.equal(hit.num, 6);
|
||||
await skills.mengsan_weak_shuying.content({}, {}, enemy);
|
||||
assert.equal(enemy.storage.mengsanWeak_shuying, 0);
|
||||
});
|
||||
|
||||
test("relics use existing items, reject duplicates and preserve belt saves", () => {
|
||||
const run = newRun();
|
||||
assert.equal(grantRelic(run, id("burning_blood")), true);
|
||||
|
||||
Reference in New Issue
Block a user