Add signature officer unit sprites
@@ -3,6 +3,10 @@ import { chromium } from 'playwright';
|
||||
|
||||
const targetUrl = process.env.VERIFY_URL ?? 'http://localhost:5173/';
|
||||
|
||||
function unitUsesTexture(state, unitId, textureBase) {
|
||||
return state?.units?.some((unit) => unit.id === unitId && unit.textureBase === textureBase && unit.actionTexture === `${textureBase}-actions`);
|
||||
}
|
||||
|
||||
let serverProcess;
|
||||
let browser;
|
||||
|
||||
@@ -109,7 +113,43 @@ try {
|
||||
'unit-wu-archer',
|
||||
'unit-wu-archer-actions',
|
||||
'unit-nanman-officer',
|
||||
'unit-nanman-officer-actions'
|
||||
'unit-nanman-officer-actions',
|
||||
'unit-zhao-yun',
|
||||
'unit-zhao-yun-actions',
|
||||
'unit-zhuge-liang',
|
||||
'unit-zhuge-liang-actions',
|
||||
'unit-jiang-wei',
|
||||
'unit-jiang-wei-actions',
|
||||
'unit-sima-yi',
|
||||
'unit-sima-yi-actions',
|
||||
'unit-ma-liang',
|
||||
'unit-ma-liang-actions',
|
||||
'unit-yi-ji',
|
||||
'unit-yi-ji-actions',
|
||||
'unit-gong-zhi',
|
||||
'unit-gong-zhi-actions',
|
||||
'unit-huang-zhong',
|
||||
'unit-huang-zhong-actions',
|
||||
'unit-wei-yan',
|
||||
'unit-wei-yan-actions',
|
||||
'unit-pang-tong',
|
||||
'unit-pang-tong-actions',
|
||||
'unit-fa-zheng',
|
||||
'unit-fa-zheng-actions',
|
||||
'unit-wu-yi',
|
||||
'unit-wu-yi-actions',
|
||||
'unit-yan-yan',
|
||||
'unit-yan-yan-actions',
|
||||
'unit-li-yan',
|
||||
'unit-li-yan-actions',
|
||||
'unit-huang-quan',
|
||||
'unit-huang-quan-actions',
|
||||
'unit-ma-chao',
|
||||
'unit-ma-chao-actions',
|
||||
'unit-ma-dai',
|
||||
'unit-ma-dai-actions',
|
||||
'unit-wang-ping',
|
||||
'unit-wang-ping-actions'
|
||||
].every((key) => textures?.exists(key));
|
||||
});
|
||||
if (!actionTexturesLoaded) {
|
||||
@@ -3020,6 +3060,10 @@ try {
|
||||
!twentySixthEnemies.some((unit) => unit.id === 'changsha-officer-wei-yan') ||
|
||||
!twentySixthAllies.some((unit) => unit.id === 'gong-zhi') ||
|
||||
!twentySixthAllies.some((unit) => unit.id === 'yi-ji') ||
|
||||
!unitUsesTexture(twentySixthBattleState, 'changsha-veteran-huang-zhong', 'unit-huang-zhong') ||
|
||||
!unitUsesTexture(twentySixthBattleState, 'changsha-officer-wei-yan', 'unit-wei-yan') ||
|
||||
!unitUsesTexture(twentySixthBattleState, 'gong-zhi', 'unit-gong-zhi') ||
|
||||
!unitUsesTexture(twentySixthBattleState, 'yi-ji', 'unit-yi-ji') ||
|
||||
twentySixthAllies.some((unit) => unit.id === 'huang-zhong') ||
|
||||
twentySixthAllies.some((unit) => unit.id === 'wei-yan')
|
||||
) {
|
||||
@@ -3455,6 +3499,9 @@ try {
|
||||
!twentyNinthAllies.some((unit) => unit.id === 'fa-zheng') ||
|
||||
!twentyNinthAllies.some((unit) => unit.id === 'pang-tong') ||
|
||||
!twentyNinthAllies.some((unit) => unit.id === 'zhuge-liang') ||
|
||||
!unitUsesTexture(twentyNinthBattleState, 'luo-officer-wu-yi', 'unit-wu-yi') ||
|
||||
!unitUsesTexture(twentyNinthBattleState, 'fa-zheng', 'unit-fa-zheng') ||
|
||||
!unitUsesTexture(twentyNinthBattleState, 'pang-tong', 'unit-pang-tong') ||
|
||||
twentyNinthAllies.some((unit) => unit.id === 'wu-yi')
|
||||
) {
|
||||
throw new Error(`Expected twenty-ninth battle to use Luo Castle map, Zhang Ren objective, Wu Yi as enemy officer, selected allied officers, mixed AI, and no Wu Yi before victory: ${JSON.stringify(twentyNinthBattleState)}`);
|
||||
@@ -3747,6 +3794,11 @@ try {
|
||||
!thirtyFirstAllies.some((unit) => unit.id === 'wu-yi') ||
|
||||
!thirtyFirstAllies.some((unit) => unit.id === 'huang-zhong') ||
|
||||
!thirtyFirstAllies.some((unit) => unit.id === 'zhang-fei') ||
|
||||
!unitUsesTexture(thirtyFirstBattleState, 'luo-main-veteran-yan-yan', 'unit-yan-yan') ||
|
||||
!unitUsesTexture(thirtyFirstBattleState, 'pang-tong', 'unit-pang-tong') ||
|
||||
!unitUsesTexture(thirtyFirstBattleState, 'fa-zheng', 'unit-fa-zheng') ||
|
||||
!unitUsesTexture(thirtyFirstBattleState, 'wu-yi', 'unit-wu-yi') ||
|
||||
!unitUsesTexture(thirtyFirstBattleState, 'huang-zhong', 'unit-huang-zhong') ||
|
||||
thirtyFirstAllies.some((unit) => unit.id === 'yan-yan')
|
||||
) {
|
||||
throw new Error(`Expected thirty-first battle to use Luo Castle main map, Zhang Ren objective, Yan Yan enemy officer, selected allied officers, and mixed AI: ${JSON.stringify(thirtyFirstBattleState)}`);
|
||||
@@ -4200,6 +4252,10 @@ try {
|
||||
!thirtyFourthAllies.some((unit) => unit.id === 'zhang-fei') ||
|
||||
!thirtyFourthAllies.some((unit) => unit.id === 'fa-zheng') ||
|
||||
!thirtyFourthAllies.some((unit) => unit.id === 'huang-zhong') ||
|
||||
!unitUsesTexture(thirtyFourthBattleState, 'jiameng-leader-ma-chao', 'unit-ma-chao') ||
|
||||
!unitUsesTexture(thirtyFourthBattleState, 'huang-quan', 'unit-huang-quan') ||
|
||||
!unitUsesTexture(thirtyFourthBattleState, 'fa-zheng', 'unit-fa-zheng') ||
|
||||
!unitUsesTexture(thirtyFourthBattleState, 'huang-zhong', 'unit-huang-zhong') ||
|
||||
thirtyFourthAllies.some((unit) => unit.id === 'ma-chao')
|
||||
) {
|
||||
throw new Error(`Expected thirty-fourth battle to use Jiameng map, Ma Chao objective, Huang Quan first sortie, selected allied officers, and mixed AI: ${JSON.stringify(thirtyFourthBattleState)}`);
|
||||
@@ -4507,6 +4563,11 @@ try {
|
||||
!thirtySixthAllies.some((unit) => unit.id === 'ma-chao') ||
|
||||
!thirtySixthAllies.some((unit) => unit.id === 'ma-dai') ||
|
||||
!thirtySixthAllies.some((unit) => unit.id === 'zhuge-liang') ||
|
||||
!unitUsesTexture(thirtySixthBattleState, 'dingjun-officer-wang-ping', 'unit-wang-ping') ||
|
||||
!unitUsesTexture(thirtySixthBattleState, 'huang-zhong', 'unit-huang-zhong') ||
|
||||
!unitUsesTexture(thirtySixthBattleState, 'fa-zheng', 'unit-fa-zheng') ||
|
||||
!unitUsesTexture(thirtySixthBattleState, 'ma-chao', 'unit-ma-chao') ||
|
||||
!unitUsesTexture(thirtySixthBattleState, 'ma-dai', 'unit-ma-dai') ||
|
||||
thirtySixthAllies.some((unit) => unit.id === 'wang-ping')
|
||||
) {
|
||||
throw new Error(`Expected thirty-sixth battle to use Dingjun map, Xiahou Yuan objective, Huang Zhong first pressure, selected allied officers, and mixed AI: ${JSON.stringify(thirtySixthBattleState)}`);
|
||||
@@ -9320,6 +9381,11 @@ try {
|
||||
!sixtyFifthAllies.some((unit) => unit.id === 'huang-quan') ||
|
||||
!sixtyFifthAllies.some((unit) => unit.id === 'li-yan') ||
|
||||
!sixtyFifthAllies.some((unit) => unit.id === 'wei-yan') ||
|
||||
!unitUsesTexture(sixtyFifthBattleState, 'ma-dai', 'unit-ma-dai') ||
|
||||
!unitUsesTexture(sixtyFifthBattleState, 'wang-ping', 'unit-wang-ping') ||
|
||||
!unitUsesTexture(sixtyFifthBattleState, 'huang-quan', 'unit-huang-quan') ||
|
||||
!unitUsesTexture(sixtyFifthBattleState, 'li-yan', 'unit-li-yan') ||
|
||||
!unitUsesTexture(sixtyFifthBattleState, 'wei-yan', 'unit-wei-yan') ||
|
||||
sixtyFifthAllies.some((unit) => unit.id === 'zhao-yun') ||
|
||||
sixtyFifthAllies.some((unit) => unit.id === 'ma-liang') ||
|
||||
sixtyFifthAllies.some((unit) => unit.id === 'liu-bei')
|
||||
|
||||
BIN
src/assets/images/units/unit-fa-zheng-actions.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/assets/images/units/unit-fa-zheng.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/images/units/unit-gong-zhi-actions.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/images/units/unit-gong-zhi.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
src/assets/images/units/unit-huang-quan-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-huang-quan.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
src/assets/images/units/unit-huang-zhong-actions.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/images/units/unit-huang-zhong.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
src/assets/images/units/unit-jiang-wei-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-jiang-wei.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-li-yan-actions.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/images/units/unit-li-yan.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
src/assets/images/units/unit-ma-chao-actions.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-ma-chao.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
src/assets/images/units/unit-ma-dai-actions.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/images/units/unit-ma-dai.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
src/assets/images/units/unit-ma-liang-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-ma-liang.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
src/assets/images/units/unit-pang-tong-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-pang-tong.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-sima-yi-actions.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/assets/images/units/unit-sima-yi.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-wang-ping-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-wang-ping.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-wei-yan-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-wei-yan.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-wu-yi-actions.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/images/units/unit-wu-yi.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
src/assets/images/units/unit-yan-yan-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-yan-yan.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/units/unit-yi-ji-actions.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
src/assets/images/units/unit-yi-ji.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-zhao-yun-actions.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/images/units/unit-zhao-yun.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
src/assets/images/units/unit-zhuge-liang-actions.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/assets/images/units/unit-zhuge-liang.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
@@ -33,16 +33,16 @@ const unitTexture: Record<string, string> = {
|
||||
'jiang-wei': 'unit-jiang-wei',
|
||||
'northern-second-officer-jiang-wei': 'unit-jiang-wei',
|
||||
'northern-third-officer-jiang-wei': 'unit-jiang-wei',
|
||||
'ma-liang': 'unit-liu-bei',
|
||||
'yi-ji': 'unit-liu-bei',
|
||||
'gong-zhi': 'unit-guan-yu',
|
||||
'huang-zhong': 'unit-rebel-archer',
|
||||
'wei-yan': 'unit-guan-yu',
|
||||
'pang-tong': 'unit-liu-bei',
|
||||
'fa-zheng': 'unit-liu-bei',
|
||||
'wu-yi': 'unit-guan-yu',
|
||||
'yan-yan': 'unit-rebel-archer',
|
||||
'li-yan': 'unit-guan-yu',
|
||||
'ma-liang': 'unit-ma-liang',
|
||||
'yi-ji': 'unit-yi-ji',
|
||||
'gong-zhi': 'unit-gong-zhi',
|
||||
'huang-zhong': 'unit-huang-zhong',
|
||||
'wei-yan': 'unit-wei-yan',
|
||||
'pang-tong': 'unit-pang-tong',
|
||||
'fa-zheng': 'unit-fa-zheng',
|
||||
'wu-yi': 'unit-wu-yi',
|
||||
'yan-yan': 'unit-yan-yan',
|
||||
'li-yan': 'unit-li-yan',
|
||||
'rebel-a': 'unit-rebel',
|
||||
'rebel-b': 'unit-rebel',
|
||||
'rebel-c': 'unit-rebel-archer',
|
||||
@@ -323,8 +323,8 @@ const unitTexture: Record<string, string> = {
|
||||
'changsha-guard-b': 'unit-rebel',
|
||||
'changsha-strategist-a': 'unit-rebel-archer',
|
||||
'changsha-strategist-b': 'unit-rebel-archer',
|
||||
'changsha-veteran-huang-zhong': 'unit-rebel-archer',
|
||||
'changsha-officer-wei-yan': 'unit-guan-yu',
|
||||
'changsha-veteran-huang-zhong': 'unit-huang-zhong',
|
||||
'changsha-officer-wei-yan': 'unit-wei-yan',
|
||||
'changsha-leader-han-xuan': 'unit-rebel-leader',
|
||||
'yizhou-scout-a': 'unit-rebel',
|
||||
'yizhou-scout-b': 'unit-rebel',
|
||||
@@ -383,7 +383,7 @@ const unitTexture: Record<string, string> = {
|
||||
'luo-strategist-b': 'unit-rebel-archer',
|
||||
'luo-ambusher-a': 'unit-rebel',
|
||||
'luo-ambusher-b': 'unit-rebel',
|
||||
'luo-officer-wu-yi': 'unit-guan-yu',
|
||||
'luo-officer-wu-yi': 'unit-wu-yi',
|
||||
'luo-leader-zhang-ren': 'unit-rebel-leader',
|
||||
'luofeng-scout-a': 'unit-rebel',
|
||||
'luofeng-scout-b': 'unit-rebel',
|
||||
@@ -430,7 +430,7 @@ const unitTexture: Record<string, string> = {
|
||||
'luo-main-ambusher-a': 'unit-rebel',
|
||||
'luo-main-ambusher-b': 'unit-rebel',
|
||||
'luo-main-ambusher-c': 'unit-rebel',
|
||||
'luo-main-veteran-yan-yan': 'unit-rebel-archer',
|
||||
'luo-main-veteran-yan-yan': 'unit-yan-yan',
|
||||
'luo-main-officer-a': 'unit-rebel-leader',
|
||||
'luo-main-leader-zhang-ren': 'unit-rebel-leader',
|
||||
'chengdu-scout-a': 'unit-rebel',
|
||||
@@ -458,8 +458,8 @@ const unitTexture: Record<string, string> = {
|
||||
'chengdu-ambusher-b': 'unit-rebel',
|
||||
'chengdu-ambusher-c': 'unit-rebel',
|
||||
'chengdu-officer-fei-guan': 'unit-rebel-leader',
|
||||
'chengdu-leader-li-yan': 'unit-rebel-leader',
|
||||
'huang-quan': 'unit-liu-bei',
|
||||
'chengdu-leader-li-yan': 'unit-li-yan',
|
||||
'huang-quan': 'unit-huang-quan',
|
||||
'chengdu-final-scout-a': 'unit-rebel',
|
||||
'chengdu-final-scout-b': 'unit-rebel',
|
||||
'chengdu-final-scout-c': 'unit-rebel',
|
||||
@@ -485,10 +485,10 @@ const unitTexture: Record<string, string> = {
|
||||
'chengdu-final-ambusher-b': 'unit-rebel',
|
||||
'chengdu-final-ambusher-c': 'unit-rebel',
|
||||
'chengdu-final-officer-a': 'unit-rebel-leader',
|
||||
'chengdu-final-leader-huang-quan': 'unit-rebel-leader',
|
||||
'ma-chao': 'unit-rebel-cavalry',
|
||||
'ma-dai': 'unit-rebel-cavalry',
|
||||
'wang-ping': 'unit-rebel',
|
||||
'chengdu-final-leader-huang-quan': 'unit-huang-quan',
|
||||
'ma-chao': 'unit-ma-chao',
|
||||
'ma-dai': 'unit-ma-dai',
|
||||
'wang-ping': 'unit-wang-ping',
|
||||
'jiameng-scout-a': 'unit-rebel',
|
||||
'jiameng-scout-b': 'unit-rebel',
|
||||
'jiameng-scout-c': 'unit-rebel',
|
||||
@@ -510,7 +510,7 @@ const unitTexture: Record<string, string> = {
|
||||
'jiameng-ambusher-a': 'unit-rebel',
|
||||
'jiameng-ambusher-b': 'unit-rebel',
|
||||
'jiameng-officer-pang-de': 'unit-rebel-leader',
|
||||
'jiameng-leader-ma-chao': 'unit-rebel-cavalry',
|
||||
'jiameng-leader-ma-chao': 'unit-ma-chao',
|
||||
'yangping-scout-a': 'unit-rebel',
|
||||
'yangping-scout-b': 'unit-rebel',
|
||||
'yangping-scout-c': 'unit-rebel',
|
||||
@@ -558,7 +558,7 @@ const unitTexture: Record<string, string> = {
|
||||
'dingjun-ambusher-a': 'unit-rebel',
|
||||
'dingjun-ambusher-b': 'unit-rebel',
|
||||
'dingjun-officer-zhang-he': 'unit-rebel-cavalry',
|
||||
'dingjun-officer-wang-ping': 'unit-rebel',
|
||||
'dingjun-officer-wang-ping': 'unit-wang-ping',
|
||||
'dingjun-leader-xiahou-yuan': 'unit-rebel-leader',
|
||||
'hanzhong-scout-a': 'unit-rebel',
|
||||
'hanzhong-scout-b': 'unit-rebel',
|
||||
@@ -933,7 +933,35 @@ const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||
};
|
||||
|
||||
const coreAllyTextureIds = new Set(['liu-bei', 'guan-yu', 'zhang-fei']);
|
||||
const signatureUnitTextureIds = new Set(['zhao-yun', 'zhuge-liang', 'jiang-wei', 'northern-second-officer-jiang-wei', 'northern-third-officer-jiang-wei']);
|
||||
const signatureUnitTextureIds = new Set([
|
||||
'zhao-yun',
|
||||
'zhuge-liang',
|
||||
'jiang-wei',
|
||||
'northern-second-officer-jiang-wei',
|
||||
'northern-third-officer-jiang-wei',
|
||||
'ma-liang',
|
||||
'yi-ji',
|
||||
'gong-zhi',
|
||||
'huang-zhong',
|
||||
'changsha-veteran-huang-zhong',
|
||||
'wei-yan',
|
||||
'changsha-officer-wei-yan',
|
||||
'pang-tong',
|
||||
'fa-zheng',
|
||||
'wu-yi',
|
||||
'luo-officer-wu-yi',
|
||||
'yan-yan',
|
||||
'luo-main-veteran-yan-yan',
|
||||
'li-yan',
|
||||
'chengdu-leader-li-yan',
|
||||
'huang-quan',
|
||||
'chengdu-final-leader-huang-quan',
|
||||
'ma-chao',
|
||||
'jiameng-leader-ma-chao',
|
||||
'ma-dai',
|
||||
'wang-ping',
|
||||
'dingjun-officer-wang-ping'
|
||||
]);
|
||||
|
||||
const earlyRebelTexturePrefixes = ['rebel-', 'pursuit-'];
|
||||
|
||||
|
||||
@@ -7,10 +7,30 @@ import zhaoYunPortraitUrl from '../../assets/images/portraits/zhao-yun.png';
|
||||
import zhangFeiPortraitUrl from '../../assets/images/portraits/zhang-fei.png';
|
||||
import zhugeLiangPortraitUrl from '../../assets/images/portraits/zhuge-liang.png';
|
||||
import titleBackgroundUrl from '../../assets/images/taoyuan-oath-title.png';
|
||||
import faZhengActionSheetUrl from '../../assets/images/units/unit-fa-zheng-actions.png';
|
||||
import faZhengUnitSheetUrl from '../../assets/images/units/unit-fa-zheng.png';
|
||||
import gongZhiActionSheetUrl from '../../assets/images/units/unit-gong-zhi-actions.png';
|
||||
import gongZhiUnitSheetUrl from '../../assets/images/units/unit-gong-zhi.png';
|
||||
import guanYuActionSheetUrl from '../../assets/images/units/unit-guan-yu-actions.png';
|
||||
import guanYuUnitSheetUrl from '../../assets/images/units/unit-guan-yu.png';
|
||||
import huangQuanActionSheetUrl from '../../assets/images/units/unit-huang-quan-actions.png';
|
||||
import huangQuanUnitSheetUrl from '../../assets/images/units/unit-huang-quan.png';
|
||||
import huangZhongActionSheetUrl from '../../assets/images/units/unit-huang-zhong-actions.png';
|
||||
import huangZhongUnitSheetUrl from '../../assets/images/units/unit-huang-zhong.png';
|
||||
import jiangWeiActionSheetUrl from '../../assets/images/units/unit-jiang-wei-actions.png';
|
||||
import jiangWeiUnitSheetUrl from '../../assets/images/units/unit-jiang-wei.png';
|
||||
import liYanActionSheetUrl from '../../assets/images/units/unit-li-yan-actions.png';
|
||||
import liYanUnitSheetUrl from '../../assets/images/units/unit-li-yan.png';
|
||||
import liuBeiActionSheetUrl from '../../assets/images/units/unit-liu-bei-actions.png';
|
||||
import liuBeiUnitSheetUrl from '../../assets/images/units/unit-liu-bei.png';
|
||||
import maChaoActionSheetUrl from '../../assets/images/units/unit-ma-chao-actions.png';
|
||||
import maChaoUnitSheetUrl from '../../assets/images/units/unit-ma-chao.png';
|
||||
import maDaiActionSheetUrl from '../../assets/images/units/unit-ma-dai-actions.png';
|
||||
import maDaiUnitSheetUrl from '../../assets/images/units/unit-ma-dai.png';
|
||||
import maLiangActionSheetUrl from '../../assets/images/units/unit-ma-liang-actions.png';
|
||||
import maLiangUnitSheetUrl from '../../assets/images/units/unit-ma-liang.png';
|
||||
import pangTongActionSheetUrl from '../../assets/images/units/unit-pang-tong-actions.png';
|
||||
import pangTongUnitSheetUrl from '../../assets/images/units/unit-pang-tong.png';
|
||||
import rebelArcherActionSheetUrl from '../../assets/images/units/unit-rebel-archer-actions.png';
|
||||
import rebelArcherUnitSheetUrl from '../../assets/images/units/unit-rebel-archer.png';
|
||||
import rebelCavalryActionSheetUrl from '../../assets/images/units/unit-rebel-cavalry-actions.png';
|
||||
@@ -19,12 +39,27 @@ import rebelLeaderActionSheetUrl from '../../assets/images/units/unit-rebel-lead
|
||||
import rebelLeaderUnitSheetUrl from '../../assets/images/units/unit-rebel-leader.png';
|
||||
import rebelActionSheetUrl from '../../assets/images/units/unit-rebel-actions.png';
|
||||
import rebelUnitSheetUrl from '../../assets/images/units/unit-rebel.png';
|
||||
import simaYiActionSheetUrl from '../../assets/images/units/unit-sima-yi-actions.png';
|
||||
import simaYiUnitSheetUrl from '../../assets/images/units/unit-sima-yi.png';
|
||||
import wangPingActionSheetUrl from '../../assets/images/units/unit-wang-ping-actions.png';
|
||||
import wangPingUnitSheetUrl from '../../assets/images/units/unit-wang-ping.png';
|
||||
import weiYanActionSheetUrl from '../../assets/images/units/unit-wei-yan-actions.png';
|
||||
import weiYanUnitSheetUrl from '../../assets/images/units/unit-wei-yan.png';
|
||||
import wuYiActionSheetUrl from '../../assets/images/units/unit-wu-yi-actions.png';
|
||||
import wuYiUnitSheetUrl from '../../assets/images/units/unit-wu-yi.png';
|
||||
import yanYanActionSheetUrl from '../../assets/images/units/unit-yan-yan-actions.png';
|
||||
import yanYanUnitSheetUrl from '../../assets/images/units/unit-yan-yan.png';
|
||||
import yiJiActionSheetUrl from '../../assets/images/units/unit-yi-ji-actions.png';
|
||||
import yiJiUnitSheetUrl from '../../assets/images/units/unit-yi-ji.png';
|
||||
import zhangFeiActionSheetUrl from '../../assets/images/units/unit-zhang-fei-actions.png';
|
||||
import zhangFeiUnitSheetUrl from '../../assets/images/units/unit-zhang-fei.png';
|
||||
import zhaoYunActionSheetUrl from '../../assets/images/units/unit-zhao-yun-actions.png';
|
||||
import zhaoYunUnitSheetUrl from '../../assets/images/units/unit-zhao-yun.png';
|
||||
import zhugeLiangActionSheetUrl from '../../assets/images/units/unit-zhuge-liang-actions.png';
|
||||
import zhugeLiangUnitSheetUrl from '../../assets/images/units/unit-zhuge-liang.png';
|
||||
import { storyBackgroundAssets } from '../data/storyAssets';
|
||||
|
||||
type UnitDirection = 'south' | 'east' | 'north' | 'west';
|
||||
type UnitSheetDecoration = 'zhaoYun' | 'zhugeLiang' | 'jiangWei' | 'simaYi';
|
||||
|
||||
type GeneratedUnitSheet = {
|
||||
key: string;
|
||||
@@ -33,7 +68,6 @@ type GeneratedUnitSheet = {
|
||||
sourceActionKey: string;
|
||||
tint: number;
|
||||
alpha: number;
|
||||
decoration?: UnitSheetDecoration;
|
||||
};
|
||||
|
||||
const unitWalkFrameCount = 4;
|
||||
@@ -54,7 +88,25 @@ const sourceUnitSheets = [
|
||||
{ key: 'unit-rebel', url: rebelUnitSheetUrl, actionKey: 'unit-rebel-actions', actionUrl: rebelActionSheetUrl },
|
||||
{ key: 'unit-rebel-archer', url: rebelArcherUnitSheetUrl, actionKey: 'unit-rebel-archer-actions', actionUrl: rebelArcherActionSheetUrl },
|
||||
{ key: 'unit-rebel-cavalry', url: rebelCavalryUnitSheetUrl, actionKey: 'unit-rebel-cavalry-actions', actionUrl: rebelCavalryActionSheetUrl },
|
||||
{ key: 'unit-rebel-leader', url: rebelLeaderUnitSheetUrl, actionKey: 'unit-rebel-leader-actions', actionUrl: rebelLeaderActionSheetUrl }
|
||||
{ key: 'unit-rebel-leader', url: rebelLeaderUnitSheetUrl, actionKey: 'unit-rebel-leader-actions', actionUrl: rebelLeaderActionSheetUrl },
|
||||
{ key: 'unit-zhao-yun', url: zhaoYunUnitSheetUrl, actionKey: 'unit-zhao-yun-actions', actionUrl: zhaoYunActionSheetUrl },
|
||||
{ key: 'unit-zhuge-liang', url: zhugeLiangUnitSheetUrl, actionKey: 'unit-zhuge-liang-actions', actionUrl: zhugeLiangActionSheetUrl },
|
||||
{ key: 'unit-jiang-wei', url: jiangWeiUnitSheetUrl, actionKey: 'unit-jiang-wei-actions', actionUrl: jiangWeiActionSheetUrl },
|
||||
{ key: 'unit-sima-yi', url: simaYiUnitSheetUrl, actionKey: 'unit-sima-yi-actions', actionUrl: simaYiActionSheetUrl },
|
||||
{ key: 'unit-ma-liang', url: maLiangUnitSheetUrl, actionKey: 'unit-ma-liang-actions', actionUrl: maLiangActionSheetUrl },
|
||||
{ key: 'unit-yi-ji', url: yiJiUnitSheetUrl, actionKey: 'unit-yi-ji-actions', actionUrl: yiJiActionSheetUrl },
|
||||
{ key: 'unit-gong-zhi', url: gongZhiUnitSheetUrl, actionKey: 'unit-gong-zhi-actions', actionUrl: gongZhiActionSheetUrl },
|
||||
{ key: 'unit-huang-zhong', url: huangZhongUnitSheetUrl, actionKey: 'unit-huang-zhong-actions', actionUrl: huangZhongActionSheetUrl },
|
||||
{ key: 'unit-wei-yan', url: weiYanUnitSheetUrl, actionKey: 'unit-wei-yan-actions', actionUrl: weiYanActionSheetUrl },
|
||||
{ key: 'unit-pang-tong', url: pangTongUnitSheetUrl, actionKey: 'unit-pang-tong-actions', actionUrl: pangTongActionSheetUrl },
|
||||
{ key: 'unit-fa-zheng', url: faZhengUnitSheetUrl, actionKey: 'unit-fa-zheng-actions', actionUrl: faZhengActionSheetUrl },
|
||||
{ key: 'unit-wu-yi', url: wuYiUnitSheetUrl, actionKey: 'unit-wu-yi-actions', actionUrl: wuYiActionSheetUrl },
|
||||
{ key: 'unit-yan-yan', url: yanYanUnitSheetUrl, actionKey: 'unit-yan-yan-actions', actionUrl: yanYanActionSheetUrl },
|
||||
{ key: 'unit-li-yan', url: liYanUnitSheetUrl, actionKey: 'unit-li-yan-actions', actionUrl: liYanActionSheetUrl },
|
||||
{ key: 'unit-huang-quan', url: huangQuanUnitSheetUrl, actionKey: 'unit-huang-quan-actions', actionUrl: huangQuanActionSheetUrl },
|
||||
{ key: 'unit-ma-chao', url: maChaoUnitSheetUrl, actionKey: 'unit-ma-chao-actions', actionUrl: maChaoActionSheetUrl },
|
||||
{ key: 'unit-ma-dai', url: maDaiUnitSheetUrl, actionKey: 'unit-ma-dai-actions', actionUrl: maDaiActionSheetUrl },
|
||||
{ key: 'unit-wang-ping', url: wangPingUnitSheetUrl, actionKey: 'unit-wang-ping-actions', actionUrl: wangPingActionSheetUrl }
|
||||
];
|
||||
|
||||
const generatedUnitSheets: GeneratedUnitSheet[] = [
|
||||
@@ -64,15 +116,11 @@ const generatedUnitSheets: GeneratedUnitSheet[] = [
|
||||
{ key: 'unit-shu-cavalry', sourceKey: 'unit-rebel-cavalry', actionKey: 'unit-shu-cavalry-actions', sourceActionKey: 'unit-rebel-cavalry-actions', tint: 0x488fc4, alpha: 0.36 },
|
||||
{ key: 'unit-shu-strategist', sourceKey: 'unit-liu-bei', actionKey: 'unit-shu-strategist-actions', sourceActionKey: 'unit-liu-bei-actions', tint: 0x75b7d8, alpha: 0.28 },
|
||||
{ key: 'unit-shu-officer', sourceKey: 'unit-guan-yu', actionKey: 'unit-shu-officer-actions', sourceActionKey: 'unit-guan-yu-actions', tint: 0x3f91c8, alpha: 0.36 },
|
||||
{ key: 'unit-zhao-yun', sourceKey: 'unit-rebel-cavalry', actionKey: 'unit-zhao-yun-actions', sourceActionKey: 'unit-rebel-cavalry-actions', tint: 0xd7edf7, alpha: 0.42, decoration: 'zhaoYun' },
|
||||
{ key: 'unit-zhuge-liang', sourceKey: 'unit-liu-bei', actionKey: 'unit-zhuge-liang-actions', sourceActionKey: 'unit-liu-bei-actions', tint: 0xd8efe3, alpha: 0.34, decoration: 'zhugeLiang' },
|
||||
{ key: 'unit-jiang-wei', sourceKey: 'unit-rebel-cavalry', actionKey: 'unit-jiang-wei-actions', sourceActionKey: 'unit-rebel-cavalry-actions', tint: 0x64bfa8, alpha: 0.38, decoration: 'jiangWei' },
|
||||
{ key: 'unit-wei-infantry', sourceKey: 'unit-rebel', actionKey: 'unit-wei-infantry-actions', sourceActionKey: 'unit-rebel-actions', tint: 0x8b3030, alpha: 0.42 },
|
||||
{ key: 'unit-wei-archer', sourceKey: 'unit-rebel-archer', actionKey: 'unit-wei-archer-actions', sourceActionKey: 'unit-rebel-archer-actions', tint: 0x9d3c3c, alpha: 0.4 },
|
||||
{ key: 'unit-wei-cavalry', sourceKey: 'unit-rebel-cavalry', actionKey: 'unit-wei-cavalry-actions', sourceActionKey: 'unit-rebel-cavalry-actions', tint: 0x7a3540, alpha: 0.44 },
|
||||
{ key: 'unit-wei-strategist', sourceKey: 'unit-rebel-archer', actionKey: 'unit-wei-strategist-actions', sourceActionKey: 'unit-rebel-archer-actions', tint: 0x7f5a8e, alpha: 0.38 },
|
||||
{ key: 'unit-wei-officer', sourceKey: 'unit-rebel-leader', actionKey: 'unit-wei-officer-actions', sourceActionKey: 'unit-rebel-leader-actions', tint: 0x8f3940, alpha: 0.44 },
|
||||
{ key: 'unit-sima-yi', sourceKey: 'unit-rebel-leader', actionKey: 'unit-sima-yi-actions', sourceActionKey: 'unit-rebel-leader-actions', tint: 0x1f2638, alpha: 0.58, decoration: 'simaYi' },
|
||||
{ key: 'unit-wu-infantry', sourceKey: 'unit-rebel', actionKey: 'unit-wu-infantry-actions', sourceActionKey: 'unit-rebel-actions', tint: 0x0b8b86, alpha: 0.42 },
|
||||
{ key: 'unit-wu-archer', sourceKey: 'unit-rebel-archer', actionKey: 'unit-wu-archer-actions', sourceActionKey: 'unit-rebel-archer-actions', tint: 0x169b91, alpha: 0.4 },
|
||||
{ key: 'unit-wu-cavalry', sourceKey: 'unit-rebel-cavalry', actionKey: 'unit-wu-cavalry-actions', sourceActionKey: 'unit-rebel-cavalry-actions', tint: 0x087b86, alpha: 0.44 },
|
||||
@@ -383,12 +431,12 @@ export class BootScene extends Phaser.Scene {
|
||||
|
||||
private createGeneratedUnitSheets() {
|
||||
generatedUnitSheets.forEach((sheet) => {
|
||||
this.createTintedUnitSheet(sheet.key, sheet.sourceKey, sheet.tint, sheet.alpha, sheet.decoration);
|
||||
this.createTintedUnitSheet(sheet.actionKey, sheet.sourceActionKey, sheet.tint, sheet.alpha, sheet.decoration);
|
||||
this.createTintedUnitSheet(sheet.key, sheet.sourceKey, sheet.tint, sheet.alpha);
|
||||
this.createTintedUnitSheet(sheet.actionKey, sheet.sourceActionKey, sheet.tint, sheet.alpha);
|
||||
});
|
||||
}
|
||||
|
||||
private createTintedUnitSheet(targetKey: string, sourceKey: string, tint: number, alpha: number, decoration?: UnitSheetDecoration) {
|
||||
private createTintedUnitSheet(targetKey: string, sourceKey: string, tint: number, alpha: number) {
|
||||
if (this.textures.exists(targetKey) || !this.textures.exists(sourceKey)) {
|
||||
return;
|
||||
}
|
||||
@@ -409,131 +457,12 @@ export class BootScene extends Phaser.Scene {
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
context.globalCompositeOperation = 'source-over';
|
||||
context.globalAlpha = 1;
|
||||
if (decoration) {
|
||||
this.decorateUnitSheet(context, decoration, canvas.width, canvas.height);
|
||||
}
|
||||
this.textures.addSpriteSheet(targetKey, canvas as unknown as HTMLImageElement, {
|
||||
frameWidth: unitSheetFrameSize,
|
||||
frameHeight: unitSheetFrameSize
|
||||
});
|
||||
}
|
||||
|
||||
private decorateUnitSheet(context: CanvasRenderingContext2D, decoration: UnitSheetDecoration, width: number, height: number) {
|
||||
const columns = Math.floor(width / unitSheetFrameSize);
|
||||
const rows = Math.floor(height / unitSheetFrameSize);
|
||||
|
||||
for (let row = 0; row < rows; row += 1) {
|
||||
for (let column = 0; column < columns; column += 1) {
|
||||
this.drawUnitDecoration(context, decoration, column * unitSheetFrameSize, row * unitSheetFrameSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private drawUnitDecoration(context: CanvasRenderingContext2D, decoration: UnitSheetDecoration, x: number, y: number) {
|
||||
context.save();
|
||||
context.lineCap = 'round';
|
||||
context.lineJoin = 'round';
|
||||
|
||||
if (decoration === 'zhaoYun') {
|
||||
context.globalAlpha = 0.82;
|
||||
context.fillStyle = '#f4fbff';
|
||||
context.beginPath();
|
||||
context.moveTo(x + 128, y + 106);
|
||||
context.lineTo(x + 86, y + 262);
|
||||
context.lineTo(x + 142, y + 246);
|
||||
context.lineTo(x + 174, y + 112);
|
||||
context.closePath();
|
||||
context.fill();
|
||||
context.strokeStyle = '#d7f2ff';
|
||||
context.lineWidth = 14;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 92, y + 62);
|
||||
context.lineTo(x + 236, y + 266);
|
||||
context.stroke();
|
||||
context.strokeStyle = '#4b87c8';
|
||||
context.lineWidth = 8;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 100, y + 128);
|
||||
context.lineTo(x + 202, y + 242);
|
||||
context.stroke();
|
||||
context.fillStyle = '#f8fbff';
|
||||
context.fillRect(x + 150, y + 38, 12, 42);
|
||||
} else if (decoration === 'zhugeLiang') {
|
||||
context.globalAlpha = 0.82;
|
||||
context.fillStyle = '#eef2df';
|
||||
context.beginPath();
|
||||
context.moveTo(x + 118, y + 112);
|
||||
context.lineTo(x + 96, y + 252);
|
||||
context.lineTo(x + 198, y + 252);
|
||||
context.lineTo(x + 176, y + 112);
|
||||
context.closePath();
|
||||
context.fill();
|
||||
context.strokeStyle = '#d8b15f';
|
||||
context.lineWidth = 8;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 142, y + 88);
|
||||
context.lineTo(x + 190, y + 72);
|
||||
context.stroke();
|
||||
context.strokeStyle = '#f7f0d6';
|
||||
context.lineWidth = 11;
|
||||
for (let index = 0; index < 5; index += 1) {
|
||||
context.beginPath();
|
||||
context.moveTo(x + 206, y + 208);
|
||||
context.lineTo(x + 178 + index * 18, y + 132 + Math.abs(index - 2) * 8);
|
||||
context.stroke();
|
||||
}
|
||||
context.fillStyle = '#f7f0d6';
|
||||
context.beginPath();
|
||||
context.ellipse(x + 206, y + 208, 18, 26, -0.5, 0, Math.PI * 2);
|
||||
context.fill();
|
||||
} else if (decoration === 'jiangWei') {
|
||||
context.globalAlpha = 0.84;
|
||||
context.strokeStyle = '#74f0c8';
|
||||
context.lineWidth = 14;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 92, y + 122);
|
||||
context.lineTo(x + 214, y + 244);
|
||||
context.stroke();
|
||||
context.strokeStyle = '#f1f5e8';
|
||||
context.lineWidth = 10;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 226, y + 60);
|
||||
context.lineTo(x + 118, y + 274);
|
||||
context.stroke();
|
||||
context.fillStyle = '#edf4dc';
|
||||
context.fillRect(x + 194, y + 176, 34, 54);
|
||||
context.strokeStyle = '#2f6e64';
|
||||
context.lineWidth = 5;
|
||||
context.strokeRect(x + 194, y + 176, 34, 54);
|
||||
} else {
|
||||
context.globalAlpha = 0.86;
|
||||
context.fillStyle = '#111522';
|
||||
context.beginPath();
|
||||
context.moveTo(x + 102, y + 102);
|
||||
context.lineTo(x + 70, y + 266);
|
||||
context.lineTo(x + 218, y + 266);
|
||||
context.lineTo(x + 194, y + 102);
|
||||
context.closePath();
|
||||
context.fill();
|
||||
context.strokeStyle = '#d8b15f';
|
||||
context.lineWidth = 8;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 86, y + 118);
|
||||
context.lineTo(x + 214, y + 118);
|
||||
context.stroke();
|
||||
context.strokeStyle = '#9d3c3c';
|
||||
context.lineWidth = 12;
|
||||
context.beginPath();
|
||||
context.moveTo(x + 212, y + 66);
|
||||
context.lineTo(x + 232, y + 238);
|
||||
context.stroke();
|
||||
context.fillStyle = '#71272f';
|
||||
context.fillRect(x + 218, y + 72, 48, 42);
|
||||
}
|
||||
|
||||
context.restore();
|
||||
}
|
||||
|
||||
private createUnitAnimations() {
|
||||
animatedUnitSheets.forEach(({ key }) => {
|
||||
(['south', 'east', 'north', 'west'] as UnitDirection[]).forEach((direction) => {
|
||||
|
||||